From a26e90b2024ca3dbdccfd44ae5a33e11aafa7ae2 Mon Sep 17 00:00:00 2001 From: "Dr. Tobias Quathamer" Date: Fri, 5 Jan 2024 00:12:20 +0100 Subject: [PATCH 001/294] Initial commit of url_replace addon. This closes https://github.com/friendica/friendica/issues/13220 --- url_replace/LICENSE.md | 21 ++++++ url_replace/README.md | 17 +++++ url_replace/lang/C/messages.po | 50 +++++++++++++ url_replace/templates/admin.tpl | 5 ++ url_replace/url_replace.php | 127 ++++++++++++++++++++++++++++++++ 5 files changed, 220 insertions(+) create mode 100644 url_replace/LICENSE.md create mode 100644 url_replace/README.md create mode 100644 url_replace/lang/C/messages.po create mode 100644 url_replace/templates/admin.tpl create mode 100644 url_replace/url_replace.php diff --git a/url_replace/LICENSE.md b/url_replace/LICENSE.md new file mode 100644 index 00000000..09dc8f64 --- /dev/null +++ b/url_replace/LICENSE.md @@ -0,0 +1,21 @@ +# MIT License + +Copyright © 2024 Dr. Tobias Quathamer + +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/url_replace/README.md b/url_replace/README.md new file mode 100644 index 00000000..278de91b --- /dev/null +++ b/url_replace/README.md @@ -0,0 +1,17 @@ +# URL replace + +This addon will replace all occurrences of specified URLs with the address of +alternative servers in all displayed postings on a Friendica node. + +You can use this to switch from Twitter (or X) to a nitter instance, from +YouTube to an invidious instance, or from some news sites to 12ft.io. + +Note: If you are using the twitter connector on your server, the links to the +contacts profile pages will not be replaced by this addon. Only links in the +body of the postings are affected. + +## Why + +- Access a website without JavaScript enabled to prevent JavaScript analytics + and potential IP-based tracking +- Avoid seeing ads on YouTube videos diff --git a/url_replace/lang/C/messages.po b/url_replace/lang/C/messages.po new file mode 100644 index 00000000..c09ad6d9 --- /dev/null +++ b/url_replace/lang/C/messages.po @@ -0,0 +1,50 @@ +# ADDON url_replace +# Copyright (C) +# This file is distributed under the same license as the Friendica url_replace addon package. +# +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-01-05 00:06+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: url_replace.php:54 +msgid "Nitter server" +msgstr "" + +#: url_replace.php:56 +msgid "Specify the URL with protocol. The default is https://nitter.net." +msgstr "" + +#: url_replace.php:62 +msgid "Invidious server" +msgstr "" + +#: url_replace.php:64 +msgid "Specify the URL with protocol. The default is https://yewtu.be." +msgstr "" + +#: url_replace.php:70 +msgid "Sites which are accessed through 12ft.io" +msgstr "" + +#: url_replace.php:72 +msgid "Specify the URLs with protocol, one per line." +msgstr "" + +#: url_replace.php:76 +msgid "Save settings" +msgstr "" + +#: url_replace.php:125 +msgid "(URL replace addon enabled for X, YouTube and some news sites.)" +msgstr "" diff --git a/url_replace/templates/admin.tpl b/url_replace/templates/admin.tpl new file mode 100644 index 00000000..b99e6355 --- /dev/null +++ b/url_replace/templates/admin.tpl @@ -0,0 +1,5 @@ +{{include file="field_input.tpl" field=$nitter_server}} +{{include file="field_input.tpl" field=$invidious_server}} +{{include file="field_textarea.tpl" field=$twelvefeet_sites}} + +
diff --git a/url_replace/url_replace.php b/url_replace/url_replace.php new file mode 100644 index 00000000..51bc10fe --- /dev/null +++ b/url_replace/url_replace.php @@ -0,0 +1,127 @@ + + * Maintainer: Dr. Tobias Quathamer + */ +use Friendica\Core\Hook; +use Friendica\Core\Renderer; +use Friendica\DI; + +function url_replace_install() +{ + Hook::register('prepare_body_final', 'addon/url_replace/url_replace.php', 'url_replace_render'); +} + +/** + * Handle sent data from admin settings + */ +function url_replace_addon_admin_post() +{ + DI::config()->set('url_replace', 'nitter_server', rtrim(trim($_POST['nitter_server']), '/')); + DI::config()->set('url_replace', 'invidious_server', rtrim(trim($_POST['invidious_server']), '/')); + // Convert twelvefeet_sites into an array before setting the new value + $twelvefeet_sites = explode(PHP_EOL, $_POST['twelvefeet_sites']); + // Normalize URLs by using lower case, removing a trailing slash and whitespace + $twelvefeet_sites = array_map(fn ($value): string => rtrim(trim(strtolower($value)), '/'), $twelvefeet_sites); + // Do not store empty lines or duplicates + $twelvefeet_sites = array_filter($twelvefeet_sites, fn ($value): bool => !empty($value)); + $twelvefeet_sites = array_unique($twelvefeet_sites); + // Ensure a protocol and default to HTTPS + $twelvefeet_sites = array_map( + fn ($value): string => substr($value, 0, 4) !== 'http' ? 'https://'.$value : $value, + $twelvefeet_sites + ); + asort($twelvefeet_sites); + DI::config()->set('url_replace', 'twelvefeet_sites', $twelvefeet_sites); +} + +/** + * Hook into admin settings to enable choosing a different server + * for twitter, youtube, and news sites. + */ +function url_replace_addon_admin(string &$o) +{ + $nitter_server = DI::config()->get('url_replace', 'nitter_server'); + $invidious_server = DI::config()->get('url_replace', 'invidious_server'); + $twelvefeet_sites = implode(PHP_EOL, DI::config()->get('url_replace', 'twelvefeet_sites')); + $t = Renderer::getMarkupTemplate('admin.tpl', 'addon/url_replace/'); + $o = Renderer::replaceMacros($t, [ + '$nitter_server' => [ + 'nitter_server', + DI::l10n()->t('Nitter server'), + $nitter_server, + DI::l10n()->t('Specify the URL with protocol. The default is https://nitter.net.'), + null, + 'placeholder="https://nitter.net"', + ], + '$invidious_server' => [ + 'invidious_server', + DI::l10n()->t('Invidious server'), + $invidious_server, + DI::l10n()->t('Specify the URL with protocol. The default is https://yewtu.be.'), + null, + 'placeholder="https://yewtu.be"', + ], + '$twelvefeet_sites' => [ + 'twelvefeet_sites', + DI::l10n()->t('Sites which are accessed through 12ft.io'), + $twelvefeet_sites, + DI::l10n()->t('Specify the URLs with protocol, one per line.'), + null, + 'rows=6' + ], + '$submit' => DI::l10n()->t('Save settings'), + ]); +} + +/** + * Replace proprietary URLs with their specified counterpart + */ +function url_replace_render(array &$b) +{ + $replaced = false; + + $nitter_server = DI::config()->get('url_replace', 'nitter_server'); + if (empty($nitter_server)) { + $nitter_server = 'https://nitter.net'; + } + + $invidious_server = DI::config()->get('url_replace', 'invidious_server'); + if (empty($invidious_server)) { + $invidious_server = 'https://yewtu.be'; + } + + // Handle some of twitter and youtube + $replacements = [ + 'https://mobile.twitter.com' => $nitter_server, + 'https://twitter.com' => $nitter_server, + 'https://mobile.x.com' => $nitter_server, + 'https://x.com' => $nitter_server, + 'https://www.youtube.com' => $invidious_server, + 'https://youtube.com' => $invidious_server, + 'https://m.youtube.com' => $invidious_server, + 'https://youtu.be' => $invidious_server, + ]; + foreach ($replacements as $server => $replacement) { + if (strpos($b['html'], $server) !== false) { + $b['html'] = str_replace($server, $replacement, $b['html']); + $replaced = true; + } + } + + $twelvefeet_sites = DI::config()->get('url_replace', 'twelvefeet_sites'); + foreach ($twelvefeet_sites as $twelvefeet_site) { + if (strpos($b['html'], $twelvefeet_site) !== false) { + $b['html'] = str_replace($twelvefeet_site, 'https://12ft.io/'.$twelvefeet_site, $b['html']); + $replaced = true; + } + } + + + if ($replaced) { + $b['html'] .= '

' . DI::l10n()->t('(URL replace addon enabled for X, YouTube and some news sites.)') . '

'; + } +} From bddb7f4d49d1f36120b0054d2763aa7c89d03f17 Mon Sep 17 00:00:00 2001 From: "Dr. Tobias Quathamer" Date: Mon, 8 Jan 2024 10:36:21 +0100 Subject: [PATCH 002/294] Fix PHP warning and use quotes --- url_replace/url_replace.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/url_replace/url_replace.php b/url_replace/url_replace.php index 51bc10fe..4c61b6c2 100644 --- a/url_replace/url_replace.php +++ b/url_replace/url_replace.php @@ -71,7 +71,7 @@ function url_replace_addon_admin(string &$o) $twelvefeet_sites, DI::l10n()->t('Specify the URLs with protocol, one per line.'), null, - 'rows=6' + 'rows="6"' ], '$submit' => DI::l10n()->t('Save settings'), ]); @@ -113,6 +113,9 @@ function url_replace_render(array &$b) } $twelvefeet_sites = DI::config()->get('url_replace', 'twelvefeet_sites'); + if (empty($twelvefeet_sites)) { + $twelvefeet_sites = []; + } foreach ($twelvefeet_sites as $twelvefeet_site) { if (strpos($b['html'], $twelvefeet_site) !== false) { $b['html'] = str_replace($twelvefeet_site, 'https://12ft.io/'.$twelvefeet_site, $b['html']); From 13fd713b66cdce186f30cb70bdcf237814f961b5 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 12 Jan 2024 01:16:01 -0500 Subject: [PATCH 003/294] [various] Rename ICanHandleHttpResponses->getBody to getBodyString - Depends on https://github.com/friendica/friendica/pull/13826 --- bluesky/bluesky.php | 14 +++++++------- discourse/discourse.php | 4 ++-- dwpost/dwpost.php | 2 +- ijpost/ijpost.php | 2 +- libertree/libertree.php | 2 +- ljpost/ljpost.php | 2 +- mailstream/mailstream.php | 2 +- mastodoncustomemojis/mastodoncustomemojis.php | 2 +- openstreetmap/openstreetmap.php | 2 +- tumblr/tumblr.php | 10 +++++----- twitter/twitter.php | 4 ++-- webdav_storage/src/WebDav.php | 4 ++-- wppost/wppost.php | 2 +- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index dac95437..a2c85ad3 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1111,11 +1111,11 @@ function bluesky_process_post(stdClass $post, int $uid, int $post_reason, int $l $uri = bluesky_get_uri($post); if ($id = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $uid])) { - return $id['id']; + return $id['id']; } if ($id = Post::selectFirst(['id'], ['extid' => $uri, 'uid' => $uid])) { - return $id['id']; + return $id['id']; } Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); @@ -1251,7 +1251,7 @@ function bluesky_get_text(stdClass $record, int $uri_id): string $url = DI::baseUrl() . '/search?tag=' . urlencode($feature->tag); $linktext = '#' . $feature->tag; break; - + default: Logger::notice('Unhandled feature type', ['type' => $feature->$type, 'feature' => $feature, 'record' => $record]); break; @@ -1736,13 +1736,13 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s } if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['error' => json_decode($curlResult->getBody()) ?: $curlResult->getBody()]); + Logger::notice('API Error', ['error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]); DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); return null; } DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); - return json_decode($curlResult->getBody()); + return json_decode($curlResult->getBodyString()); } function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass @@ -1767,9 +1767,9 @@ function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEF } if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['error' => json_decode($curlResult->getBody()) ?: $curlResult->getBody()]); + Logger::notice('API Error', ['error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]); return null; } - return json_decode($curlResult->getBody()); + return json_decode($curlResult->getBodyString()); } diff --git a/discourse/discourse.php b/discourse/discourse.php index 3d27c5b0..298b3f3e 100644 --- a/discourse/discourse.php +++ b/discourse/discourse.php @@ -126,7 +126,7 @@ function discourse_fetch_post($host, $topic, $pid) return false; } - $raw = $curlResult->getBody(); + $raw = $curlResult->getBodyString(); $data = json_decode($raw, true); $posts = $data['post_stream']['posts']; foreach($posts as $post) { @@ -162,7 +162,7 @@ function discourse_fetch_post_from_api(&$message, $post, $host) return false; } - $raw = $curlResult->getBody(); + $raw = $curlResult->getBodyString(); $data = json_decode($raw, true); if (empty($data)) { return false; diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 6c1742e4..4ad5021f 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -192,7 +192,7 @@ EOT; Logger::debug('dwpost: data: ' . $xml); if ($dw_blog !== 'test') { - $x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBody(); + $x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } Logger::info('posted to dreamwidth: ' . ($x) ? $x : ''); diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index 55d3fb05..885bc289 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -186,7 +186,7 @@ EOT; Logger::debug('ijpost: data: ' . $xml); if ($ij_blog !== 'test') { - $x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBody(); + $x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } Logger::info('posted to insanejournal: ' . $x ? $x : ''); } diff --git a/libertree/libertree.php b/libertree/libertree.php index c0f896c0..f69c0aab 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -201,7 +201,7 @@ function libertree_send(array &$b) // 'token' => $ltree_api_token ]; - $result = DI::httpClient()->post($ltree_blog, $params)->getBody(); + $result = DI::httpClient()->post($ltree_blog, $params)->getBodyString(); Logger::notice('libertree: ' . $result); } } diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index f6f2b79a..fac44767 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -207,7 +207,7 @@ EOT; Logger::debug('ljpost: data: ' . $xml); if ($lj_blog !== 'test') { - $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBody(); + $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } Logger::info('posted to livejournal: ' . ($x) ? $x : ''); diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index d76ccf86..968ee4c0 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -221,7 +221,7 @@ function mailstream_do_images(array &$item, array &$attachments) continue; } $attachments[$url] = [ - 'data' => $curlResult->getBody(), + 'data' => $curlResult->getBodyString(), 'guid' => hash('crc32', $url), 'filename' => basename($components['path']), 'type' => $curlResult->getContentType() diff --git a/mastodoncustomemojis/mastodoncustomemojis.php b/mastodoncustomemojis/mastodoncustomemojis.php index c84f1a4f..f67054a1 100644 --- a/mastodoncustomemojis/mastodoncustomemojis.php +++ b/mastodoncustomemojis/mastodoncustomemojis.php @@ -82,7 +82,7 @@ function mastodoncustomemojis_fetch_custom_emojis_for_url($api_base_url) $fetchResult = DI::httpClient()->fetchFull($api_url); if ($fetchResult->isSuccess()) { - $emojis_array = json_decode($fetchResult->getBody(), true); + $emojis_array = json_decode($fetchResult->getBodyString(), true); if (is_array($emojis_array) && count($emojis_array)) { foreach ($emojis_array as $emoji) { diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index 3b7c4a58..ae22aff0 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -121,7 +121,7 @@ function openstreetmap_get_coordinates(array &$b) if (is_null($j)) { $curlResult = DI::httpClient()->get($nomserver . $args); if ($curlResult->isSuccess()) { - $j = json_decode($curlResult->getBody(), true); + $j = json_decode($curlResult->getBodyString(), true); DI::cache()->set($cachekey, $j, Duration::MONTH); } } diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 4d5368b8..d6508ff8 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -1244,7 +1244,7 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array } catch (\Exception $e) { return null; } - $html = $curlResult->getBody(); + $html = $curlResult->getBodyString(); if (empty($html)) { return null; } @@ -1372,7 +1372,7 @@ function tumblr_delete(int $uid, string $url, array $parameters): stdClass */ function tumblr_format_result(ICanHandleHttpResponses $curlResult): stdClass { - $result = json_decode($curlResult->getBody()); + $result = json_decode($curlResult->getBodyString()); if (empty($result) || empty($result->meta)) { $result = new stdClass; $result->meta = new stdClass; @@ -1426,11 +1426,11 @@ function tumblr_get_token(int $uid, string $code = ''): string $curlResult = DI::httpClient()->post('https://api.tumblr.com/v2/oauth2/token', $parameters); if (!$curlResult->isSuccess()) { - Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBody(), 'parameters' => $parameters]); + Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); return ''; } - $result = json_decode($curlResult->getBody()); + $result = json_decode($curlResult->getBodyString()); if (empty($result)) { Logger::info('Invalid result when updating token', ['uid' => $uid]); return ''; @@ -1479,7 +1479,7 @@ function tumblr_exchange_token(int $uid): stdClass ]); $response = $client->post('oauth2/exchange', ['auth' => 'oauth']); - return json_decode($response->getBody()->getContents()); + return json_decode($response->getBodyString()->getContents()); } catch (RequestException $exception) { Logger::notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); return new stdClass; diff --git a/twitter/twitter.php b/twitter/twitter.php index b01345b7..8c906daf 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -362,7 +362,7 @@ function twitter_post(int $uid, string $url, string $type, array $data): stdClas ]); $response = $client->post($url, ['auth' => 'oauth', $type => $data]); - $body = $response->getBody()->getContents(); + $body = $response->getBodyString()->getContents(); $status = [ 'code' => $response->getStatusCode(), @@ -399,7 +399,7 @@ function twitter_test_connection(int $uid) $status = [ 'code' => $response->getStatusCode(), 'reason' => $response->getReasonPhrase(), - 'content' => $response->getBody()->getContents() + 'content' => $response->getBodyString()->getContents() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); Logger::info('Test successful', ['uid' => $uid]); diff --git a/webdav_storage/src/WebDav.php b/webdav_storage/src/WebDav.php index de9fc476..ddf2dae0 100644 --- a/webdav_storage/src/WebDav.php +++ b/webdav_storage/src/WebDav.php @@ -113,7 +113,7 @@ class WebDav implements ICanWriteToStorage $response = $this->client->request('propfind', $uri, $opts); $responseDoc = new \DOMDocument(); - $responseDoc->loadXML($response->getBody()); + $responseDoc->loadXML($response->getBodyString()); $responseDoc->formatOutput = true; $xpath = new \DOMXPath($responseDoc); @@ -205,7 +205,7 @@ class WebDav implements ICanWriteToStorage throw new ReferenceStorageException(sprintf('Invalid reference %s', $reference)); } - return $response->getBody(); + return $response->getBodyString(); } /** diff --git a/wppost/wppost.php b/wppost/wppost.php index 0405f78a..e27079aa 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -269,7 +269,7 @@ EOT; Logger::debug('wppost: data: ' . $xml); if ($wp_blog !== 'test') { - $x = DI::httpClient()->post($wp_blog, $xml)->getBody(); + $x = DI::httpClient()->post($wp_blog, $xml)->getBodyString(); } Logger::info('posted to wordpress: ' . (($x) ? $x : '')); } From 4dd903b473e914b1f8814220dff50fe1f2baf480 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 14 Jan 2024 19:21:08 +0000 Subject: [PATCH 004/294] New addon "tesseract" for OCR --- tesseract/composer.json | 5 + tesseract/composer.lock | 66 +++ tesseract/tesseract.php | 33 ++ tesseract/vendor/autoload.php | 7 + tesseract/vendor/composer/ClassLoader.php | 445 +++++++++++++++ tesseract/vendor/composer/LICENSE | 21 + .../vendor/composer/autoload_classmap.php | 9 + .../vendor/composer/autoload_namespaces.php | 9 + tesseract/vendor/composer/autoload_psr4.php | 10 + tesseract/vendor/composer/autoload_real.php | 55 ++ tesseract/vendor/composer/autoload_static.php | 31 ++ tesseract/vendor/composer/installed.json | 48 ++ .../thiagoalessio/tesseract_ocr/.appveyor.yml | 14 + .../thiagoalessio/tesseract_ocr/MIT-LICENSE | 19 + .../thiagoalessio/tesseract_ocr/README.md | 508 ++++++++++++++++++ .../thiagoalessio/tesseract_ocr/codecov.yml | 4 + .../thiagoalessio/tesseract_ocr/composer.json | 35 ++ .../tesseract_ocr/src/Command.php | 80 +++ .../src/FeatureNotAvailableException.php | 7 + .../tesseract_ocr/src/FriendlyErrors.php | 120 +++++ .../src/ImageNotFoundException.php | 7 + .../src/NoWritePermissionsForOutputFile.php | 7 + .../tesseract_ocr/src/Option.php | 79 +++ .../tesseract_ocr/src/Process.php | 83 +++ .../src/TesseractNotFoundException.php | 7 + .../tesseract_ocr/src/TesseractOCR.php | 181 +++++++ .../src/TesseractOcrException.php | 7 + .../src/UnsuccessfulCommandException.php | 7 + 28 files changed, 1904 insertions(+) create mode 100644 tesseract/composer.json create mode 100644 tesseract/composer.lock create mode 100644 tesseract/tesseract.php create mode 100644 tesseract/vendor/autoload.php create mode 100644 tesseract/vendor/composer/ClassLoader.php create mode 100644 tesseract/vendor/composer/LICENSE create mode 100644 tesseract/vendor/composer/autoload_classmap.php create mode 100644 tesseract/vendor/composer/autoload_namespaces.php create mode 100644 tesseract/vendor/composer/autoload_psr4.php create mode 100644 tesseract/vendor/composer/autoload_real.php create mode 100644 tesseract/vendor/composer/autoload_static.php create mode 100644 tesseract/vendor/composer/installed.json create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/.appveyor.yml create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/MIT-LICENSE create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/README.md create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/codecov.yml create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/composer.json create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/Command.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/FeatureNotAvailableException.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/FriendlyErrors.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/ImageNotFoundException.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/NoWritePermissionsForOutputFile.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/Option.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/Process.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractNotFoundException.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractOCR.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractOcrException.php create mode 100644 tesseract/vendor/thiagoalessio/tesseract_ocr/src/UnsuccessfulCommandException.php diff --git a/tesseract/composer.json b/tesseract/composer.json new file mode 100644 index 00000000..2a0937c0 --- /dev/null +++ b/tesseract/composer.json @@ -0,0 +1,5 @@ +{ + "require": { + "thiagoalessio/tesseract_ocr": "^2.13" + } +} diff --git a/tesseract/composer.lock b/tesseract/composer.lock new file mode 100644 index 00000000..036868e7 --- /dev/null +++ b/tesseract/composer.lock @@ -0,0 +1,66 @@ +{ + "_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": "778b5479cb5d2b31b57f40473a87f8eb", + "packages": [ + { + "name": "thiagoalessio/tesseract_ocr", + "version": "2.13.0", + "source": { + "type": "git", + "url": "https://github.com/thiagoalessio/tesseract-ocr-for-php.git", + "reference": "232a8cb9d571992f9bd1e263f2f6909cf6c173a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thiagoalessio/tesseract-ocr-for-php/zipball/232a8cb9d571992f9bd1e263f2f6909cf6c173a1", + "reference": "232a8cb9d571992f9bd1e263f2f6909cf6c173a1", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/php-code-coverage": "^2.2.4 || ^9.0.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "thiagoalessio\\TesseractOCR\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "thiagoalessio", + "email": "thiagoalessio@me.com" + } + ], + "description": "A wrapper to work with Tesseract OCR inside PHP.", + "keywords": [ + "OCR", + "Tesseract", + "text recognition" + ], + "time": "2023-10-05T21:14:48+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "platform-overrides": { + "php": "7.2" + }, + "plugin-api-version": "1.1.0" +} diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php new file mode 100644 index 00000000..3c61273f --- /dev/null +++ b/tesseract/tesseract.php @@ -0,0 +1,33 @@ + + */ + +use Friendica\Core\Hook; +use Friendica\Core\Logger; +use Friendica\Core\System; +use thiagoalessio\TesseractOCR\TesseractOCR; + +require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; + +function tesseract_install() +{ + Hook::register('ocr-detection', __FILE__, 'tesseract_ocr_detection'); + + Logger::notice('installed tesseract'); +} + +function tesseract_ocr_detection(&$media) +{ + $ocr = new TesseractOCR(); + try { + $ocr->tempDir(System::getTempPath()); + $ocr->imageData($media['img_str'], strlen($media['img_str'])); + $media['description'] = $ocr->run(); + } catch (\Throwable $th) { + Logger::info('Error calling TesseractOCR', ['message' => $th->getMessage()]); + } +} diff --git a/tesseract/vendor/autoload.php b/tesseract/vendor/autoload.php new file mode 100644 index 00000000..1238ecea --- /dev/null +++ b/tesseract/vendor/autoload.php @@ -0,0 +1,7 @@ + + * 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 http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // 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; + + 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); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * 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; + } + + 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/tesseract/vendor/composer/LICENSE b/tesseract/vendor/composer/LICENSE new file mode 100644 index 00000000..f27399a0 --- /dev/null +++ b/tesseract/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +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/tesseract/vendor/composer/autoload_classmap.php b/tesseract/vendor/composer/autoload_classmap.php new file mode 100644 index 00000000..7a91153b --- /dev/null +++ b/tesseract/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + array($vendorDir . '/thiagoalessio/tesseract_ocr/src'), +); diff --git a/tesseract/vendor/composer/autoload_real.php b/tesseract/vendor/composer/autoload_real.php new file mode 100644 index 00000000..10af9c56 --- /dev/null +++ b/tesseract/vendor/composer/autoload_real.php @@ -0,0 +1,55 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit695d781792f754383aa61632167d066e::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); + + return $loader; + } +} diff --git a/tesseract/vendor/composer/autoload_static.php b/tesseract/vendor/composer/autoload_static.php new file mode 100644 index 00000000..59b66053 --- /dev/null +++ b/tesseract/vendor/composer/autoload_static.php @@ -0,0 +1,31 @@ + + array ( + 'thiagoalessio\\TesseractOCR\\' => 27, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'thiagoalessio\\TesseractOCR\\' => + array ( + 0 => __DIR__ . '/..' . '/thiagoalessio/tesseract_ocr/src', + ), + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit695d781792f754383aa61632167d066e::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit695d781792f754383aa61632167d066e::$prefixDirsPsr4; + + }, null, ClassLoader::class); + } +} diff --git a/tesseract/vendor/composer/installed.json b/tesseract/vendor/composer/installed.json new file mode 100644 index 00000000..70bcc01c --- /dev/null +++ b/tesseract/vendor/composer/installed.json @@ -0,0 +1,48 @@ +[ + { + "name": "thiagoalessio/tesseract_ocr", + "version": "2.13.0", + "version_normalized": "2.13.0.0", + "source": { + "type": "git", + "url": "https://github.com/thiagoalessio/tesseract-ocr-for-php.git", + "reference": "232a8cb9d571992f9bd1e263f2f6909cf6c173a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thiagoalessio/tesseract-ocr-for-php/zipball/232a8cb9d571992f9bd1e263f2f6909cf6c173a1", + "reference": "232a8cb9d571992f9bd1e263f2f6909cf6c173a1", + "shasum": "" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/php-code-coverage": "^2.2.4 || ^9.0.0" + }, + "time": "2023-10-05T21:14:48+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "thiagoalessio\\TesseractOCR\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "thiagoalessio", + "email": "thiagoalessio@me.com" + } + ], + "description": "A wrapper to work with Tesseract OCR inside PHP.", + "keywords": [ + "OCR", + "Tesseract", + "text recognition" + ] + } +] diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/.appveyor.yml b/tesseract/vendor/thiagoalessio/tesseract_ocr/.appveyor.yml new file mode 100644 index 00000000..1debc1a1 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/.appveyor.yml @@ -0,0 +1,14 @@ +--- +build: false + +install: + - ps: Set-Service wuauserv -StartupType Manual + - choco install php + - choco install capture2text --version 3.9 + - choco install composer + - refreshenv + - cd %APPVEYOR_BUILD_FOLDER% + - composer install + +test_script: + - php tests\run.php unit e2e diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/MIT-LICENSE b/tesseract/vendor/thiagoalessio/tesseract_ocr/MIT-LICENSE new file mode 100644 index 00000000..448104d6 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/MIT-LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2012-2021 Thiago Alessio Pereira + +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/tesseract/vendor/thiagoalessio/tesseract_ocr/README.md b/tesseract/vendor/thiagoalessio/tesseract_ocr/README.md new file mode 100644 index 00000000..b828344c --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/README.md @@ -0,0 +1,508 @@ +Tesseract OCR for PHP + +# Tesseract OCR for PHP + +A wrapper to work with Tesseract OCR inside PHP. + +[![CI][ci_badge]][ci] +[![AppVeyor][appveyor_badge]][appveyor] +[![Codacy][codacy_badge]][codacy] +[![Test Coverage][test_coverage_badge]][test_coverage] +
+[![Latest Stable Version][stable_version_badge]][packagist] +[![Total Downloads][total_downloads_badge]][packagist] +[![Monthly Downloads][monthly_downloads_badge]][packagist] + +## Installation + +Via [Composer][]: + + $ composer require thiagoalessio/tesseract_ocr + +:bangbang: **This library depends on [Tesseract OCR][], version _3.02_ or later.** + +
+ +### ![][windows_icon] Note for Windows users + +There are [many ways][tesseract_installation_on_windows] to install +[Tesseract OCR][] on your system, but if you just want something quick to +get up and running, I recommend installing the [Capture2Text][] package with +[Chocolatey][]. + + choco install capture2text --version 3.9 + +:warning: Recent versions of [Capture2Text][] stopped shipping the `tesseract` binary. + +
+ +### ![][macos_icon] Note for macOS users + +With [MacPorts][] you can install support for individual languages, like so: + + $ sudo port install tesseract- + +But that is not possible with [Homebrew][]. It comes only with **English** support +by default, so if you intend to use it for other language, the quickest solution +is to install them all: + + $ brew install tesseract tesseract-lang + +
+ +## Usage + +### Basic usage + + + +```php +use thiagoalessio\TesseractOCR\TesseractOCR; +echo (new TesseractOCR('text.png')) + ->run(); +``` + +``` +The quick brown fox +jumps over +the lazy dog. +``` + +
+ +### Other languages + + + +```php +use thiagoalessio\TesseractOCR\TesseractOCR; +echo (new TesseractOCR('german.png')) + ->lang('deu') + ->run(); +``` + +``` +Bülowstraße +``` + +
+ +### Multiple languages + + + +```php +use thiagoalessio\TesseractOCR\TesseractOCR; +echo (new TesseractOCR('mixed-languages.png')) + ->lang('eng', 'jpn', 'spa') + ->run(); +``` + +``` +I eat すし y Pollo +``` + +
+ +### Inducing recognition + + + +```php +use thiagoalessio\TesseractOCR\TesseractOCR; +echo (new TesseractOCR('8055.png')) + ->allowlist(range('A', 'Z')) + ->run(); +``` + +``` +BOSS +``` + +
+ +### Breaking CAPTCHAs + +Yes, I know some of you might want to use this library for the *noble* purpose +of breaking CAPTCHAs, so please take a look at this comment: + + + +## API + +### run + +Executes a `tesseract` command, optionally receiving an integer as `timeout`, +in case you experience stalled tesseract processes. + +```php +$ocr = new TesseractOCR(); +$ocr->run(); +``` +```php +$ocr = new TesseractOCR(); +$timeout = 500; +$ocr->run($timeout); +``` + +### image + +Define the path of an image to be recognized by `tesseract`. + +```php +$ocr = new TesseractOCR(); +$ocr->image('/path/to/image.png'); +$ocr->run(); +``` + +### imageData + +Set the image to be recognized by `tesseract` from a string, with its size. +This can be useful when dealing with files that are already loaded in memory. +You can easily retrieve the image data and size of an image object : +```php +//Using Imagick +$data = $img->getImageBlob(); +$size = $img->getImageLength(); +//Using GD +ob_start(); +// Note that you can use any format supported by tesseract +imagepng($img, null, 0); +$size = ob_get_length(); +$data = ob_get_clean(); + +$ocr = new TesseractOCR(); +$ocr->imageData($data, $size); +$ocr->run(); +``` + +### executable + +Define a custom location of the `tesseract` executable, +if by any reason it is not present in the `$PATH`. + +```php +echo (new TesseractOCR('img.png')) + ->executable('/path/to/tesseract') + ->run(); +``` + +### version + +Returns the current version of `tesseract`. + +```php +echo (new TesseractOCR())->version(); +``` + +### availableLanguages + +Returns a list of available languages/scripts. + +```php +foreach((new TesseractOCR())->availableLanguages() as $lang) echo $lang; +``` + +__More info:__ + +### tessdataDir + +Specify a custom location for the tessdata directory. + +```php +echo (new TesseractOCR('img.png')) + ->tessdataDir('/path') + ->run(); +``` + +### userWords + +Specify the location of user words file. + +This is a plain text file containing a list of words that you want to be +considered as a normal dictionary words by `tesseract`. + +Useful when dealing with contents that contain technical terminology, jargon, +etc. + +``` +$ cat /path/to/user-words.txt +foo +bar +``` + +```php +echo (new TesseractOCR('img.png')) + ->userWords('/path/to/user-words.txt') + ->run(); +``` + +### userPatterns + +Specify the location of user patterns file. + +If the contents you are dealing with have known patterns, this option can help +a lot tesseract's recognition accuracy. + +``` +$ cat /path/to/user-patterns.txt' +1-\d\d\d-GOOG-441 +www.\n\\\*.com +``` + +```php +echo (new TesseractOCR('img.png')) + ->userPatterns('/path/to/user-patterns.txt') + ->run(); +``` + +### lang + +Define one or more languages to be used during the recognition. +A complete list of available languages can be found at: + + +__Tip from [@daijiale][]:__ Use the combination `->lang('chi_sim', 'chi_tra')` +for proper recognition of Chinese. + +```php + echo (new TesseractOCR('img.png')) + ->lang('lang1', 'lang2', 'lang3') + ->run(); +``` + +### psm + +Specify the Page Segmentation Method, which instructs `tesseract` how to +interpret the given image. + +__More info:__ + +```php +echo (new TesseractOCR('img.png')) + ->psm(6) + ->run(); +``` + +### oem + +Specify the OCR Engine Mode. (see `tesseract --help-oem`) + +```php +echo (new TesseractOCR('img.png')) + ->oem(2) + ->run(); +``` + +### dpi + +Specify the image DPI. It is useful if your image does not contain this information in its metadata. + +```php +echo (new TesseractOCR('img.png')) + ->dpi(300) + ->run(); +``` + +### allowlist + +This is a shortcut for `->config('tessedit_char_whitelist', 'abcdef....')`. + +```php +echo (new TesseractOCR('img.png')) + ->allowlist(range('a', 'z'), range(0, 9), '-_@') + ->run(); +``` + +### configFile + +Specify a config file to be used. It can either be the path to your own +config file or the name of one of the predefined config files: + + +```php +echo (new TesseractOCR('img.png')) + ->configFile('hocr') + ->run(); +``` + +### setOutputFile + +Specify an Outputfile to be used. Be aware: If you set an outputfile then +the option `withoutTempFiles` is ignored. +Tempfiles are written (and deleted) even if `withoutTempFiles = true`. + +In combination with `configFile` you are able to get the `hocr`, `tsv` or +`pdf` files. + +```php +echo (new TesseractOCR('img.png')) + ->configFile('pdf') + ->setOutputFile('/PATH_TO_MY_OUTPUTFILE/searchable.pdf') + ->run(); +``` + +### digits + +Shortcut for `->configFile('digits')`. + +```php +echo (new TesseractOCR('img.png')) + ->digits() + ->run(); +``` + +### hocr + +Shortcut for `->configFile('hocr')`. + +```php +echo (new TesseractOCR('img.png')) + ->hocr() + ->run(); +``` + +### pdf + +Shortcut for `->configFile('pdf')`. + +```php +echo (new TesseractOCR('img.png')) + ->pdf() + ->run(); +``` + +### quiet + +Shortcut for `->configFile('quiet')`. + +```php +echo (new TesseractOCR('img.png')) + ->quiet() + ->run(); +``` + +### tsv + +Shortcut for `->configFile('tsv')`. + +```php +echo (new TesseractOCR('img.png')) + ->tsv() + ->run(); +``` + +### txt + +Shortcut for `->configFile('txt')`. + +```php +echo (new TesseractOCR('img.png')) + ->txt() + ->run(); +``` + +### tempDir + +Define a custom directory to store temporary files generated by tesseract. +Make sure the directory actually exists and the user running `php` is allowed +to write in there. + +```php +echo (new TesseractOCR('img.png')) + ->tempDir('./my/custom/temp/dir') + ->run(); +``` + +### withoutTempFiles + +Specify that `tesseract` should output the recognized text without writing to temporary files. +The data is gathered from the standard output of `tesseract` instead. + +```php +echo (new TesseractOCR('img.png')) + ->withoutTempFiles() + ->run(); +``` + +### Other options + +Any configuration option offered by Tesseract can be used like that: + +```php +echo (new TesseractOCR('img.png')) + ->config('config_var', 'value') + ->config('other_config_var', 'other value') + ->run(); +``` + +Or like that: + +```php +echo (new TesseractOCR('img.png')) + ->configVar('value') + ->otherConfigVar('other value') + ->run(); +``` + +__More info:__ + +### Thread-limit + +Sometimes, it may be useful to limit the number of threads that tesseract is +allowed to use (e.g. in [this case](https://github.com/tesseract-ocr/tesseract/issues/898)). +Set the maxmium number of threads as param for the `run` function: + +```php +echo (new TesseractOCR('img.png')) + ->threadLimit(1) + ->run(); +``` + +## How to contribute + +You can contribute to this project by: + +* Opening an [Issue][] if you found a bug or wish to propose a new feature; +* Placing a [Pull Request][] with code that fix a bug, missing/wrong documentation + or implement a new feature; + +Just make sure you take a look at our [Code of Conduct][] and [Contributing][] +instructions. + +## License + +tesseract-ocr-for-php is released under the [MIT License][]. + + +

Made with love in Berlin

+ +[ci_badge]: https://github.com/thiagoalessio/tesseract-ocr-for-php/workflows/CI/badge.svg?event=push&branch=main +[ci]: https://github.com/thiagoalessio/tesseract-ocr-for-php/actions?query=workflow%3ACI +[appveyor_badge]: https://ci.appveyor.com/api/projects/status/xwy5ls0798iwcim3/branch/main?svg=true +[appveyor]: https://ci.appveyor.com/project/thiagoalessio/tesseract-ocr-for-php/branch/main +[codacy_badge]: https://app.codacy.com/project/badge/Grade/a81aa10012874f23a57df5b492d835f2 +[codacy]: https://www.codacy.com/gh/thiagoalessio/tesseract-ocr-for-php/dashboard +[test_coverage_badge]: https://codecov.io/gh/thiagoalessio/tesseract-ocr-for-php/branch/main/graph/badge.svg?token=Y0VnrqiSIf +[test_coverage]: https://codecov.io/gh/thiagoalessio/tesseract-ocr-for-php +[stable_version_badge]: https://img.shields.io/packagist/v/thiagoalessio/tesseract_ocr.svg +[packagist]: https://packagist.org/packages/thiagoalessio/tesseract_ocr +[total_downloads_badge]: https://img.shields.io/packagist/dt/thiagoalessio/tesseract_ocr.svg +[monthly_downloads_badge]: https://img.shields.io/packagist/dm/thiagoalessio/tesseract_ocr.svg +[Tesseract OCR]: https://github.com/tesseract-ocr/tesseract +[Composer]: http://getcomposer.org/ +[windows_icon]: https://thiagoalessio.github.io/tesseract-ocr-for-php/images/windows-18.svg +[macos_icon]: https://thiagoalessio.github.io/tesseract-ocr-for-php/images/apple-18.svg +[tesseract_installation_on_windows]: https://github.com/tesseract-ocr/tesseract/wiki#windows +[Capture2Text]: https://chocolatey.org/packages/capture2text +[Chocolatey]: https://chocolatey.org +[MacPorts]: https://www.macports.org +[Homebrew]: https://brew.sh +[@daijiale]: https://github.com/daijiale +[HOCR]: https://github.com/tesseract-ocr/tesseract/wiki/Command-Line-Usage#hocr-output +[TSV]: https://github.com/tesseract-ocr/tesseract/wiki/Command-Line-Usage#tsv-output-currently-available-in-305-dev-in-master-branch-on-github +[Issue]: https://github.com/thiagoalessio/tesseract-ocr-for-php/issues +[Pull Request]: https://github.com/thiagoalessio/tesseract-ocr-for-php/pulls +[Code of Conduct]: https://github.com/thiagoalessio/tesseract-ocr-for-php/blob/main/.github/CODE_OF_CONDUCT.md +[Contributing]: https://github.com/thiagoalessio/tesseract-ocr-for-php/blob/main/.github/CONTRIBUTING.md +[MIT License]: https://github.com/thiagoalessio/tesseract-ocr-for-php/blob/main/MIT-LICENSE diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/codecov.yml b/tesseract/vendor/thiagoalessio/tesseract_ocr/codecov.yml new file mode 100644 index 00000000..8fd4c921 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/codecov.yml @@ -0,0 +1,4 @@ +fixes: +- "/home/runner/work/tesseract-ocr-for-php/tesseract-ocr-for-php/::" +- "/Users/runner/work/tesseract-ocr-for-php/tesseract-ocr-for-php/::" +- "C:\\projects\\tesseract-ocr-for-php\\::" diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/composer.json b/tesseract/vendor/thiagoalessio/tesseract_ocr/composer.json new file mode 100644 index 00000000..9a07e6d5 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/composer.json @@ -0,0 +1,35 @@ +{ + "name": "thiagoalessio/tesseract_ocr", + "description": "A wrapper to work with Tesseract OCR inside PHP.", + "version": "2.13.0", + "type": "library", + "keywords": ["Tesseract", "OCR", "text recognition"], + "license": "MIT", + "authors": [ + { + "name": "thiagoalessio", + "email": "thiagoalessio@me.com" + } + ], + "support": { + "issues": "https://github.com/thiagoalessio/tesseract-ocr-for-php/issues", + "irc": "irc://irc.freenode.net/tesseract-ocr-for-php", + "source": "https://github.com/thiagoalessio/tesseract-ocr-for-php" + }, + "require": { + "php": "^5.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/php-code-coverage": "^2.2.4 || ^9.0.0" + }, + "autoload": { + "psr-4": { + "thiagoalessio\\TesseractOCR\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "thiagoalessio\\TesseractOCR\\Tests\\": "tests/" + } + } +} diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/src/Command.php b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/Command.php new file mode 100644 index 00000000..ad123e82 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/Command.php @@ -0,0 +1,80 @@ +image = $image; + $this->outputFile = $outputFile; + } + + public function build() { return "$this"; } + + public function __toString() + { + $cmd = array(); + if ($this->threadLimit) $cmd[] = "OMP_THREAD_LIMIT={$this->threadLimit}"; + $cmd[] = self::escape($this->executable); + $cmd[] = $this->useFileAsInput ? self::escape($this->image) : "-"; + $cmd[] = $this->useFileAsOutput ? self::escape($this->getOutputFile(false)) : "-"; + + $version = $this->getTesseractVersion(); + + foreach ($this->options as $option) { + $cmd[] = is_callable($option) ? $option($version) : "$option"; + } + if ($this->configFile) $cmd[] = $this->configFile; + + return join(' ', $cmd); + } + + public function getOutputFile($withExt=true) + { + if (!$this->outputFile) + $this->outputFile = $this->getTempDir() + .DIRECTORY_SEPARATOR + .basename(tempnam($this->getTempDir(), 'ocr')); + if (!$withExt) return $this->outputFile; + + $hasCustomExt = array('hocr', 'tsv', 'pdf'); + $ext = in_array($this->configFile, $hasCustomExt) ? $this->configFile : 'txt'; + return "{$this->outputFile}.{$ext}"; + } + + public function getTempDir() + { + return $this->tempDir ?: sys_get_temp_dir(); + } + + public function getTesseractVersion() + { + exec(self::escape($this->executable).' --version 2>&1', $output); + $outputParts = explode(' ', $output[0]); + return $outputParts[1]; + } + + public function getAvailableLanguages() + { + exec(self::escape($this->executable) . ' --list-langs 2>&1', $output); + array_shift($output); + sort($output); + return $output; + } + + public static function escape($str) + { + $charlist = strtoupper(substr(PHP_OS, 0, 3)) == 'WIN' ? '$"`' : '$"\\`'; + return '"'.addcslashes($str, $charlist).'"'; + } +} diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/src/FeatureNotAvailableException.php b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/FeatureNotAvailableException.php new file mode 100644 index 00000000..12264f5c --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/FeatureNotAvailableException.php @@ -0,0 +1,7 @@ + NUL 2>&1' + : 'type '.Command::escape($executable).' > /dev/null 2>&1'; + system($cmd, $exitCode); + + if ($exitCode == 0) return; + + $currentPath = getenv('PATH'); + $msg = array(); + $msg[] = "Error! The command \"$executable\" was not found."; + $msg[] = ''; + $msg[] = 'Make sure you have Tesseract OCR installed on your system:'; + $msg[] = 'https://github.com/tesseract-ocr/tesseract'; + $msg[] = ''; + $msg[] = "The current \$PATH is $currentPath"; + $msg = join(PHP_EOL, $msg); + + throw new TesseractNotFoundException($msg); + } + + public static function checkCommandExecution($command, $stdout, $stderr) + { + if ($command->useFileAsOutput) { + $file = $command->getOutputFile(); + if (file_exists($file) && filesize($file) > 0) return; + } + + if (!$command->useFileAsOutput && $stdout) { + return; + } + + $msg = array(); + $msg[] = 'Error! The command did not produce any output.'; + $msg[] = ''; + $msg[] = 'Generated command:'; + $msg[] = "$command"; + $msg[] = ''; + $msg[] = 'Returned message:'; + $arrayStderr = explode(PHP_EOL, $stderr); + array_pop($arrayStderr); + $msg = array_merge($msg, $arrayStderr); + $msg = join(PHP_EOL, $msg); + + throw new UnsuccessfulCommandException($msg); + } + + public static function checkProcessCreation($processHandle, $command) + { + if ($processHandle !== FALSE) return; + + $msg = array(); + $msg[] = 'Error! The command could not be launched.'; + $msg[] = ''; + $msg[] = 'Generated command:'; + $msg[] = "$command"; + $msg = join(PHP_EOL, $msg); + + throw new UnsuccessfulCommandException($msg); + } + + public static function checkTesseractVersion($expected, $action, $command) + { + $actual = $command->getTesseractVersion(); + + if ($actual[0] === 'v') + $actual = substr($actual, 1); + + if (version_compare($actual, $expected, ">=")) return; + + $msg = array(); + $msg[] = "Error! $action is not available this tesseract version"; + $msg[] = "Required version is $expected, actual version is $actual"; + $msg[] = ''; + $msg[] = 'Generated command:'; + $msg[] = "$command"; + $msg = join(PHP_EOL, $msg); + + throw new FeatureNotAvailableException($msg); + } + + public static function checkWritePermissions($path) + { + if (!is_dir(dirname($path))) mkdir(dirname($path)); + $writableDirectory = is_writable(dirname($path)); + $writableFile = true; + if (file_exists($path)) $writableFile = is_writable($path); + if ($writableFile && $writableDirectory) return; + + $msg = array(); + $msg[] = "Error! No permission to write to $path"; + $msg[] = "Make sure you have the right outputFile and permissions " + ."to write to the folder"; + $msg[] = ''; + $msg = join(PHP_EOL, $msg); + + throw new NoWritePermissionsForOutputFile($msg); + } +} diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/src/ImageNotFoundException.php b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/ImageNotFoundException.php new file mode 100644 index 00000000..2ba7df64 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/ImageNotFoundException.php @@ -0,0 +1,7 @@ +=') ? '-' : '')."-psm $psm"; + }; + } + + public static function oem($oem) + { + return function($version) use ($oem) { + Option::checkMinVersion('3.05', $version, 'oem'); + return "--oem $oem"; + }; + } + + public static function dpi($dpi) + { + return function() use ($dpi) { + return "--dpi $dpi"; + }; + } + + public static function userWords($path) + { + return function($version) use ($path) { + Option::checkMinVersion('3.04', $version, 'user-words'); + return '--user-words "'.addcslashes($path, '\\"').'"'; + }; + } + + public static function userPatterns($path) + { + return function($version) use ($path) { + Option::checkMinVersion('3.04', $version, 'user-patterns'); + return '--user-patterns "'.addcslashes($path, '\\"').'"'; + }; + } + + public static function tessdataDir($path) + { + return function() use ($path) { + return '--tessdata-dir "'.addcslashes($path, '\\"').'"'; + }; + } + + public static function lang() + { + $languages = func_get_args(); + return function() use ($languages) { + return '-l '.join('+', $languages); + }; + } + + public static function config($var, $value) + { + return function() use($var, $value) { + $snakeCase = function($str) { + return strtolower(preg_replace('/([A-Z])+/', '_$1', $str)); + }; + $pair = $snakeCase($var).'='.$value; + return '-c "'.addcslashes($pair, '\\"').'"'; + }; + } + + public static function checkMinVersion($minVersion, $currVersion, $option) + { + $minVersion = preg_replace('/^v/', '', $minVersion); + $currVersion = preg_replace('/^v/', '', $currVersion); + if (!version_compare($currVersion, $minVersion, '<')) return; + $msg = "$option option is only available on Tesseract $minVersion or later."; + $msg.= PHP_EOL."Your version of Tesseract is $currVersion"; + throw new \Exception($msg); + } +} diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/src/Process.php b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/Process.php new file mode 100644 index 00000000..38460eb0 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/Process.php @@ -0,0 +1,83 @@ +startTime = microtime(true); + $streamDescriptors = [ + array("pipe", "r"), + array("pipe", "w"), + array("pipe", "w") + ]; + $this->handle = proc_open($command, $streamDescriptors, $pipes, NULL, NULL, ["bypass_shell" => true]); + list($this->stdin, $this->stdout, $this->stderr) = $pipes; + + FriendlyErrors::checkProcessCreation($this->handle, $command); + + //This is can avoid deadlock on some cases (when stderr buffer is filled up before writing to stdout and vice-versa) + stream_set_blocking($this->stdout, 0); + stream_set_blocking($this->stderr, 0); + } + + public function write($data, $len) + { + $total = 0; + do + { + $res = fwrite($this->stdin, substr($data, $total)); + } while($res && $total += $res < $len); + return $total === $len; + } + + + public function wait($timeout = 0) + { + $running = true; + $data = ["out" => "", "err" => ""]; + while (($running === true) && !$this->hasTimedOut($timeout)) + { + $data["out"] .= fread($this->stdout, 8192); + $data["err"] .= fread($this->stderr, 8192); + $procInfo = proc_get_status($this->handle); + $running = $procInfo["running"]; + if ($running) { + usleep(1000); // Sleep 1ms to yield CPU time + } + } + return $data; + } + + public function close() + { + $this->closeStream($this->stdin); + $this->closeStream($this->stdout); + $this->closeStream($this->stderr); + return proc_close($this->handle); + } + + public function closeStdin() + { + $this->closeStream($this->stdin); + } + + private function hasTimedOut($timeout) + { + return (($timeout > 0) && ($this->startTime + $timeout < microtime(true))); + } + + private function closeStream(&$stream) + { + if ($stream !== NULL) + { + fclose($stream); + $stream = NULL; + } + } +} diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractNotFoundException.php b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractNotFoundException.php new file mode 100644 index 00000000..7b7f0c1e --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractNotFoundException.php @@ -0,0 +1,7 @@ +command = $command ?: new Command; + $this->image("$image"); + } + + public function run($timeout = 0) + { + try { + if ($this->outputFile !== null) { + FriendlyErrors::checkWritePermissions($this->outputFile); + $this->command->useFileAsOutput = true; + } + + FriendlyErrors::checkTesseractPresence($this->command->executable); + if ($this->command->useFileAsInput) { + FriendlyErrors::checkImagePath($this->command->image); + } + + $process = new Process("{$this->command}"); + + if (!$this->command->useFileAsInput) { + $process->write($this->command->image, $this->command->imageSize); + $process->closeStdin(); + } + $output = $process->wait($timeout); + + FriendlyErrors::checkCommandExecution($this->command, $output["out"], $output["err"]); + } + catch (TesseractOcrException $e) { + if ($this->command->useFileAsOutput) $this->cleanTempFiles(); + throw $e; + } + + if ($this->command->useFileAsOutput) { + $text = file_get_contents($this->command->getOutputFile()); + + if ($this->outputFile !== null) { + rename($this->command->getOutputFile(), $this->outputFile); + } + + $this->cleanTempFiles(); + } + else + $text = $output["out"]; + + return trim($text, " \t\n\r\0\x0A\x0B\x0C"); + } + + public function imageData($image, $size) + { + FriendlyErrors::checkTesseractVersion("3.03-rc1", "Reading image data from stdin", $this->command); + $this->command->useFileAsInput = false; + $this->command->image = $image; + $this->command->imageSize = $size; + return $this; + } + + public function withoutTempFiles() + { + FriendlyErrors::checkTesseractVersion("3.03-rc1", "Writing to stdout (without using temp files)", $this->command); + $this->command->useFileAsOutput = false; + return $this; + } + + public function image($image) + { + $this->command->image = $image; + return $this; + } + + public function executable($executable) + { + FriendlyErrors::checkTesseractPresence($executable); + $this->command->executable = $executable; + return $this; + } + + public function configFile($configFile) + { + $this->command->configFile = $configFile; + return $this; + } + + public function tempDir($tempDir) + { + $this->command->tempDir = $tempDir; + return $this; + } + + public function threadLimit($limit) + { + $this->command->threadLimit = $limit; + return $this; + } + + // @deprecated + public function format($fmt) { return $this->configFile($fmt); } + + public function setOutputFile($path) { + $this->outputFile = $path; + return $this; + } + + public function allowlist() + { + $concat = function ($arg) { return is_array($arg) ? join('', $arg) : $arg; }; + $allowlist = join('', array_map($concat, func_get_args())); + $this->command->options[] = Option::config('tessedit_char_whitelist', $allowlist); + return $this; + } + + public function whitelist() + { + $warningMsg = 'Notice: whitelist is deprecated, use allowlist instead.'; + trigger_error($warningMsg, E_USER_NOTICE); + + $concat = function ($arg) { return is_array($arg) ? join('', $arg) : $arg; }; + $allowlist = join('', array_map($concat, func_get_args())); + return $this->allowlist($allowlist); + } + + public function version() + { + return $this->command->getTesseractVersion(); + } + + public function availableLanguages() + { + return $this->command->getAvailableLanguages(); + } + + public function __call($method, $args) + { + if ($this->isConfigFile($method)) return $this->configFile($method); + if ($this->isOption($method)) { + $option = $this->getOptionClassName().'::'.$method; + $this->command->options[] = call_user_func_array($option, $args); + return $this; + } + $arg = empty($args) ? null : $args[0]; + $this->command->options[] = Option::config($method, $arg); + return $this; + } + + private function isConfigFile($name) + { + return in_array($name, array('digits', 'hocr', 'pdf', 'quiet', 'tsv', 'txt')); + } + + private function isOption($name) + { + return in_array($name, get_class_methods($this->getOptionClassName())); + } + + private function getOptionClassName() + { + return __NAMESPACE__.'\\Option'; + } + + private function cleanTempFiles() + { + if (file_exists($this->command->getOutputFile(false))) { + unlink($this->command->getOutputFile(false)); + } + if (file_exists($this->command->getOutputFile(true))) { + unlink($this->command->getOutputFile(true)); + } + } +} diff --git a/tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractOcrException.php b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractOcrException.php new file mode 100644 index 00000000..8c078616 --- /dev/null +++ b/tesseract/vendor/thiagoalessio/tesseract_ocr/src/TesseractOcrException.php @@ -0,0 +1,7 @@ + Date: Mon, 15 Jan 2024 20:09:03 +0000 Subject: [PATCH 005/294] README.md created --- tesseract/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 tesseract/README.md diff --git a/tesseract/README.md b/tesseract/README.md new file mode 100644 index 00000000..d0b5eee2 --- /dev/null +++ b/tesseract/README.md @@ -0,0 +1 @@ +To make the addon work, you have to install the tesseract-ocr command line tool. \ No newline at end of file From c28af61873b71b5de2d1cdd4ebb64cd3ec535960 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 21 Jan 2024 21:24:08 +0000 Subject: [PATCH 006/294] Twitter: Fix error after posting --- twitter/twitter.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/twitter/twitter.php b/twitter/twitter.php index 8c906daf..b01345b7 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -362,7 +362,7 @@ function twitter_post(int $uid, string $url, string $type, array $data): stdClas ]); $response = $client->post($url, ['auth' => 'oauth', $type => $data]); - $body = $response->getBodyString()->getContents(); + $body = $response->getBody()->getContents(); $status = [ 'code' => $response->getStatusCode(), @@ -399,7 +399,7 @@ function twitter_test_connection(int $uid) $status = [ 'code' => $response->getStatusCode(), 'reason' => $response->getReasonPhrase(), - 'content' => $response->getBodyString()->getContents() + 'content' => $response->getBody()->getContents() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); Logger::info('Test successful', ['uid' => $uid]); From a30e9b788c427c73b3e3a0b621d70cb85de38eb1 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Fri, 12 Jan 2024 00:08:24 -0500 Subject: [PATCH 007/294] [advancedcontentfilter] Migrate Slim to version 4 to avoid PHP 8.2 deprecation error - Fix https://github.com/friendica/friendica/issues/13822 --- .../advancedcontentfilter.php | 24 +- advancedcontentfilter/composer.json | 3 +- advancedcontentfilter/composer.lock | 553 +++++--- advancedcontentfilter/src/middlewares.php | 33 +- advancedcontentfilter/src/routes.php | 21 +- .../vendor/composer/ClassLoader.php | 6 +- .../vendor/composer/autoload_classmap.php | 133 +- .../vendor/composer/autoload_namespaces.php | 1 - .../vendor/composer/autoload_psr4.php | 4 +- .../vendor/composer/autoload_real.php | 3 + .../vendor/composer/autoload_static.php | 161 +-- .../vendor/composer/installed.json | 572 +++++--- .../container-interop/.gitignore | 3 - .../container-interop/LICENSE | 20 - .../container-interop/README.md | 148 -- .../container-interop/composer.json | 15 - .../docs/ContainerInterface-meta.md | 114 -- .../docs/ContainerInterface.md | 158 --- .../docs/Delegate-lookup-meta.md | 259 ---- .../container-interop/docs/Delegate-lookup.md | 60 - .../docs/images/interoperating_containers.png | Bin 25738 -> 0 bytes .../docs/images/priority.png | Bin 16252 -> 0 bytes .../docs/images/side_by_side_containers.png | Bin 16265 -> 0 bytes .../Interop/Container/ContainerInterface.php | 15 - .../Exception/ContainerException.php | 15 - .../Container/Exception/NotFoundException.php | 15 - .../vendor/pimple/pimple/.gitignore | 3 - .../vendor/pimple/pimple/.travis.yml | 40 - .../vendor/pimple/pimple/CHANGELOG | 59 - .../vendor/pimple/pimple/README.rst | 326 ----- .../vendor/pimple/pimple/composer.json | 29 - .../pimple/pimple/ext/pimple/.gitignore | 30 - .../vendor/pimple/pimple/ext/pimple/README.md | 12 - .../vendor/pimple/pimple/ext/pimple/config.m4 | 63 - .../pimple/pimple/ext/pimple/config.w32 | 13 - .../pimple/pimple/ext/pimple/php_pimple.h | 137 -- .../vendor/pimple/pimple/ext/pimple/pimple.c | 1114 --------------- .../pimple/pimple/ext/pimple/pimple_compat.h | 81 -- .../pimple/pimple/ext/pimple/tests/001.phpt | 45 - .../pimple/pimple/ext/pimple/tests/002.phpt | 15 - .../pimple/pimple/ext/pimple/tests/003.phpt | 16 - .../pimple/pimple/ext/pimple/tests/004.phpt | 30 - .../pimple/pimple/ext/pimple/tests/005.phpt | 27 - .../pimple/pimple/ext/pimple/tests/006.phpt | 51 - .../pimple/pimple/ext/pimple/tests/007.phpt | 22 - .../pimple/pimple/ext/pimple/tests/008.phpt | 29 - .../pimple/pimple/ext/pimple/tests/009.phpt | 13 - .../pimple/pimple/ext/pimple/tests/010.phpt | 45 - .../pimple/pimple/ext/pimple/tests/011.phpt | 19 - .../pimple/pimple/ext/pimple/tests/012.phpt | 28 - .../pimple/pimple/ext/pimple/tests/013.phpt | 33 - .../pimple/pimple/ext/pimple/tests/014.phpt | 30 - .../pimple/pimple/ext/pimple/tests/015.phpt | 17 - .../pimple/pimple/ext/pimple/tests/016.phpt | 24 - .../pimple/pimple/ext/pimple/tests/017.phpt | 17 - .../pimple/pimple/ext/pimple/tests/017_1.phpt | 17 - .../pimple/pimple/ext/pimple/tests/018.phpt | 23 - .../pimple/pimple/ext/pimple/tests/019.phpt | 18 - .../pimple/pimple/ext/pimple/tests/bench.phpb | 51 - .../pimple/ext/pimple/tests/bench_shared.phpb | 25 - .../vendor/pimple/pimple/phpunit.xml.dist | 14 - .../pimple/pimple/src/Pimple/Container.php | 298 ---- .../Exception/ExpectedInvokableException.php | 38 - .../Exception/FrozenServiceException.php | 45 - .../InvalidServiceIdentifierException.php | 45 - .../Exception/UnknownIdentifierException.php | 45 - .../pimple/src/Pimple/Psr11/Container.php | 55 - .../src/Pimple/Psr11/ServiceLocator.php | 75 - .../pimple/src/Pimple/ServiceIterator.php | 69 - .../src/Pimple/ServiceProviderInterface.php | 46 - .../src/Pimple/Tests/Fixtures/Invokable.php | 38 - .../Pimple/Tests/Fixtures/NonInvokable.php | 34 - .../Tests/Fixtures/PimpleServiceProvider.php | 54 - .../src/Pimple/Tests/Fixtures/Service.php | 35 - .../PimpleServiceProviderInterfaceTest.php | 76 - .../pimple/src/Pimple/Tests/PimpleTest.php | 589 -------- .../src/Pimple/Tests/Psr11/ContainerTest.php | 77 -- .../Pimple/Tests/Psr11/ServiceLocatorTest.php | 134 -- .../src/Pimple/Tests/ServiceIteratorTest.php | 52 - .../vendor/psr/container/README.md | 14 +- .../vendor/psr/container/composer.json | 6 +- .../src/ContainerExceptionInterface.php | 7 +- .../psr/container/src/ContainerInterface.php | 9 +- .../src/NotFoundExceptionInterface.php | 3 - .../pimple => psr/http-factory}/LICENSE | 12 +- .../vendor/psr/http-factory/README.md | 12 + .../vendor/psr/http-factory/composer.json | 35 + .../src/RequestFactoryInterface.php | 18 + .../src/ResponseFactoryInterface.php | 18 + .../src/ServerRequestFactoryInterface.php | 24 + .../src/StreamFactoryInterface.php | 45 + .../src/UploadedFileFactoryInterface.php | 34 + .../http-factory/src/UriFactoryInterface.php | 17 + .../vendor/psr/http-message/README.md | 5 +- .../vendor/psr/http-message/composer.json | 4 +- .../psr/http-message/docs/PSR7-Interfaces.md | 130 ++ .../psr/http-message/docs/PSR7-Usage.md | 159 +++ .../psr/http-message/src/MessageInterface.php | 16 +- .../psr/http-message/src/RequestInterface.php | 10 +- .../http-message/src/ResponseInterface.php | 4 +- .../src/ServerRequestInterface.php | 8 +- .../psr/http-message/src/StreamInterface.php | 12 +- .../src/UploadedFileInterface.php | 4 +- .../psr/http-message/src/UriInterface.php | 17 +- .../vendor/psr/http-server-handler/LICENSE | 21 + .../vendor/psr/http-server-handler/README.md | 12 + .../psr/http-server-handler/composer.json | 36 + .../src/RequestHandlerInterface.php | 22 + .../vendor/psr/http-server-middleware/LICENSE | 21 + .../psr/http-server-middleware/README.md | 12 + .../psr/http-server-middleware/composer.json | 36 + .../src/MiddlewareInterface.php | 25 + .../vendor/psr/log/.gitignore | 1 - .../vendor/psr/log/Psr/Log/AbstractLogger.php | 32 +- .../psr/log/Psr/Log/LoggerAwareTrait.php | 2 +- .../psr/log/Psr/Log/LoggerInterface.php | 40 +- .../vendor/psr/log/Psr/Log/LoggerTrait.php | 2 + .../vendor/psr/log/Psr/Log/NullLogger.php | 2 + .../vendor/psr/log/Psr/Log/Test/DummyTest.php | 18 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 14 +- .../psr/log/Psr/Log/Test/TestLogger.php | 147 ++ .../vendor/psr/log/README.md | 13 + .../vendor/psr/log/composer.json | 4 +- .../vendor/slim/slim/CHANGELOG.md | 237 ++++ .../vendor/slim/slim/LICENSE.md | 2 +- .../vendor/slim/slim/MAINTAINERS.md | 17 + .../vendor/slim/slim/SECURITY.md | 14 + .../vendor/slim/slim/Slim/App.php | 730 ++-------- .../slim/slim/Slim/CallableResolver.php | 227 ++- .../slim/Slim/CallableResolverAwareTrait.php | 47 - .../vendor/slim/slim/Slim/Collection.php | 202 --- .../vendor/slim/slim/Slim/Container.php | 179 --- .../slim/Slim/DefaultServicesProvider.php | 211 --- .../slim/slim/Slim/DeferredCallable.php | 45 - .../slim/Slim/Error/AbstractErrorRenderer.php | 46 + .../Error/Renderers/HtmlErrorRenderer.php | 84 ++ .../Error/Renderers/JsonErrorRenderer.php | 56 + .../Renderers/PlainTextErrorRenderer.php | 59 + .../Slim/Error/Renderers/XmlErrorRenderer.php | 54 + .../Slim/Exception/ContainerException.php | 20 - .../ContainerValueNotFoundException.php | 20 - .../Exception/HttpBadRequestException.php | 28 + .../slim/Slim/Exception/HttpException.php | 64 + .../Slim/Exception/HttpForbiddenException.php | 27 + .../slim/Slim/Exception/HttpGoneException.php | 27 + .../HttpInternalServerErrorException.php | 27 + .../HttpMethodNotAllowedException.php | 52 + .../Slim/Exception/HttpNotFoundException.php | 27 + .../Exception/HttpNotImplementedException.php | 27 + .../Exception/HttpSpecializedException.php | 31 + .../Exception/HttpUnauthorizedException.php | 27 + .../Slim/Exception/InvalidMethodException.php | 27 - .../Exception/MethodNotAllowedException.php | 45 - .../slim/Slim/Exception/NotFoundException.php | 14 - .../slim/Slim/Exception/SlimException.php | 69 - .../slim/slim/Slim/Factory/AppFactory.php | 206 +++ .../Slim/Factory/Psr17/GuzzlePsr17Factory.php | 19 + .../Factory/Psr17/HttpSoftPsr17Factory.php | 19 + .../Psr17/LaminasDiactorosPsr17Factory.php | 19 + .../Slim/Factory/Psr17/NyholmPsr17Factory.php | 36 + .../slim/Slim/Factory/Psr17/Psr17Factory.php | 101 ++ .../Factory/Psr17/Psr17FactoryProvider.php | 53 + .../Factory/Psr17/ServerRequestCreator.php | 44 + .../Factory/Psr17/SlimHttpPsr17Factory.php | 39 + .../Psr17/SlimHttpServerRequestCreator.php | 56 + .../Slim/Factory/Psr17/SlimPsr17Factory.php | 19 + .../Factory/ServerRequestCreatorFactory.php | 87 ++ .../slim/slim/Slim/Handlers/AbstractError.php | 99 -- .../slim/Slim/Handlers/AbstractHandler.php | 59 - .../vendor/slim/slim/Slim/Handlers/Error.php | 224 --- .../slim/slim/Slim/Handlers/ErrorHandler.php | 308 +++++ .../slim/slim/Slim/Handlers/NotAllowed.php | 147 -- .../slim/slim/Slim/Handlers/NotFound.php | 141 -- .../slim/slim/Slim/Handlers/PhpError.php | 205 --- .../Handlers/Strategies/RequestHandler.php | 48 + .../Handlers/Strategies/RequestResponse.php | 19 +- .../Strategies/RequestResponseArgs.php | 24 +- .../Strategies/RequestResponseNamedArgs.php | 44 + .../vendor/slim/slim/Slim/Http/Body.php | 22 - .../vendor/slim/slim/Slim/Http/Cookies.php | 195 --- .../slim/slim/Slim/Http/Environment.php | 63 - .../vendor/slim/slim/Slim/Http/Headers.php | 222 --- .../vendor/slim/slim/Slim/Http/Message.php | 305 ---- .../vendor/slim/slim/Slim/Http/Request.php | 1227 ----------------- .../slim/slim/Slim/Http/RequestBody.php | 27 - .../vendor/slim/slim/Slim/Http/Response.php | 508 ------- .../vendor/slim/slim/Slim/Http/Stream.php | 450 ------ .../slim/slim/Slim/Http/UploadedFile.php | 327 ----- .../vendor/slim/slim/Slim/Http/Uri.php | 845 ------------ .../AdvancedCallableResolverInterface.php | 28 + .../Interfaces/CallableResolverInterface.php | 22 +- .../Slim/Interfaces/CollectionInterface.php | 32 - .../Slim/Interfaces/DispatcherInterface.php | 28 + .../Slim/Interfaces/ErrorHandlerInterface.php | 26 + .../Interfaces/ErrorRendererInterface.php | 18 + .../Slim/Interfaces/Http/CookiesInterface.php | 23 - .../Interfaces/Http/EnvironmentInterface.php | 20 - .../Slim/Interfaces/Http/HeadersInterface.php | 24 - .../InvocationStrategyInterface.php | 20 +- .../MiddlewareDispatcherInterface.php | 42 + .../Slim/Interfaces/Psr17FactoryInterface.php | 48 + .../Psr17FactoryProviderInterface.php | 26 + ...uestHandlerInvocationStrategyInterface.php | 15 + .../Interfaces/RouteCollectorInterface.php | 102 ++ .../RouteCollectorProxyInterface.php | 118 ++ .../Slim/Interfaces/RouteGroupInterface.php | 51 +- .../slim/Slim/Interfaces/RouteInterface.php | 151 +- .../Slim/Interfaces/RouteParserInterface.php | 52 + .../Interfaces/RouteResolverInterface.php | 17 + .../slim/Slim/Interfaces/RouterInterface.php | 111 -- .../ServerRequestCreatorInterface.php | 18 + .../vendor/slim/slim/Slim/Logger.php | 32 + .../Slim/Middleware/BodyParsingMiddleware.php | 196 +++ .../Middleware/ContentLengthMiddleware.php | 32 + .../slim/Slim/Middleware/ErrorMiddleware.php | 212 +++ .../Middleware/MethodOverrideMiddleware.php | 43 + .../Middleware/OutputBufferingMiddleware.php | 74 + .../Slim/Middleware/RoutingMiddleware.php | 98 ++ .../slim/slim/Slim/MiddlewareAwareTrait.php | 121 -- .../slim/slim/Slim/MiddlewareDispatcher.php | 275 ++++ .../vendor/slim/slim/Slim/ResponseEmitter.php | 136 ++ .../vendor/slim/slim/Slim/Routable.php | 106 -- .../vendor/slim/slim/Slim/Route.php | 349 ----- .../vendor/slim/slim/Slim/RouteGroup.php | 47 - .../vendor/slim/slim/Slim/Router.php | 455 ------ .../slim/slim/Slim/Routing/Dispatcher.php | 78 ++ .../slim/Slim/Routing/FastRouteDispatcher.php | 109 ++ .../vendor/slim/slim/Slim/Routing/Route.php | 360 +++++ .../slim/slim/Slim/Routing/RouteCollector.php | 293 ++++ .../slim/Slim/Routing/RouteCollectorProxy.php | 187 +++ .../slim/slim/Slim/Routing/RouteContext.php | 88 ++ .../slim/slim/Slim/Routing/RouteGroup.php | 104 ++ .../slim/slim/Slim/Routing/RouteParser.php | 127 ++ .../slim/slim/Slim/Routing/RouteResolver.php | 56 + .../slim/slim/Slim/Routing/RouteRunner.php | 70 + .../slim/slim/Slim/Routing/RoutingResults.php | 112 ++ .../vendor/slim/slim/composer.json | 74 +- .../symfony/cache/Adapter/AbstractAdapter.php | 94 +- .../cache/Adapter/AdapterInterface.php | 2 +- .../symfony/cache/Adapter/ArrayAdapter.php | 23 +- .../symfony/cache/Adapter/ChainAdapter.php | 48 +- .../symfony/cache/Adapter/DoctrineAdapter.php | 5 +- .../symfony/cache/Adapter/NullAdapter.php | 2 +- .../symfony/cache/Adapter/PdoAdapter.php | 4 +- .../symfony/cache/Adapter/PhpArrayAdapter.php | 62 +- .../symfony/cache/Adapter/PhpFilesAdapter.php | 4 +- .../symfony/cache/Adapter/ProxyAdapter.php | 42 +- .../cache/Adapter/SimpleCacheAdapter.php | 8 +- .../symfony/cache/Adapter/TagAwareAdapter.php | 183 ++- .../cache/Adapter/TraceableAdapter.php | 18 +- .../vendor/symfony/cache/CacheItem.php | 53 +- .../DataCollector/CacheDataCollector.php | 44 +- .../vendor/symfony/cache/DoctrineProvider.php | 3 +- .../vendor/symfony/cache/LICENSE | 2 +- .../symfony/cache/Simple/AbstractCache.php | 55 +- .../symfony/cache/Simple/ArrayCache.php | 30 +- .../symfony/cache/Simple/ChainCache.php | 14 +- .../symfony/cache/Simple/DoctrineCache.php | 5 +- .../symfony/cache/Simple/MemcachedCache.php | 5 +- .../vendor/symfony/cache/Simple/PdoCache.php | 4 +- .../symfony/cache/Simple/PhpArrayCache.php | 60 +- .../symfony/cache/Simple/PhpFilesCache.php | 4 +- .../vendor/symfony/cache/Simple/Psr6Cache.php | 69 +- .../symfony/cache/Simple/TraceableCache.php | 14 +- .../Adapter/AbstractRedisAdapterTest.php | 15 +- .../cache/Tests/Adapter/AdapterTestCase.php | 8 +- .../cache/Tests/Adapter/ApcuAdapterTest.php | 14 +- .../cache/Tests/Adapter/ArrayAdapterTest.php | 4 +- .../cache/Tests/Adapter/ChainAdapterTest.php | 157 ++- .../Tests/Adapter/DoctrineAdapterTest.php | 4 +- .../Tests/Adapter/FilesystemAdapterTest.php | 2 +- .../Tests/Adapter/MaxIdLengthAdapterTest.php | 50 +- .../Tests/Adapter/MemcachedAdapterTest.php | 112 +- .../cache/Tests/Adapter/NullAdapterTest.php | 4 +- .../cache/Tests/Adapter/PdoAdapterTest.php | 4 +- .../Tests/Adapter/PdoDbalAdapterTest.php | 8 +- .../Tests/Adapter/PhpArrayAdapterTest.php | 30 +- .../PhpArrayAdapterWithFallbackTest.php | 8 +- .../Tests/Adapter/PhpFilesAdapterTest.php | 4 +- .../cache/Tests/Adapter/PredisAdapterTest.php | 12 +- .../Adapter/PredisClusterAdapterTest.php | 6 +- .../Adapter/PredisRedisClusterAdapterTest.php | 28 + .../cache/Tests/Adapter/ProxyAdapterTest.php | 10 +- .../cache/Tests/Adapter/RedisAdapterTest.php | 36 +- .../Tests/Adapter/RedisArrayAdapterTest.php | 4 +- .../Tests/Adapter/RedisClusterAdapterTest.php | 27 + .../Tests/Adapter/SimpleCacheAdapterTest.php | 17 +- .../Tests/Adapter/TagAwareAdapterTest.php | 183 ++- ...TagAwareAndProxyAdapterIntegrationTest.php | 38 + .../Tests/Adapter/TraceableAdapterTest.php | 24 +- .../Adapter/TraceableTagAwareAdapterTest.php | 2 +- .../symfony/cache/Tests/CacheItemTest.php | 48 +- .../cache/Tests/Fixtures/ArrayCache.php | 8 +- .../cache/Tests/Fixtures/ExternalAdapter.php | 6 +- .../Tests/Simple/AbstractRedisCacheTest.php | 15 +- .../cache/Tests/Simple/ApcuCacheTest.php | 8 +- .../cache/Tests/Simple/CacheTestCase.php | 19 +- .../cache/Tests/Simple/ChainCacheTest.php | 37 +- .../cache/Tests/Simple/DoctrineCacheTest.php | 4 +- .../cache/Tests/Simple/MemcachedCacheTest.php | 99 +- .../Simple/MemcachedCacheTextModeTest.php | 25 + .../cache/Tests/Simple/NullCacheTest.php | 6 +- .../cache/Tests/Simple/PdoCacheTest.php | 4 +- .../cache/Tests/Simple/PdoDbalCacheTest.php | 8 +- .../cache/Tests/Simple/PhpArrayCacheTest.php | 36 +- .../Simple/PhpArrayCacheWithFallbackTest.php | 8 +- .../cache/Tests/Simple/PhpFilesCacheTest.php | 4 +- .../cache/Tests/Simple/Psr6CacheTest.php | 4 +- .../Tests/Simple/RedisArrayCacheTest.php | 4 +- .../cache/Tests/Simple/RedisCacheTest.php | 32 +- .../Tests/Simple/RedisClusterCacheTest.php | 27 + .../cache/Tests/Simple/TraceableCacheTest.php | 26 +- .../cache/Tests/Traits/PdoPruneableTrait.php | 6 +- .../symfony/cache/Traits/AbstractTrait.php | 52 +- .../vendor/symfony/cache/Traits/ApcuTrait.php | 16 +- .../symfony/cache/Traits/ArrayTrait.php | 12 +- .../symfony/cache/Traits/DoctrineTrait.php | 2 +- .../cache/Traits/FilesystemCommonTrait.php | 20 +- .../symfony/cache/Traits/FilesystemTrait.php | 6 +- .../symfony/cache/Traits/MemcachedTrait.php | 105 +- .../vendor/symfony/cache/Traits/PdoTrait.php | 105 +- .../symfony/cache/Traits/PhpArrayTrait.php | 40 +- .../symfony/cache/Traits/PhpFilesTrait.php | 24 +- .../symfony/cache/Traits/ProxyTrait.php | 2 + .../symfony/cache/Traits/RedisProxy.php | 2 +- .../symfony/cache/Traits/RedisTrait.php | 180 +-- .../vendor/symfony/cache/composer.json | 13 +- .../vendor/symfony/cache/phpunit.xml.dist | 12 +- .../symfony/expression-language/Compiler.php | 16 +- .../ExpressionFunction.php | 10 +- .../ExpressionLanguage.php | 20 +- .../symfony/expression-language/LICENSE | 2 +- .../symfony/expression-language/Lexer.php | 30 +- .../Node/ArgumentsNode.php | 2 +- .../expression-language/Node/ArrayNode.php | 14 +- .../expression-language/Node/BinaryNode.php | 28 +- .../Node/ConditionalNode.php | 4 +- .../expression-language/Node/ConstantNode.php | 8 +- .../expression-language/Node/FunctionNode.php | 14 +- .../expression-language/Node/GetAttrNode.php | 28 +- .../expression-language/Node/NameNode.php | 6 +- .../symfony/expression-language/Node/Node.php | 16 +- .../expression-language/Node/UnaryNode.php | 10 +- .../symfony/expression-language/Parser.php | 88 +- .../ParserCache/ArrayParserCache.php | 4 +- .../ParserCache/ParserCacheAdapter.php | 18 +- .../ParserCache/ParserCacheInterface.php | 2 +- .../Resources/bin/generate_operator_regex.php | 14 +- .../expression-language/SyntaxError.php | 4 +- .../Tests/ExpressionFunctionTest.php | 12 +- .../Tests/ExpressionLanguageTest.php | 130 +- .../Tests/Fixtures/TestProvider.php | 4 +- .../expression-language/Tests/LexerTest.php | 92 +- .../Tests/Node/AbstractNodeTest.php | 4 +- .../Tests/Node/ArgumentsNodeTest.php | 12 +- .../Tests/Node/ArrayNodeTest.php | 18 +- .../Tests/Node/BinaryNodeTest.php | 194 +-- .../Tests/Node/ConditionalNodeTest.php | 24 +- .../Tests/Node/ConstantNodeTest.php | 62 +- .../Tests/Node/FunctionNodeTest.php | 24 +- .../Tests/Node/GetAttrNodeTest.php | 46 +- .../Tests/Node/NameNodeTest.php | 18 +- .../Tests/Node/NodeTest.php | 6 +- .../Tests/Node/UnaryNodeTest.php | 38 +- .../ParserCache/ParserCacheAdapterTest.php | 26 +- .../expression-language/Tests/ParserTest.php | 193 +-- .../symfony/expression-language/Token.php | 2 +- .../expression-language/TokenStream.php | 4 +- .../symfony/expression-language/composer.json | 10 +- .../expression-language/phpunit.xml.dist | 2 +- .../vendor/symfony/polyfill-apcu/Apcu.php | 18 +- .../vendor/symfony/polyfill-apcu/LICENSE | 2 +- .../vendor/symfony/polyfill-apcu/README.md | 4 +- .../symfony/polyfill-apcu/bootstrap.php | 67 +- .../symfony/polyfill-apcu/bootstrap80.php | 75 + .../symfony/polyfill-apcu/composer.json | 8 +- 376 files changed, 10144 insertions(+), 15497 deletions(-) delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/.gitignore delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/LICENSE delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/README.md delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/composer.json delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface.md delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/Delegate-lookup.md delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/images/interoperating_containers.png delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/images/priority.png delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/docs/images/side_by_side_containers.png delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php delete mode 100644 advancedcontentfilter/vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/.gitignore delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/.travis.yml delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/CHANGELOG delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/README.rst delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/composer.json delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/.gitignore delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/README.md delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.m4 delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.w32 delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/php_pimple.h delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple.c delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple_compat.h delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/001.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/002.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/003.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/004.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/005.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/006.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/007.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/008.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/009.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/010.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/011.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/012.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/013.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/014.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/015.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/016.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/018.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/019.phpt delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench.phpb delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/phpunit.xml.dist delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Container.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/Container.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceIterator.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php delete mode 100644 advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php rename advancedcontentfilter/vendor/{pimple/pimple => psr/http-factory}/LICENSE (87%) create mode 100644 advancedcontentfilter/vendor/psr/http-factory/README.md create mode 100644 advancedcontentfilter/vendor/psr/http-factory/composer.json create mode 100644 advancedcontentfilter/vendor/psr/http-factory/src/RequestFactoryInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-factory/src/ResponseFactoryInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-factory/src/ServerRequestFactoryInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-factory/src/StreamFactoryInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-factory/src/UploadedFileFactoryInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-factory/src/UriFactoryInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Interfaces.md create mode 100644 advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Usage.md create mode 100644 advancedcontentfilter/vendor/psr/http-server-handler/LICENSE create mode 100644 advancedcontentfilter/vendor/psr/http-server-handler/README.md create mode 100644 advancedcontentfilter/vendor/psr/http-server-handler/composer.json create mode 100644 advancedcontentfilter/vendor/psr/http-server-handler/src/RequestHandlerInterface.php create mode 100644 advancedcontentfilter/vendor/psr/http-server-middleware/LICENSE create mode 100644 advancedcontentfilter/vendor/psr/http-server-middleware/README.md create mode 100644 advancedcontentfilter/vendor/psr/http-server-middleware/composer.json create mode 100644 advancedcontentfilter/vendor/psr/http-server-middleware/src/MiddlewareInterface.php delete mode 100644 advancedcontentfilter/vendor/psr/log/.gitignore create mode 100644 advancedcontentfilter/vendor/psr/log/Psr/Log/Test/DummyTest.php create mode 100644 advancedcontentfilter/vendor/psr/log/Psr/Log/Test/TestLogger.php create mode 100644 advancedcontentfilter/vendor/slim/slim/CHANGELOG.md create mode 100644 advancedcontentfilter/vendor/slim/slim/MAINTAINERS.md create mode 100644 advancedcontentfilter/vendor/slim/slim/SECURITY.md delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/CallableResolverAwareTrait.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Collection.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Container.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/DefaultServicesProvider.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/DeferredCallable.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Error/AbstractErrorRenderer.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/HtmlErrorRenderer.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/JsonErrorRenderer.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/PlainTextErrorRenderer.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/XmlErrorRenderer.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/ContainerException.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/ContainerValueNotFoundException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpBadRequestException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpForbiddenException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpGoneException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpInternalServerErrorException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpMethodNotAllowedException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpNotFoundException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpNotImplementedException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpSpecializedException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpUnauthorizedException.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/InvalidMethodException.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/MethodNotAllowedException.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/NotFoundException.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Exception/SlimException.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/AppFactory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/HttpSoftPsr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/LaminasDiactorosPsr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/NyholmPsr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/Psr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/Psr17FactoryProvider.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/ServerRequestCreator.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimHttpPsr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimHttpServerRequestCreator.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimPsr17Factory.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Factory/ServerRequestCreatorFactory.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractError.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractHandler.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Error.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/ErrorHandler.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotAllowed.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotFound.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/PhpError.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestHandler.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseNamedArgs.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Body.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Cookies.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Environment.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Headers.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Message.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Request.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/RequestBody.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Response.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Stream.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/UploadedFile.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Http/Uri.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/AdvancedCallableResolverInterface.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/CollectionInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/DispatcherInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/ErrorHandlerInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/ErrorRendererInterface.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/Http/CookiesInterface.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/Http/EnvironmentInterface.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/Http/HeadersInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/MiddlewareDispatcherInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/Psr17FactoryInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/Psr17FactoryProviderInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RequestHandlerInvocationStrategyInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteCollectorInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteCollectorProxyInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteParserInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteResolverInterface.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouterInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/ServerRequestCreatorInterface.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Logger.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Middleware/BodyParsingMiddleware.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ContentLengthMiddleware.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Middleware/MethodOverrideMiddleware.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Middleware/OutputBufferingMiddleware.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareAwareTrait.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareDispatcher.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/ResponseEmitter.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routable.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Route.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/RouteGroup.php delete mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Router.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/Dispatcher.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/FastRouteDispatcher.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/Route.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollector.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollectorProxy.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteContext.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteGroup.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteParser.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteResolver.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteRunner.php create mode 100644 advancedcontentfilter/vendor/slim/slim/Slim/Routing/RoutingResults.php create mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php create mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php create mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php create mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php create mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php create mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index f2927f57..55bc5005 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -190,7 +190,7 @@ function advancedcontentfilter_module() {} function advancedcontentfilter_init() { if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] == 'api') { - $slim = new \Slim\App(); + $slim = \Slim\Factory\AppFactory::create(); require __DIR__ . '/src/middlewares.php'; @@ -305,7 +305,7 @@ function advancedcontentfilter_build_fields($data) * API */ -function advancedcontentfilter_get_rules() +function advancedcontentfilter_get_rules(ServerRequestInterface $request, ResponseInterface $response) { if (!DI::userSession()->getLocalUserId()) { throw new HTTPException\UnauthorizedException(DI::l10n()->t('You must be logged in to use this method')); @@ -313,7 +313,8 @@ function advancedcontentfilter_get_rules() $rules = DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])); - return json_encode($rules); + $response->getBody()->write(json_encode($rules)); + return $response->withHeader('Content-Type', 'application/json'); } function advancedcontentfilter_get_rules_id(ServerRequestInterface $request, ResponseInterface $response, $args) @@ -324,10 +325,11 @@ function advancedcontentfilter_get_rules_id(ServerRequestInterface $request, Res $rule = DBA::selectFirst('advancedcontentfilter_rules', [], ['id' => $args['id'], 'uid' => DI::userSession()->getLocalUserId()]); - return json_encode($rule); + $response->getBody()->write(json_encode($rule)); + return $response->withHeader('Content-Type', 'application/json'); } -function advancedcontentfilter_post_rules(ServerRequestInterface $request) +function advancedcontentfilter_post_rules(ServerRequestInterface $request, ResponseInterface $response) { if (!DI::userSession()->getLocalUserId()) { throw new HTTPException\UnauthorizedException(DI::l10n()->t('You must be logged in to use this method')); @@ -360,7 +362,8 @@ function advancedcontentfilter_post_rules(ServerRequestInterface $request) DI::cache()->delete('rules_' . DI::userSession()->getLocalUserId()); - return json_encode(['message' => DI::l10n()->t('Rule successfully added'), 'rule' => $rule]); + $response->getBody()->write(json_encode(['message' => DI::l10n()->t('Rule successfully added'), 'rule' => $rule])); + return $response->withHeader('Content-Type', 'application/json'); } function advancedcontentfilter_put_rules_id(ServerRequestInterface $request, ResponseInterface $response, $args) @@ -391,7 +394,8 @@ function advancedcontentfilter_put_rules_id(ServerRequestInterface $request, Res DI::cache()->delete('rules_' . DI::userSession()->getLocalUserId()); - return json_encode(['message' => DI::l10n()->t('Rule successfully updated')]); + $response->getBody()->write(json_encode(['message' => DI::l10n()->t('Rule successfully updated')])); + return $response->withHeader('Content-Type', 'application/json'); } function advancedcontentfilter_delete_rules_id(ServerRequestInterface $request, ResponseInterface $response, $args) @@ -414,7 +418,8 @@ function advancedcontentfilter_delete_rules_id(ServerRequestInterface $request, DI::cache()->delete('rules_' . DI::userSession()->getLocalUserId()); - return json_encode(['message' => DI::l10n()->t('Rule successfully deleted')]); + $response->getBody()->write(json_encode(['message' => DI::l10n()->t('Rule successfully deleted')])); + return $response->withHeader('Content-Type', 'application/json'); } function advancedcontentfilter_get_variables_guid(ServerRequestInterface $request, ResponseInterface $response, $args) @@ -437,7 +442,8 @@ function advancedcontentfilter_get_variables_guid(ServerRequestInterface $reques $return = advancedcontentfilter_get_filter_fields(advancedcontentfilter_prepare_item_row($item_row)); - return json_encode(['variables' => str_replace('\\\'', '\'', var_export($return, true))]); + $response->getBody()->write(json_encode(['variables' => str_replace('\\\'', '\'', var_export($return, true))])); + return $response->withHeader('Content-Type', 'application/json'); } /** diff --git a/advancedcontentfilter/composer.json b/advancedcontentfilter/composer.json index 93b19cd5..ceb152e7 100644 --- a/advancedcontentfilter/composer.json +++ b/advancedcontentfilter/composer.json @@ -11,8 +11,7 @@ } ], "require": { - "php": ">=5.6.0", - "slim/slim": "^3.1", + "slim/slim": "^4", "symfony/expression-language": "^3.4" }, "license": "3-clause BSD license", diff --git a/advancedcontentfilter/composer.lock b/advancedcontentfilter/composer.lock index 774b5ec8..83d61074 100644 --- a/advancedcontentfilter/composer.lock +++ b/advancedcontentfilter/composer.lock @@ -4,40 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d0e3662dd9d910ffe4f71d325bc39319", + "content-hash": "3e87f0369e4799fc35d98f399c67f1e9", "packages": [ - { - "name": "container-interop/container-interop", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/container-interop/container-interop.git", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "shasum": "" - }, - "require": { - "psr/container": "^1.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "homepage": "https://github.com/container-interop/container-interop", - "abandoned": "psr/container", - "time": "2017-02-14T19:40:03+00:00" - }, { "name": "nikic/fast-route", "version": "v1.3.0", @@ -84,56 +52,6 @@ ], "time": "2018-02-13T20:26:39+00:00" }, - { - "name": "pimple/pimple", - "version": "v3.2.3", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32", - "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/container": "^1.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "^3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2.x-dev" - } - }, - "autoload": { - "psr-0": { - "Pimple": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple, a simple Dependency Injection Container", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ], - "time": "2018-01-21T07:42:36+00:00" - }, { "name": "psr/cache", "version": "1.0.1", @@ -182,25 +100,25 @@ }, { "name": "psr/container", - "version": "1.0.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -215,7 +133,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -227,24 +145,25 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { - "name": "psr/http-message", - "version": "1.0.1", + "name": "psr/http-factory", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" }, "type": "library", "extra": { @@ -261,6 +180,57 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "time": "2023-04-10T20:10:41+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], "authors": [ { "name": "PHP-FIG", @@ -277,20 +247,126 @@ "request", "response" ], - "time": "2016-08-06T14:39:51+00:00" + "time": "2023-04-04T09:50:52+00:00" }, { - "name": "psr/log", - "version": "1.1.2", + "name": "psr/http-server-handler", + "version": "1.0.2", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801" + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801", - "reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "time": "2023-04-10T20:06:20+00:00" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "time": "2023-04-11T06:14:47+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -314,7 +390,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -324,7 +400,7 @@ "psr", "psr-3" ], - "time": "2019-11-01T11:05:21+00:00" + "time": "2021-05-03T11:20:27+00:00" }, { "name": "psr/simple-cache", @@ -376,32 +452,51 @@ }, { "name": "slim/slim", - "version": "3.9.2", + "version": "4.12.0", "source": { "type": "git", "url": "https://github.com/slimphp/Slim.git", - "reference": "4086d0106cf5a7135c69fce4161fe355a8feb118" + "reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slimphp/Slim/zipball/4086d0106cf5a7135c69fce4161fe355a8feb118", - "reference": "4086d0106cf5a7135c69fce4161fe355a8feb118", + "url": "https://api.github.com/repos/slimphp/Slim/zipball/e9e99c2b24398b967841c6c4c3048622cc7e2b18", + "reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18", "shasum": "" }, "require": { - "container-interop/container-interop": "^1.2", - "nikic/fast-route": "^1.0", - "php": ">=5.5.0", - "pimple/pimple": "^3.0", - "psr/container": "^1.0", - "psr/http-message": "^1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" + "ext-json": "*", + "nikic/fast-route": "^1.3", + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.1 || ^2.0 || ^3.0" }, "require-dev": { - "phpunit/phpunit": "^4.0", - "squizlabs/php_codesniffer": "^2.5" + "adriansuter/php-autoload-override": "^1.4", + "ext-simplexml": "*", + "guzzlehttp/psr7": "^2.5", + "httpsoft/http-message": "^1.1", + "httpsoft/http-server-request": "^1.1", + "laminas/laminas-diactoros": "^2.17", + "nyholm/psr7": "^1.8", + "nyholm/psr7-server": "^1.0", + "phpspec/prophecy": "^1.17", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "slim/http": "^1.3", + "slim/psr7": "^1.6", + "squizlabs/php_codesniffer": "^3.7" + }, + "suggest": { + "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", + "ext-xml": "Needed to support XML format in BodyParsingMiddleware", + "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", + "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." }, "type": "library", "autoload": { @@ -414,49 +509,64 @@ "MIT" ], "authors": [ - { - "name": "Rob Allen", - "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" - }, { "name": "Josh Lockhart", "email": "hello@joshlockhart.com", "homepage": "https://joshlockhart.com" }, - { - "name": "Gabriel Manricks", - "email": "gmanricks@me.com", - "homepage": "http://gabrielmanricks.com" - }, { "name": "Andrew Smith", "email": "a.smith@silentworks.co.uk", "homepage": "http://silentworks.co.uk" + }, + { + "name": "Rob Allen", + "email": "rob@akrabat.com", + "homepage": "http://akrabat.com" + }, + { + "name": "Pierre Berube", + "email": "pierre@lgse.com", + "homepage": "http://www.lgse.com" + }, + { + "name": "Gabriel Manricks", + "email": "gmanricks@me.com", + "homepage": "http://gabrielmanricks.com" } ], "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", - "homepage": "https://slimframework.com", + "homepage": "https://www.slimframework.com", "keywords": [ "api", "framework", "micro", "router" ], - "time": "2017-11-26T19:13:09+00:00" + "funding": [ + { + "url": "https://opencollective.com/slimphp", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slim/slim", + "type": "tidelift" + } + ], + "time": "2023-07-23T04:54:29+00:00" }, { "name": "symfony/cache", - "version": "v3.4.36", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "3d9f46a6960fd5cd7f030f86adc5b4b63bcfa4e3" + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/3d9f46a6960fd5cd7f030f86adc5b4b63bcfa4e3", - "reference": "3d9f46a6960fd5cd7f030f86adc5b4b63bcfa4e3", + "url": "https://api.github.com/repos/symfony/cache/zipball/a7a14c4832760bd1fbd31be2859ffedc9b6ff813", + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813", "shasum": "" }, "require": { @@ -475,16 +585,11 @@ }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/cache": "~1.6", - "doctrine/dbal": "~2.4", - "predis/predis": "~1.0" + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Cache\\": "" @@ -513,32 +618,42 @@ "caching", "psr6" ], - "time": "2019-12-01T10:45:41+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" }, { "name": "symfony/expression-language", - "version": "v3.4.8", + "version": "v3.4.47", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "867e4d1f5d4e52435a8ffff6b24fd6a801582241" + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/867e4d1f5d4e52435a8ffff6b24fd6a801582241", - "reference": "867e4d1f5d4e52435a8ffff6b24fd6a801582241", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", "shasum": "" }, "require": { "php": "^5.5.9|>=7.0.8", - "symfony/cache": "~3.1|~4.0" + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\ExpressionLanguage\\": "" @@ -563,38 +678,56 @@ ], "description": "Symfony ExpressionLanguage Component", "homepage": "https://symfony.com", - "time": "2018-01-03T07:37:34+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" }, { "name": "symfony/polyfill-apcu", - "version": "v1.13.1", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-apcu.git", - "reference": "a8e961c841b9ec52927a87914f8820a1ad8f8116" + "reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/a8e961c841b9ec52927a87914f8820a1ad8f8116", - "reference": "a8e961c841b9ec52927a87914f8820a1ad8f8116", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899", + "reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.13-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Apcu\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Apcu\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -619,7 +752,86 @@ "portable", "shim" ], - "time": "2019-11-27T13:56:44+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "metapackage", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" } ], "packages-dev": [], @@ -631,5 +843,6 @@ "platform": { "php": ">=5.6.0" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/advancedcontentfilter/src/middlewares.php b/advancedcontentfilter/src/middlewares.php index dffb9363..84dd6ed8 100644 --- a/advancedcontentfilter/src/middlewares.php +++ b/advancedcontentfilter/src/middlewares.php @@ -21,31 +21,12 @@ use Friendica\DI; -$container = $slim->getContainer(); +/** @var $slim \Slim\App */ -// Error handler based off https://stackoverflow.com/a/48135009/757392 -$container['errorHandler'] = function () { - return function(Psr\Http\Message\RequestInterface $request, Psr\Http\Message\ResponseInterface $response, Exception $exception) - { - $responseCode = 500; +/** + * The routing middleware should be added before the ErrorMiddleware + * Otherwise exceptions thrown from it will not be handled + */ +$slim->addRoutingMiddleware(); - if (is_a($exception, 'Friendica\Network\HTTPException')) { - $responseCode = $exception->getCode(); - } - - $errors['message'] = $exception->getMessage(); - - $errors['responseCode'] = $responseCode; - - return $response - ->withStatus($responseCode) - ->withJson($errors); - }; -}; - -$container['notFoundHandler'] = function () { - return function () - { - throw new \Friendica\Network\HTTPException\NotFoundException(DI::l10n()->t('Method not found')); - }; -}; +$errorMiddleware = $slim->addErrorMiddleware(true, true, true); diff --git a/advancedcontentfilter/src/routes.php b/advancedcontentfilter/src/routes.php index 09077bda..a46f1b4b 100644 --- a/advancedcontentfilter/src/routes.php +++ b/advancedcontentfilter/src/routes.php @@ -20,20 +20,17 @@ */ /* @var $slim Slim\App */ -$slim->group('/advancedcontentfilter/api', function () { - /* @var $this Slim\App */ - $this->group('/rules', function () { - /* @var $this Slim\App */ - $this->get('', 'advancedcontentfilter_get_rules'); - $this->post('', 'advancedcontentfilter_post_rules'); +$slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->get('', 'advancedcontentfilter_get_rules'); + $app->post('', 'advancedcontentfilter_post_rules'); - $this->get('/{id}', 'advancedcontentfilter_get_rules_id'); - $this->put('/{id}', 'advancedcontentfilter_put_rules_id'); - $this->delete('/{id}', 'advancedcontentfilter_delete_rules_id'); + $app->get('/{id}', 'advancedcontentfilter_get_rules_id'); + $app->put('/{id}', 'advancedcontentfilter_put_rules_id'); + $app->delete('/{id}', 'advancedcontentfilter_delete_rules_id'); }); - $this->group('/variables', function () { - /* @var $this Slim\App */ - $this->get('/{guid}', 'advancedcontentfilter_get_variables_guid'); + $app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->get('/{guid}', 'advancedcontentfilter_get_variables_guid'); }); }); diff --git a/advancedcontentfilter/vendor/composer/ClassLoader.php b/advancedcontentfilter/vendor/composer/ClassLoader.php index dc02dfb1..03b9bb9c 100644 --- a/advancedcontentfilter/vendor/composer/ClassLoader.php +++ b/advancedcontentfilter/vendor/composer/ClassLoader.php @@ -60,7 +60,7 @@ class ClassLoader public function getPrefixes() { if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); } return array(); @@ -279,7 +279,7 @@ class ClassLoader */ public function setApcuPrefix($apcuPrefix) { - $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null; + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; } /** @@ -377,7 +377,7 @@ class ClassLoader $subPath = $class; while (false !== $lastPos = strrpos($subPath, '\\')) { $subPath = substr($subPath, 0, $lastPos); - $search = $subPath.'\\'; + $search = $subPath . '\\'; if (isset($this->prefixDirsPsr4[$search])) { $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); foreach ($this->prefixDirsPsr4[$search] as $dir) { diff --git a/advancedcontentfilter/vendor/composer/autoload_classmap.php b/advancedcontentfilter/vendor/composer/autoload_classmap.php index 4f884be1..aa3de8a3 100644 --- a/advancedcontentfilter/vendor/composer/autoload_classmap.php +++ b/advancedcontentfilter/vendor/composer/autoload_classmap.php @@ -23,27 +23,6 @@ return array( 'FastRoute\\RouteCollector' => $vendorDir . '/nikic/fast-route/src/RouteCollector.php', 'FastRoute\\RouteParser' => $vendorDir . '/nikic/fast-route/src/RouteParser.php', 'FastRoute\\RouteParser\\Std' => $vendorDir . '/nikic/fast-route/src/RouteParser/Std.php', - 'Interop\\Container\\ContainerInterface' => $vendorDir . '/container-interop/container-interop/src/Interop/Container/ContainerInterface.php', - 'Interop\\Container\\Exception\\ContainerException' => $vendorDir . '/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php', - 'Interop\\Container\\Exception\\NotFoundException' => $vendorDir . '/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php', - 'Pimple\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Container.php', - 'Pimple\\Exception\\ExpectedInvokableException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php', - 'Pimple\\Exception\\FrozenServiceException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php', - 'Pimple\\Exception\\InvalidServiceIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php', - 'Pimple\\Exception\\UnknownIdentifierException' => $vendorDir . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php', - 'Pimple\\Psr11\\Container' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/Container.php', - 'Pimple\\Psr11\\ServiceLocator' => $vendorDir . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php', - 'Pimple\\ServiceIterator' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceIterator.php', - 'Pimple\\ServiceProviderInterface' => $vendorDir . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php', - 'Pimple\\Tests\\Fixtures\\Invokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php', - 'Pimple\\Tests\\Fixtures\\NonInvokable' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php', - 'Pimple\\Tests\\Fixtures\\PimpleServiceProvider' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php', - 'Pimple\\Tests\\Fixtures\\Service' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php', - 'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php', - 'Pimple\\Tests\\PimpleTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php', - 'Pimple\\Tests\\Psr11\\ContainerTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php', - 'Pimple\\Tests\\Psr11\\ServiceLocatorTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php', - 'Pimple\\Tests\\ServiceIteratorTest' => $vendorDir . '/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php', 'Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php', 'Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php', 'Psr\\Cache\\CacheItemPoolInterface' => $vendorDir . '/psr/cache/src/CacheItemPoolInterface.php', @@ -52,12 +31,20 @@ return array( 'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', 'Psr\\Container\\NotFoundExceptionInterface' => $vendorDir . '/psr/container/src/NotFoundExceptionInterface.php', 'Psr\\Http\\Message\\MessageInterface' => $vendorDir . '/psr/http-message/src/MessageInterface.php', + 'Psr\\Http\\Message\\RequestFactoryInterface' => $vendorDir . '/psr/http-factory/src/RequestFactoryInterface.php', 'Psr\\Http\\Message\\RequestInterface' => $vendorDir . '/psr/http-message/src/RequestInterface.php', + 'Psr\\Http\\Message\\ResponseFactoryInterface' => $vendorDir . '/psr/http-factory/src/ResponseFactoryInterface.php', 'Psr\\Http\\Message\\ResponseInterface' => $vendorDir . '/psr/http-message/src/ResponseInterface.php', + 'Psr\\Http\\Message\\ServerRequestFactoryInterface' => $vendorDir . '/psr/http-factory/src/ServerRequestFactoryInterface.php', 'Psr\\Http\\Message\\ServerRequestInterface' => $vendorDir . '/psr/http-message/src/ServerRequestInterface.php', + 'Psr\\Http\\Message\\StreamFactoryInterface' => $vendorDir . '/psr/http-factory/src/StreamFactoryInterface.php', 'Psr\\Http\\Message\\StreamInterface' => $vendorDir . '/psr/http-message/src/StreamInterface.php', + 'Psr\\Http\\Message\\UploadedFileFactoryInterface' => $vendorDir . '/psr/http-factory/src/UploadedFileFactoryInterface.php', 'Psr\\Http\\Message\\UploadedFileInterface' => $vendorDir . '/psr/http-message/src/UploadedFileInterface.php', + 'Psr\\Http\\Message\\UriFactoryInterface' => $vendorDir . '/psr/http-factory/src/UriFactoryInterface.php', 'Psr\\Http\\Message\\UriInterface' => $vendorDir . '/psr/http-message/src/UriInterface.php', + 'Psr\\Http\\Server\\MiddlewareInterface' => $vendorDir . '/psr/http-server-middleware/src/MiddlewareInterface.php', + 'Psr\\Http\\Server\\RequestHandlerInterface' => $vendorDir . '/psr/http-server-handler/src/RequestHandlerInterface.php', 'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/Psr/Log/LogLevel.php', @@ -66,57 +53,83 @@ return array( 'Psr\\Log\\LoggerInterface' => $vendorDir . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => $vendorDir . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => $vendorDir . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\DummyTest' => $vendorDir . '/psr/log/Psr/Log/Test/DummyTest.php', 'Psr\\Log\\Test\\LoggerInterfaceTest' => $vendorDir . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\TestLogger' => $vendorDir . '/psr/log/Psr/Log/Test/TestLogger.php', 'Psr\\SimpleCache\\CacheException' => $vendorDir . '/psr/simple-cache/src/CacheException.php', 'Psr\\SimpleCache\\CacheInterface' => $vendorDir . '/psr/simple-cache/src/CacheInterface.php', 'Psr\\SimpleCache\\InvalidArgumentException' => $vendorDir . '/psr/simple-cache/src/InvalidArgumentException.php', 'Slim\\App' => $vendorDir . '/slim/slim/Slim/App.php', 'Slim\\CallableResolver' => $vendorDir . '/slim/slim/Slim/CallableResolver.php', - 'Slim\\CallableResolverAwareTrait' => $vendorDir . '/slim/slim/Slim/CallableResolverAwareTrait.php', - 'Slim\\Collection' => $vendorDir . '/slim/slim/Slim/Collection.php', - 'Slim\\Container' => $vendorDir . '/slim/slim/Slim/Container.php', - 'Slim\\DefaultServicesProvider' => $vendorDir . '/slim/slim/Slim/DefaultServicesProvider.php', - 'Slim\\DeferredCallable' => $vendorDir . '/slim/slim/Slim/DeferredCallable.php', - 'Slim\\Exception\\ContainerException' => $vendorDir . '/slim/slim/Slim/Exception/ContainerException.php', - 'Slim\\Exception\\ContainerValueNotFoundException' => $vendorDir . '/slim/slim/Slim/Exception/ContainerValueNotFoundException.php', - 'Slim\\Exception\\InvalidMethodException' => $vendorDir . '/slim/slim/Slim/Exception/InvalidMethodException.php', - 'Slim\\Exception\\MethodNotAllowedException' => $vendorDir . '/slim/slim/Slim/Exception/MethodNotAllowedException.php', - 'Slim\\Exception\\NotFoundException' => $vendorDir . '/slim/slim/Slim/Exception/NotFoundException.php', - 'Slim\\Exception\\SlimException' => $vendorDir . '/slim/slim/Slim/Exception/SlimException.php', - 'Slim\\Handlers\\AbstractError' => $vendorDir . '/slim/slim/Slim/Handlers/AbstractError.php', - 'Slim\\Handlers\\AbstractHandler' => $vendorDir . '/slim/slim/Slim/Handlers/AbstractHandler.php', - 'Slim\\Handlers\\Error' => $vendorDir . '/slim/slim/Slim/Handlers/Error.php', - 'Slim\\Handlers\\NotAllowed' => $vendorDir . '/slim/slim/Slim/Handlers/NotAllowed.php', - 'Slim\\Handlers\\NotFound' => $vendorDir . '/slim/slim/Slim/Handlers/NotFound.php', - 'Slim\\Handlers\\PhpError' => $vendorDir . '/slim/slim/Slim/Handlers/PhpError.php', + 'Slim\\Error\\AbstractErrorRenderer' => $vendorDir . '/slim/slim/Slim/Error/AbstractErrorRenderer.php', + 'Slim\\Error\\Renderers\\HtmlErrorRenderer' => $vendorDir . '/slim/slim/Slim/Error/Renderers/HtmlErrorRenderer.php', + 'Slim\\Error\\Renderers\\JsonErrorRenderer' => $vendorDir . '/slim/slim/Slim/Error/Renderers/JsonErrorRenderer.php', + 'Slim\\Error\\Renderers\\PlainTextErrorRenderer' => $vendorDir . '/slim/slim/Slim/Error/Renderers/PlainTextErrorRenderer.php', + 'Slim\\Error\\Renderers\\XmlErrorRenderer' => $vendorDir . '/slim/slim/Slim/Error/Renderers/XmlErrorRenderer.php', + 'Slim\\Exception\\HttpBadRequestException' => $vendorDir . '/slim/slim/Slim/Exception/HttpBadRequestException.php', + 'Slim\\Exception\\HttpException' => $vendorDir . '/slim/slim/Slim/Exception/HttpException.php', + 'Slim\\Exception\\HttpForbiddenException' => $vendorDir . '/slim/slim/Slim/Exception/HttpForbiddenException.php', + 'Slim\\Exception\\HttpGoneException' => $vendorDir . '/slim/slim/Slim/Exception/HttpGoneException.php', + 'Slim\\Exception\\HttpInternalServerErrorException' => $vendorDir . '/slim/slim/Slim/Exception/HttpInternalServerErrorException.php', + 'Slim\\Exception\\HttpMethodNotAllowedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpMethodNotAllowedException.php', + 'Slim\\Exception\\HttpNotFoundException' => $vendorDir . '/slim/slim/Slim/Exception/HttpNotFoundException.php', + 'Slim\\Exception\\HttpNotImplementedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpNotImplementedException.php', + 'Slim\\Exception\\HttpSpecializedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpSpecializedException.php', + 'Slim\\Exception\\HttpUnauthorizedException' => $vendorDir . '/slim/slim/Slim/Exception/HttpUnauthorizedException.php', + 'Slim\\Factory\\AppFactory' => $vendorDir . '/slim/slim/Slim/Factory/AppFactory.php', + 'Slim\\Factory\\Psr17\\GuzzlePsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php', + 'Slim\\Factory\\Psr17\\HttpSoftPsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/HttpSoftPsr17Factory.php', + 'Slim\\Factory\\Psr17\\LaminasDiactorosPsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/LaminasDiactorosPsr17Factory.php', + 'Slim\\Factory\\Psr17\\NyholmPsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/NyholmPsr17Factory.php', + 'Slim\\Factory\\Psr17\\Psr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/Psr17Factory.php', + 'Slim\\Factory\\Psr17\\Psr17FactoryProvider' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/Psr17FactoryProvider.php', + 'Slim\\Factory\\Psr17\\ServerRequestCreator' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/ServerRequestCreator.php', + 'Slim\\Factory\\Psr17\\SlimHttpPsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/SlimHttpPsr17Factory.php', + 'Slim\\Factory\\Psr17\\SlimHttpServerRequestCreator' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/SlimHttpServerRequestCreator.php', + 'Slim\\Factory\\Psr17\\SlimPsr17Factory' => $vendorDir . '/slim/slim/Slim/Factory/Psr17/SlimPsr17Factory.php', + 'Slim\\Factory\\ServerRequestCreatorFactory' => $vendorDir . '/slim/slim/Slim/Factory/ServerRequestCreatorFactory.php', + 'Slim\\Handlers\\ErrorHandler' => $vendorDir . '/slim/slim/Slim/Handlers/ErrorHandler.php', + 'Slim\\Handlers\\Strategies\\RequestHandler' => $vendorDir . '/slim/slim/Slim/Handlers/Strategies/RequestHandler.php', 'Slim\\Handlers\\Strategies\\RequestResponse' => $vendorDir . '/slim/slim/Slim/Handlers/Strategies/RequestResponse.php', 'Slim\\Handlers\\Strategies\\RequestResponseArgs' => $vendorDir . '/slim/slim/Slim/Handlers/Strategies/RequestResponseArgs.php', - 'Slim\\Http\\Body' => $vendorDir . '/slim/slim/Slim/Http/Body.php', - 'Slim\\Http\\Cookies' => $vendorDir . '/slim/slim/Slim/Http/Cookies.php', - 'Slim\\Http\\Environment' => $vendorDir . '/slim/slim/Slim/Http/Environment.php', - 'Slim\\Http\\Headers' => $vendorDir . '/slim/slim/Slim/Http/Headers.php', - 'Slim\\Http\\Message' => $vendorDir . '/slim/slim/Slim/Http/Message.php', - 'Slim\\Http\\Request' => $vendorDir . '/slim/slim/Slim/Http/Request.php', - 'Slim\\Http\\RequestBody' => $vendorDir . '/slim/slim/Slim/Http/RequestBody.php', - 'Slim\\Http\\Response' => $vendorDir . '/slim/slim/Slim/Http/Response.php', - 'Slim\\Http\\Stream' => $vendorDir . '/slim/slim/Slim/Http/Stream.php', - 'Slim\\Http\\UploadedFile' => $vendorDir . '/slim/slim/Slim/Http/UploadedFile.php', - 'Slim\\Http\\Uri' => $vendorDir . '/slim/slim/Slim/Http/Uri.php', + 'Slim\\Handlers\\Strategies\\RequestResponseNamedArgs' => $vendorDir . '/slim/slim/Slim/Handlers/Strategies/RequestResponseNamedArgs.php', + 'Slim\\Interfaces\\AdvancedCallableResolverInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/AdvancedCallableResolverInterface.php', 'Slim\\Interfaces\\CallableResolverInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/CallableResolverInterface.php', - 'Slim\\Interfaces\\CollectionInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/CollectionInterface.php', - 'Slim\\Interfaces\\Http\\CookiesInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/Http/CookiesInterface.php', - 'Slim\\Interfaces\\Http\\EnvironmentInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/Http/EnvironmentInterface.php', - 'Slim\\Interfaces\\Http\\HeadersInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/Http/HeadersInterface.php', + 'Slim\\Interfaces\\DispatcherInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/DispatcherInterface.php', + 'Slim\\Interfaces\\ErrorHandlerInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/ErrorHandlerInterface.php', + 'Slim\\Interfaces\\ErrorRendererInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/ErrorRendererInterface.php', 'Slim\\Interfaces\\InvocationStrategyInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/InvocationStrategyInterface.php', + 'Slim\\Interfaces\\MiddlewareDispatcherInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/MiddlewareDispatcherInterface.php', + 'Slim\\Interfaces\\Psr17FactoryInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/Psr17FactoryInterface.php', + 'Slim\\Interfaces\\Psr17FactoryProviderInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/Psr17FactoryProviderInterface.php', + 'Slim\\Interfaces\\RequestHandlerInvocationStrategyInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RequestHandlerInvocationStrategyInterface.php', + 'Slim\\Interfaces\\RouteCollectorInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouteCollectorInterface.php', + 'Slim\\Interfaces\\RouteCollectorProxyInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouteCollectorProxyInterface.php', 'Slim\\Interfaces\\RouteGroupInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouteGroupInterface.php', 'Slim\\Interfaces\\RouteInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouteInterface.php', - 'Slim\\Interfaces\\RouterInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouterInterface.php', - 'Slim\\MiddlewareAwareTrait' => $vendorDir . '/slim/slim/Slim/MiddlewareAwareTrait.php', - 'Slim\\Routable' => $vendorDir . '/slim/slim/Slim/Routable.php', - 'Slim\\Route' => $vendorDir . '/slim/slim/Slim/Route.php', - 'Slim\\RouteGroup' => $vendorDir . '/slim/slim/Slim/RouteGroup.php', - 'Slim\\Router' => $vendorDir . '/slim/slim/Slim/Router.php', + 'Slim\\Interfaces\\RouteParserInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouteParserInterface.php', + 'Slim\\Interfaces\\RouteResolverInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/RouteResolverInterface.php', + 'Slim\\Interfaces\\ServerRequestCreatorInterface' => $vendorDir . '/slim/slim/Slim/Interfaces/ServerRequestCreatorInterface.php', + 'Slim\\Logger' => $vendorDir . '/slim/slim/Slim/Logger.php', + 'Slim\\MiddlewareDispatcher' => $vendorDir . '/slim/slim/Slim/MiddlewareDispatcher.php', + 'Slim\\Middleware\\BodyParsingMiddleware' => $vendorDir . '/slim/slim/Slim/Middleware/BodyParsingMiddleware.php', + 'Slim\\Middleware\\ContentLengthMiddleware' => $vendorDir . '/slim/slim/Slim/Middleware/ContentLengthMiddleware.php', + 'Slim\\Middleware\\ErrorMiddleware' => $vendorDir . '/slim/slim/Slim/Middleware/ErrorMiddleware.php', + 'Slim\\Middleware\\MethodOverrideMiddleware' => $vendorDir . '/slim/slim/Slim/Middleware/MethodOverrideMiddleware.php', + 'Slim\\Middleware\\OutputBufferingMiddleware' => $vendorDir . '/slim/slim/Slim/Middleware/OutputBufferingMiddleware.php', + 'Slim\\Middleware\\RoutingMiddleware' => $vendorDir . '/slim/slim/Slim/Middleware/RoutingMiddleware.php', + 'Slim\\ResponseEmitter' => $vendorDir . '/slim/slim/Slim/ResponseEmitter.php', + 'Slim\\Routing\\Dispatcher' => $vendorDir . '/slim/slim/Slim/Routing/Dispatcher.php', + 'Slim\\Routing\\FastRouteDispatcher' => $vendorDir . '/slim/slim/Slim/Routing/FastRouteDispatcher.php', + 'Slim\\Routing\\Route' => $vendorDir . '/slim/slim/Slim/Routing/Route.php', + 'Slim\\Routing\\RouteCollector' => $vendorDir . '/slim/slim/Slim/Routing/RouteCollector.php', + 'Slim\\Routing\\RouteCollectorProxy' => $vendorDir . '/slim/slim/Slim/Routing/RouteCollectorProxy.php', + 'Slim\\Routing\\RouteContext' => $vendorDir . '/slim/slim/Slim/Routing/RouteContext.php', + 'Slim\\Routing\\RouteGroup' => $vendorDir . '/slim/slim/Slim/Routing/RouteGroup.php', + 'Slim\\Routing\\RouteParser' => $vendorDir . '/slim/slim/Slim/Routing/RouteParser.php', + 'Slim\\Routing\\RouteResolver' => $vendorDir . '/slim/slim/Slim/Routing/RouteResolver.php', + 'Slim\\Routing\\RouteRunner' => $vendorDir . '/slim/slim/Slim/Routing/RouteRunner.php', + 'Slim\\Routing\\RoutingResults' => $vendorDir . '/slim/slim/Slim/Routing/RoutingResults.php', 'Symfony\\Component\\Cache\\Adapter\\AbstractAdapter' => $vendorDir . '/symfony/cache/Adapter/AbstractAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\AdapterInterface' => $vendorDir . '/symfony/cache/Adapter/AdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\ApcuAdapter' => $vendorDir . '/symfony/cache/Adapter/ApcuAdapter.php', diff --git a/advancedcontentfilter/vendor/composer/autoload_namespaces.php b/advancedcontentfilter/vendor/composer/autoload_namespaces.php index c3cd0229..b7fc0125 100644 --- a/advancedcontentfilter/vendor/composer/autoload_namespaces.php +++ b/advancedcontentfilter/vendor/composer/autoload_namespaces.php @@ -6,5 +6,4 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - 'Pimple' => array($vendorDir . '/pimple/pimple/src'), ); diff --git a/advancedcontentfilter/vendor/composer/autoload_psr4.php b/advancedcontentfilter/vendor/composer/autoload_psr4.php index f466cc18..87606585 100644 --- a/advancedcontentfilter/vendor/composer/autoload_psr4.php +++ b/advancedcontentfilter/vendor/composer/autoload_psr4.php @@ -12,9 +12,9 @@ return array( 'Slim\\' => array($vendorDir . '/slim/slim/Slim'), 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'), + 'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), - 'Interop\\Container\\' => array($vendorDir . '/container-interop/container-interop/src/Interop/Container'), 'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'), ); diff --git a/advancedcontentfilter/vendor/composer/autoload_real.php b/advancedcontentfilter/vendor/composer/autoload_real.php index 6d7169ae..d6532d7d 100644 --- a/advancedcontentfilter/vendor/composer/autoload_real.php +++ b/advancedcontentfilter/vendor/composer/autoload_real.php @@ -13,6 +13,9 @@ class ComposerAutoloaderInitAdvancedContentFilterAddon } } + /** + * @return \Composer\Autoload\ClassLoader + */ public static function getLoader() { if (null !== self::$loader) { diff --git a/advancedcontentfilter/vendor/composer/autoload_static.php b/advancedcontentfilter/vendor/composer/autoload_static.php index e7c2f8de..917d3d90 100644 --- a/advancedcontentfilter/vendor/composer/autoload_static.php +++ b/advancedcontentfilter/vendor/composer/autoload_static.php @@ -23,14 +23,11 @@ class ComposerStaticInitAdvancedContentFilterAddon array ( 'Psr\\SimpleCache\\' => 16, 'Psr\\Log\\' => 8, + 'Psr\\Http\\Server\\' => 16, 'Psr\\Http\\Message\\' => 17, 'Psr\\Container\\' => 14, 'Psr\\Cache\\' => 10, ), - 'I' => - array ( - 'Interop\\Container\\' => 18, - ), 'F' => array ( 'FastRoute\\' => 10, @@ -62,9 +59,15 @@ class ComposerStaticInitAdvancedContentFilterAddon array ( 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', ), + 'Psr\\Http\\Server\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/http-server-handler/src', + 1 => __DIR__ . '/..' . '/psr/http-server-middleware/src', + ), 'Psr\\Http\\Message\\' => array ( - 0 => __DIR__ . '/..' . '/psr/http-message/src', + 0 => __DIR__ . '/..' . '/psr/http-factory/src', + 1 => __DIR__ . '/..' . '/psr/http-message/src', ), 'Psr\\Container\\' => array ( @@ -74,26 +77,12 @@ class ComposerStaticInitAdvancedContentFilterAddon array ( 0 => __DIR__ . '/..' . '/psr/cache/src', ), - 'Interop\\Container\\' => - array ( - 0 => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container', - ), 'FastRoute\\' => array ( 0 => __DIR__ . '/..' . '/nikic/fast-route/src', ), ); - public static $prefixesPsr0 = array ( - 'P' => - array ( - 'Pimple' => - array ( - 0 => __DIR__ . '/..' . '/pimple/pimple/src', - ), - ), - ); - public static $classMap = array ( 'FastRoute\\BadRouteException' => __DIR__ . '/..' . '/nikic/fast-route/src/BadRouteException.php', 'FastRoute\\DataGenerator' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator.php', @@ -112,27 +101,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'FastRoute\\RouteCollector' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteCollector.php', 'FastRoute\\RouteParser' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteParser.php', 'FastRoute\\RouteParser\\Std' => __DIR__ . '/..' . '/nikic/fast-route/src/RouteParser/Std.php', - 'Interop\\Container\\ContainerInterface' => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container/ContainerInterface.php', - 'Interop\\Container\\Exception\\ContainerException' => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php', - 'Interop\\Container\\Exception\\NotFoundException' => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php', - 'Pimple\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Container.php', - 'Pimple\\Exception\\ExpectedInvokableException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php', - 'Pimple\\Exception\\FrozenServiceException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php', - 'Pimple\\Exception\\InvalidServiceIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php', - 'Pimple\\Exception\\UnknownIdentifierException' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php', - 'Pimple\\Psr11\\Container' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/Container.php', - 'Pimple\\Psr11\\ServiceLocator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php', - 'Pimple\\ServiceIterator' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceIterator.php', - 'Pimple\\ServiceProviderInterface' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/ServiceProviderInterface.php', - 'Pimple\\Tests\\Fixtures\\Invokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Invokable.php', - 'Pimple\\Tests\\Fixtures\\NonInvokable' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php', - 'Pimple\\Tests\\Fixtures\\PimpleServiceProvider' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/PimpleServiceProvider.php', - 'Pimple\\Tests\\Fixtures\\Service' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php', - 'Pimple\\Tests\\PimpleServiceProviderInterfaceTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php', - 'Pimple\\Tests\\PimpleTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/PimpleTest.php', - 'Pimple\\Tests\\Psr11\\ContainerTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php', - 'Pimple\\Tests\\Psr11\\ServiceLocatorTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php', - 'Pimple\\Tests\\ServiceIteratorTest' => __DIR__ . '/..' . '/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php', 'Psr\\Cache\\CacheException' => __DIR__ . '/..' . '/psr/cache/src/CacheException.php', 'Psr\\Cache\\CacheItemInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemInterface.php', 'Psr\\Cache\\CacheItemPoolInterface' => __DIR__ . '/..' . '/psr/cache/src/CacheItemPoolInterface.php', @@ -141,12 +109,20 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php', 'Psr\\Container\\NotFoundExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/NotFoundExceptionInterface.php', 'Psr\\Http\\Message\\MessageInterface' => __DIR__ . '/..' . '/psr/http-message/src/MessageInterface.php', + 'Psr\\Http\\Message\\RequestFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/RequestFactoryInterface.php', 'Psr\\Http\\Message\\RequestInterface' => __DIR__ . '/..' . '/psr/http-message/src/RequestInterface.php', + 'Psr\\Http\\Message\\ResponseFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/ResponseFactoryInterface.php', 'Psr\\Http\\Message\\ResponseInterface' => __DIR__ . '/..' . '/psr/http-message/src/ResponseInterface.php', + 'Psr\\Http\\Message\\ServerRequestFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/ServerRequestFactoryInterface.php', 'Psr\\Http\\Message\\ServerRequestInterface' => __DIR__ . '/..' . '/psr/http-message/src/ServerRequestInterface.php', + 'Psr\\Http\\Message\\StreamFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/StreamFactoryInterface.php', 'Psr\\Http\\Message\\StreamInterface' => __DIR__ . '/..' . '/psr/http-message/src/StreamInterface.php', + 'Psr\\Http\\Message\\UploadedFileFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/UploadedFileFactoryInterface.php', 'Psr\\Http\\Message\\UploadedFileInterface' => __DIR__ . '/..' . '/psr/http-message/src/UploadedFileInterface.php', + 'Psr\\Http\\Message\\UriFactoryInterface' => __DIR__ . '/..' . '/psr/http-factory/src/UriFactoryInterface.php', 'Psr\\Http\\Message\\UriInterface' => __DIR__ . '/..' . '/psr/http-message/src/UriInterface.php', + 'Psr\\Http\\Server\\MiddlewareInterface' => __DIR__ . '/..' . '/psr/http-server-middleware/src/MiddlewareInterface.php', + 'Psr\\Http\\Server\\RequestHandlerInterface' => __DIR__ . '/..' . '/psr/http-server-handler/src/RequestHandlerInterface.php', 'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/AbstractLogger.php', 'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/Psr/Log/InvalidArgumentException.php', 'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/Psr/Log/LogLevel.php', @@ -155,57 +131,83 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Psr\\Log\\LoggerInterface' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerInterface.php', 'Psr\\Log\\LoggerTrait' => __DIR__ . '/..' . '/psr/log/Psr/Log/LoggerTrait.php', 'Psr\\Log\\NullLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/NullLogger.php', - 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\DummyTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/DummyTest.php', 'Psr\\Log\\Test\\LoggerInterfaceTest' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/LoggerInterfaceTest.php', + 'Psr\\Log\\Test\\TestLogger' => __DIR__ . '/..' . '/psr/log/Psr/Log/Test/TestLogger.php', 'Psr\\SimpleCache\\CacheException' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheException.php', 'Psr\\SimpleCache\\CacheInterface' => __DIR__ . '/..' . '/psr/simple-cache/src/CacheInterface.php', 'Psr\\SimpleCache\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/simple-cache/src/InvalidArgumentException.php', 'Slim\\App' => __DIR__ . '/..' . '/slim/slim/Slim/App.php', 'Slim\\CallableResolver' => __DIR__ . '/..' . '/slim/slim/Slim/CallableResolver.php', - 'Slim\\CallableResolverAwareTrait' => __DIR__ . '/..' . '/slim/slim/Slim/CallableResolverAwareTrait.php', - 'Slim\\Collection' => __DIR__ . '/..' . '/slim/slim/Slim/Collection.php', - 'Slim\\Container' => __DIR__ . '/..' . '/slim/slim/Slim/Container.php', - 'Slim\\DefaultServicesProvider' => __DIR__ . '/..' . '/slim/slim/Slim/DefaultServicesProvider.php', - 'Slim\\DeferredCallable' => __DIR__ . '/..' . '/slim/slim/Slim/DeferredCallable.php', - 'Slim\\Exception\\ContainerException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/ContainerException.php', - 'Slim\\Exception\\ContainerValueNotFoundException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/ContainerValueNotFoundException.php', - 'Slim\\Exception\\InvalidMethodException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/InvalidMethodException.php', - 'Slim\\Exception\\MethodNotAllowedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/MethodNotAllowedException.php', - 'Slim\\Exception\\NotFoundException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/NotFoundException.php', - 'Slim\\Exception\\SlimException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/SlimException.php', - 'Slim\\Handlers\\AbstractError' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/AbstractError.php', - 'Slim\\Handlers\\AbstractHandler' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/AbstractHandler.php', - 'Slim\\Handlers\\Error' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/Error.php', - 'Slim\\Handlers\\NotAllowed' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/NotAllowed.php', - 'Slim\\Handlers\\NotFound' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/NotFound.php', - 'Slim\\Handlers\\PhpError' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/PhpError.php', + 'Slim\\Error\\AbstractErrorRenderer' => __DIR__ . '/..' . '/slim/slim/Slim/Error/AbstractErrorRenderer.php', + 'Slim\\Error\\Renderers\\HtmlErrorRenderer' => __DIR__ . '/..' . '/slim/slim/Slim/Error/Renderers/HtmlErrorRenderer.php', + 'Slim\\Error\\Renderers\\JsonErrorRenderer' => __DIR__ . '/..' . '/slim/slim/Slim/Error/Renderers/JsonErrorRenderer.php', + 'Slim\\Error\\Renderers\\PlainTextErrorRenderer' => __DIR__ . '/..' . '/slim/slim/Slim/Error/Renderers/PlainTextErrorRenderer.php', + 'Slim\\Error\\Renderers\\XmlErrorRenderer' => __DIR__ . '/..' . '/slim/slim/Slim/Error/Renderers/XmlErrorRenderer.php', + 'Slim\\Exception\\HttpBadRequestException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpBadRequestException.php', + 'Slim\\Exception\\HttpException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpException.php', + 'Slim\\Exception\\HttpForbiddenException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpForbiddenException.php', + 'Slim\\Exception\\HttpGoneException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpGoneException.php', + 'Slim\\Exception\\HttpInternalServerErrorException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpInternalServerErrorException.php', + 'Slim\\Exception\\HttpMethodNotAllowedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpMethodNotAllowedException.php', + 'Slim\\Exception\\HttpNotFoundException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpNotFoundException.php', + 'Slim\\Exception\\HttpNotImplementedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpNotImplementedException.php', + 'Slim\\Exception\\HttpSpecializedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpSpecializedException.php', + 'Slim\\Exception\\HttpUnauthorizedException' => __DIR__ . '/..' . '/slim/slim/Slim/Exception/HttpUnauthorizedException.php', + 'Slim\\Factory\\AppFactory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/AppFactory.php', + 'Slim\\Factory\\Psr17\\GuzzlePsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php', + 'Slim\\Factory\\Psr17\\HttpSoftPsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/HttpSoftPsr17Factory.php', + 'Slim\\Factory\\Psr17\\LaminasDiactorosPsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/LaminasDiactorosPsr17Factory.php', + 'Slim\\Factory\\Psr17\\NyholmPsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/NyholmPsr17Factory.php', + 'Slim\\Factory\\Psr17\\Psr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/Psr17Factory.php', + 'Slim\\Factory\\Psr17\\Psr17FactoryProvider' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/Psr17FactoryProvider.php', + 'Slim\\Factory\\Psr17\\ServerRequestCreator' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/ServerRequestCreator.php', + 'Slim\\Factory\\Psr17\\SlimHttpPsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/SlimHttpPsr17Factory.php', + 'Slim\\Factory\\Psr17\\SlimHttpServerRequestCreator' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/SlimHttpServerRequestCreator.php', + 'Slim\\Factory\\Psr17\\SlimPsr17Factory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/Psr17/SlimPsr17Factory.php', + 'Slim\\Factory\\ServerRequestCreatorFactory' => __DIR__ . '/..' . '/slim/slim/Slim/Factory/ServerRequestCreatorFactory.php', + 'Slim\\Handlers\\ErrorHandler' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/ErrorHandler.php', + 'Slim\\Handlers\\Strategies\\RequestHandler' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/Strategies/RequestHandler.php', 'Slim\\Handlers\\Strategies\\RequestResponse' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/Strategies/RequestResponse.php', 'Slim\\Handlers\\Strategies\\RequestResponseArgs' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/Strategies/RequestResponseArgs.php', - 'Slim\\Http\\Body' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Body.php', - 'Slim\\Http\\Cookies' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Cookies.php', - 'Slim\\Http\\Environment' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Environment.php', - 'Slim\\Http\\Headers' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Headers.php', - 'Slim\\Http\\Message' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Message.php', - 'Slim\\Http\\Request' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Request.php', - 'Slim\\Http\\RequestBody' => __DIR__ . '/..' . '/slim/slim/Slim/Http/RequestBody.php', - 'Slim\\Http\\Response' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Response.php', - 'Slim\\Http\\Stream' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Stream.php', - 'Slim\\Http\\UploadedFile' => __DIR__ . '/..' . '/slim/slim/Slim/Http/UploadedFile.php', - 'Slim\\Http\\Uri' => __DIR__ . '/..' . '/slim/slim/Slim/Http/Uri.php', + 'Slim\\Handlers\\Strategies\\RequestResponseNamedArgs' => __DIR__ . '/..' . '/slim/slim/Slim/Handlers/Strategies/RequestResponseNamedArgs.php', + 'Slim\\Interfaces\\AdvancedCallableResolverInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/AdvancedCallableResolverInterface.php', 'Slim\\Interfaces\\CallableResolverInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/CallableResolverInterface.php', - 'Slim\\Interfaces\\CollectionInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/CollectionInterface.php', - 'Slim\\Interfaces\\Http\\CookiesInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/Http/CookiesInterface.php', - 'Slim\\Interfaces\\Http\\EnvironmentInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/Http/EnvironmentInterface.php', - 'Slim\\Interfaces\\Http\\HeadersInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/Http/HeadersInterface.php', + 'Slim\\Interfaces\\DispatcherInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/DispatcherInterface.php', + 'Slim\\Interfaces\\ErrorHandlerInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/ErrorHandlerInterface.php', + 'Slim\\Interfaces\\ErrorRendererInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/ErrorRendererInterface.php', 'Slim\\Interfaces\\InvocationStrategyInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/InvocationStrategyInterface.php', + 'Slim\\Interfaces\\MiddlewareDispatcherInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/MiddlewareDispatcherInterface.php', + 'Slim\\Interfaces\\Psr17FactoryInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/Psr17FactoryInterface.php', + 'Slim\\Interfaces\\Psr17FactoryProviderInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/Psr17FactoryProviderInterface.php', + 'Slim\\Interfaces\\RequestHandlerInvocationStrategyInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RequestHandlerInvocationStrategyInterface.php', + 'Slim\\Interfaces\\RouteCollectorInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouteCollectorInterface.php', + 'Slim\\Interfaces\\RouteCollectorProxyInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouteCollectorProxyInterface.php', 'Slim\\Interfaces\\RouteGroupInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouteGroupInterface.php', 'Slim\\Interfaces\\RouteInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouteInterface.php', - 'Slim\\Interfaces\\RouterInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouterInterface.php', - 'Slim\\MiddlewareAwareTrait' => __DIR__ . '/..' . '/slim/slim/Slim/MiddlewareAwareTrait.php', - 'Slim\\Routable' => __DIR__ . '/..' . '/slim/slim/Slim/Routable.php', - 'Slim\\Route' => __DIR__ . '/..' . '/slim/slim/Slim/Route.php', - 'Slim\\RouteGroup' => __DIR__ . '/..' . '/slim/slim/Slim/RouteGroup.php', - 'Slim\\Router' => __DIR__ . '/..' . '/slim/slim/Slim/Router.php', + 'Slim\\Interfaces\\RouteParserInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouteParserInterface.php', + 'Slim\\Interfaces\\RouteResolverInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/RouteResolverInterface.php', + 'Slim\\Interfaces\\ServerRequestCreatorInterface' => __DIR__ . '/..' . '/slim/slim/Slim/Interfaces/ServerRequestCreatorInterface.php', + 'Slim\\Logger' => __DIR__ . '/..' . '/slim/slim/Slim/Logger.php', + 'Slim\\MiddlewareDispatcher' => __DIR__ . '/..' . '/slim/slim/Slim/MiddlewareDispatcher.php', + 'Slim\\Middleware\\BodyParsingMiddleware' => __DIR__ . '/..' . '/slim/slim/Slim/Middleware/BodyParsingMiddleware.php', + 'Slim\\Middleware\\ContentLengthMiddleware' => __DIR__ . '/..' . '/slim/slim/Slim/Middleware/ContentLengthMiddleware.php', + 'Slim\\Middleware\\ErrorMiddleware' => __DIR__ . '/..' . '/slim/slim/Slim/Middleware/ErrorMiddleware.php', + 'Slim\\Middleware\\MethodOverrideMiddleware' => __DIR__ . '/..' . '/slim/slim/Slim/Middleware/MethodOverrideMiddleware.php', + 'Slim\\Middleware\\OutputBufferingMiddleware' => __DIR__ . '/..' . '/slim/slim/Slim/Middleware/OutputBufferingMiddleware.php', + 'Slim\\Middleware\\RoutingMiddleware' => __DIR__ . '/..' . '/slim/slim/Slim/Middleware/RoutingMiddleware.php', + 'Slim\\ResponseEmitter' => __DIR__ . '/..' . '/slim/slim/Slim/ResponseEmitter.php', + 'Slim\\Routing\\Dispatcher' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/Dispatcher.php', + 'Slim\\Routing\\FastRouteDispatcher' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/FastRouteDispatcher.php', + 'Slim\\Routing\\Route' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/Route.php', + 'Slim\\Routing\\RouteCollector' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteCollector.php', + 'Slim\\Routing\\RouteCollectorProxy' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteCollectorProxy.php', + 'Slim\\Routing\\RouteContext' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteContext.php', + 'Slim\\Routing\\RouteGroup' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteGroup.php', + 'Slim\\Routing\\RouteParser' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteParser.php', + 'Slim\\Routing\\RouteResolver' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteResolver.php', + 'Slim\\Routing\\RouteRunner' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RouteRunner.php', + 'Slim\\Routing\\RoutingResults' => __DIR__ . '/..' . '/slim/slim/Slim/Routing/RoutingResults.php', 'Symfony\\Component\\Cache\\Adapter\\AbstractAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/AbstractAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\AdapterInterface' => __DIR__ . '/..' . '/symfony/cache/Adapter/AdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\ApcuAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/ApcuAdapter.php', @@ -294,7 +296,6 @@ class ComposerStaticInitAdvancedContentFilterAddon return \Closure::bind(function () use ($loader) { $loader->prefixLengthsPsr4 = ComposerStaticInitAdvancedContentFilterAddon::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInitAdvancedContentFilterAddon::$prefixDirsPsr4; - $loader->prefixesPsr0 = ComposerStaticInitAdvancedContentFilterAddon::$prefixesPsr0; $loader->classMap = ComposerStaticInitAdvancedContentFilterAddon::$classMap; }, null, ClassLoader::class); diff --git a/advancedcontentfilter/vendor/composer/installed.json b/advancedcontentfilter/vendor/composer/installed.json index 8e6b80dc..1a84a8fd 100644 --- a/advancedcontentfilter/vendor/composer/installed.json +++ b/advancedcontentfilter/vendor/composer/installed.json @@ -1,37 +1,4 @@ [ - { - "name": "container-interop/container-interop", - "version": "1.2.0", - "version_normalized": "1.2.0.0", - "source": { - "type": "git", - "url": "https://github.com/container-interop/container-interop.git", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "shasum": "" - }, - "require": { - "psr/container": "^1.0" - }, - "time": "2017-02-14T19:40:03+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "homepage": "https://github.com/container-interop/container-interop" - }, { "name": "nikic/fast-route", "version": "v1.3.0", @@ -80,58 +47,6 @@ "routing" ] }, - { - "name": "pimple/pimple", - "version": "v3.2.3", - "version_normalized": "3.2.3.0", - "source": { - "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32", - "reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32", - "shasum": "" - }, - "require": { - "php": ">=5.3.0", - "psr/container": "^1.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "^3.2" - }, - "time": "2018-01-21T07:42:36+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.2.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-0": { - "Pimple": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Pimple, a simple Dependency Injection Container", - "homepage": "http://pimple.sensiolabs.org", - "keywords": [ - "container", - "dependency injection" - ] - }, { "name": "psr/cache", "version": "1.0.1", @@ -182,27 +97,27 @@ }, { "name": "psr/container", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "2.0.2", + "version_normalized": "2.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.4.0" }, - "time": "2017-02-14T16:28:37+00:00", + "time": "2021-11-05T16:47:00+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "installation-source": "dist", @@ -218,7 +133,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -232,24 +147,25 @@ ] }, { - "name": "psr/http-message", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "name": "psr/http-factory", + "version": "1.0.2", + "version_normalized": "1.0.2.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", - "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" }, - "time": "2016-08-06T14:39:51+00:00", + "time": "2023-04-10T20:10:41+00:00", "type": "library", "extra": { "branch-alias": { @@ -266,6 +182,59 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ] + }, + { + "name": "psr/http-message", + "version": "1.1", + "version_normalized": "1.1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:50:52+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], "authors": [ { "name": "PHP-FIG", @@ -284,28 +253,138 @@ ] }, { - "name": "psr/log", + "name": "psr/http-server-handler", "version": "1.0.2", "version_normalized": "1.0.2.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", - "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "time": "2023-04-10T20:06:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ] + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "time": "2023-04-11T06:14:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ] + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "time": "2016-10-10T12:19:37+00:00", + "time": "2021-05-03T11:20:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "installation-source": "dist", @@ -321,7 +400,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -384,35 +463,54 @@ }, { "name": "slim/slim", - "version": "3.9.2", - "version_normalized": "3.9.2.0", + "version": "4.12.0", + "version_normalized": "4.12.0.0", "source": { "type": "git", "url": "https://github.com/slimphp/Slim.git", - "reference": "4086d0106cf5a7135c69fce4161fe355a8feb118" + "reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slimphp/Slim/zipball/4086d0106cf5a7135c69fce4161fe355a8feb118", - "reference": "4086d0106cf5a7135c69fce4161fe355a8feb118", + "url": "https://api.github.com/repos/slimphp/Slim/zipball/e9e99c2b24398b967841c6c4c3048622cc7e2b18", + "reference": "e9e99c2b24398b967841c6c4c3048622cc7e2b18", "shasum": "" }, "require": { - "container-interop/container-interop": "^1.2", - "nikic/fast-route": "^1.0", - "php": ">=5.5.0", - "pimple/pimple": "^3.0", - "psr/container": "^1.0", - "psr/http-message": "^1.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" + "ext-json": "*", + "nikic/fast-route": "^1.3", + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.1 || ^2.0 || ^3.0" }, "require-dev": { - "phpunit/phpunit": "^4.0", - "squizlabs/php_codesniffer": "^2.5" + "adriansuter/php-autoload-override": "^1.4", + "ext-simplexml": "*", + "guzzlehttp/psr7": "^2.5", + "httpsoft/http-message": "^1.1", + "httpsoft/http-server-request": "^1.1", + "laminas/laminas-diactoros": "^2.17", + "nyholm/psr7": "^1.8", + "nyholm/psr7-server": "^1.0", + "phpspec/prophecy": "^1.17", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "slim/http": "^1.3", + "slim/psr7": "^1.6", + "squizlabs/php_codesniffer": "^3.7" }, - "time": "2017-11-26T19:13:09+00:00", + "suggest": { + "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", + "ext-xml": "Needed to support XML format in BodyParsingMiddleware", + "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", + "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." + }, + "time": "2023-07-23T04:54:29+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -425,49 +523,64 @@ "MIT" ], "authors": [ - { - "name": "Rob Allen", - "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" - }, { "name": "Josh Lockhart", "email": "hello@joshlockhart.com", "homepage": "https://joshlockhart.com" }, - { - "name": "Gabriel Manricks", - "email": "gmanricks@me.com", - "homepage": "http://gabrielmanricks.com" - }, { "name": "Andrew Smith", "email": "a.smith@silentworks.co.uk", "homepage": "http://silentworks.co.uk" + }, + { + "name": "Rob Allen", + "email": "rob@akrabat.com", + "homepage": "http://akrabat.com" + }, + { + "name": "Pierre Berube", + "email": "pierre@lgse.com", + "homepage": "http://www.lgse.com" + }, + { + "name": "Gabriel Manricks", + "email": "gmanricks@me.com", + "homepage": "http://gabrielmanricks.com" } ], "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", - "homepage": "https://slimframework.com", + "homepage": "https://www.slimframework.com", "keywords": [ "api", "framework", "micro", "router" + ], + "funding": [ + { + "url": "https://opencollective.com/slimphp", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slim/slim", + "type": "tidelift" + } ] }, { "name": "symfony/cache", - "version": "v3.4.8", - "version_normalized": "3.4.8.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "13255ddd056e49f3154747943f8ee175d555d394" + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/13255ddd056e49f3154747943f8ee175d555d394", - "reference": "13255ddd056e49f3154747943f8ee175d555d394", + "url": "https://api.github.com/repos/symfony/cache/zipball/a7a14c4832760bd1fbd31be2859ffedc9b6ff813", + "reference": "a7a14c4832760bd1fbd31be2859ffedc9b6ff813", "shasum": "" }, "require": { @@ -486,17 +599,12 @@ }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/cache": "~1.6", - "doctrine/dbal": "~2.4", - "predis/predis": "~1.0" + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" }, - "time": "2018-04-02T14:35:16+00:00", + "time": "2020-10-24T10:57:07+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -525,34 +633,44 @@ "keywords": [ "caching", "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ] }, { "name": "symfony/expression-language", - "version": "v3.4.8", - "version_normalized": "3.4.8.0", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", "source": { "type": "git", "url": "https://github.com/symfony/expression-language.git", - "reference": "867e4d1f5d4e52435a8ffff6b24fd6a801582241" + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/867e4d1f5d4e52435a8ffff6b24fd6a801582241", - "reference": "867e4d1f5d4e52435a8ffff6b24fd6a801582241", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", "shasum": "" }, "require": { "php": "^5.5.9|>=7.0.8", - "symfony/cache": "~3.1|~4.0" + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" }, - "time": "2018-01-03T07:37:34+00:00", + "time": "2020-10-24T10:57:07+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -577,41 +695,59 @@ } ], "description": "Symfony ExpressionLanguage Component", - "homepage": "https://symfony.com" + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] }, { "name": "symfony/polyfill-apcu", - "version": "v1.7.0", - "version_normalized": "1.7.0.0", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-apcu.git", - "reference": "e8ae2136ddb53dea314df56fcd88e318ab936c00" + "reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/e8ae2136ddb53dea314df56fcd88e318ab936c00", - "reference": "e8ae2136ddb53dea314df56fcd88e318ab936c00", + "url": "https://api.github.com/repos/symfony/polyfill-apcu/zipball/c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899", + "reference": "c6c2c0f5f4cb0b100c5dfea807ef5cd27bbe9899", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, - "time": "2018-01-30T19:27:44+00:00", + "time": "2023-01-26T09:26:14+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "installation-source": "dist", "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Apcu\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Apcu\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -635,6 +771,86 @@ "polyfill", "portable", "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.20.0", + "version_normalized": "1.20.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2020-10-23T14:02:19+00:00", + "type": "metapackage", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } ] } ] diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/.gitignore b/advancedcontentfilter/vendor/container-interop/container-interop/.gitignore deleted file mode 100644 index b2395aa0..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -composer.lock -composer.phar -/vendor/ diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/LICENSE b/advancedcontentfilter/vendor/container-interop/container-interop/LICENSE deleted file mode 100644 index 7671d902..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013 container-interop - -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/advancedcontentfilter/vendor/container-interop/container-interop/README.md b/advancedcontentfilter/vendor/container-interop/container-interop/README.md deleted file mode 100644 index cdd7a44c..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/README.md +++ /dev/null @@ -1,148 +0,0 @@ -# Container Interoperability - -[![Latest Stable Version](https://poser.pugx.org/container-interop/container-interop/v/stable.png)](https://packagist.org/packages/container-interop/container-interop) -[![Total Downloads](https://poser.pugx.org/container-interop/container-interop/downloads.svg)](https://packagist.org/packages/container-interop/container-interop) - -## Deprecation warning! - -Starting Feb. 13th 2017, container-interop is officially deprecated in favor of [PSR-11](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-11-container.md). -Container-interop has been the test-bed of PSR-11. From v1.2, container-interop directly extends PSR-11 interfaces. -Therefore, all containers implementing container-interop are now *de-facto* compatible with PSR-11. - -- Projects implementing container-interop interfaces are encouraged to directly implement PSR-11 interfaces instead. -- Projects consuming container-interop interfaces are very strongly encouraged to directly type-hint on PSR-11 interfaces, in order to be compatible with PSR-11 containers that are not compatible with container-interop. - -Regarding the delegate lookup feature, that is present in container-interop and not in PSR-11, the feature is actually a design pattern. It is therefore not deprecated. Documentation regarding this design pattern will be migrated from this repository into a separate website in the future. - -## About - -*container-interop* tries to identify and standardize features in *container* objects (service locators, -dependency injection containers, etc.) to achieve interoperability. - -Through discussions and trials, we try to create a standard, made of common interfaces but also recommendations. - -If PHP projects that provide container implementations begin to adopt these common standards, then PHP -applications and projects that use containers can depend on the common interfaces instead of specific -implementations. This facilitates a high-level of interoperability and flexibility that allows users to consume -*any* container implementation that can be adapted to these interfaces. - -The work done in this project is not officially endorsed by the [PHP-FIG](http://www.php-fig.org/), but it is being -worked on by members of PHP-FIG and other good developers. We adhere to the spirit and ideals of PHP-FIG, and hope -this project will pave the way for one or more future PSRs. - - -## Installation - -You can install this package through Composer: - -```json -composer require container-interop/container-interop -``` - -The packages adheres to the [SemVer](http://semver.org/) specification, and there will be full backward compatibility -between minor versions. - -## Standards - -### Available - -- [`ContainerInterface`](src/Interop/Container/ContainerInterface.php). -[Description](docs/ContainerInterface.md) [Meta Document](docs/ContainerInterface-meta.md). -Describes the interface of a container that exposes methods to read its entries. -- [*Delegate lookup feature*](docs/Delegate-lookup.md). -[Meta Document](docs/Delegate-lookup-meta.md). -Describes the ability for a container to delegate the lookup of its dependencies to a third-party container. This -feature lets several containers work together in a single application. - -### Proposed - -View open [request for comments](https://github.com/container-interop/container-interop/labels/RFC) - -## Compatible projects - -### Projects implementing `ContainerInterface` - -- [Acclimate](https://github.com/jeremeamia/acclimate-container): Adapters for - Aura.Di, Laravel, Nette DI, Pimple, Symfony DI, ZF2 Service manager, ZF2 - Dependency injection and any container using `ArrayAccess` -- [Aura.Di](https://github.com/auraphp/Aura.Di) -- [auryn-container-interop](https://github.com/elazar/auryn-container-interop) -- [Burlap](https://github.com/codeeverything/burlap) -- [Chernozem](https://github.com/pyrsmk/Chernozem) -- [Data Manager](https://github.com/chrismichaels84/data-manager) -- [Disco](https://github.com/bitexpert/disco) -- [InDI](https://github.com/idealogica/indi) -- [League/Container](http://container.thephpleague.com/) -- [Mouf](http://mouf-php.com) -- [Njasm Container](https://github.com/njasm/container) -- [PHP-DI](http://php-di.org) -- [Picotainer](https://github.com/thecodingmachine/picotainer) -- [PimpleInterop](https://github.com/moufmouf/pimple-interop) -- [Pimple3-ContainerInterop](https://github.com/Sam-Burns/pimple3-containerinterop) (using Pimple v3) -- [SitePoint Container](https://github.com/sitepoint/Container) -- [Thruster Container](https://github.com/ThrusterIO/container) (PHP7 only) -- [Ultra-Lite Container](https://github.com/ultra-lite/container) -- [Unbox](https://github.com/mindplay-dk/unbox) -- [XStatic](https://github.com/jeremeamia/xstatic) -- [Zend\ServiceManager](https://github.com/zendframework/zend-servicemanager) -- [Zit](https://github.com/inxilpro/Zit) - -### Projects implementing the *delegate lookup* feature - -- [Aura.Di](https://github.com/auraphp/Aura.Di) -- [Burlap](https://github.com/codeeverything/burlap) -- [Chernozem](https://github.com/pyrsmk/Chernozem) -- [InDI](https://github.com/idealogica/indi) -- [League/Container](http://container.thephpleague.com/) -- [Mouf](http://mouf-php.com) -- [Picotainer](https://github.com/thecodingmachine/picotainer) -- [PHP-DI](http://php-di.org) -- [PimpleInterop](https://github.com/moufmouf/pimple-interop) -- [Ultra-Lite Container](https://github.com/ultra-lite/container) - -### Middlewares implementing `ContainerInterface` - -- [Alias-Container](https://github.com/thecodingmachine/alias-container): add - aliases support to any container -- [Prefixer-Container](https://github.com/thecodingmachine/prefixer-container): - dynamically prefix identifiers -- [Lazy-Container](https://github.com/snapshotpl/lazy-container): lazy services - -### Projects using `ContainerInterface` - -The list below contains only a sample of all the projects consuming `ContainerInterface`. For a more complete list have a look [here](http://packanalyst.com/class?q=Interop%5CContainer%5CContainerInterface). - -| | Downloads | -| --- | --- | -| [Adroit](https://github.com/bitexpert/adroit) | ![](https://img.shields.io/packagist/dt/bitexpert/adroit.svg) | -| [Behat](https://github.com/Behat/Behat/pull/974) | ![](https://img.shields.io/packagist/dt/behat/behat.svg) | -| [blast-facades](https://github.com/phpthinktank/blast-facades): Minimize complexity and represent dependencies as facades. | ![](https://img.shields.io/packagist/dt/blast/facades.svg) | -| [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di): an extension to [Silex](http://silex.sensiolabs.org/) that adds support for any *container-interop* compatible container | ![](https://img.shields.io/packagist/dt/mouf/interop.silex.di.svg) | -| [mindplay/walkway](https://github.com/mindplay-dk/walkway): a modular request router | ![](https://img.shields.io/packagist/dt/mindplay/walkway.svg) | -| [mindplay/middleman](https://github.com/mindplay-dk/middleman): minimalist PSR-7 middleware dispatcher | ![](https://img.shields.io/packagist/dt/mindplay/middleman.svg) | -| [PHP-DI/Invoker](https://github.com/PHP-DI/Invoker): extensible and configurable invoker/dispatcher | ![](https://img.shields.io/packagist/dt/php-di/invoker.svg) | -| [Prophiler](https://github.com/fabfuel/prophiler) | ![](https://img.shields.io/packagist/dt/fabfuel/prophiler.svg) | -| [Silly](https://github.com/mnapoli/silly): CLI micro-framework | ![](https://img.shields.io/packagist/dt/mnapoli/silly.svg) | -| [Slim v3](https://github.com/slimphp/Slim) | ![](https://img.shields.io/packagist/dt/slim/slim.svg) | -| [Splash](http://mouf-php.com/packages/mouf/mvc.splash-common/version/8.0-dev/README.md) | ![](https://img.shields.io/packagist/dt/mouf/mvc.splash-common.svg) | -| [Woohoo Labs. Harmony](https://github.com/woohoolabs/harmony): a flexible micro-framework | ![](https://img.shields.io/packagist/dt/woohoolabs/harmony.svg) | -| [zend-expressive](https://github.com/zendframework/zend-expressive) | ![](https://img.shields.io/packagist/dt/zendframework/zend-expressive.svg) | - - -## Workflow - -Everyone is welcome to join and contribute. - -The general workflow looks like this: - -1. Someone opens a discussion (GitHub issue) to suggest an interface -1. Feedback is gathered -1. The interface is added to a development branch -1. We release alpha versions so that the interface can be experimented with -1. Discussions and edits ensue until the interface is deemed stable by a general consensus -1. A new minor version of the package is released - -We try to not break BC by creating new interfaces instead of editing existing ones. - -While we currently work on interfaces, we are open to anything that might help towards interoperability, may that -be code, best practices, etc. diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/composer.json b/advancedcontentfilter/vendor/container-interop/container-interop/composer.json deleted file mode 100644 index 855f7667..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/composer.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "container-interop/container-interop", - "type": "library", - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "homepage": "https://github.com/container-interop/container-interop", - "license": "MIT", - "autoload": { - "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" - } - }, - "require": { - "psr/container": "^1.0" - } -} diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md b/advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md deleted file mode 100644 index 59f3d559..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface-meta.md +++ /dev/null @@ -1,114 +0,0 @@ -# ContainerInterface Meta Document - -## Introduction - -This document describes the process and discussions that lead to the `ContainerInterface`. -Its goal is to explain the reasons behind each decision. - -## Goal - -The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a -container to obtain objects and parameters. - -By standardizing such a behavior, frameworks and libraries using the `ContainerInterface` -could work with any compatible container. -That would allow end users to choose their own container based on their own preferences. - -It is important to distinguish the two usages of a container: - -- configuring entries -- fetching entries - -Most of the time, those two sides are not used by the same party. -While it is often end users who tend to configure entries, it is generally the framework that fetch -entries to build the application. - -This is why this interface focuses only on how entries can be fetched from a container. - -## Interface name - -The interface name has been thoroughly discussed and was decided by a vote. - -The list of options considered with their respective votes are: - -- `ContainerInterface`: +8 -- `ProviderInterface`: +2 -- `LocatorInterface`: 0 -- `ReadableContainerInterface`: -5 -- `ServiceLocatorInterface`: -6 -- `ObjectFactory`: -6 -- `ObjectStore`: -8 -- `ConsumerInterface`: -9 - -[Full results of the vote](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote) - -The complete discussion can be read in [the issue #1](https://github.com/container-interop/container-interop/issues/1). - -## Interface methods - -The choice of which methods the interface would contain was made after a statistical analysis of existing containers. -The results of this analysis are available [in this document](https://gist.github.com/mnapoli/6159681). - -The summary of the analysis showed that: - -- all containers offer a method to get an entry by its id -- a large majority name such method `get()` -- for all containers, the `get()` method has 1 mandatory parameter of type string -- some containers have an optional additional argument for `get()`, but it doesn't have the same purpose between containers -- a large majority of the containers offer a method to test if it can return an entry by its id -- a majority name such method `has()` -- for all containers offering `has()`, the method has exactly 1 parameter of type string -- a large majority of the containers throw an exception rather than returning null when an entry is not found in `get()` -- a large majority of the containers don't implement `ArrayAccess` - -The question of whether to include methods to define entries has been discussed in -[issue #1](https://github.com/container-interop/container-interop/issues/1). -It has been judged that such methods do not belong in the interface described here because it is out of its scope -(see the "Goal" section). - -As a result, the `ContainerInterface` contains two methods: - -- `get()`, returning anything, with one mandatory string parameter. Should throw an exception if the entry is not found. -- `has()`, returning a boolean, with one mandatory string parameter. - -### Number of parameters in `get()` method - -While `ContainerInterface` only defines one mandatory parameter in `get()`, it is not incompatible with -existing containers that have additional optional parameters. PHP allows an implementation to offer more parameters -as long as they are optional, because the implementation *does* satisfy the interface. - -This issue has been discussed in [issue #6](https://github.com/container-interop/container-interop/issues/6). - -### Type of the `$id` parameter - -The type of the `$id` parameter in `get()` and `has()` has been discussed in -[issue #6](https://github.com/container-interop/container-interop/issues/6). -While `string` is used in all the containers that were analyzed, it was suggested that allowing -anything (such as objects) could allow containers to offer a more advanced query API. - -An example given was to use the container as an object builder. The `$id` parameter would then be an -object that would describe how to create an instance. - -The conclusion of the discussion was that this was beyond the scope of getting entries from a container without -knowing how the container provided them, and it was more fit for a factory. - -## Contributors - -Are listed here all people that contributed in the discussions or votes, by alphabetical order: - -- [Amy Stephen](https://github.com/AmyStephen) -- [David Négrier](https://github.com/moufmouf) -- [Don Gilbert](https://github.com/dongilbert) -- [Jason Judge](https://github.com/judgej) -- [Jeremy Lindblom](https://github.com/jeremeamia) -- [Marco Pivetta](https://github.com/Ocramius) -- [Matthieu Napoli](https://github.com/mnapoli) -- [Paul M. Jones](https://github.com/pmjones) -- [Stephan Hochdörfer](https://github.com/shochdoerfer) -- [Taylor Otwell](https://github.com/taylorotwell) - -## Relevant links - -- [`ContainerInterface.php`](https://github.com/container-interop/container-interop/blob/master/src/Interop/Container/ContainerInterface.php) -- [List of all issues](https://github.com/container-interop/container-interop/issues?labels=ContainerInterface&milestone=&page=1&state=closed) -- [Vote for the interface name](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote) diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface.md b/advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface.md deleted file mode 100644 index bda973d6..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/docs/ContainerInterface.md +++ /dev/null @@ -1,158 +0,0 @@ -Container interface -=================== - -This document describes a common interface for dependency injection containers. - -The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a -container to obtain objects and parameters (called *entries* in the rest of this document). - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", -"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be -interpreted as described in [RFC 2119][]. - -The word `implementor` in this document is to be interpreted as someone -implementing the `ContainerInterface` in a dependency injection-related library or framework. -Users of dependency injections containers (DIC) are referred to as `user`. - -[RFC 2119]: http://tools.ietf.org/html/rfc2119 - -1. Specification ------------------ - -### 1.1 Basics - -- The `Interop\Container\ContainerInterface` exposes two methods : `get` and `has`. - -- `get` takes one mandatory parameter: an entry identifier. It MUST be a string. - A call to `get` can return anything (a *mixed* value), or throws an exception if the identifier - is not known to the container. Two successive calls to `get` with the same - identifier SHOULD return the same value. However, depending on the `implementor` - design and/or `user` configuration, different values might be returned, so - `user` SHOULD NOT rely on getting the same value on 2 successive calls. - While `ContainerInterface` only defines one mandatory parameter in `get()`, implementations - MAY accept additional optional parameters. - -- `has` takes one unique parameter: an entry identifier. It MUST return `true` - if an entry identifier is known to the container and `false` if it is not. - `has($id)` returning true does not mean that `get($id)` will not throw an exception. - It does however mean that `get($id)` will not throw a `NotFoundException`. - -### 1.2 Exceptions - -Exceptions directly thrown by the container MUST implement the -[`Interop\Container\Exception\ContainerException`](../src/Interop/Container/Exception/ContainerException.php). - -A call to the `get` method with a non-existing id SHOULD throw a -[`Interop\Container\Exception\NotFoundException`](../src/Interop/Container/Exception/NotFoundException.php). - -### 1.3 Additional features - -This section describes additional features that MAY be added to a container. Containers are not -required to implement these features to respect the ContainerInterface. - -#### 1.3.1 Delegate lookup feature - -The goal of the *delegate lookup* feature is to allow several containers to share entries. -Containers implementing this feature can perform dependency lookups in other containers. - -Containers implementing this feature will offer a greater lever of interoperability -with other containers. Implementation of this feature is therefore RECOMMENDED. - -A container implementing this feature: - -- MUST implement the `ContainerInterface` -- MUST provide a way to register a delegate container (using a constructor parameter, or a setter, - or any possible way). The delegate container MUST implement the `ContainerInterface`. - -When a container is configured to use a delegate container for dependencies: - -- Calls to the `get` method should only return an entry if the entry is part of the container. - If the entry is not part of the container, an exception should be thrown - (as requested by the `ContainerInterface`). -- Calls to the `has` method should only return `true` if the entry is part of the container. - If the entry is not part of the container, `false` should be returned. -- If the fetched entry has dependencies, **instead** of performing - the dependency lookup in the container, the lookup is performed on the *delegate container*. - -Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself. - -It is however allowed for containers to provide exception cases for special entries, and a way to lookup -into the same container (or another container) instead of the delegate container. - -2. Package ----------- - -The interfaces and classes described as well as relevant exception are provided as part of the -[container-interop/container-interop](https://packagist.org/packages/container-interop/container-interop) package. - -3. `Interop\Container\ContainerInterface` ------------------------------------------ - -```php -setParentContainer($this); - } - } - ... - } -} - -``` - -**Cons:** - -Cons have been extensively discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777). -Basically, forcing a setter into an interface is a bad idea. Setters are similar to constructor arguments, -and it's a bad idea to standardize a constructor: how the delegate container is configured into a container is an implementation detail. This outweights the benefits of the interface. - -### 4.4 Alternative: no exception case for delegate lookups - -Originally, the proposed wording for delegate lookup calls was: - -> Important! The lookup MUST be performed on the delegate container **only**, not on the container itself. - -This was later replaced by: - -> Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself. -> -> It is however allowed for containers to provide exception cases for special entries, and a way to lookup -> into the same container (or another container) instead of the delegate container. - -Exception cases have been allowed to avoid breaking dependencies with some services that must be provided -by the container (on @njasm proposal). This was proposed here: https://github.com/container-interop/container-interop/pull/20#issuecomment-56597235 - -### 4.5 Alternative: having one of the containers act as the composite container - -In real-life scenarios, we usually have a big framework (Symfony 2, Zend Framework 2, etc...) and we want to -add another DI container to this container. Most of the time, the "big" framework will be responsible for -creating the controller's instances, using it's own DI container. Until *container-interop* is fully adopted, -the "big" framework will not be aware of the existence of a composite container that it should use instead -of its own container. - -For this real-life use cases, @mnapoli and @moufmouf proposed to extend the "big" framework's DI container -to make it act as a composite container. - -This has been discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-40367194) -and [here](http://mouf-php.com/container-interop-whats-next#solution4). - -This was implemented in Symfony 2 using: - -- [interop.symfony.di](https://github.com/thecodingmachine/interop.symfony.di/tree/v0.1.0) -- [framework interop](https://github.com/mnapoli/framework-interop/) - -This was implemented in Silex using: - -- [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di) - -Having a container act as the composite container is not part of the delegate lookup standard because it is -simply a temporary design pattern used to make existing frameworks that do not support yet ContainerInterop -play nice with other DI containers. - - -5. Implementations ------------------- - -The following projects already implement the delegate lookup feature: - -- [Mouf](http://mouf-php.com), through the [`setDelegateLookupContainer` method](https://github.com/thecodingmachine/mouf/blob/2.0/src/Mouf/MoufManager.php#L2120) -- [PHP-DI](http://php-di.org/), through the [`$wrapperContainer` parameter of the constructor](https://github.com/mnapoli/PHP-DI/blob/master/src/DI/Container.php#L72) -- [pimple-interop](https://github.com/moufmouf/pimple-interop), through the [`$container` parameter of the constructor](https://github.com/moufmouf/pimple-interop/blob/master/src/Interop/Container/Pimple/PimpleInterop.php#L62) - -6. People ---------- - -Are listed here all people that contributed in the discussions, by alphabetical order: - -- [Alexandru Pătrănescu](https://github.com/drealecs) -- [Ben Peachey](https://github.com/potherca) -- [David Négrier](https://github.com/moufmouf) -- [Jeremy Lindblom](https://github.com/jeremeamia) -- [Marco Pivetta](https://github.com/Ocramius) -- [Matthieu Napoli](https://github.com/mnapoli) -- [Nelson J Morais](https://github.com/njasm) -- [Phil Sturgeon](https://github.com/philsturgeon) -- [Stephan Hochdörfer](https://github.com/shochdoerfer) - -7. Relevant Links ------------------ - -_**Note:** Order descending chronologically._ - -- [Pull request on the delegate lookup feature](https://github.com/container-interop/container-interop/pull/20) -- [Pull request on the interface idea](https://github.com/container-interop/container-interop/pull/8) -- [Original article exposing the delegate lookup idea along many others](http://mouf-php.com/container-interop-whats-next) - diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/docs/Delegate-lookup.md b/advancedcontentfilter/vendor/container-interop/container-interop/docs/Delegate-lookup.md deleted file mode 100644 index f64a8f78..00000000 --- a/advancedcontentfilter/vendor/container-interop/container-interop/docs/Delegate-lookup.md +++ /dev/null @@ -1,60 +0,0 @@ -Delegate lookup feature -======================= - -This document describes a standard for dependency injection containers. - -The goal set by the *delegate lookup* feature is to allow several containers to share entries. -Containers implementing this feature can perform dependency lookups in other containers. - -Containers implementing this feature will offer a greater lever of interoperability -with other containers. Implementation of this feature is therefore RECOMMENDED. - -The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", -"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be -interpreted as described in [RFC 2119][]. - -The word `implementor` in this document is to be interpreted as someone -implementing the delegate lookup feature in a dependency injection-related library or framework. -Users of dependency injections containers (DIC) are referred to as `user`. - -[RFC 2119]: http://tools.ietf.org/html/rfc2119 - -1. Vocabulary -------------- - -In a dependency injection container, the container is used to fetch entries. -Entries can have dependencies on other entries. Usually, these other entries are fetched by the container. - -The *delegate lookup* feature is the ability for a container to fetch dependencies in -another container. In the rest of the document, the word "container" will reference the container -implemented by the implementor. The word "delegate container" will reference the container we are -fetching the dependencies from. - -2. Specification ----------------- - -A container implementing the *delegate lookup* feature: - -- MUST implement the [`ContainerInterface`](ContainerInterface.md) -- MUST provide a way to register a delegate container (using a constructor parameter, or a setter, - or any possible way). The delegate container MUST implement the [`ContainerInterface`](ContainerInterface.md). - -When a container is configured to use a delegate container for dependencies: - -- Calls to the `get` method should only return an entry if the entry is part of the container. - If the entry is not part of the container, an exception should be thrown - (as requested by the [`ContainerInterface`](ContainerInterface.md)). -- Calls to the `has` method should only return `true` if the entry is part of the container. - If the entry is not part of the container, `false` should be returned. -- If the fetched entry has dependencies, **instead** of performing - the dependency lookup in the container, the lookup is performed on the *delegate container*. - -Important: By default, the dependency lookups SHOULD be performed on the delegate container **only**, not on the container itself. - -It is however allowed for containers to provide exception cases for special entries, and a way to lookup -into the same container (or another container) instead of the delegate container. - -3. Package / Interface ----------------------- - -This feature is not tied to any code, interface or package. diff --git a/advancedcontentfilter/vendor/container-interop/container-interop/docs/images/interoperating_containers.png b/advancedcontentfilter/vendor/container-interop/container-interop/docs/images/interoperating_containers.png deleted file mode 100644 index 1d3fdd0ddbea28d77c08cfb65834ec11357be5fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25738 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 lDg62tY5@ou6EsiaCMAN!E;xV!uGoVl#pK=> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi - -script: - - cd ext/pimple - - if [ "$PIMPLE_EXT" == "yes" ]; then yes n | make test | tee output ; grep -E 'Tests failed +. +0' output; fi - - if [ "$PIMPLE_EXT" == "yes" ]; then export SYMFONY_DEPRECATIONS_HELPER=weak; fi - - cd ../.. - - ./vendor/bin/simple-phpunit - -matrix: - include: - - php: hhvm - dist: trusty - env: PIMPLE_EXT=no - exclude: - - php: 7.0 - env: PIMPLE_EXT=yes - - php: 7.1 - env: PIMPLE_EXT=yes diff --git a/advancedcontentfilter/vendor/pimple/pimple/CHANGELOG b/advancedcontentfilter/vendor/pimple/pimple/CHANGELOG deleted file mode 100644 index ba56760c..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/CHANGELOG +++ /dev/null @@ -1,59 +0,0 @@ -* 3.2.3 (2017-XX-XX) - - * n/a - -* 3.2.2 (2017-07-23) - - * reverted extending a protected closure throws an exception (deprecated it instead) - -* 3.2.1 (2017-07-17) - - * fixed PHP error - -* 3.2.0 (2017-07-17) - - * added a PSR-11 service locator - * added a PSR-11 wrapper - * added ServiceIterator - * fixed extending a protected closure (now throws InvalidServiceIdentifierException) - -* 3.1.0 (2017-07-03) - - * deprecated the C extension - * added support for PSR-11 exceptions - -* 3.0.2 (2015-09-11) - - * refactored the C extension - * minor non-significant changes - -* 3.0.1 (2015-07-30) - - * simplified some code - * fixed a segfault in the C extension - -* 3.0.0 (2014-07-24) - - * removed the Pimple class alias (use Pimple\Container instead) - -* 2.1.1 (2014-07-24) - - * fixed compiler warnings for the C extension - * fixed code when dealing with circular references - -* 2.1.0 (2014-06-24) - - * moved the Pimple to Pimple\Container (with a BC layer -- Pimple is now a - deprecated alias which will be removed in Pimple 3.0) - * added Pimple\ServiceProviderInterface (and Pimple::register()) - -* 2.0.0 (2014-02-10) - - * changed extend to automatically re-assign the extended service and keep it as shared or factory - (to keep BC, extend still returns the extended service) - * changed services to be shared by default (use factory() for factory - services) - -* 1.0.0 - - * initial version diff --git a/advancedcontentfilter/vendor/pimple/pimple/README.rst b/advancedcontentfilter/vendor/pimple/pimple/README.rst deleted file mode 100644 index a03b6d3a..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/README.rst +++ /dev/null @@ -1,326 +0,0 @@ -Pimple -====== - -.. caution:: - - This is the documentation for Pimple 3.x. If you are using Pimple 1.x, read - the `Pimple 1.x documentation`_. Reading the Pimple 1.x code is also a good - way to learn more about how to create a simple Dependency Injection - Container (recent versions of Pimple are more focused on performance). - -Pimple is a small Dependency Injection Container for PHP. - -Installation ------------- - -Before using Pimple in your project, add it to your ``composer.json`` file: - -.. code-block:: bash - - $ ./composer.phar require pimple/pimple "^3.0" - -Usage ------ - -Creating a container is a matter of creating a ``Container`` instance: - -.. code-block:: php - - use Pimple\Container; - - $container = new Container(); - -As many other dependency injection containers, Pimple manages two different -kind of data: **services** and **parameters**. - -Defining Services -~~~~~~~~~~~~~~~~~ - -A service is an object that does something as part of a larger system. Examples -of services: a database connection, a templating engine, or a mailer. Almost -any **global** object can be a service. - -Services are defined by **anonymous functions** that return an instance of an -object: - -.. code-block:: php - - // define some services - $container['session_storage'] = function ($c) { - return new SessionStorage('SESSION_ID'); - }; - - $container['session'] = function ($c) { - return new Session($c['session_storage']); - }; - -Notice that the anonymous function has access to the current container -instance, allowing references to other services or parameters. - -As objects are only created when you get them, the order of the definitions -does not matter. - -Using the defined services is also very easy: - -.. code-block:: php - - // get the session object - $session = $container['session']; - - // the above call is roughly equivalent to the following code: - // $storage = new SessionStorage('SESSION_ID'); - // $session = new Session($storage); - -Defining Factory Services -~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, each time you get a service, Pimple returns the **same instance** -of it. If you want a different instance to be returned for all calls, wrap your -anonymous function with the ``factory()`` method - -.. code-block:: php - - $container['session'] = $container->factory(function ($c) { - return new Session($c['session_storage']); - }); - -Now, each call to ``$container['session']`` returns a new instance of the -session. - -Defining Parameters -~~~~~~~~~~~~~~~~~~~ - -Defining a parameter allows to ease the configuration of your container from -the outside and to store global values: - -.. code-block:: php - - // define some parameters - $container['cookie_name'] = 'SESSION_ID'; - $container['session_storage_class'] = 'SessionStorage'; - -If you change the ``session_storage`` service definition like below: - -.. code-block:: php - - $container['session_storage'] = function ($c) { - return new $c['session_storage_class']($c['cookie_name']); - }; - -You can now easily change the cookie name by overriding the -``cookie_name`` parameter instead of redefining the service -definition. - -Protecting Parameters -~~~~~~~~~~~~~~~~~~~~~ - -Because Pimple sees anonymous functions as service definitions, you need to -wrap anonymous functions with the ``protect()`` method to store them as -parameters: - -.. code-block:: php - - $container['random_func'] = $container->protect(function () { - return rand(); - }); - -Modifying Services after Definition -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -In some cases you may want to modify a service definition after it has been -defined. You can use the ``extend()`` method to define additional code to be -run on your service just after it is created: - -.. code-block:: php - - $container['session_storage'] = function ($c) { - return new $c['session_storage_class']($c['cookie_name']); - }; - - $container->extend('session_storage', function ($storage, $c) { - $storage->...(); - - return $storage; - }); - -The first argument is the name of the service to extend, the second a function -that gets access to the object instance and the container. - -Extending a Container -~~~~~~~~~~~~~~~~~~~~~ - -If you use the same libraries over and over, you might want to reuse some -services from one project to the next one; package your services into a -**provider** by implementing ``Pimple\ServiceProviderInterface``: - -.. code-block:: php - - use Pimple\Container; - - class FooProvider implements Pimple\ServiceProviderInterface - { - public function register(Container $pimple) - { - // register some services and parameters - // on $pimple - } - } - -Then, register the provider on a Container: - -.. code-block:: php - - $pimple->register(new FooProvider()); - -Fetching the Service Creation Function -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -When you access an object, Pimple automatically calls the anonymous function -that you defined, which creates the service object for you. If you want to get -raw access to this function, you can use the ``raw()`` method: - -.. code-block:: php - - $container['session'] = function ($c) { - return new Session($c['session_storage']); - }; - - $sessionFunction = $container->raw('session'); - -PSR-11 compatibility --------------------- - -For historical reasons, the ``Container`` class does not implement the PSR-11 -``ContainerInterface``. However, Pimple provides a helper class that will let -you decouple your code from the Pimple container class. - -The PSR-11 container class -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -The ``Pimple\Psr11\Container`` class lets you access the content of an -underlying Pimple container using ``Psr\Container\ContainerInterface`` -methods: - -.. code-block:: php - - use Pimple\Container; - use Pimple\Psr11\Container as PsrContainer; - - $container = new Container(); - $container['service'] = function ($c) { - return new Service(); - }; - $psr11 = new PsrContainer($container); - - $controller = function (PsrContainer $container) { - $service = $container->get('service'); - }; - $controller($psr11); - -Using the PSR-11 ServiceLocator -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Sometimes, a service needs access to several other services without being sure -that all of them will actually be used. In those cases, you may want the -instantiation of the services to be lazy. - -The traditional solution is to inject the entire service container to get only -the services really needed. However, this is not recommended because it gives -services a too broad access to the rest of the application and it hides their -actual dependencies. - -The ``ServiceLocator`` is intended to solve this problem by giving access to a -set of predefined services while instantiating them only when actually needed. - -It also allows you to make your services available under a different name than -the one used to register them. For instance, you may want to use an object -that expects an instance of ``EventDispatcherInterface`` to be available under -the name ``event_dispatcher`` while your event dispatcher has been -registered under the name ``dispatcher``: - -.. code-block:: php - - use Monolog\Logger; - use Pimple\Psr11\ServiceLocator; - use Psr\Container\ContainerInterface; - use Symfony\Component\EventDispatcher\EventDispatcher; - - class MyService - { - /** - * "logger" must be an instance of Psr\Log\LoggerInterface - * "event_dispatcher" must be an instance of Symfony\Component\EventDispatcher\EventDispatcherInterface - */ - private $services; - - public function __construct(ContainerInterface $services) - { - $this->services = $services; - } - } - - $container['logger'] = function ($c) { - return new Monolog\Logger(); - }; - $container['dispatcher'] = function () { - return new EventDispatcher(); - }; - - $container['service'] = function ($c) { - $locator = new ServiceLocator($c, array('logger', 'event_dispatcher' => 'dispatcher')); - - return new MyService($locator); - }; - -Referencing a Collection of Services Lazily -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Passing a collection of services instances in an array may prove inefficient -if the class that consumes the collection only needs to iterate over it at a -later stage, when one of its method is called. It can also lead to problems -if there is a circular dependency between one of the services stored in the -collection and the class that consumes it. - -The ``ServiceIterator`` class helps you solve these issues. It receives a -list of service names during instantiation and will retrieve the services -when iterated over: - -.. code-block:: php - - use Pimple\Container; - use Pimple\ServiceIterator; - - class AuthorizationService - { - private $voters; - - public function __construct($voters) - { - $this->voters = $voters; - } - - public function canAccess($resource) - { - foreach ($this->voters as $voter) { - if (true === $voter->canAccess($resource) { - return true; - } - } - - return false; - } - } - - $container = new Container(); - - $container['voter1'] = function ($c) { - return new SomeVoter(); - } - $container['voter2'] = function ($c) { - return new SomeOtherVoter($c['auth']); - } - $container['auth'] = function ($c) { - return new AuthorizationService(new ServiceIterator($c, array('voter1', 'voter2')); - } - -.. _Pimple 1.x documentation: https://github.com/silexphp/Pimple/tree/1.1 diff --git a/advancedcontentfilter/vendor/pimple/pimple/composer.json b/advancedcontentfilter/vendor/pimple/pimple/composer.json deleted file mode 100644 index dabf190a..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/composer.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "pimple/pimple", - "type": "library", - "description": "Pimple, a simple Dependency Injection Container", - "keywords": ["dependency injection", "container"], - "homepage": "http://pimple.sensiolabs.org", - "license": "MIT", - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "require": { - "php": ">=5.3.0", - "psr/container": "^1.0" - }, - "require-dev": { - "symfony/phpunit-bridge": "^3.2" - }, - "autoload": { - "psr-0": { "Pimple": "src/" } - }, - "extra": { - "branch-alias": { - "dev-master": "3.2.x-dev" - } - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/.gitignore b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/.gitignore deleted file mode 100644 index 1861088a..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -*.sw* -.deps -Makefile -Makefile.fragments -Makefile.global -Makefile.objects -acinclude.m4 -aclocal.m4 -build/ -config.cache -config.guess -config.h -config.h.in -config.log -config.nice -config.status -config.sub -configure -configure.in -install-sh -libtool -ltmain.sh -missing -mkinstalldirs -run-tests.php -*.loT -.libs/ -modules/ -*.la -*.lo diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/README.md b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/README.md deleted file mode 100644 index 7b39eb29..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/README.md +++ /dev/null @@ -1,12 +0,0 @@ -This is Pimple 2 implemented in C - -* PHP >= 5.3 -* Not tested under Windows, might work - -Install -======= - - > phpize - > ./configure - > make - > make install diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.m4 b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.m4 deleted file mode 100644 index 3a6e9aae..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.m4 +++ /dev/null @@ -1,63 +0,0 @@ -dnl $Id$ -dnl config.m4 for extension pimple - -dnl Comments in this file start with the string 'dnl'. -dnl Remove where necessary. This file will not work -dnl without editing. - -dnl If your extension references something external, use with: - -dnl PHP_ARG_WITH(pimple, for pimple support, -dnl Make sure that the comment is aligned: -dnl [ --with-pimple Include pimple support]) - -dnl Otherwise use enable: - -PHP_ARG_ENABLE(pimple, whether to enable pimple support, -dnl Make sure that the comment is aligned: -[ --enable-pimple Enable pimple support]) - -if test "$PHP_PIMPLE" != "no"; then - dnl Write more examples of tests here... - - dnl # --with-pimple -> check with-path - dnl SEARCH_PATH="/usr/local /usr" # you might want to change this - dnl SEARCH_FOR="/include/pimple.h" # you most likely want to change this - dnl if test -r $PHP_PIMPLE/$SEARCH_FOR; then # path given as parameter - dnl PIMPLE_DIR=$PHP_PIMPLE - dnl else # search default path list - dnl AC_MSG_CHECKING([for pimple files in default path]) - dnl for i in $SEARCH_PATH ; do - dnl if test -r $i/$SEARCH_FOR; then - dnl PIMPLE_DIR=$i - dnl AC_MSG_RESULT(found in $i) - dnl fi - dnl done - dnl fi - dnl - dnl if test -z "$PIMPLE_DIR"; then - dnl AC_MSG_RESULT([not found]) - dnl AC_MSG_ERROR([Please reinstall the pimple distribution]) - dnl fi - - dnl # --with-pimple -> add include path - dnl PHP_ADD_INCLUDE($PIMPLE_DIR/include) - - dnl # --with-pimple -> check for lib and symbol presence - dnl LIBNAME=pimple # you may want to change this - dnl LIBSYMBOL=pimple # you most likely want to change this - - dnl PHP_CHECK_LIBRARY($LIBNAME,$LIBSYMBOL, - dnl [ - dnl PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $PIMPLE_DIR/lib, PIMPLE_SHARED_LIBADD) - dnl AC_DEFINE(HAVE_PIMPLELIB,1,[ ]) - dnl ],[ - dnl AC_MSG_ERROR([wrong pimple lib version or lib not found]) - dnl ],[ - dnl -L$PIMPLE_DIR/lib -lm - dnl ]) - dnl - dnl PHP_SUBST(PIMPLE_SHARED_LIBADD) - - PHP_NEW_EXTENSION(pimple, pimple.c, $ext_shared) -fi diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.w32 b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.w32 deleted file mode 100644 index 39857b32..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/config.w32 +++ /dev/null @@ -1,13 +0,0 @@ -// $Id$ -// vim:ft=javascript - -// If your extension references something external, use ARG_WITH -// ARG_WITH("pimple", "for pimple support", "no"); - -// Otherwise, use ARG_ENABLE -// ARG_ENABLE("pimple", "enable pimple support", "no"); - -if (PHP_PIMPLE != "no") { - EXTENSION("pimple", "pimple.c"); -} - diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/php_pimple.h b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/php_pimple.h deleted file mode 100644 index eed7c173..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/php_pimple.h +++ /dev/null @@ -1,137 +0,0 @@ - -/* - * This file is part of Pimple. - * - * Copyright (c) 2014 Fabien Potencier - * - * 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. - */ - -#ifndef PHP_PIMPLE_H -#define PHP_PIMPLE_H - -extern zend_module_entry pimple_module_entry; -#define phpext_pimple_ptr &pimple_module_entry - -#ifdef PHP_WIN32 -# define PHP_PIMPLE_API __declspec(dllexport) -#elif defined(__GNUC__) && __GNUC__ >= 4 -# define PHP_PIMPLE_API __attribute__ ((visibility("default"))) -#else -# define PHP_PIMPLE_API -#endif - -#ifdef ZTS -#include "TSRM.h" -#endif - -#define PIMPLE_VERSION "3.2.3-DEV" - -#define PIMPLE_NS "Pimple" -#define PSR_CONTAINER_NS "Psr\\Container" -#define PIMPLE_EXCEPTION_NS "Pimple\\Exception" - -#define PIMPLE_DEFAULT_ZVAL_CACHE_NUM 5 -#define PIMPLE_DEFAULT_ZVAL_VALUES_NUM 10 - -#define PIMPLE_DEPRECATE do { \ - int er = EG(error_reporting); \ - EG(error_reporting) = 0;\ - php_error(E_DEPRECATED, "The Pimple C extension is deprecated since version 3.1 and will be removed in 4.0."); \ - EG(error_reporting) = er; \ -} while (0); - -zend_module_entry *get_module(void); - -PHP_MINIT_FUNCTION(pimple); -PHP_MINFO_FUNCTION(pimple); - -PHP_METHOD(FrozenServiceException, __construct); -PHP_METHOD(InvalidServiceIdentifierException, __construct); -PHP_METHOD(UnknownIdentifierException, __construct); - -PHP_METHOD(Pimple, __construct); -PHP_METHOD(Pimple, factory); -PHP_METHOD(Pimple, protect); -PHP_METHOD(Pimple, raw); -PHP_METHOD(Pimple, extend); -PHP_METHOD(Pimple, keys); -PHP_METHOD(Pimple, register); -PHP_METHOD(Pimple, offsetSet); -PHP_METHOD(Pimple, offsetUnset); -PHP_METHOD(Pimple, offsetGet); -PHP_METHOD(Pimple, offsetExists); - -PHP_METHOD(PimpleClosure, invoker); - -typedef struct _pimple_bucket_value { - zval *value; /* Must be the first element */ - zval *raw; - zend_object_handle handle_num; - enum { - PIMPLE_IS_PARAM = 0, - PIMPLE_IS_SERVICE = 2 - } type; - zend_bool initialized; - zend_fcall_info_cache fcc; -} pimple_bucket_value; - -typedef struct _pimple_object { - zend_object zobj; - HashTable values; - HashTable factories; - HashTable protected; -} pimple_object; - -typedef struct _pimple_closure_object { - zend_object zobj; - zval *callable; - zval *factory; -} pimple_closure_object; - -static const char sensiolabs_logo[] = ""; - -static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC); - -static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC); -static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC); - -static void pimple_bucket_dtor(pimple_bucket_value *bucket); -static void pimple_free_bucket(pimple_bucket_value *bucket); - -static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC); -static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC); -static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC); -static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC); -static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC); -static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC); - -static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC); -static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC); -static zend_function *pimple_closure_get_constructor(zval * TSRMLS_DC); -static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC); - -#ifdef ZTS -#define PIMPLE_G(v) TSRMG(pimple_globals_id, zend_pimple_globals *, v) -#else -#define PIMPLE_G(v) (pimple_globals.v) -#endif - -#endif /* PHP_PIMPLE_H */ - diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple.c b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple.c deleted file mode 100644 index c80499b3..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple.c +++ /dev/null @@ -1,1114 +0,0 @@ - -/* - * This file is part of Pimple. - * - * Copyright (c) 2014 Fabien Potencier - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_pimple.h" -#include "pimple_compat.h" -#include "zend_interfaces.h" -#include "zend.h" -#include "Zend/zend_closures.h" -#include "ext/spl/spl_exceptions.h" -#include "Zend/zend_exceptions.h" -#include "main/php_output.h" -#include "SAPI.h" - -static zend_class_entry *pimple_ce_PsrContainerInterface; -static zend_class_entry *pimple_ce_PsrContainerExceptionInterface; -static zend_class_entry *pimple_ce_PsrNotFoundExceptionInterface; - -static zend_class_entry *pimple_ce_ExpectedInvokableException; -static zend_class_entry *pimple_ce_FrozenServiceException; -static zend_class_entry *pimple_ce_InvalidServiceIdentifierException; -static zend_class_entry *pimple_ce_UnknownIdentifierException; - -static zend_class_entry *pimple_ce; -static zend_object_handlers pimple_object_handlers; -static zend_class_entry *pimple_closure_ce; -static zend_class_entry *pimple_serviceprovider_ce; -static zend_object_handlers pimple_closure_object_handlers; -static zend_internal_function pimple_closure_invoker_function; - -#define FETCH_DIM_HANDLERS_VARS pimple_object *pimple_obj = NULL; \ - ulong index; \ - pimple_obj = (pimple_object *)zend_object_store_get_object(object TSRMLS_CC); \ - -#define PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS do { \ - if (ce != pimple_ce) { \ - zend_hash_find(&ce->function_table, ZEND_STRS("offsetget"), (void **)&function); \ - if (function->common.scope != ce) { /* if the function is not defined in this actual class */ \ - pimple_object_handlers.read_dimension = pimple_object_read_dimension; /* then overwrite the handler to use custom one */ \ - } \ - zend_hash_find(&ce->function_table, ZEND_STRS("offsetset"), (void **)&function); \ - if (function->common.scope != ce) { \ - pimple_object_handlers.write_dimension = pimple_object_write_dimension; \ - } \ - zend_hash_find(&ce->function_table, ZEND_STRS("offsetexists"), (void **)&function); \ - if (function->common.scope != ce) { \ - pimple_object_handlers.has_dimension = pimple_object_has_dimension; \ - } \ - zend_hash_find(&ce->function_table, ZEND_STRS("offsetunset"), (void **)&function); \ - if (function->common.scope != ce) { \ - pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \ - } \ - } else { \ - pimple_object_handlers.read_dimension = pimple_object_read_dimension; \ - pimple_object_handlers.write_dimension = pimple_object_write_dimension; \ - pimple_object_handlers.has_dimension = pimple_object_has_dimension; \ - pimple_object_handlers.unset_dimension = pimple_object_unset_dimension; \ - }\ - } while(0); - -#define PIMPLE_CALL_CB do { \ - zend_fcall_info_argn(&fci TSRMLS_CC, 1, &object); \ - fci.size = sizeof(fci); \ - fci.object_ptr = retval->fcc.object_ptr; \ - fci.function_name = retval->value; \ - fci.no_separation = 1; \ - fci.retval_ptr_ptr = &retval_ptr_ptr; \ -\ - zend_call_function(&fci, &retval->fcc TSRMLS_CC); \ - efree(fci.params); \ - if (EG(exception)) { \ - return EG(uninitialized_zval_ptr); \ - } \ - } while(0); - - -/* Psr\Container\ContainerInterface */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_get, 0, 0, 1) -ZEND_ARG_INFO(0, id) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_pimple_PsrContainerInterface_has, 0, 0, 1) -ZEND_ARG_INFO(0, id) -ZEND_END_ARG_INFO() - -static const zend_function_entry pimple_ce_PsrContainerInterface_functions[] = { - PHP_ABSTRACT_ME(ContainerInterface, get, arginfo_pimple_PsrContainerInterface_get) - PHP_ABSTRACT_ME(ContainerInterface, has, arginfo_pimple_PsrContainerInterface_has) - PHP_FE_END -}; - -/* Psr\Container\ContainerExceptionInterface */ -static const zend_function_entry pimple_ce_PsrContainerExceptionInterface_functions[] = { - PHP_FE_END -}; - -/* Psr\Container\NotFoundExceptionInterface */ -static const zend_function_entry pimple_ce_PsrNotFoundExceptionInterface_functions[] = { - PHP_FE_END -}; - -/* Pimple\Exception\FrozenServiceException */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_FrozenServiceException___construct, 0, 0, 1) -ZEND_ARG_INFO(0, id) -ZEND_END_ARG_INFO() - -static const zend_function_entry pimple_ce_FrozenServiceException_functions[] = { - PHP_ME(FrozenServiceException, __construct, arginfo_FrozenServiceException___construct, ZEND_ACC_PUBLIC) - PHP_FE_END -}; - -/* Pimple\Exception\InvalidServiceIdentifierException */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_InvalidServiceIdentifierException___construct, 0, 0, 1) -ZEND_ARG_INFO(0, id) -ZEND_END_ARG_INFO() - -static const zend_function_entry pimple_ce_InvalidServiceIdentifierException_functions[] = { - PHP_ME(InvalidServiceIdentifierException, __construct, arginfo_InvalidServiceIdentifierException___construct, ZEND_ACC_PUBLIC) - PHP_FE_END -}; - -/* Pimple\Exception\UnknownIdentifierException */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_UnknownIdentifierException___construct, 0, 0, 1) -ZEND_ARG_INFO(0, id) -ZEND_END_ARG_INFO() - -static const zend_function_entry pimple_ce_UnknownIdentifierException_functions[] = { - PHP_ME(UnknownIdentifierException, __construct, arginfo_UnknownIdentifierException___construct, ZEND_ACC_PUBLIC) - PHP_FE_END -}; - -/* Pimple\Container */ -ZEND_BEGIN_ARG_INFO_EX(arginfo___construct, 0, 0, 0) -ZEND_ARG_ARRAY_INFO(0, value, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetset, 0, 0, 2) -ZEND_ARG_INFO(0, offset) -ZEND_ARG_INFO(0, value) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetget, 0, 0, 1) -ZEND_ARG_INFO(0, offset) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetexists, 0, 0, 1) -ZEND_ARG_INFO(0, offset) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetunset, 0, 0, 1) -ZEND_ARG_INFO(0, offset) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_factory, 0, 0, 1) -ZEND_ARG_INFO(0, callable) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_protect, 0, 0, 1) -ZEND_ARG_INFO(0, callable) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_raw, 0, 0, 1) -ZEND_ARG_INFO(0, id) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_extend, 0, 0, 2) -ZEND_ARG_INFO(0, id) -ZEND_ARG_INFO(0, callable) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_keys, 0, 0, 0) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_register, 0, 0, 1) -ZEND_ARG_OBJ_INFO(0, provider, Pimple\\ServiceProviderInterface, 0) -ZEND_ARG_ARRAY_INFO(0, values, 1) -ZEND_END_ARG_INFO() - -static const zend_function_entry pimple_ce_functions[] = { - PHP_ME(Pimple, __construct, arginfo___construct, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, factory, arginfo_factory, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, protect, arginfo_protect, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, raw, arginfo_raw, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, extend, arginfo_extend, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, keys, arginfo_keys, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, register, arginfo_register, ZEND_ACC_PUBLIC) - - PHP_ME(Pimple, offsetSet, arginfo_offsetset, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, offsetGet, arginfo_offsetget, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, offsetExists, arginfo_offsetexists, ZEND_ACC_PUBLIC) - PHP_ME(Pimple, offsetUnset, arginfo_offsetunset, ZEND_ACC_PUBLIC) - PHP_FE_END -}; - -/* Pimple\ServiceProviderInterface */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_serviceprovider_register, 0, 0, 1) -ZEND_ARG_OBJ_INFO(0, pimple, Pimple\\Container, 0) -ZEND_END_ARG_INFO() - -static const zend_function_entry pimple_serviceprovider_iface_ce_functions[] = { - PHP_ABSTRACT_ME(ServiceProviderInterface, register, arginfo_serviceprovider_register) - PHP_FE_END -}; - -/* parent::__construct(sprintf("Something with %s", $arg1)) */ -static void pimple_exception_call_parent_constructor(zval *this_ptr, const char *format, const char *arg1 TSRMLS_DC) -{ - zend_class_entry *ce = Z_OBJCE_P(this_ptr); - char *message = NULL; - int message_len; - zval *constructor_arg; - - message_len = spprintf(&message, 0, format, arg1); - ALLOC_INIT_ZVAL(constructor_arg); - ZVAL_STRINGL(constructor_arg, message, message_len, 1); - - zend_call_method_with_1_params(&this_ptr, ce, &ce->parent->constructor, "__construct", NULL, constructor_arg); - - efree(message); - zval_ptr_dtor(&constructor_arg); -} - -/** - * Pass a single string parameter to exception constructor and throw - */ -static void pimple_throw_exception_string(zend_class_entry *ce, const char *message, zend_uint message_len TSRMLS_DC) -{ - zval *exception, *param; - - ALLOC_INIT_ZVAL(exception); - object_init_ex(exception, ce); - - ALLOC_INIT_ZVAL(param); - ZVAL_STRINGL(param, message, message_len, 1); - - zend_call_method_with_1_params(&exception, ce, &ce->constructor, "__construct", NULL, param); - - zend_throw_exception_object(exception TSRMLS_CC); - - zval_ptr_dtor(¶m); -} - -static void pimple_closure_free_object_storage(pimple_closure_object *obj TSRMLS_DC) -{ - zend_object_std_dtor(&obj->zobj TSRMLS_CC); - if (obj->factory) { - zval_ptr_dtor(&obj->factory); - } - if (obj->callable) { - zval_ptr_dtor(&obj->callable); - } - efree(obj); -} - -static void pimple_free_object_storage(pimple_object *obj TSRMLS_DC) -{ - zend_hash_destroy(&obj->factories); - zend_hash_destroy(&obj->protected); - zend_hash_destroy(&obj->values); - zend_object_std_dtor(&obj->zobj TSRMLS_CC); - efree(obj); -} - -static void pimple_free_bucket(pimple_bucket_value *bucket) -{ - if (bucket->raw) { - zval_ptr_dtor(&bucket->raw); - } -} - -static zend_object_value pimple_closure_object_create(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - pimple_closure_object *pimple_closure_obj = NULL; - - pimple_closure_obj = ecalloc(1, sizeof(pimple_closure_object)); - ZEND_OBJ_INIT(&pimple_closure_obj->zobj, ce); - - pimple_closure_object_handlers.get_constructor = pimple_closure_get_constructor; - retval.handlers = &pimple_closure_object_handlers; - retval.handle = zend_objects_store_put(pimple_closure_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_closure_free_object_storage, NULL TSRMLS_CC); - - return retval; -} - -static zend_function *pimple_closure_get_constructor(zval *obj TSRMLS_DC) -{ - zend_error(E_ERROR, "Pimple\\ContainerClosure is an internal class and cannot be instantiated"); - - return NULL; -} - -static int pimple_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, union _zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC) -{ - *zobj_ptr = obj; - *ce_ptr = Z_OBJCE_P(obj); - *fptr_ptr = (zend_function *)&pimple_closure_invoker_function; - - return SUCCESS; -} - -static zend_object_value pimple_object_create(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - pimple_object *pimple_obj = NULL; - zend_function *function = NULL; - - pimple_obj = emalloc(sizeof(pimple_object)); - ZEND_OBJ_INIT(&pimple_obj->zobj, ce); - - PIMPLE_OBJECT_HANDLE_INHERITANCE_OBJECT_HANDLERS - - retval.handlers = &pimple_object_handlers; - retval.handle = zend_objects_store_put(pimple_obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) pimple_free_object_storage, NULL TSRMLS_CC); - - zend_hash_init(&pimple_obj->factories, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0); - zend_hash_init(&pimple_obj->protected, PIMPLE_DEFAULT_ZVAL_CACHE_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0); - zend_hash_init(&pimple_obj->values, PIMPLE_DEFAULT_ZVAL_VALUES_NUM, NULL, (dtor_func_t)pimple_bucket_dtor, 0); - - return retval; -} - -static void pimple_object_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) -{ - FETCH_DIM_HANDLERS_VARS - - pimple_bucket_value pimple_value = {0}, *found_value = NULL; - ulong hash; - - pimple_zval_to_pimpleval(value, &pimple_value TSRMLS_CC); - - if (!offset) {/* $p[] = 'foo' when not overloaded */ - zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL); - Z_ADDREF_P(value); - return; - } - - switch (Z_TYPE_P(offset)) { - case IS_STRING: - hash = zend_hash_func(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - zend_hash_quick_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void **)&found_value); - if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) { - pimple_free_bucket(&pimple_value); - pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - return; - } - if (zend_hash_quick_update(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hash, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) { - pimple_free_bucket(&pimple_value); - return; - } - Z_ADDREF_P(value); - break; - case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: - if (Z_TYPE_P(offset) == IS_DOUBLE) { - index = (ulong)Z_DVAL_P(offset); - } else { - index = Z_LVAL_P(offset); - } - zend_hash_index_find(&pimple_obj->values, index, (void **)&found_value); - if (found_value && found_value->type == PIMPLE_IS_SERVICE && found_value->initialized == 1) { - pimple_free_bucket(&pimple_value); - convert_to_string(offset); - pimple_throw_exception_string(pimple_ce_FrozenServiceException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - return; - } - if (zend_hash_index_update(&pimple_obj->values, index, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL) == FAILURE) { - pimple_free_bucket(&pimple_value); - return; - } - Z_ADDREF_P(value); - break; - case IS_NULL: /* $p[] = 'foo' when overloaded */ - zend_hash_next_index_insert(&pimple_obj->values, (void *)&pimple_value, sizeof(pimple_bucket_value), NULL); - Z_ADDREF_P(value); - break; - default: - pimple_free_bucket(&pimple_value); - zend_error(E_WARNING, "Unsupported offset type"); - } -} - -static void pimple_object_unset_dimension(zval *object, zval *offset TSRMLS_DC) -{ - FETCH_DIM_HANDLERS_VARS - - switch (Z_TYPE_P(offset)) { - case IS_STRING: - zend_symtable_del(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - zend_symtable_del(&pimple_obj->factories, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - zend_symtable_del(&pimple_obj->protected, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1); - break; - case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: - if (Z_TYPE_P(offset) == IS_DOUBLE) { - index = (ulong)Z_DVAL_P(offset); - } else { - index = Z_LVAL_P(offset); - } - zend_hash_index_del(&pimple_obj->values, index); - zend_hash_index_del(&pimple_obj->factories, index); - zend_hash_index_del(&pimple_obj->protected, index); - break; - default: - zend_error(E_WARNING, "Unsupported offset type"); - } -} - -static int pimple_object_has_dimension(zval *object, zval *offset, int check_empty TSRMLS_DC) -{ - FETCH_DIM_HANDLERS_VARS - - pimple_bucket_value *retval = NULL; - - switch (Z_TYPE_P(offset)) { - case IS_STRING: - if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == SUCCESS) { - switch (check_empty) { - case 0: /* isset */ - return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;) */ - case 1: /* empty */ - default: - return zend_is_true(retval->value); - } - } - return 0; - break; - case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: - if (Z_TYPE_P(offset) == IS_DOUBLE) { - index = (ulong)Z_DVAL_P(offset); - } else { - index = Z_LVAL_P(offset); - } - if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == SUCCESS) { - switch (check_empty) { - case 0: /* isset */ - return 1; /* Differs from PHP behavior (Z_TYPE_P(retval->value) != IS_NULL;)*/ - case 1: /* empty */ - default: - return zend_is_true(retval->value); - } - } - return 0; - break; - default: - zend_error(E_WARNING, "Unsupported offset type"); - return 0; - } -} - -static zval *pimple_object_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) -{ - FETCH_DIM_HANDLERS_VARS - - pimple_bucket_value *retval = NULL; - zend_fcall_info fci = {0}; - zval *retval_ptr_ptr = NULL; - - switch (Z_TYPE_P(offset)) { - case IS_STRING: - if (zend_symtable_find(&pimple_obj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void **)&retval) == FAILURE) { - pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - - return EG(uninitialized_zval_ptr); - } - break; - case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: - if (Z_TYPE_P(offset) == IS_DOUBLE) { - index = (ulong)Z_DVAL_P(offset); - } else { - index = Z_LVAL_P(offset); - } - if (zend_hash_index_find(&pimple_obj->values, index, (void **)&retval) == FAILURE) { - return EG(uninitialized_zval_ptr); - } - break; - case IS_NULL: /* $p[][3] = 'foo' first dim access */ - return EG(uninitialized_zval_ptr); - break; - default: - zend_error(E_WARNING, "Unsupported offset type"); - return EG(uninitialized_zval_ptr); - } - - if(retval->type == PIMPLE_IS_PARAM) { - return retval->value; - } - - if (zend_hash_index_exists(&pimple_obj->protected, retval->handle_num)) { - /* Service is protected, return the value every time */ - return retval->value; - } - - if (zend_hash_index_exists(&pimple_obj->factories, retval->handle_num)) { - /* Service is a factory, call it every time and never cache its result */ - PIMPLE_CALL_CB - Z_DELREF_P(retval_ptr_ptr); /* fetch dim addr will increment refcount */ - return retval_ptr_ptr; - } - - if (retval->initialized == 1) { - /* Service has already been called, return its cached value */ - return retval->value; - } - - ALLOC_INIT_ZVAL(retval->raw); - MAKE_COPY_ZVAL(&retval->value, retval->raw); - - PIMPLE_CALL_CB - - retval->initialized = 1; - zval_ptr_dtor(&retval->value); - retval->value = retval_ptr_ptr; - - return retval->value; -} - -static int pimple_zval_is_valid_callback(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC) -{ - if (Z_TYPE_P(_zval) != IS_OBJECT) { - return FAILURE; - } - - if (_pimple_bucket_value->fcc.called_scope) { - return SUCCESS; - } - - if (Z_OBJ_HANDLER_P(_zval, get_closure) && Z_OBJ_HANDLER_P(_zval, get_closure)(_zval, &_pimple_bucket_value->fcc.calling_scope, &_pimple_bucket_value->fcc.function_handler, &_pimple_bucket_value->fcc.object_ptr TSRMLS_CC) == SUCCESS) { - _pimple_bucket_value->fcc.called_scope = _pimple_bucket_value->fcc.calling_scope; - return SUCCESS; - } else { - return FAILURE; - } -} - -static int pimple_zval_to_pimpleval(zval *_zval, pimple_bucket_value *_pimple_bucket_value TSRMLS_DC) -{ - _pimple_bucket_value->value = _zval; - - if (Z_TYPE_P(_zval) != IS_OBJECT) { - return PIMPLE_IS_PARAM; - } - - if (pimple_zval_is_valid_callback(_zval, _pimple_bucket_value TSRMLS_CC) == SUCCESS) { - _pimple_bucket_value->type = PIMPLE_IS_SERVICE; - _pimple_bucket_value->handle_num = Z_OBJ_HANDLE_P(_zval); - } - - return PIMPLE_IS_SERVICE; -} - -static void pimple_bucket_dtor(pimple_bucket_value *bucket) -{ - zval_ptr_dtor(&bucket->value); - pimple_free_bucket(bucket); -} - -PHP_METHOD(FrozenServiceException, __construct) -{ - char *id = NULL; - int id_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) { - return; - } - pimple_exception_call_parent_constructor(getThis(), "Cannot override frozen service \"%s\".", id TSRMLS_CC); -} - -PHP_METHOD(InvalidServiceIdentifierException, __construct) -{ - char *id = NULL; - int id_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) { - return; - } - pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" does not contain an object definition.", id TSRMLS_CC); -} - -PHP_METHOD(UnknownIdentifierException, __construct) -{ - char *id = NULL; - int id_len; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &id, &id_len) == FAILURE) { - return; - } - pimple_exception_call_parent_constructor(getThis(), "Identifier \"%s\" is not defined.", id TSRMLS_CC); -} - -PHP_METHOD(Pimple, protect) -{ - zval *protected = NULL; - pimple_object *pobj = NULL; - pimple_bucket_value bucket = {0}; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &protected) == FAILURE) { - return; - } - - if (pimple_zval_is_valid_callback(protected, &bucket TSRMLS_CC) == FAILURE) { - pimple_free_bucket(&bucket); - zend_throw_exception(pimple_ce_ExpectedInvokableException, "Callable is not a Closure or invokable object.", 0 TSRMLS_CC); - return; - } - - pimple_zval_to_pimpleval(protected, &bucket TSRMLS_CC); - pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC); - - if (zend_hash_index_update(&pobj->protected, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) { - Z_ADDREF_P(protected); - RETURN_ZVAL(protected, 1 , 0); - } else { - pimple_free_bucket(&bucket); - } - RETURN_FALSE; -} - -PHP_METHOD(Pimple, raw) -{ - zval *offset = NULL; - pimple_object *pobj = NULL; - pimple_bucket_value *value = NULL; - ulong index; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) { - return; - } - - pobj = zend_object_store_get_object(getThis() TSRMLS_CC); - - switch (Z_TYPE_P(offset)) { - case IS_STRING: - if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) { - pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - RETURN_NULL(); - } - break; - case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: - if (Z_TYPE_P(offset) == IS_DOUBLE) { - index = (ulong)Z_DVAL_P(offset); - } else { - index = Z_LVAL_P(offset); - } - if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) { - RETURN_NULL(); - } - break; - case IS_NULL: - default: - zend_error(E_WARNING, "Unsupported offset type"); - } - - if (value->raw) { - RETVAL_ZVAL(value->raw, 1, 0); - } else { - RETVAL_ZVAL(value->value, 1, 0); - } -} - -PHP_METHOD(Pimple, extend) -{ - zval *offset = NULL, *callable = NULL, *pimple_closure_obj = NULL; - pimple_bucket_value bucket = {0}, *value = NULL; - pimple_object *pobj = NULL; - pimple_closure_object *pcobj = NULL; - ulong index; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &callable) == FAILURE) { - return; - } - - pobj = zend_object_store_get_object(getThis() TSRMLS_CC); - - switch (Z_TYPE_P(offset)) { - case IS_STRING: - if (zend_symtable_find(&pobj->values, Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, (void *)&value) == FAILURE) { - pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - RETURN_NULL(); - } - - if (value->type != PIMPLE_IS_SERVICE) { - pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - RETURN_NULL(); - } - if (zend_hash_index_exists(&pobj->protected, value->handle_num)) { - int er = EG(error_reporting); - EG(error_reporting) = 0; - php_error(E_DEPRECATED, "How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure \"%s\" should be protected?", Z_STRVAL_P(offset)); - EG(error_reporting) = er; - } - break; - case IS_DOUBLE: - case IS_BOOL: - case IS_LONG: - if (Z_TYPE_P(offset) == IS_DOUBLE) { - index = (ulong)Z_DVAL_P(offset); - } else { - index = Z_LVAL_P(offset); - } - if (zend_hash_index_find(&pobj->values, index, (void *)&value) == FAILURE) { - convert_to_string(offset); - pimple_throw_exception_string(pimple_ce_UnknownIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - RETURN_NULL(); - } - if (value->type != PIMPLE_IS_SERVICE) { - convert_to_string(offset); - pimple_throw_exception_string(pimple_ce_InvalidServiceIdentifierException, Z_STRVAL_P(offset), Z_STRLEN_P(offset) TSRMLS_CC); - RETURN_NULL(); - } - if (zend_hash_index_exists(&pobj->protected, value->handle_num)) { - int er = EG(error_reporting); - EG(error_reporting) = 0; - php_error(E_DEPRECATED, "How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure \"%ld\" should be protected?", index); - EG(error_reporting) = er; - } - break; - case IS_NULL: - default: - zend_error(E_WARNING, "Unsupported offset type"); - } - - if (pimple_zval_is_valid_callback(callable, &bucket TSRMLS_CC) == FAILURE) { - pimple_free_bucket(&bucket); - zend_throw_exception(pimple_ce_ExpectedInvokableException, "Extension service definition is not a Closure or invokable object.", 0 TSRMLS_CC); - RETURN_NULL(); - } - pimple_free_bucket(&bucket); - - ALLOC_INIT_ZVAL(pimple_closure_obj); - object_init_ex(pimple_closure_obj, pimple_closure_ce); - - pcobj = zend_object_store_get_object(pimple_closure_obj TSRMLS_CC); - pcobj->callable = callable; - pcobj->factory = value->value; - Z_ADDREF_P(callable); - Z_ADDREF_P(value->value); - - if (zend_hash_index_exists(&pobj->factories, value->handle_num)) { - pimple_zval_to_pimpleval(pimple_closure_obj, &bucket TSRMLS_CC); - zend_hash_index_del(&pobj->factories, value->handle_num); - zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL); - Z_ADDREF_P(pimple_closure_obj); - } - - pimple_object_write_dimension(getThis(), offset, pimple_closure_obj TSRMLS_CC); - - RETVAL_ZVAL(pimple_closure_obj, 1, 1); -} - -PHP_METHOD(Pimple, keys) -{ - HashPosition pos; - pimple_object *pobj = NULL; - zval **value = NULL; - zval *endval = NULL; - char *str_index = NULL; - int str_len; - ulong num_index; - - if (zend_parse_parameters_none() == FAILURE) { - return; - } - - pobj = zend_object_store_get_object(getThis() TSRMLS_CC); - array_init_size(return_value, zend_hash_num_elements(&pobj->values)); - - zend_hash_internal_pointer_reset_ex(&pobj->values, &pos); - - while(zend_hash_get_current_data_ex(&pobj->values, (void **)&value, &pos) == SUCCESS) { - MAKE_STD_ZVAL(endval); - switch (zend_hash_get_current_key_ex(&pobj->values, &str_index, (uint *)&str_len, &num_index, 0, &pos)) { - case HASH_KEY_IS_STRING: - ZVAL_STRINGL(endval, str_index, str_len - 1, 1); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL); - break; - case HASH_KEY_IS_LONG: - ZVAL_LONG(endval, num_index); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &endval, sizeof(zval *), NULL); - break; - } - zend_hash_move_forward_ex(&pobj->values, &pos); - } -} - -PHP_METHOD(Pimple, factory) -{ - zval *factory = NULL; - pimple_object *pobj = NULL; - pimple_bucket_value bucket = {0}; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &factory) == FAILURE) { - return; - } - - if (pimple_zval_is_valid_callback(factory, &bucket TSRMLS_CC) == FAILURE) { - pimple_free_bucket(&bucket); - zend_throw_exception(pimple_ce_ExpectedInvokableException, "Service definition is not a Closure or invokable object.", 0 TSRMLS_CC); - return; - } - - pimple_zval_to_pimpleval(factory, &bucket TSRMLS_CC); - pobj = (pimple_object *)zend_object_store_get_object(getThis() TSRMLS_CC); - - if (zend_hash_index_update(&pobj->factories, bucket.handle_num, (void *)&bucket, sizeof(pimple_bucket_value), NULL) == SUCCESS) { - Z_ADDREF_P(factory); - RETURN_ZVAL(factory, 1 , 0); - } else { - pimple_free_bucket(&bucket); - } - - RETURN_FALSE; -} - -PHP_METHOD(Pimple, offsetSet) -{ - zval *offset = NULL, *value = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &offset, &value) == FAILURE) { - return; - } - - pimple_object_write_dimension(getThis(), offset, value TSRMLS_CC); -} - -PHP_METHOD(Pimple, offsetGet) -{ - zval *offset = NULL, *retval = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) { - return; - } - - retval = pimple_object_read_dimension(getThis(), offset, 0 TSRMLS_CC); - - RETVAL_ZVAL(retval, 1, 0); -} - -PHP_METHOD(Pimple, offsetUnset) -{ - zval *offset = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) { - return; - } - - pimple_object_unset_dimension(getThis(), offset TSRMLS_CC); -} - -PHP_METHOD(Pimple, offsetExists) -{ - zval *offset = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &offset) == FAILURE) { - return; - } - - RETVAL_BOOL(pimple_object_has_dimension(getThis(), offset, 1 TSRMLS_CC)); -} - -PHP_METHOD(Pimple, register) -{ - zval *provider; - zval **data; - zval *retval = NULL; - zval key; - - HashTable *array = NULL; - HashPosition pos; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|h", &provider, pimple_serviceprovider_ce, &array) == FAILURE) { - return; - } - - RETVAL_ZVAL(getThis(), 1, 0); - - zend_call_method_with_1_params(&provider, Z_OBJCE_P(provider), NULL, "register", &retval, getThis()); - - if (retval) { - zval_ptr_dtor(&retval); - } - - if (!array) { - return; - } - - zend_hash_internal_pointer_reset_ex(array, &pos); - - while(zend_hash_get_current_data_ex(array, (void **)&data, &pos) == SUCCESS) { - zend_hash_get_current_key_zval_ex(array, &key, &pos); - pimple_object_write_dimension(getThis(), &key, *data TSRMLS_CC); - zend_hash_move_forward_ex(array, &pos); - } -} - -PHP_METHOD(Pimple, __construct) -{ - zval *values = NULL, **pData = NULL, offset; - HashPosition pos; - char *str_index = NULL; - zend_uint str_length; - ulong num_index; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &values) == FAILURE) { - return; - } - - PIMPLE_DEPRECATE - - if (!values) { - return; - } - - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos); - while (zend_hash_has_more_elements_ex(Z_ARRVAL_P(values), &pos) == SUCCESS) { - zend_hash_get_current_data_ex(Z_ARRVAL_P(values), (void **)&pData, &pos); - zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &str_index, &str_length, &num_index, 0, &pos); - INIT_ZVAL(offset); - if (zend_hash_get_current_key_type_ex(Z_ARRVAL_P(values), &pos) == HASH_KEY_IS_LONG) { - ZVAL_LONG(&offset, num_index); - } else { - ZVAL_STRINGL(&offset, str_index, (str_length - 1), 0); - } - pimple_object_write_dimension(getThis(), &offset, *pData TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos); - } -} - -/* - * This is PHP code snippet handling extend()s calls : - - $extended = function ($c) use ($callable, $factory) { - return $callable($factory($c), $c); - }; - - */ -PHP_METHOD(PimpleClosure, invoker) -{ - pimple_closure_object *pcobj = NULL; - zval *arg = NULL, *retval = NULL, *newretval = NULL; - zend_fcall_info fci = {0}; - zval **args[2]; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &arg) == FAILURE) { - return; - } - - pcobj = zend_object_store_get_object(getThis() TSRMLS_CC); - - fci.function_name = pcobj->factory; - args[0] = &arg; - zend_fcall_info_argp(&fci TSRMLS_CC, 1, args); - fci.retval_ptr_ptr = &retval; - fci.size = sizeof(fci); - - if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) { - efree(fci.params); - return; /* Should here return default zval */ - } - - efree(fci.params); - memset(&fci, 0, sizeof(fci)); - fci.size = sizeof(fci); - - fci.function_name = pcobj->callable; - args[0] = &retval; - args[1] = &arg; - zend_fcall_info_argp(&fci TSRMLS_CC, 2, args); - fci.retval_ptr_ptr = &newretval; - - if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE || EG(exception)) { - efree(fci.params); - zval_ptr_dtor(&retval); - return; - } - - efree(fci.params); - zval_ptr_dtor(&retval); - - RETVAL_ZVAL(newretval, 1 ,1); -} - -PHP_MINIT_FUNCTION(pimple) -{ - zend_class_entry tmp_ce_PsrContainerInterface, tmp_ce_PsrContainerExceptionInterface, tmp_ce_PsrNotFoundExceptionInterface; - zend_class_entry tmp_ce_ExpectedInvokableException, tmp_ce_FrozenServiceException, tmp_ce_InvalidServiceIdentifierException, tmp_ce_UnknownIdentifierException; - zend_class_entry tmp_pimple_ce, tmp_pimple_closure_ce, tmp_pimple_serviceprovider_iface_ce; - - /* Psr\Container namespace */ - INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerInterface, PSR_CONTAINER_NS, "ContainerInterface", pimple_ce_PsrContainerInterface_functions); - INIT_NS_CLASS_ENTRY(tmp_ce_PsrContainerExceptionInterface, PSR_CONTAINER_NS, "ContainerExceptionInterface", pimple_ce_PsrContainerExceptionInterface_functions); - INIT_NS_CLASS_ENTRY(tmp_ce_PsrNotFoundExceptionInterface, PSR_CONTAINER_NS, "NotFoundExceptionInterface", pimple_ce_PsrNotFoundExceptionInterface_functions); - - pimple_ce_PsrContainerInterface = zend_register_internal_interface(&tmp_ce_PsrContainerInterface TSRMLS_CC); - pimple_ce_PsrContainerExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrContainerExceptionInterface TSRMLS_CC); - pimple_ce_PsrNotFoundExceptionInterface = zend_register_internal_interface(&tmp_ce_PsrNotFoundExceptionInterface TSRMLS_CC); - - zend_class_implements(pimple_ce_PsrNotFoundExceptionInterface TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface); - - /* Pimple\Exception namespace */ - INIT_NS_CLASS_ENTRY(tmp_ce_ExpectedInvokableException, PIMPLE_EXCEPTION_NS, "ExpectedInvokableException", NULL); - INIT_NS_CLASS_ENTRY(tmp_ce_FrozenServiceException, PIMPLE_EXCEPTION_NS, "FrozenServiceException", pimple_ce_FrozenServiceException_functions); - INIT_NS_CLASS_ENTRY(tmp_ce_InvalidServiceIdentifierException, PIMPLE_EXCEPTION_NS, "InvalidServiceIdentifierException", pimple_ce_InvalidServiceIdentifierException_functions); - INIT_NS_CLASS_ENTRY(tmp_ce_UnknownIdentifierException, PIMPLE_EXCEPTION_NS, "UnknownIdentifierException", pimple_ce_UnknownIdentifierException_functions); - - pimple_ce_ExpectedInvokableException = zend_register_internal_class_ex(&tmp_ce_ExpectedInvokableException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC); - pimple_ce_FrozenServiceException = zend_register_internal_class_ex(&tmp_ce_FrozenServiceException, spl_ce_RuntimeException, NULL TSRMLS_CC); - pimple_ce_InvalidServiceIdentifierException = zend_register_internal_class_ex(&tmp_ce_InvalidServiceIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC); - pimple_ce_UnknownIdentifierException = zend_register_internal_class_ex(&tmp_ce_UnknownIdentifierException, spl_ce_InvalidArgumentException, NULL TSRMLS_CC); - - zend_class_implements(pimple_ce_ExpectedInvokableException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface); - zend_class_implements(pimple_ce_FrozenServiceException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface); - zend_class_implements(pimple_ce_InvalidServiceIdentifierException TSRMLS_CC, 1, pimple_ce_PsrContainerExceptionInterface); - zend_class_implements(pimple_ce_UnknownIdentifierException TSRMLS_CC, 1, pimple_ce_PsrNotFoundExceptionInterface); - - /* Pimple namespace */ - INIT_NS_CLASS_ENTRY(tmp_pimple_ce, PIMPLE_NS, "Container", pimple_ce_functions); - INIT_NS_CLASS_ENTRY(tmp_pimple_closure_ce, PIMPLE_NS, "ContainerClosure", NULL); - INIT_NS_CLASS_ENTRY(tmp_pimple_serviceprovider_iface_ce, PIMPLE_NS, "ServiceProviderInterface", pimple_serviceprovider_iface_ce_functions); - - tmp_pimple_ce.create_object = pimple_object_create; - tmp_pimple_closure_ce.create_object = pimple_closure_object_create; - - pimple_ce = zend_register_internal_class(&tmp_pimple_ce TSRMLS_CC); - zend_class_implements(pimple_ce TSRMLS_CC, 1, zend_ce_arrayaccess); - - pimple_closure_ce = zend_register_internal_class(&tmp_pimple_closure_ce TSRMLS_CC); - pimple_closure_ce->ce_flags |= ZEND_ACC_FINAL_CLASS; - - pimple_serviceprovider_ce = zend_register_internal_interface(&tmp_pimple_serviceprovider_iface_ce TSRMLS_CC); - - memcpy(&pimple_closure_object_handlers, zend_get_std_object_handlers(), sizeof(*zend_get_std_object_handlers())); - pimple_object_handlers = std_object_handlers; - pimple_closure_object_handlers.get_closure = pimple_closure_get_closure; - - pimple_closure_invoker_function.function_name = "Pimple closure internal invoker"; - pimple_closure_invoker_function.fn_flags |= ZEND_ACC_CLOSURE; - pimple_closure_invoker_function.handler = ZEND_MN(PimpleClosure_invoker); - pimple_closure_invoker_function.num_args = 1; - pimple_closure_invoker_function.required_num_args = 1; - pimple_closure_invoker_function.scope = pimple_closure_ce; - pimple_closure_invoker_function.type = ZEND_INTERNAL_FUNCTION; - pimple_closure_invoker_function.module = &pimple_module_entry; - - return SUCCESS; -} - -PHP_MINFO_FUNCTION(pimple) -{ - php_info_print_table_start(); - php_info_print_table_header(2, "SensioLabs Pimple C support", "enabled"); - php_info_print_table_row(2, "Pimple supported version", PIMPLE_VERSION); - php_info_print_table_end(); - - php_info_print_box_start(0); - php_write((void *)ZEND_STRL("SensioLabs Pimple C support developed by Julien Pauli") TSRMLS_CC); - if (!sapi_module.phpinfo_as_text) { - php_write((void *)ZEND_STRL(sensiolabs_logo) TSRMLS_CC); - } - php_info_print_box_end(); -} - -zend_module_entry pimple_module_entry = { - STANDARD_MODULE_HEADER, - "pimple", - NULL, - PHP_MINIT(pimple), - NULL, - NULL, - NULL, - PHP_MINFO(pimple), - PIMPLE_VERSION, - STANDARD_MODULE_PROPERTIES -}; - -#ifdef COMPILE_DL_PIMPLE -ZEND_GET_MODULE(pimple) -#endif diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple_compat.h b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple_compat.h deleted file mode 100644 index d234e174..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/pimple_compat.h +++ /dev/null @@ -1,81 +0,0 @@ - -/* - * This file is part of Pimple. - * - * Copyright (c) 2014 Fabien Potencier - * - * 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. - */ - -#ifndef PIMPLE_COMPAT_H_ -#define PIMPLE_COMPAT_H_ - -#include "Zend/zend_extensions.h" /* for ZEND_EXTENSION_API_NO */ - -#define PHP_5_0_X_API_NO 220040412 -#define PHP_5_1_X_API_NO 220051025 -#define PHP_5_2_X_API_NO 220060519 -#define PHP_5_3_X_API_NO 220090626 -#define PHP_5_4_X_API_NO 220100525 -#define PHP_5_5_X_API_NO 220121212 -#define PHP_5_6_X_API_NO 220131226 - -#define IS_PHP_56 ZEND_EXTENSION_API_NO == PHP_5_6_X_API_NO -#define IS_AT_LEAST_PHP_56 ZEND_EXTENSION_API_NO >= PHP_5_6_X_API_NO - -#define IS_PHP_55 ZEND_EXTENSION_API_NO == PHP_5_5_X_API_NO -#define IS_AT_LEAST_PHP_55 ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO - -#define IS_PHP_54 ZEND_EXTENSION_API_NO == PHP_5_4_X_API_NO -#define IS_AT_LEAST_PHP_54 ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO - -#define IS_PHP_53 ZEND_EXTENSION_API_NO == PHP_5_3_X_API_NO -#define IS_AT_LEAST_PHP_53 ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO - -#if IS_PHP_53 -#define object_properties_init(obj, ce) do { \ - zend_hash_copy(obj->properties, &ce->default_properties, zval_copy_property_ctor(ce), NULL, sizeof(zval *)); \ - } while (0); -#endif - -#define ZEND_OBJ_INIT(obj, ce) do { \ - zend_object_std_init(obj, ce TSRMLS_CC); \ - object_properties_init((obj), (ce)); \ - } while(0); - -#if IS_PHP_53 || IS_PHP_54 -static void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) { - Bucket *p; - - p = pos ? (*pos) : ht->pInternalPointer; - - if (!p) { - Z_TYPE_P(key) = IS_NULL; - } else if (p->nKeyLength) { - Z_TYPE_P(key) = IS_STRING; - Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1); - Z_STRLEN_P(key) = p->nKeyLength - 1; - } else { - Z_TYPE_P(key) = IS_LONG; - Z_LVAL_P(key) = p->h; - } -} -#endif - -#endif /* PIMPLE_COMPAT_H_ */ diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/001.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/001.phpt deleted file mode 100644 index 0809ea23..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/001.phpt +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -Test for read_dim/write_dim handlers ---SKIPIF-- - ---FILE-- - - ---EXPECTF-- -foo -42 -foo2 -foo99 -baz -strstr \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/002.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/002.phpt deleted file mode 100644 index 7b56d2c1..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/002.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Test for constructor ---SKIPIF-- - ---FILE-- -'foo')); -var_dump($p[42]); -?> ---EXPECT-- -NULL -string(3) "foo" diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/003.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/003.phpt deleted file mode 100644 index a22cfa35..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/003.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Test empty dimensions ---SKIPIF-- - ---FILE-- - ---EXPECT-- -int(42) -string(3) "bar" \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/004.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/004.phpt deleted file mode 100644 index 1e1d2513..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/004.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Test has/unset dim handlers ---SKIPIF-- - ---FILE-- - ---EXPECT-- -int(42) -NULL -bool(true) -bool(false) -bool(true) -bool(true) \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/005.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/005.phpt deleted file mode 100644 index 0479ee05..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/005.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Test simple class inheritance ---SKIPIF-- - ---FILE-- -someAttr; -?> ---EXPECT-- -string(3) "hit" -foo -fooAttr \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/006.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/006.phpt deleted file mode 100644 index cfe8a119..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/006.phpt +++ /dev/null @@ -1,51 +0,0 @@ ---TEST-- -Test complex class inheritance ---SKIPIF-- - ---FILE-- - 'bar', 88 => 'baz'); - -$p = new TestPimple($defaultValues); -$p[42] = 'foo'; -var_dump($p[42]); -var_dump($p[0]); -?> ---EXPECT-- -string(13) "hit offsetset" -string(27) "hit offsetget in TestPimple" -string(25) "hit offsetget in MyPimple" -string(3) "foo" -string(27) "hit offsetget in TestPimple" -string(25) "hit offsetget in MyPimple" -string(3) "baz" \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/007.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/007.phpt deleted file mode 100644 index 5aac6838..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/007.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Test for read_dim/write_dim handlers ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -foo -42 \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/008.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/008.phpt deleted file mode 100644 index db7eeec4..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/008.phpt +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -Test frozen services ---SKIPIF-- - ---FILE-- - ---EXPECTF-- diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/009.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/009.phpt deleted file mode 100644 index bb05ea29..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/009.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Test service is called as callback, and only once ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -bool(true) \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/010.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/010.phpt deleted file mode 100644 index badce014..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/010.phpt +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -Test service is called as callback for every callback type ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -callme -called -Foo::bar -array(2) { - [0]=> - string(3) "Foo" - [1]=> - string(3) "bar" -} \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/011.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/011.phpt deleted file mode 100644 index 6682ab8e..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/011.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Test service callback throwing an exception ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -all right! \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/012.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/012.phpt deleted file mode 100644 index 4c6ac486..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/012.phpt +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -Test service factory ---SKIPIF-- - ---FILE-- -factory($f = function() { var_dump('called-1'); return 'ret-1';}); - -$p[] = $f; - -$p[] = function () { var_dump('called-2'); return 'ret-2'; }; - -var_dump($p[0]); -var_dump($p[0]); -var_dump($p[1]); -var_dump($p[1]); -?> ---EXPECTF-- -string(8) "called-1" -string(5) "ret-1" -string(8) "called-1" -string(5) "ret-1" -string(8) "called-2" -string(5) "ret-2" -string(5) "ret-2" \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/013.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/013.phpt deleted file mode 100644 index f419958c..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/013.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -Test keys() ---SKIPIF-- - ---FILE-- -keys()); - -$p['foo'] = 'bar'; -$p[] = 'foo'; - -var_dump($p->keys()); - -unset($p['foo']); - -var_dump($p->keys()); -?> ---EXPECTF-- -array(0) { -} -array(2) { - [0]=> - string(3) "foo" - [1]=> - int(0) -} -array(1) { - [0]=> - int(0) -} \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/014.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/014.phpt deleted file mode 100644 index ac937213..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/014.phpt +++ /dev/null @@ -1,30 +0,0 @@ ---TEST-- -Test raw() ---SKIPIF-- - ---FILE-- -raw('foo')); -var_dump($p[42]); - -unset($p['foo']); - -try { - $p->raw('foo'); - echo "expected exception"; -} catch (InvalidArgumentException $e) { } ---EXPECTF-- -string(8) "called-2" -string(5) "ret-2" -object(Closure)#%i (0) { -} -string(8) "called-2" -string(5) "ret-2" \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/015.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/015.phpt deleted file mode 100644 index 314f008a..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/015.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Test protect() ---SKIPIF-- - ---FILE-- -protect($f); - -var_dump($p['foo']); ---EXPECTF-- -object(Closure)#%i (0) { -} \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/016.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/016.phpt deleted file mode 100644 index e55edb0a..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/016.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -Test extend() ---SKIPIF-- - ---FILE-- -extend(12, function ($w) { var_dump($w); return 'bar'; }); /* $callable in code above */ - -var_dump($c('param')); ---EXPECTF-- -string(5) "param" -string(3) "foo" -string(3) "bar" \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017.phpt deleted file mode 100644 index bac23ce0..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Test extend() with exception in service extension ---SKIPIF-- - ---FILE-- -extend(12, function ($w) { throw new BadMethodCallException; }); - -try { - $p[12]; - echo "Exception expected"; -} catch (BadMethodCallException $e) { } ---EXPECTF-- diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt deleted file mode 100644 index 8f881d6e..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/017_1.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -Test extend() with exception in service factory ---SKIPIF-- - ---FILE-- -extend(12, function ($w) { return 'foobar'; }); - -try { - $p[12]; - echo "Exception expected"; -} catch (BadMethodCallException $e) { } ---EXPECTF-- diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/018.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/018.phpt deleted file mode 100644 index 27c12a14..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/018.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -Test register() ---SKIPIF-- - ---FILE-- -register(new Foo, array(42 => 'bar')); - -var_dump($p[42]); ---EXPECTF-- -object(Pimple\Container)#1 (0) { -} -string(3) "bar" \ No newline at end of file diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/019.phpt b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/019.phpt deleted file mode 100644 index 28a9aeca..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/019.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Test register() returns static and is a fluent interface ---SKIPIF-- - ---FILE-- -register(new Foo)); ---EXPECTF-- -bool(true) diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench.phpb b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench.phpb deleted file mode 100644 index 8f983e65..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench.phpb +++ /dev/null @@ -1,51 +0,0 @@ -factory($factory); - -$p['factory'] = $factory; - -echo $p['factory']; -echo $p['factory']; -echo $p['factory']; - -} - -echo microtime(true) - $time; diff --git a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb b/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb deleted file mode 100644 index aec541f0..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/ext/pimple/tests/bench_shared.phpb +++ /dev/null @@ -1,25 +0,0 @@ - diff --git a/advancedcontentfilter/vendor/pimple/pimple/phpunit.xml.dist b/advancedcontentfilter/vendor/pimple/pimple/phpunit.xml.dist deleted file mode 100644 index 5c8d487f..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/phpunit.xml.dist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - ./src/Pimple/Tests - - - diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Container.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Container.php deleted file mode 100644 index 707b92b8..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Container.php +++ /dev/null @@ -1,298 +0,0 @@ -factories = new \SplObjectStorage(); - $this->protected = new \SplObjectStorage(); - - foreach ($values as $key => $value) { - $this->offsetSet($key, $value); - } - } - - /** - * Sets a parameter or an object. - * - * Objects must be defined as Closures. - * - * Allowing any PHP callable leads to difficult to debug problems - * as function names (strings) are callable (creating a function with - * the same name as an existing parameter would break your container). - * - * @param string $id The unique identifier for the parameter or object - * @param mixed $value The value of the parameter or a closure to define an object - * - * @throws FrozenServiceException Prevent override of a frozen service - */ - public function offsetSet($id, $value) - { - if (isset($this->frozen[$id])) { - throw new FrozenServiceException($id); - } - - $this->values[$id] = $value; - $this->keys[$id] = true; - } - - /** - * Gets a parameter or an object. - * - * @param string $id The unique identifier for the parameter or object - * - * @return mixed The value of the parameter or an object - * - * @throws UnknownIdentifierException If the identifier is not defined - */ - public function offsetGet($id) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if ( - isset($this->raw[$id]) - || !\is_object($this->values[$id]) - || isset($this->protected[$this->values[$id]]) - || !\method_exists($this->values[$id], '__invoke') - ) { - return $this->values[$id]; - } - - if (isset($this->factories[$this->values[$id]])) { - return $this->values[$id]($this); - } - - $raw = $this->values[$id]; - $val = $this->values[$id] = $raw($this); - $this->raw[$id] = $raw; - - $this->frozen[$id] = true; - - return $val; - } - - /** - * Checks if a parameter or an object is set. - * - * @param string $id The unique identifier for the parameter or object - * - * @return bool - */ - public function offsetExists($id) - { - return isset($this->keys[$id]); - } - - /** - * Unsets a parameter or an object. - * - * @param string $id The unique identifier for the parameter or object - */ - public function offsetUnset($id) - { - if (isset($this->keys[$id])) { - if (\is_object($this->values[$id])) { - unset($this->factories[$this->values[$id]], $this->protected[$this->values[$id]]); - } - - unset($this->values[$id], $this->frozen[$id], $this->raw[$id], $this->keys[$id]); - } - } - - /** - * Marks a callable as being a factory service. - * - * @param callable $callable A service definition to be used as a factory - * - * @return callable The passed callable - * - * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object - */ - public function factory($callable) - { - if (!\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Service definition is not a Closure or invokable object.'); - } - - $this->factories->attach($callable); - - return $callable; - } - - /** - * Protects a callable from being interpreted as a service. - * - * This is useful when you want to store a callable as a parameter. - * - * @param callable $callable A callable to protect from being evaluated - * - * @return callable The passed callable - * - * @throws ExpectedInvokableException Service definition has to be a closure or an invokable object - */ - public function protect($callable) - { - if (!\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Callable is not a Closure or invokable object.'); - } - - $this->protected->attach($callable); - - return $callable; - } - - /** - * Gets a parameter or the closure defining an object. - * - * @param string $id The unique identifier for the parameter or object - * - * @return mixed The value of the parameter or the closure defining an object - * - * @throws UnknownIdentifierException If the identifier is not defined - */ - public function raw($id) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if (isset($this->raw[$id])) { - return $this->raw[$id]; - } - - return $this->values[$id]; - } - - /** - * Extends an object definition. - * - * Useful when you want to extend an existing object definition, - * without necessarily loading that object. - * - * @param string $id The unique identifier for the object - * @param callable $callable A service definition to extend the original - * - * @return callable The wrapped callable - * - * @throws UnknownIdentifierException If the identifier is not defined - * @throws FrozenServiceException If the service is frozen - * @throws InvalidServiceIdentifierException If the identifier belongs to a parameter - * @throws ExpectedInvokableException If the extension callable is not a closure or an invokable object - */ - public function extend($id, $callable) - { - if (!isset($this->keys[$id])) { - throw new UnknownIdentifierException($id); - } - - if (isset($this->frozen[$id])) { - throw new FrozenServiceException($id); - } - - if (!\is_object($this->values[$id]) || !\method_exists($this->values[$id], '__invoke')) { - throw new InvalidServiceIdentifierException($id); - } - - if (isset($this->protected[$this->values[$id]])) { - @\trigger_error(\sprintf('How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "%s" should be protected?', $id), \E_USER_DEPRECATED); - } - - if (!\is_object($callable) || !\method_exists($callable, '__invoke')) { - throw new ExpectedInvokableException('Extension service definition is not a Closure or invokable object.'); - } - - $factory = $this->values[$id]; - - $extended = function ($c) use ($callable, $factory) { - return $callable($factory($c), $c); - }; - - if (isset($this->factories[$factory])) { - $this->factories->detach($factory); - $this->factories->attach($extended); - } - - return $this[$id] = $extended; - } - - /** - * Returns all defined value names. - * - * @return array An array of value names - */ - public function keys() - { - return \array_keys($this->values); - } - - /** - * Registers a service provider. - * - * @param ServiceProviderInterface $provider A ServiceProviderInterface instance - * @param array $values An array of values that customizes the provider - * - * @return static - */ - public function register(ServiceProviderInterface $provider, array $values = array()) - { - $provider->register($this); - - foreach ($values as $key => $value) { - $this[$key] = $value; - } - - return $this; - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php deleted file mode 100644 index 7228421b..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/ExpectedInvokableException.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ -class ExpectedInvokableException extends \InvalidArgumentException implements ContainerExceptionInterface -{ -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php deleted file mode 100644 index e4d2f6d3..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/FrozenServiceException.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class FrozenServiceException extends \RuntimeException implements ContainerExceptionInterface -{ - /** - * @param string $id Identifier of the frozen service - */ - public function __construct($id) - { - parent::__construct(\sprintf('Cannot override frozen service "%s".', $id)); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php deleted file mode 100644 index 91e82f98..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/InvalidServiceIdentifierException.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class InvalidServiceIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface -{ - /** - * @param string $id The invalid identifier - */ - public function __construct($id) - { - parent::__construct(\sprintf('Identifier "%s" does not contain an object definition.', $id)); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php deleted file mode 100644 index fb6b626e..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Exception/UnknownIdentifierException.php +++ /dev/null @@ -1,45 +0,0 @@ - - */ -class UnknownIdentifierException extends \InvalidArgumentException implements NotFoundExceptionInterface -{ - /** - * @param string $id The unknown identifier - */ - public function __construct($id) - { - parent::__construct(\sprintf('Identifier "%s" is not defined.', $id)); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/Container.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/Container.php deleted file mode 100644 index cadbfffa..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/Container.php +++ /dev/null @@ -1,55 +0,0 @@ - - */ -final class Container implements ContainerInterface -{ - private $pimple; - - public function __construct(PimpleContainer $pimple) - { - $this->pimple = $pimple; - } - - public function get($id) - { - return $this->pimple[$id]; - } - - public function has($id) - { - return isset($this->pimple[$id]); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php deleted file mode 100644 index 3361c6f1..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Psr11/ServiceLocator.php +++ /dev/null @@ -1,75 +0,0 @@ - - */ -class ServiceLocator implements ContainerInterface -{ - private $container; - private $aliases = array(); - - /** - * @param PimpleContainer $container The Container instance used to locate services - * @param array $ids Array of service ids that can be located. String keys can be used to define aliases - */ - public function __construct(PimpleContainer $container, array $ids) - { - $this->container = $container; - - foreach ($ids as $key => $id) { - $this->aliases[\is_int($key) ? $id : $key] = $id; - } - } - - /** - * {@inheritdoc} - */ - public function get($id) - { - if (!isset($this->aliases[$id])) { - throw new UnknownIdentifierException($id); - } - - return $this->container[$this->aliases[$id]]; - } - - /** - * {@inheritdoc} - */ - public function has($id) - { - return isset($this->aliases[$id]) && isset($this->container[$this->aliases[$id]]); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceIterator.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceIterator.php deleted file mode 100644 index 5cde5188..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceIterator.php +++ /dev/null @@ -1,69 +0,0 @@ - - */ -final class ServiceIterator implements \Iterator -{ - private $container; - private $ids; - - public function __construct(Container $container, array $ids) - { - $this->container = $container; - $this->ids = $ids; - } - - public function rewind() - { - \reset($this->ids); - } - - public function current() - { - return $this->container[\current($this->ids)]; - } - - public function key() - { - return \current($this->ids); - } - - public function next() - { - \next($this->ids); - } - - public function valid() - { - return null !== \key($this->ids); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php deleted file mode 100644 index c004594b..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/ServiceProviderInterface.php +++ /dev/null @@ -1,46 +0,0 @@ -value = $value; - - return $service; - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php deleted file mode 100644 index 33cd4e54..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/NonInvokable.php +++ /dev/null @@ -1,34 +0,0 @@ -factory(function () { - return new Service(); - }); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php deleted file mode 100644 index d71b184d..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Fixtures/Service.php +++ /dev/null @@ -1,35 +0,0 @@ - - */ -class Service -{ - public $value; -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php deleted file mode 100644 index 8e5c4c73..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleServiceProviderInterfaceTest.php +++ /dev/null @@ -1,76 +0,0 @@ - - */ -class PimpleServiceProviderInterfaceTest extends \PHPUnit_Framework_TestCase -{ - public function testProvider() - { - $pimple = new Container(); - - $pimpleServiceProvider = new Fixtures\PimpleServiceProvider(); - $pimpleServiceProvider->register($pimple); - - $this->assertEquals('value', $pimple['param']); - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']); - - $serviceOne = $pimple['factory']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne); - - $serviceTwo = $pimple['factory']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo); - - $this->assertNotSame($serviceOne, $serviceTwo); - } - - public function testProviderWithRegisterMethod() - { - $pimple = new Container(); - - $pimple->register(new Fixtures\PimpleServiceProvider(), array( - 'anotherParameter' => 'anotherValue', - )); - - $this->assertEquals('value', $pimple['param']); - $this->assertEquals('anotherValue', $pimple['anotherParameter']); - - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']); - - $serviceOne = $pimple['factory']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne); - - $serviceTwo = $pimple['factory']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo); - - $this->assertNotSame($serviceOne, $serviceTwo); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php deleted file mode 100644 index acb66e00..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/PimpleTest.php +++ /dev/null @@ -1,589 +0,0 @@ - - */ -class PimpleTest extends \PHPUnit_Framework_TestCase -{ - public function testWithString() - { - $pimple = new Container(); - $pimple['param'] = 'value'; - - $this->assertEquals('value', $pimple['param']); - } - - public function testWithClosure() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']); - } - - public function testServicesShouldBeDifferent() - { - $pimple = new Container(); - $pimple['service'] = $pimple->factory(function () { - return new Fixtures\Service(); - }); - - $serviceOne = $pimple['service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne); - - $serviceTwo = $pimple['service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo); - - $this->assertNotSame($serviceOne, $serviceTwo); - } - - public function testShouldPassContainerAsParameter() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $pimple['container'] = function ($container) { - return $container; - }; - - $this->assertNotSame($pimple, $pimple['service']); - $this->assertSame($pimple, $pimple['container']); - } - - public function testIsset() - { - $pimple = new Container(); - $pimple['param'] = 'value'; - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - - $pimple['null'] = null; - - $this->assertTrue(isset($pimple['param'])); - $this->assertTrue(isset($pimple['service'])); - $this->assertTrue(isset($pimple['null'])); - $this->assertFalse(isset($pimple['non_existent'])); - } - - public function testConstructorInjection() - { - $params = array('param' => 'value'); - $pimple = new Container($params); - - $this->assertSame($params['param'], $pimple['param']); - } - - /** - * @expectedException \Pimple\Exception\UnknownIdentifierException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testOffsetGetValidatesKeyIsPresent() - { - $pimple = new Container(); - echo $pimple['foo']; - } - - /** - * @group legacy - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testLegacyOffsetGetValidatesKeyIsPresent() - { - $pimple = new Container(); - echo $pimple['foo']; - } - - public function testOffsetGetHonorsNullValues() - { - $pimple = new Container(); - $pimple['foo'] = null; - $this->assertNull($pimple['foo']); - } - - public function testUnset() - { - $pimple = new Container(); - $pimple['param'] = 'value'; - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - - unset($pimple['param'], $pimple['service']); - $this->assertFalse(isset($pimple['param'])); - $this->assertFalse(isset($pimple['service'])); - } - - /** - * @dataProvider serviceDefinitionProvider - */ - public function testShare($service) - { - $pimple = new Container(); - $pimple['shared_service'] = $service; - - $serviceOne = $pimple['shared_service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne); - - $serviceTwo = $pimple['shared_service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo); - - $this->assertSame($serviceOne, $serviceTwo); - } - - /** - * @dataProvider serviceDefinitionProvider - */ - public function testProtect($service) - { - $pimple = new Container(); - $pimple['protected'] = $pimple->protect($service); - - $this->assertSame($service, $pimple['protected']); - } - - public function testGlobalFunctionNameAsParameterValue() - { - $pimple = new Container(); - $pimple['global_function'] = 'strlen'; - $this->assertSame('strlen', $pimple['global_function']); - } - - public function testRaw() - { - $pimple = new Container(); - $pimple['service'] = $definition = $pimple->factory(function () { return 'foo'; }); - $this->assertSame($definition, $pimple->raw('service')); - } - - public function testRawHonorsNullValues() - { - $pimple = new Container(); - $pimple['foo'] = null; - $this->assertNull($pimple->raw('foo')); - } - - public function testFluentRegister() - { - $pimple = new Container(); - $this->assertSame($pimple, $pimple->register($this->getMockBuilder('Pimple\ServiceProviderInterface')->getMock())); - } - - /** - * @expectedException \Pimple\Exception\UnknownIdentifierException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testRawValidatesKeyIsPresent() - { - $pimple = new Container(); - $pimple->raw('foo'); - } - - /** - * @group legacy - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testLegacyRawValidatesKeyIsPresent() - { - $pimple = new Container(); - $pimple->raw('foo'); - } - - /** - * @dataProvider serviceDefinitionProvider - */ - public function testExtend($service) - { - $pimple = new Container(); - $pimple['shared_service'] = function () { - return new Fixtures\Service(); - }; - $pimple['factory_service'] = $pimple->factory(function () { - return new Fixtures\Service(); - }); - - $pimple->extend('shared_service', $service); - $serviceOne = $pimple['shared_service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne); - $serviceTwo = $pimple['shared_service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo); - $this->assertSame($serviceOne, $serviceTwo); - $this->assertSame($serviceOne->value, $serviceTwo->value); - - $pimple->extend('factory_service', $service); - $serviceOne = $pimple['factory_service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne); - $serviceTwo = $pimple['factory_service']; - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo); - $this->assertNotSame($serviceOne, $serviceTwo); - $this->assertNotSame($serviceOne->value, $serviceTwo->value); - } - - public function testExtendDoesNotLeakWithFactories() - { - if (extension_loaded('pimple')) { - $this->markTestSkipped('Pimple extension does not support this test'); - } - $pimple = new Container(); - - $pimple['foo'] = $pimple->factory(function () { return; }); - $pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) { return; }); - unset($pimple['foo']); - - $p = new \ReflectionProperty($pimple, 'values'); - $p->setAccessible(true); - $this->assertEmpty($p->getValue($pimple)); - - $p = new \ReflectionProperty($pimple, 'factories'); - $p->setAccessible(true); - $this->assertCount(0, $p->getValue($pimple)); - } - - /** - * @expectedException \Pimple\Exception\UnknownIdentifierException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testExtendValidatesKeyIsPresent() - { - $pimple = new Container(); - $pimple->extend('foo', function () {}); - } - - /** - * @group legacy - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testLegacyExtendValidatesKeyIsPresent() - { - $pimple = new Container(); - $pimple->extend('foo', function () {}); - } - - public function testKeys() - { - $pimple = new Container(); - $pimple['foo'] = 123; - $pimple['bar'] = 123; - - $this->assertEquals(array('foo', 'bar'), $pimple->keys()); - } - - /** @test */ - public function settingAnInvokableObjectShouldTreatItAsFactory() - { - $pimple = new Container(); - $pimple['invokable'] = new Fixtures\Invokable(); - - $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['invokable']); - } - - /** @test */ - public function settingNonInvokableObjectShouldTreatItAsParameter() - { - $pimple = new Container(); - $pimple['non_invokable'] = new Fixtures\NonInvokable(); - - $this->assertInstanceOf('Pimple\Tests\Fixtures\NonInvokable', $pimple['non_invokable']); - } - - /** - * @dataProvider badServiceDefinitionProvider - * @expectedException \Pimple\Exception\ExpectedInvokableException - * @expectedExceptionMessage Service definition is not a Closure or invokable object. - */ - public function testFactoryFailsForInvalidServiceDefinitions($service) - { - $pimple = new Container(); - $pimple->factory($service); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Service definition is not a Closure or invokable object. - */ - public function testLegacyFactoryFailsForInvalidServiceDefinitions($service) - { - $pimple = new Container(); - $pimple->factory($service); - } - - /** - * @dataProvider badServiceDefinitionProvider - * @expectedException \Pimple\Exception\ExpectedInvokableException - * @expectedExceptionMessage Callable is not a Closure or invokable object. - */ - public function testProtectFailsForInvalidServiceDefinitions($service) - { - $pimple = new Container(); - $pimple->protect($service); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Callable is not a Closure or invokable object. - */ - public function testLegacyProtectFailsForInvalidServiceDefinitions($service) - { - $pimple = new Container(); - $pimple->protect($service); - } - - /** - * @dataProvider badServiceDefinitionProvider - * @expectedException \Pimple\Exception\InvalidServiceIdentifierException - * @expectedExceptionMessage Identifier "foo" does not contain an object definition. - */ - public function testExtendFailsForKeysNotContainingServiceDefinitions($service) - { - $pimple = new Container(); - $pimple['foo'] = $service; - $pimple->extend('foo', function () {}); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Identifier "foo" does not contain an object definition. - */ - public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service) - { - $pimple = new Container(); - $pimple['foo'] = $service; - $pimple->extend('foo', function () {}); - } - - /** - * @group legacy - * @expectedDeprecation How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "foo" should be protected? - */ - public function testExtendingProtectedClosureDeprecation() - { - $pimple = new Container(); - $pimple['foo'] = $pimple->protect(function () { - return 'bar'; - }); - - $pimple->extend('foo', function ($value) { - return $value.'-baz'; - }); - - $this->assertSame('bar-baz', $pimple['foo']); - } - - /** - * @dataProvider badServiceDefinitionProvider - * @expectedException \Pimple\Exception\ExpectedInvokableException - * @expectedExceptionMessage Extension service definition is not a Closure or invokable object. - */ - public function testExtendFailsForInvalidServiceDefinitions($service) - { - $pimple = new Container(); - $pimple['foo'] = function () {}; - $pimple->extend('foo', $service); - } - - /** - * @group legacy - * @dataProvider badServiceDefinitionProvider - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Extension service definition is not a Closure or invokable object. - */ - public function testLegacyExtendFailsForInvalidServiceDefinitions($service) - { - $pimple = new Container(); - $pimple['foo'] = function () {}; - $pimple->extend('foo', $service); - } - - /** - * @expectedException \Pimple\Exception\FrozenServiceException - * @expectedExceptionMessage Cannot override frozen service "foo". - */ - public function testExtendFailsIfFrozenServiceIsNonInvokable() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return new Fixtures\NonInvokable(); - }; - $foo = $pimple['foo']; - - $pimple->extend('foo', function () {}); - } - - /** - * @expectedException \Pimple\Exception\FrozenServiceException - * @expectedExceptionMessage Cannot override frozen service "foo". - */ - public function testExtendFailsIfFrozenServiceIsInvokable() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return new Fixtures\Invokable(); - }; - $foo = $pimple['foo']; - - $pimple->extend('foo', function () {}); - } - - /** - * Provider for invalid service definitions. - */ - public function badServiceDefinitionProvider() - { - return array( - array(123), - array(new Fixtures\NonInvokable()), - ); - } - - /** - * Provider for service definitions. - */ - public function serviceDefinitionProvider() - { - return array( - array(function ($value) { - $service = new Fixtures\Service(); - $service->value = $value; - - return $service; - }), - array(new Fixtures\Invokable()), - ); - } - - public function testDefiningNewServiceAfterFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - $pimple['bar'] = function () { - return 'bar'; - }; - $this->assertSame('bar', $pimple['bar']); - } - - /** - * @expectedException \Pimple\Exception\FrozenServiceException - * @expectedExceptionMessage Cannot override frozen service "foo". - */ - public function testOverridingServiceAfterFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - $pimple['foo'] = function () { - return 'bar'; - }; - } - - /** - * @group legacy - * @expectedException \RuntimeException - * @expectedExceptionMessage Cannot override frozen service "foo". - */ - public function testLegacyOverridingServiceAfterFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - $pimple['foo'] = function () { - return 'bar'; - }; - } - - public function testRemovingServiceAfterFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $foo = $pimple['foo']; - - unset($pimple['foo']); - $pimple['foo'] = function () { - return 'bar'; - }; - $this->assertSame('bar', $pimple['foo']); - } - - public function testExtendingService() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) { - return "$foo.bar"; - }); - $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) { - return "$foo.baz"; - }); - $this->assertSame('foo.bar.baz', $pimple['foo']); - } - - public function testExtendingServiceAfterOtherServiceFreeze() - { - $pimple = new Container(); - $pimple['foo'] = function () { - return 'foo'; - }; - $pimple['bar'] = function () { - return 'bar'; - }; - $foo = $pimple['foo']; - - $pimple['bar'] = $pimple->extend('bar', function ($bar, $app) { - return "$bar.baz"; - }); - $this->assertSame('bar.baz', $pimple['bar']); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php deleted file mode 100644 index 7ca2d7ff..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ContainerTest.php +++ /dev/null @@ -1,77 +0,0 @@ -assertSame($pimple['service'], $psr->get('service')); - } - - /** - * @expectedException \Psr\Container\NotFoundExceptionInterface - * @expectedExceptionMessage Identifier "service" is not defined. - */ - public function testGetThrowsExceptionIfServiceIsNotFound() - { - $pimple = new Container(); - $psr = new PsrContainer($pimple); - - $psr->get('service'); - } - - public function testHasReturnsTrueIfServiceExists() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Service(); - }; - $psr = new PsrContainer($pimple); - - $this->assertTrue($psr->has('service')); - } - - public function testHasReturnsFalseIfServiceDoesNotExist() - { - $pimple = new Container(); - $psr = new PsrContainer($pimple); - - $this->assertFalse($psr->has('service')); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php deleted file mode 100644 index c9a08125..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/Psr11/ServiceLocatorTest.php +++ /dev/null @@ -1,134 +0,0 @@ - - */ -class ServiceLocatorTest extends TestCase -{ - public function testCanAccessServices() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('service')); - - $this->assertSame($pimple['service'], $locator->get('service')); - } - - public function testCanAccessAliasedServices() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('alias' => 'service')); - - $this->assertSame($pimple['service'], $locator->get('alias')); - } - - /** - * @expectedException \Pimple\Exception\UnknownIdentifierException - * @expectedExceptionMessage Identifier "service" is not defined. - */ - public function testCannotAccessAliasedServiceUsingRealIdentifier() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('alias' => 'service')); - - $service = $locator->get('service'); - } - - /** - * @expectedException \Pimple\Exception\UnknownIdentifierException - * @expectedExceptionMessage Identifier "foo" is not defined. - */ - public function testGetValidatesServiceCanBeLocated() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('alias' => 'service')); - - $service = $locator->get('foo'); - } - - /** - * @expectedException \Pimple\Exception\UnknownIdentifierException - * @expectedExceptionMessage Identifier "invalid" is not defined. - */ - public function testGetValidatesTargetServiceExists() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('alias' => 'invalid')); - - $service = $locator->get('alias'); - } - - public function testHasValidatesServiceCanBeLocated() - { - $pimple = new Container(); - $pimple['service1'] = function () { - return new Fixtures\Service(); - }; - $pimple['service2'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('service1')); - - $this->assertTrue($locator->has('service1')); - $this->assertFalse($locator->has('service2')); - } - - public function testHasChecksIfTargetServiceExists() - { - $pimple = new Container(); - $pimple['service'] = function () { - return new Fixtures\Service(); - }; - $locator = new ServiceLocator($pimple, array('foo' => 'service', 'bar' => 'invalid')); - - $this->assertTrue($locator->has('foo')); - $this->assertFalse($locator->has('bar')); - } -} diff --git a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php b/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php deleted file mode 100644 index 5dd52f0d..00000000 --- a/advancedcontentfilter/vendor/pimple/pimple/src/Pimple/Tests/ServiceIteratorTest.php +++ /dev/null @@ -1,52 +0,0 @@ -assertSame(array('service1' => $pimple['service1'], 'service2' => $pimple['service2']), iterator_to_array($iterator)); - } -} diff --git a/advancedcontentfilter/vendor/psr/container/README.md b/advancedcontentfilter/vendor/psr/container/README.md index 084f6df5..1b9d9e57 100644 --- a/advancedcontentfilter/vendor/psr/container/README.md +++ b/advancedcontentfilter/vendor/psr/container/README.md @@ -1,5 +1,13 @@ -# PSR Container +Container interface +============== -This repository holds all interfaces/classes/traits related to [PSR-11](https://github.com/container-interop/fig-standards/blob/master/proposed/container.md). +This repository holds all interfaces related to [PSR-11 (Container Interface)][psr-url]. + +Note that this is not a Container implementation of its own. It is merely abstractions that describe the components of a Dependency Injection Container. + +The installable [package][package-url] and [implementations][implementation-url] are listed on Packagist. + +[psr-url]: https://www.php-fig.org/psr/psr-11/ +[package-url]: https://packagist.org/packages/psr/container +[implementation-url]: https://packagist.org/providers/psr/container-implementation -Note that this is not a container implementation of its own. See the specification for more details. diff --git a/advancedcontentfilter/vendor/psr/container/composer.json b/advancedcontentfilter/vendor/psr/container/composer.json index b8ee0126..baf6cd1a 100644 --- a/advancedcontentfilter/vendor/psr/container/composer.json +++ b/advancedcontentfilter/vendor/psr/container/composer.json @@ -8,11 +8,11 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "require": { - "php": ">=5.3.0" + "php": ">=7.4.0" }, "autoload": { "psr-4": { @@ -21,7 +21,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } } } diff --git a/advancedcontentfilter/vendor/psr/container/src/ContainerExceptionInterface.php b/advancedcontentfilter/vendor/psr/container/src/ContainerExceptionInterface.php index d35c6b4d..0f213f2f 100644 --- a/advancedcontentfilter/vendor/psr/container/src/ContainerExceptionInterface.php +++ b/advancedcontentfilter/vendor/psr/container/src/ContainerExceptionInterface.php @@ -1,13 +1,12 @@ =7.0.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/advancedcontentfilter/vendor/psr/http-factory/src/RequestFactoryInterface.php b/advancedcontentfilter/vendor/psr/http-factory/src/RequestFactoryInterface.php new file mode 100644 index 00000000..cb39a08b --- /dev/null +++ b/advancedcontentfilter/vendor/psr/http-factory/src/RequestFactoryInterface.php @@ -0,0 +1,18 @@ +=5.3.0" + "php": "^7.2 || ^8.0" }, "autoload": { "psr-4": { @@ -20,7 +20,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } } } diff --git a/advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Interfaces.md b/advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Interfaces.md new file mode 100644 index 00000000..3a7e7dda --- /dev/null +++ b/advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Interfaces.md @@ -0,0 +1,130 @@ +# Interfaces + +The purpose of this list is to help in finding the methods when working with PSR-7. This can be considered as a cheatsheet for PSR-7 interfaces. + +The interfaces defined in PSR-7 are the following: + +| Class Name | Description | +|---|---| +| [Psr\Http\Message\MessageInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagemessageinterface) | Representation of a HTTP message | +| [Psr\Http\Message\RequestInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagerequestinterface) | Representation of an outgoing, client-side request. | +| [Psr\Http\Message\ServerRequestInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageserverrequestinterface) | Representation of an incoming, server-side HTTP request. | +| [Psr\Http\Message\ResponseInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageresponseinterface) | Representation of an outgoing, server-side response. | +| [Psr\Http\Message\StreamInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagestreaminterface) | Describes a data stream | +| [Psr\Http\Message\UriInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageuriinterface) | Value object representing a URI. | +| [Psr\Http\Message\UploadedFileInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageuploadedfileinterface) | Value object representing a file uploaded through an HTTP request. | + +## `Psr\Http\Message\MessageInterface` Methods + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `getProtocolVersion()` | Retrieve HTTP protocol version | 1.0 or 1.1 | +| `withProtocolVersion($version)` | Returns new message instance with given HTTP protocol version | | +| `getHeaders()` | Retrieve all HTTP Headers | [Request Header List](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields), [Response Header List](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields) | +| `hasHeader($name)` | Checks if HTTP Header with given name exists | | +| `getHeader($name)` | Retrieves a array with the values for a single header | | +| `getHeaderLine($name)` | Retrieves a comma-separated string of the values for a single header | | +| `withHeader($name, $value)` | Returns new message instance with given HTTP Header | if the header existed in the original instance, replaces the header value from the original message with the value provided when creating the new instance. | +| `withAddedHeader($name, $value)` | Returns new message instance with appended value to given header | If header already exists value will be appended, if not a new header will be created | +| `withoutHeader($name)` | Removes HTTP Header with given name| | +| `getBody()` | Retrieves the HTTP Message Body | Returns object implementing `StreamInterface`| +| `withBody(StreamInterface $body)` | Returns new message instance with given HTTP Message Body | | + + +## `Psr\Http\Message\RequestInterface` Methods + +Same methods as `Psr\Http\Message\MessageInterface` + the following methods: + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `getRequestTarget()` | Retrieves the message's request target | origin-form, absolute-form, authority-form, asterisk-form ([RFC7230](https://www.rfc-editor.org/rfc/rfc7230.txt)) | +| `withRequestTarget($requestTarget)` | Return a new message instance with the specific request-target | | +| `getMethod()` | Retrieves the HTTP method of the request. | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE (defined in [RFC7231](https://tools.ietf.org/html/rfc7231)), PATCH (defined in [RFC5789](https://tools.ietf.org/html/rfc5789)) | +| `withMethod($method)` | Returns a new message instance with the provided HTTP method | | +| `getUri()` | Retrieves the URI instance | | +| `withUri(UriInterface $uri, $preserveHost = false)` | Returns a new message instance with the provided URI | | + + +## `Psr\Http\Message\ServerRequestInterface` Methods + +Same methods as `Psr\Http\Message\RequestInterface` + the following methods: + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `getServerParams() ` | Retrieve server parameters | Typically derived from `$_SERVER` | +| `getCookieParams()` | Retrieves cookies sent by the client to the server. | Typically derived from `$_COOKIES` | +| `withCookieParams(array $cookies)` | Returns a new request instance with the specified cookies | | +| `withQueryParams(array $query)` | Returns a new request instance with the specified query string arguments | | +| `getUploadedFiles()` | Retrieve normalized file upload data | | +| `withUploadedFiles(array $uploadedFiles)` | Returns a new request instance with the specified uploaded files | | +| `getParsedBody()` | Retrieve any parameters provided in the request body | | +| `withParsedBody($data)` | Returns a new request instance with the specified body parameters | | +| `getAttributes()` | Retrieve attributes derived from the request | | +| `getAttribute($name, $default = null)` | Retrieve a single derived request attribute | | +| `withAttribute($name, $value)` | Returns a new request instance with the specified derived request attribute | | +| `withoutAttribute($name)` | Returns a new request instance that without the specified derived request attribute | | + +## `Psr\Http\Message\ResponseInterface` Methods: + +Same methods as `Psr\Http\Message\MessageInterface` + the following methods: + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `getStatusCode()` | Gets the response status code. | | +| `withStatus($code, $reasonPhrase = '')` | Returns a new response instance with the specified status code and, optionally, reason phrase. | | +| `getReasonPhrase()` | Gets the response reason phrase associated with the status code. | | + +## `Psr\Http\Message\StreamInterface` Methods + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `__toString()` | Reads all data from the stream into a string, from the beginning to end. | | +| `close()` | Closes the stream and any underlying resources. | | +| `detach()` | Separates any underlying resources from the stream. | | +| `getSize()` | Get the size of the stream if known. | | +| `eof()` | Returns true if the stream is at the end of the stream.| | +| `isSeekable()` | Returns whether or not the stream is seekable. | | +| `seek($offset, $whence = SEEK_SET)` | Seek to a position in the stream. | | +| `rewind()` | Seek to the beginning of the stream. | | +| `isWritable()` | Returns whether or not the stream is writable. | | +| `write($string)` | Write data to the stream. | | +| `isReadable()` | Returns whether or not the stream is readable. | | +| `read($length)` | Read data from the stream. | | +| `getContents()` | Returns the remaining contents in a string | | +| `getMetadata($key = null)()` | Get stream metadata as an associative array or retrieve a specific key. | | + +## `Psr\Http\Message\UriInterface` Methods + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `getScheme()` | Retrieve the scheme component of the URI. | | +| `getAuthority()` | Retrieve the authority component of the URI. | | +| `getUserInfo()` | Retrieve the user information component of the URI. | | +| `getHost()` | Retrieve the host component of the URI. | | +| `getPort()` | Retrieve the port component of the URI. | | +| `getPath()` | Retrieve the path component of the URI. | | +| `getQuery()` | Retrieve the query string of the URI. | | +| `getFragment()` | Retrieve the fragment component of the URI. | | +| `withScheme($scheme)` | Return an instance with the specified scheme. | | +| `withUserInfo($user, $password = null)` | Return an instance with the specified user information. | | +| `withHost($host)` | Return an instance with the specified host. | | +| `withPort($port)` | Return an instance with the specified port. | | +| `withPath($path)` | Return an instance with the specified path. | | +| `withQuery($query)` | Return an instance with the specified query string. | | +| `withFragment($fragment)` | Return an instance with the specified URI fragment. | | +| `__toString()` | Return the string representation as a URI reference. | | + +## `Psr\Http\Message\UploadedFileInterface` Methods + +| Method Name | Description | Notes | +|------------------------------------| ----------- | ----- | +| `getStream()` | Retrieve a stream representing the uploaded file. | | +| `moveTo($targetPath)` | Move the uploaded file to a new location. | | +| `getSize()` | Retrieve the file size. | | +| `getError()` | Retrieve the error associated with the uploaded file. | | +| `getClientFilename()` | Retrieve the filename sent by the client. | | +| `getClientMediaType()` | Retrieve the media type sent by the client. | | + +> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`. +> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered. + diff --git a/advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Usage.md b/advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Usage.md new file mode 100644 index 00000000..b6d048a3 --- /dev/null +++ b/advancedcontentfilter/vendor/psr/http-message/docs/PSR7-Usage.md @@ -0,0 +1,159 @@ +### PSR-7 Usage + +All PSR-7 applications comply with these interfaces +They were created to establish a standard between middleware implementations. + +> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`. +> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered. + + +The following examples will illustrate how basic operations are done in PSR-7. + +##### Examples + + +For this examples to work (at least) a PSR-7 implementation package is required. (eg: zendframework/zend-diactoros, guzzlehttp/psr7, slim/slim, etc) +All PSR-7 implementations should have the same behaviour. + +The following will be assumed: +`$request` is an object of `Psr\Http\Message\RequestInterface` and + +`$response` is an object implementing `Psr\Http\Message\RequestInterface` + + +### Working with HTTP Headers + +#### Adding headers to response: + +```php +$response->withHeader('My-Custom-Header', 'My Custom Message'); +``` + +#### Appending values to headers + +```php +$response->withAddedHeader('My-Custom-Header', 'The second message'); +``` + +#### Checking if header exists: + +```php +$request->hasHeader('My-Custom-Header'); // will return false +$response->hasHeader('My-Custom-Header'); // will return true +``` + +> Note: My-Custom-Header was only added in the Response + +#### Getting comma-separated values from a header (also applies to request) + +```php +// getting value from request headers +$request->getHeaderLine('Content-Type'); // will return: "text/html; charset=UTF-8" +// getting value from response headers +$response->getHeaderLine('My-Custom-Header'); // will return: "My Custom Message; The second message" +``` + +#### Getting array of value from a header (also applies to request) +```php +// getting value from request headers +$request->getHeader('Content-Type'); // will return: ["text/html", "charset=UTF-8"] +// getting value from response headers +$response->getHeader('My-Custom-Header'); // will return: ["My Custom Message", "The second message"] +``` + +#### Removing headers from HTTP Messages +```php +// removing a header from Request, removing deprecated "Content-MD5" header +$request->withoutHeader('Content-MD5'); + +// removing a header from Response +// effect: the browser won't know the size of the stream +// the browser will download the stream till it ends +$response->withoutHeader('Content-Length'); +``` + +### Working with HTTP Message Body + +When working with the PSR-7 there are two methods of implementation: +#### 1. Getting the body separately + +> This method makes the body handling easier to understand and is useful when repeatedly calling body methods. (You only call `getBody()` once). Using this method mistakes like `$response->write()` are also prevented. + +```php +$body = $response->getBody(); +// operations on body, eg. read, write, seek +// ... +// replacing the old body +$response->withBody($body); +// this last statement is optional as we working with objects +// in this case the "new" body is same with the "old" one +// the $body variable has the same value as the one in $request, only the reference is passed +``` + +#### 2. Working directly on response + +> This method is useful when only performing few operations as the `$request->getBody()` statement fragment is required + +```php +$response->getBody()->write('hello'); +``` + +### Getting the body contents + +The following snippet gets the contents of a stream contents. +> Note: Streams must be rewinded, if content was written into streams, it will be ignored when calling `getContents()` because the stream pointer is set to the last character, which is `\0` - meaning end of stream. +```php +$body = $response->getBody(); +$body->rewind(); // or $body->seek(0); +$bodyText = $body->getContents(); +``` +> Note: If `$body->seek(1)` is called before `$body->getContents()`, the first character will be ommited as the starting pointer is set to `1`, not `0`. This is why using `$body->rewind()` is recommended. + +### Append to body + +```php +$response->getBody()->write('Hello'); // writing directly +$body = $request->getBody(); // which is a `StreamInterface` +$body->write('xxxxx'); +``` + +### Prepend to body +Prepending is different when it comes to streams. The content must be copied before writing the content to be prepended. +The following example will explain the behaviour of streams. + +```php +// assuming our response is initially empty +$body = $repsonse->getBody(); +// writing the string "abcd" +$body->write('abcd'); + +// seeking to start of stream +$body->seek(0); +// writing 'ef' +$body->write('ef'); // at this point the stream contains "efcd" +``` + +#### Prepending by rewriting separately + +```php +// assuming our response body stream only contains: "abcd" +$body = $response->getBody(); +$body->rewind(); +$contents = $body->getContents(); // abcd +// seeking the stream to beginning +$body->rewind(); +$body->write('ef'); // stream contains "efcd" +$body->write($contents); // stream contains "efabcd" +``` + +> Note: `getContents()` seeks the stream while reading it, therefore if the second `rewind()` method call was not present the stream would have resulted in `abcdefabcd` because the `write()` method appends to stream if not preceeded by `rewind()` or `seek(0)`. + +#### Prepending by using contents as a string +```php +$body = $response->getBody(); +$body->rewind(); +$contents = $body->getContents(); // efabcd +$contents = 'ef'.$contents; +$body->rewind(); +$body->write($contents); +``` diff --git a/advancedcontentfilter/vendor/psr/http-message/src/MessageInterface.php b/advancedcontentfilter/vendor/psr/http-message/src/MessageInterface.php index dd46e5ec..8cdb4ed6 100644 --- a/advancedcontentfilter/vendor/psr/http-message/src/MessageInterface.php +++ b/advancedcontentfilter/vendor/psr/http-message/src/MessageInterface.php @@ -1,5 +1,7 @@ =7.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/advancedcontentfilter/vendor/psr/http-server-handler/src/RequestHandlerInterface.php b/advancedcontentfilter/vendor/psr/http-server-handler/src/RequestHandlerInterface.php new file mode 100644 index 00000000..83911e26 --- /dev/null +++ b/advancedcontentfilter/vendor/psr/http-server-handler/src/RequestHandlerInterface.php @@ -0,0 +1,22 @@ +=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} diff --git a/advancedcontentfilter/vendor/psr/http-server-middleware/src/MiddlewareInterface.php b/advancedcontentfilter/vendor/psr/http-server-middleware/src/MiddlewareInterface.php new file mode 100644 index 00000000..a6c14f8c --- /dev/null +++ b/advancedcontentfilter/vendor/psr/http-server-middleware/src/MiddlewareInterface.php @@ -0,0 +1,25 @@ + true, 'null' => null, @@ -110,6 +114,7 @@ abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase 'nested' => array('with object' => new DummyTest), 'object' => new \DateTime, 'resource' => fopen('php://memory', 'r'), + 'closed' => $closed, ); $this->getLogger()->warning('Crazy context data', $context); @@ -131,10 +136,3 @@ abstract class LoggerInterfaceTest extends \PHPUnit_Framework_TestCase $this->assertEquals($expected, $this->getLogs()); } } - -class DummyTest -{ - public function __toString() - { - } -} diff --git a/advancedcontentfilter/vendor/psr/log/Psr/Log/Test/TestLogger.php b/advancedcontentfilter/vendor/psr/log/Psr/Log/Test/TestLogger.php new file mode 100644 index 00000000..1be32304 --- /dev/null +++ b/advancedcontentfilter/vendor/psr/log/Psr/Log/Test/TestLogger.php @@ -0,0 +1,147 @@ + $level, + 'message' => $message, + 'context' => $context, + ]; + + $this->recordsByLevel[$record['level']][] = $record; + $this->records[] = $record; + } + + public function hasRecords($level) + { + return isset($this->recordsByLevel[$level]); + } + + public function hasRecord($record, $level) + { + if (is_string($record)) { + $record = ['message' => $record]; + } + return $this->hasRecordThatPasses(function ($rec) use ($record) { + if ($rec['message'] !== $record['message']) { + return false; + } + if (isset($record['context']) && $rec['context'] !== $record['context']) { + return false; + } + return true; + }, $level); + } + + public function hasRecordThatContains($message, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($message) { + return strpos($rec['message'], $message) !== false; + }, $level); + } + + public function hasRecordThatMatches($regex, $level) + { + return $this->hasRecordThatPasses(function ($rec) use ($regex) { + return preg_match($regex, $rec['message']) > 0; + }, $level); + } + + public function hasRecordThatPasses(callable $predicate, $level) + { + if (!isset($this->recordsByLevel[$level])) { + return false; + } + foreach ($this->recordsByLevel[$level] as $i => $rec) { + if (call_user_func($predicate, $rec, $i)) { + return true; + } + } + return false; + } + + public function __call($method, $args) + { + if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { + $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; + $level = strtolower($matches[2]); + if (method_exists($this, $genericMethod)) { + $args[] = $level; + return call_user_func_array([$this, $genericMethod], $args); + } + } + throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); + } + + public function reset() + { + $this->records = []; + $this->recordsByLevel = []; + } +} diff --git a/advancedcontentfilter/vendor/psr/log/README.md b/advancedcontentfilter/vendor/psr/log/README.md index 574bc1cb..a9f20c43 100644 --- a/advancedcontentfilter/vendor/psr/log/README.md +++ b/advancedcontentfilter/vendor/psr/log/README.md @@ -7,6 +7,13 @@ This repository holds all interfaces/classes/traits related to Note that this is not a logger of its own. It is merely an interface that describes a logger. See the specification for more details. +Installation +------------ + +```bash +composer require psr/log +``` + Usage ----- @@ -31,6 +38,12 @@ class Foo if ($this->logger) { $this->logger->info('Doing work'); } + + try { + $this->doSomethingElse(); + } catch (Exception $exception) { + $this->logger->error('Oh no!', array('exception' => $exception)); + } // do something useful } diff --git a/advancedcontentfilter/vendor/psr/log/composer.json b/advancedcontentfilter/vendor/psr/log/composer.json index 87934d70..ca056953 100644 --- a/advancedcontentfilter/vendor/psr/log/composer.json +++ b/advancedcontentfilter/vendor/psr/log/composer.json @@ -7,7 +7,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "require": { @@ -20,7 +20,7 @@ }, "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } } } diff --git a/advancedcontentfilter/vendor/slim/slim/CHANGELOG.md b/advancedcontentfilter/vendor/slim/slim/CHANGELOG.md new file mode 100644 index 00000000..6bcb127d --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/CHANGELOG.md @@ -0,0 +1,237 @@ +# Changelog + +# 4.11.0 - 2022-11-06 +- [3180: Declare types](https://github.com/slimphp/Slim/pull/3180) thanks to @nbayramberdiyev +- [3181: Update laminas/laminas-diactoros requirement from ^2.8 to ^2.9](https://github.com/slimphp/Slim/pull/3181) thanks to @dependabot[bot] +- [3182: Update guzzlehttp/psr7 requirement from ^2.1 to ^2.2](https://github.com/slimphp/Slim/pull/3182) thanks to @dependabot[bot] +- [3183: Update phpstan/phpstan requirement from ^1.4 to ^1.5](https://github.com/slimphp/Slim/pull/3183) thanks to @dependabot[bot] +- [3184: Update adriansuter/php-autoload-override requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/3184) thanks to @dependabot[bot] +- [3189: Update phpstan/phpstan requirement from ^1.5 to ^1.6](https://github.com/slimphp/Slim/pull/3189) thanks to @dependabot[bot] +- [3191: Adding property types to Middleware classes](https://github.com/slimphp/Slim/pull/3191) thanks to @ashleycoles +- [3193: Handlers types](https://github.com/slimphp/Slim/pull/3193) thanks to @ashleycoles +- [3194: Adding types to AbstractErrorRenderer](https://github.com/slimphp/Slim/pull/3194) thanks to @ashleycoles +- [3195: Adding prop types for Exception classes](https://github.com/slimphp/Slim/pull/3195) thanks to @ashleycoles +- [3196: Adding property type declarations for Factory classes](https://github.com/slimphp/Slim/pull/3196) thanks to @ashleycoles +- [3197: Remove redundant docblock types](https://github.com/slimphp/Slim/pull/3197) thanks to @theodorejb +- [3199: Update laminas/laminas-diactoros requirement from ^2.9 to ^2.11](https://github.com/slimphp/Slim/pull/3199) thanks to @dependabot[bot] +- [3200: Update phpstan/phpstan requirement from ^1.6 to ^1.7](https://github.com/slimphp/Slim/pull/3200) thanks to @dependabot[bot] +- [3205: Update guzzlehttp/psr7 requirement from ^2.2 to ^2.4](https://github.com/slimphp/Slim/pull/3205) thanks to @dependabot[bot] +- [3206: Update squizlabs/php_codesniffer requirement from ^3.6 to ^3.7](https://github.com/slimphp/Slim/pull/3206) thanks to @dependabot[bot] +- [3207: Update phpstan/phpstan requirement from ^1.7 to ^1.8](https://github.com/slimphp/Slim/pull/3207) thanks to @dependabot[bot] +- [3211: Assign null coalescing to coalesce equal](https://github.com/slimphp/Slim/pull/3211) thanks to @MathiasReker +- [3213: Void return](https://github.com/slimphp/Slim/pull/3213) thanks to @MathiasReker +- [3214: Is null](https://github.com/slimphp/Slim/pull/3214) thanks to @MathiasReker +- [3216: Refactor](https://github.com/slimphp/Slim/pull/3216) thanks to @mehdihasanpour +- [3218: Refactor some code](https://github.com/slimphp/Slim/pull/3218) thanks to @mehdihasanpour +- [3221: Cleanup](https://github.com/slimphp/Slim/pull/3221) thanks to @mehdihasanpour +- [3225: Update laminas/laminas-diactoros requirement from ^2.11 to ^2.14](https://github.com/slimphp/Slim/pull/3225) thanks to @dependabot[bot] +- [3228: Using assertSame to let assert equal be restricted](https://github.com/slimphp/Slim/pull/3228) thanks to @peter279k +- [3229: Update laminas/laminas-diactoros requirement from ^2.14 to ^2.17](https://github.com/slimphp/Slim/pull/3229) thanks to @dependabot[bot] +- [3235: Persist routes indexed by name in RouteCollector for improved performance.](https://github.com/slimphp/Slim/pull/3235) thanks to @BusterNeece + +# 4.10.0 - 2022-03-14 +- [3120: Add a new PSR-17 factory to Psr17FactoryProvider](https://github.com/slimphp/Slim/pull/3120) thanks to @solventt +- [3123: Replace deprecated setMethods() in tests](https://github.com/slimphp/Slim/pull/3123) thanks to @solventt +- [3126: Update guzzlehttp/psr7 requirement from ^2.0 to ^2.1](https://github.com/slimphp/Slim/pull/3126) thanks to @dependabot[bot] +- [3127: PHPStan v1.0](https://github.com/slimphp/Slim/pull/3127) thanks to @t0mmy742 +- [3128: Update phpstan/phpstan requirement from ^1.0 to ^1.2](https://github.com/slimphp/Slim/pull/3128) thanks to @dependabot[bot] +- [3129: Deprecate PHP 7.3](https://github.com/slimphp/Slim/pull/3129) thanks to @l0gicgate +- [3130: Removed double defined PHP 7.4](https://github.com/slimphp/Slim/pull/3130) thanks to @flangofas +- [3132: Add new `RequestResponseNamedArgs` route strategy](https://github.com/slimphp/Slim/pull/3132) thanks to @adoy +- [3133: Improve typehinting for `RouteParserInterface`](https://github.com/slimphp/Slim/pull/3133) thanks to @jerowork +- [3135: Update phpstan/phpstan requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/3135) thanks to @dependabot[bot] +- [3137: Update phpspec/prophecy requirement from ^1.14 to ^1.15](https://github.com/slimphp/Slim/pull/3137) thanks to @dependabot[bot] +- [3138: Update license year](https://github.com/slimphp/Slim/pull/3138) thanks to @Awilum +- [3139: Fixed #1730 (reintroduced in 4.x)](https://github.com/slimphp/Slim/pull/3139) thanks to @adoy +- [3145: Update phpstan/phpstan requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3145) thanks to @dependabot[bot] +- [3146: Inherit HttpException from RuntimeException](https://github.com/slimphp/Slim/pull/3146) thanks to @nbayramberdiyev +- [3148: Upgrade to HTML5](https://github.com/slimphp/Slim/pull/3148) thanks to @nbayramberdiyev +- [3172: Update nyholm/psr7 requirement from ^1.4 to ^1.5](https://github.com/slimphp/Slim/pull/3172) thanks to @dependabot[bot] + +# 4.9.0 - 2021-10-05 +- [3058: Implement exception class for Gone Http error](https://github.com/slimphp/Slim/pull/3058) thanks to @TheKernelPanic +- [3086: Update slim/psr7 requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3086) thanks to @dependabot[bot] +- [3087: Update nyholm/psr7-server requirement from ^1.0.1 to ^1.0.2](https://github.com/slimphp/Slim/pull/3087) thanks to @dependabot[bot] +- [3093: Update phpstan/phpstan requirement from ^0.12.85 to ^0.12.90](https://github.com/slimphp/Slim/pull/3093) thanks to @dependabot[bot] +- [3099: Allow updated psr log](https://github.com/slimphp/Slim/pull/3099) thanks to @t0mmy742 +- [3104: Drop php7.2](https://github.com/slimphp/Slim/pull/3104) thanks to @t0mmy742 +- [3106: Use PSR-17 factory from Guzzle/psr7 2.0](https://github.com/slimphp/Slim/pull/3106) thanks to @t0mmy742 +- [3108: Update README file](https://github.com/slimphp/Slim/pull/3108) thanks to @t0mmy742 +- [3112: Update laminas/laminas-diactoros requirement from ^2.6 to ^2.8](https://github.com/slimphp/Slim/pull/3112) thanks to @dependabot[bot] +- [3114: Update slim/psr7 requirement from ^1.4 to ^1.5](https://github.com/slimphp/Slim/pull/3114) thanks to @dependabot[bot] +- [3115: Update phpstan/phpstan requirement from ^0.12.96 to ^0.12.99](https://github.com/slimphp/Slim/pull/3115) thanks to @dependabot[bot] +- [3116: Remove Zend Diactoros references](https://github.com/slimphp/Slim/pull/3116) thanks to @l0gicgate + +# 4.8.0 - 2021-05-19 +- [3034: Fix phpunit dependency version](https://github.com/slimphp/Slim/pull/3034) thanks to @l0gicgate +- [3037: Replace Travis by GitHub Actions](https://github.com/slimphp/Slim/pull/3037) thanks to @t0mmy742 +- [3043: Cover App creation from AppFactory with empty Container](https://github.com/slimphp/Slim/pull/3043) thanks to @t0mmy742 +- [3045: Update phpstan/phpstan requirement from ^0.12.58 to ^0.12.64](https://github.com/slimphp/Slim/pull/3045) thanks to @dependabot-preview[bot] +- [3047: documentation: min php 7.2 required](https://github.com/slimphp/Slim/pull/3047) thanks to @Rotzbua +- [3054: Update phpstan/phpstan requirement from ^0.12.64 to ^0.12.70](https://github.com/slimphp/Slim/pull/3054) thanks to @dependabot-preview[bot] +- [3056: Fix docblock in ErrorMiddleware](https://github.com/slimphp/Slim/pull/3056) thanks to @piotr-cz +- [3060: Update phpstan/phpstan requirement from ^0.12.70 to ^0.12.80](https://github.com/slimphp/Slim/pull/3060) thanks to @dependabot-preview[bot] +- [3061: Update nyholm/psr7 requirement from ^1.3 to ^1.4](https://github.com/slimphp/Slim/pull/3061) thanks to @dependabot-preview[bot] +- [3063: Allow ^1.0 || ^2.0 in psr/container](https://github.com/slimphp/Slim/pull/3063) thanks to @Ayesh +- [3069: Classname/Method Callable Arrays](https://github.com/slimphp/Slim/pull/3069) thanks to @ddrv +- [3078: Update squizlabs/php_codesniffer requirement from ^3.5 to ^3.6](https://github.com/slimphp/Slim/pull/3078) thanks to @dependabot[bot] +- [3079: Update phpspec/prophecy requirement from ^1.12 to ^1.13](https://github.com/slimphp/Slim/pull/3079) thanks to @dependabot[bot] +- [3080: Update guzzlehttp/psr7 requirement from ^1.7 to ^1.8](https://github.com/slimphp/Slim/pull/3080) thanks to @dependabot[bot] +- [3082: Update phpstan/phpstan requirement from ^0.12.80 to ^0.12.85](https://github.com/slimphp/Slim/pull/3082) thanks to @dependabot[bot] + +# 4.7.0 - 2020-11-30 + +### Fixed +- [3027: Fix: FastRoute dispatcher and data generator should match](https://github.com/slimphp/Slim/pull/3027) thanks to @edudobay + +### Added +- [3015: PHP 8 support](https://github.com/slimphp/Slim/pull/3015) thanks to @edudobay + +### Optimizations +- [3024: Randomize tests](https://github.com/slimphp/Slim/pull/3024) thanks to @pawel-slowik + +## 4.6.0 - 2020-11-15 + +### Fixed +- [2942: Fix PHPdoc for error handlers in ErrorMiddleware ](https://github.com/slimphp/Slim/pull/2942) thanks to @TiMESPLiNTER +- [2944: Remove unused function in ErrorHandler](https://github.com/slimphp/Slim/pull/2944) thanks to @l0gicgate +- [2960: Fix phpstan 0.12 errors](https://github.com/slimphp/Slim/pull/2960) thanks to @adriansuter +- [2982: Removing cloning statements in tests](https://github.com/slimphp/Slim/pull/2982) thanks to @l0gicgate +- [3017: Fix request creator factory test](https://github.com/slimphp/Slim/pull/3017) thanks to @pawel-slowik +- [3022: Ensure RouteParser Always Present After Routing](https://github.com/slimphp/Slim/pull/3022) thanks to @l0gicgate + +### Added +- [2949: Add the support in composer.json](https://github.com/slimphp/Slim/pull/2949) thanks to @ddrv +- [2958: Strict empty string content type checking in BodyParsingMiddleware::getMediaType](https://github.com/slimphp/Slim/pull/2958) thanks to @Ayesh +- [2997: Add hints to methods](https://github.com/slimphp/Slim/pull/2997) thanks to @evgsavosin - [3000: Fix route controller test](https://github.com/slimphp/Slim/pull/3000) thanks to @pawel-slowik +- [3001: Add missing `$strategy` parameter in a Route test](https://github.com/slimphp/Slim/pull/3001) thanks to @pawel-slowik + +### Optimizations +- [2951: Minor optimizations in if() blocks](https://github.com/slimphp/Slim/pull/2951) thanks to @Ayesh +- [2959: Micro optimization: Declare closures in BodyParsingMiddleware as static](https://github.com/slimphp/Slim/pull/2959) thanks to @Ayesh +- [2978: Split the routing results to its own function.](https://github.com/slimphp/Slim/pull/2978) thanks to @dlundgren + +### Dependencies Updated +- [2953: Update nyholm/psr7-server requirement from ^0.4.1](https://github.com/slimphp/Slim/pull/2953) thanks to @dependabot-preview[bot] +- [2954: Update laminas/laminas-diactoros requirement from ^2.1 to ^2.3](https://github.com/slimphp/Slim/pull/2954) thanks to @dependabot-preview[bot] +- [2955: Update guzzlehttp/psr7 requirement from ^1.5 to ^1.6](https://github.com/slimphp/Slim/pull/2955) thanks to @dependabot-preview[bot] +- [2956: Update slim/psr7 requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/2956) thanks to @dependabot-preview[bot] +- [2957: Update nyholm/psr7 requirement from ^1.1 to ^1.2](https://github.com/slimphp/Slim/pull/2957) thanks to @dependabot-preview[bot] +- [2963: Update phpstan/phpstan requirement from ^0.12.23 to ^0.12.25](https://github.com/slimphp/Slim/pull/2963) thanks to @dependabot-preview[bot] +- [2965: Update adriansuter/php-autoload-override requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/2965) thanks to @dependabot-preview[bot] +- [2967: Update nyholm/psr7 requirement from ^1.2 to ^1.3](https://github.com/slimphp/Slim/pull/2967) thanks to @dependabot-preview[bot] +- [2969: Update nyholm/psr7-server requirement from ^0.4.1 to ^1.0.0](https://github.com/slimphp/Slim/pull/2969) thanks to @dependabot-preview[bot] +- [2970: Update phpstan/phpstan requirement from ^0.12.25 to ^0.12.26](https://github.com/slimphp/Slim/pull/2970) thanks to @dependabot-preview[bot] +- [2971: Update phpstan/phpstan requirement from ^0.12.26 to ^0.12.27](https://github.com/slimphp/Slim/pull/2971) thanks to @dependabot-preview[bot] +- [2972: Update phpstan/phpstan requirement from ^0.12.27 to ^0.12.28](https://github.com/slimphp/Slim/pull/2972) thanks to @dependabot-preview[bot] +- [2973: Update phpstan/phpstan requirement from ^0.12.28 to ^0.12.29](https://github.com/slimphp/Slim/pull/2973) thanks to @dependabot-preview[bot] +- [2975: Update phpstan/phpstan requirement from ^0.12.29 to ^0.12.30](https://github.com/slimphp/Slim/pull/2975) thanks to @dependabot-preview[bot] +- [2976: Update phpstan/phpstan requirement from ^0.12.30 to ^0.12.31](https://github.com/slimphp/Slim/pull/2976) thanks to @dependabot-preview[bot] +- [2980: Update phpstan/phpstan requirement from ^0.12.31 to ^0.12.32](https://github.com/slimphp/Slim/pull/2980) thanks to @dependabot-preview[bot] +- [2981: Update phpspec/prophecy requirement from ^1.10 to ^1.11](https://github.com/slimphp/Slim/pull/2981) thanks to @dependabot-preview[bot] +- [2986: Update phpstan/phpstan requirement from ^0.12.32 to ^0.12.33](https://github.com/slimphp/Slim/pull/2986) thanks to @dependabot-preview[bot] +- [2990: Update phpstan/phpstan requirement from ^0.12.33 to ^0.12.34](https://github.com/slimphp/Slim/pull/2990) thanks to @dependabot-preview[bot] +- [2991: Update phpstan/phpstan requirement from ^0.12.34 to ^0.12.35](https://github.com/slimphp/Slim/pull/2991) thanks to @dependabot-preview[bot] +- [2993: Update phpstan/phpstan requirement from ^0.12.35 to ^0.12.36](https://github.com/slimphp/Slim/pull/2993) thanks to @dependabot-preview[bot] +- [2995: Update phpstan/phpstan requirement from ^0.12.36 to ^0.12.37](https://github.com/slimphp/Slim/pull/2995) thanks to @dependabot-preview[bot] +- [3010: Update guzzlehttp/psr7 requirement from ^1.6 to ^1.7](https://github.com/slimphp/Slim/pull/3010) thanks to @dependabot-preview[bot] +- [3011: Update phpspec/prophecy requirement from ^1.11 to ^1.12](https://github.com/slimphp/Slim/pull/3011) thanks to @dependabot-preview[bot] +- [3012: Update slim/http requirement from ^1.0 to ^1.1](https://github.com/slimphp/Slim/pull/3012) thanks to @dependabot-preview[bot] +- [3013: Update slim/psr7 requirement from ^1.1 to ^1.2](https://github.com/slimphp/Slim/pull/3013) thanks to @dependabot-preview[bot] +- [3014: Update laminas/laminas-diactoros requirement from ^2.3 to ^2.4](https://github.com/slimphp/Slim/pull/3014) thanks to @dependabot-preview[bot] +- [3018: Update phpstan/phpstan requirement from ^0.12.37 to ^0.12.54](https://github.com/slimphp/Slim/pull/3018) thanks to @dependabot-preview[bot] + +## 4.5.0 - 2020-04-14 + +### Added +- [2928](https://github.com/slimphp/Slim/pull/2928) Test against PHP 7.4 +- [2937](https://github.com/slimphp/Slim/pull/2937) Add support for PSR-3 + +### Fixed +- [2916](https://github.com/slimphp/Slim/pull/2916) Rename phpcs.xml to phpcs.xml.dist +- [2917](https://github.com/slimphp/Slim/pull/2917) Update .editorconfig +- [2925](https://github.com/slimphp/Slim/pull/2925) ResponseEmitter: Don't remove Content-Type and Content-Length when body is empt +- [2932](https://github.com/slimphp/Slim/pull/2932) Update the Tidelift enterprise language +- [2938](https://github.com/slimphp/Slim/pull/2938) Modify usage of deprecated expectExceptionMessageRegExp() method + +## 4.4.0 - 2020-01-04 + +### Added +- [2862](https://github.com/slimphp/Slim/pull/2862) Optionally handle subclasses of exceptions in custom error handler +- [2869](https://github.com/slimphp/Slim/pull/2869) php-di/php-di added in composer suggestion +- [2874](https://github.com/slimphp/Slim/pull/2874) Add `null` to param type-hints +- [2889](https://github.com/slimphp/Slim/pull/2889) Make `RouteContext` attributes customizable and change default to use private names +- [2907](https://github.com/slimphp/Slim/pull/2907) Migrate to PSR-12 convention +- [2910](https://github.com/slimphp/Slim/pull/2910) Migrate Zend to Laminas +- [2912](https://github.com/slimphp/Slim/pull/2912) Add Laminas PSR17 Factory +- [2913](https://github.com/slimphp/Slim/pull/2913) Update php-autoload-override version +- [2914](https://github.com/slimphp/Slim/pull/2914) Added ability to add handled exceptions as an array + +### Fixed +- [2864](https://github.com/slimphp/Slim/pull/2864) Optimize error message in error handling if displayErrorDetails was not set +- [2876](https://github.com/slimphp/Slim/pull/2876) Update links from http to https +- [2877](https://github.com/slimphp/Slim/pull/2877) Fix docblock for `Slim\Routing\RouteCollector::cacheFile` +- [2878](https://github.com/slimphp/Slim/pull/2878) check body is writable only on ouput buffering append +- [2896](https://github.com/slimphp/Slim/pull/2896) Render errors uniformly +- [2902](https://github.com/slimphp/Slim/pull/2902) Fix prophecies +- [2908](https://github.com/slimphp/Slim/pull/2908) Use autoload-dev for `Slim\Tests` namespace + +### Removed +- [2871](https://github.com/slimphp/Slim/pull/2871) Remove explicit type-hint +- [2872](https://github.com/slimphp/Slim/pull/2872) Remove type-hint + +## 4.3.0 - 2019-10-05 + +### Added +- [2819](https://github.com/slimphp/Slim/pull/2819) Added description to addRoutingMiddleware() +- [2820](https://github.com/slimphp/Slim/pull/2820) Update link to homepage in composer.json +- [2828](https://github.com/slimphp/Slim/pull/2828) Allow URIs with leading multi-slashes +- [2832](https://github.com/slimphp/Slim/pull/2832) Refactor `FastRouteDispatcher` +- [2835](https://github.com/slimphp/Slim/pull/2835) Rename `pathFor` to `urlFor` in docblock +- [2846](https://github.com/slimphp/Slim/pull/2846) Correcting the branch name as per issue-2843 +- [2849](https://github.com/slimphp/Slim/pull/2849) Create class alias for FastRoute\RouteCollector +- [2855](https://github.com/slimphp/Slim/pull/2855) Add list of allowed methods to HttpMethodNotAllowedException +- [2860](https://github.com/slimphp/Slim/pull/2860) Add base path to `$request` and use `RouteContext` to read + +### Fixed +- [2839](https://github.com/slimphp/Slim/pull/2839) Fix description for handler signature in phpdocs +- [2844](https://github.com/slimphp/Slim/pull/2844) Handle base path by routeCollector instead of RouteCollectorProxy +- [2845](https://github.com/slimphp/Slim/pull/2845) Fix composer scripts +- [2851](https://github.com/slimphp/Slim/pull/2851) Fix example of 'Hello World' app +- [2854](https://github.com/slimphp/Slim/pull/2854) Fix undefined property in tests + +### Removed +- [2853](https://github.com/slimphp/Slim/pull/2853) Remove unused classes + +## 4.2.0 - 2019-08-20 + +### Added +- [2787](https://github.com/slimphp/Slim/pull/2787) Add an advanced callable resolver +- [2791](https://github.com/slimphp/Slim/pull/2791) Add `inferPrivatePropertyTypeFromConstructor` to phpstan +- [2793](https://github.com/slimphp/Slim/pull/2793) Add ability to configure application via a container in `AppFactory` +- [2798](https://github.com/slimphp/Slim/pull/2798) Add PSR-7 Agnostic Body Parsing Middleware +- [2801](https://github.com/slimphp/Slim/pull/2801) Add `setLogErrorRenderer()` method to `ErrorHandler` +- [2807](https://github.com/slimphp/Slim/pull/2807) Add check for Slim callable notation if no resolver given +- [2803](https://github.com/slimphp/Slim/pull/2803) Add ability to emit non seekable streams in `ResponseEmitter` +- [2817](https://github.com/slimphp/Slim/pull/2817) Add the ability to pass in a custom `MiddlewareDispatcherInterface` to the `App` + +### Fixed +- [2789](https://github.com/slimphp/Slim/pull/2789) Fix Cookie header detection in `ResponseEmitter` +- [2796](https://github.com/slimphp/Slim/pull/2796) Fix http message format +- [2800](https://github.com/slimphp/Slim/pull/2800) Fix null comparisons more clear in `ErrorHandler` +- [2802](https://github.com/slimphp/Slim/pull/2802) Fix incorrect search of a header in stack +- [2806](https://github.com/slimphp/Slim/pull/2806) Simplify `Route::prepare()` method argument preparation +- [2809](https://github.com/slimphp/Slim/pull/2809) Eliminate a duplicate code via HOF in `MiddlewareDispatcher` +- [2816](https://github.com/slimphp/Slim/pull/2816) Fix RouteCollectorProxy::redirect() bug + +### Removed +- [2811](https://github.com/slimphp/Slim/pull/2811) Remove `DeferredCallable` + +## 4.1.0 - 2019-08-06 + +### Added +- [#2779](https://github.com/slimphp/Slim/pull/2774) Add support for Slim callables `Class:method` resolution & Container Closure auto-binding in `MiddlewareDispatcher` +- [#2774](https://github.com/slimphp/Slim/pull/2774) Add possibility for custom `RequestHandler` invocation strategies + +### Fixed +- [#2776](https://github.com/slimphp/Slim/pull/2774) Fix group middleware on multiple nested groups diff --git a/advancedcontentfilter/vendor/slim/slim/LICENSE.md b/advancedcontentfilter/vendor/slim/slim/LICENSE.md index 682c21dc..d6fd559c 100644 --- a/advancedcontentfilter/vendor/slim/slim/LICENSE.md +++ b/advancedcontentfilter/vendor/slim/slim/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2011-2017 Josh Lockhart +Copyright (c) 2011-2022 Josh Lockhart Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/advancedcontentfilter/vendor/slim/slim/MAINTAINERS.md b/advancedcontentfilter/vendor/slim/slim/MAINTAINERS.md new file mode 100644 index 00000000..2b8ad049 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/MAINTAINERS.md @@ -0,0 +1,17 @@ +# Maintainers + +There aren't many rules for maintainers of Slim to remember; what we have is listed here. + +## We don't merge our own PRs + +Our code is better if more than one set of eyes looks at it. Therefore we do not merge our own pull requests unless there is an exceptional circumstance. This helps to spot errors in the patch and also enables us to share information about the project around the maintainer team. + +## PRs tagged `WIP` are not ready to be merged + +Sometimes it's helpful to collaborate on a patch before it's ready to be merged. We use the text `WIP` (for _Work in Progress_) in the title to mark these PRs. + +If a PR has `WIP` in its title, then it is not to be merged. The person who raised the PR will remove the `WIP` text when they are ready for a full review and merge. + +## Assign a merged PR to a milestone + +By ensuring that all merged PRs are assigned to a milestone, we can easily find which PRs were in which release. diff --git a/advancedcontentfilter/vendor/slim/slim/SECURITY.md b/advancedcontentfilter/vendor/slim/slim/SECURITY.md new file mode 100644 index 00000000..a5b6df0b --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/SECURITY.md @@ -0,0 +1,14 @@ +# Security Policy + +### Supported Versions + + +| Version | Supported | +| ------- | ------------------ | +| 3.x.x | :white_check_mark: | +| 4.x.x | :white_check_mark: | + + +### Reporting a Vulnerability + +To report a vulnerability please send an email to security@slimframework.com diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/App.php b/advancedcontentfilter/vendor/slim/slim/Slim/App.php index c5a0f2d3..ebcc751f 100644 --- a/advancedcontentfilter/vendor/slim/slim/Slim/App.php +++ b/advancedcontentfilter/vendor/slim/slim/Slim/App.php @@ -1,696 +1,216 @@ container = $container; - } + public function __construct( + ResponseFactoryInterface $responseFactory, + ?ContainerInterface $container = null, + ?CallableResolverInterface $callableResolver = null, + ?RouteCollectorInterface $routeCollector = null, + ?RouteResolverInterface $routeResolver = null, + ?MiddlewareDispatcherInterface $middlewareDispatcher = null + ) { + parent::__construct( + $responseFactory, + $callableResolver ?? new CallableResolver($container), + $container, + $routeCollector + ); - /** - * Enable access to the DI container by consumers of $app - * - * @return ContainerInterface - */ - public function getContainer() - { - return $this->container; - } + $this->routeResolver = $routeResolver ?? new RouteResolver($this->routeCollector); + $routeRunner = new RouteRunner($this->routeResolver, $this->routeCollector->getRouteParser(), $this); - /** - * Add middleware - * - * This method prepends new middleware to the app's middleware stack. - * - * @param callable|string $callable The callback routine - * - * @return static - */ - public function add($callable) - { - return $this->addMiddleware(new DeferredCallable($callable, $this->container)); - } - - /** - * Calling a non-existant method on App checks to see if there's an item - * in the container that is callable and if so, calls it. - * - * @param string $method - * @param array $args - * @return mixed - */ - public function __call($method, $args) - { - if ($this->container->has($method)) { - $obj = $this->container->get($method); - if (is_callable($obj)) { - return call_user_func_array($obj, $args); - } + if (!$middlewareDispatcher) { + $middlewareDispatcher = new MiddlewareDispatcher($routeRunner, $this->callableResolver, $container); + } else { + $middlewareDispatcher->seedMiddlewareStack($routeRunner); } - throw new \BadMethodCallException("Method $method is not a valid method"); - } - - /******************************************************************************** - * Router proxy methods - *******************************************************************************/ - - /** - * Add GET route - * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine - * - * @return \Slim\Interfaces\RouteInterface - */ - public function get($pattern, $callable) - { - return $this->map(['GET'], $pattern, $callable); + $this->middlewareDispatcher = $middlewareDispatcher; } /** - * Add POST route - * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine - * - * @return \Slim\Interfaces\RouteInterface + * @return RouteResolverInterface */ - public function post($pattern, $callable) + public function getRouteResolver(): RouteResolverInterface { - return $this->map(['POST'], $pattern, $callable); + return $this->routeResolver; } /** - * Add PUT route - * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine - * - * @return \Slim\Interfaces\RouteInterface + * @return MiddlewareDispatcherInterface */ - public function put($pattern, $callable) + public function getMiddlewareDispatcher(): MiddlewareDispatcherInterface { - return $this->map(['PUT'], $pattern, $callable); + return $this->middlewareDispatcher; } /** - * Add PATCH route - * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine - * - * @return \Slim\Interfaces\RouteInterface + * @param MiddlewareInterface|string|callable $middleware */ - public function patch($pattern, $callable) + public function add($middleware): self { - return $this->map(['PATCH'], $pattern, $callable); + $this->middlewareDispatcher->add($middleware); + return $this; } /** - * Add DELETE route - * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine - * - * @return \Slim\Interfaces\RouteInterface + * @param MiddlewareInterface $middleware */ - public function delete($pattern, $callable) + public function addMiddleware(MiddlewareInterface $middleware): self { - return $this->map(['DELETE'], $pattern, $callable); + $this->middlewareDispatcher->addMiddleware($middleware); + return $this; } /** - * Add OPTIONS route + * Add the Slim built-in routing middleware to the app middleware stack * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine + * This method can be used to control middleware order and is not required for default routing operation. * - * @return \Slim\Interfaces\RouteInterface + * @return RoutingMiddleware */ - public function options($pattern, $callable) + public function addRoutingMiddleware(): RoutingMiddleware { - return $this->map(['OPTIONS'], $pattern, $callable); + $routingMiddleware = new RoutingMiddleware( + $this->getRouteResolver(), + $this->getRouteCollector()->getRouteParser() + ); + $this->add($routingMiddleware); + return $routingMiddleware; } /** - * Add route for any HTTP method + * Add the Slim built-in error middleware to the app middleware stack * - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine + * @param bool $displayErrorDetails + * @param bool $logErrors + * @param bool $logErrorDetails + * @param LoggerInterface|null $logger * - * @return \Slim\Interfaces\RouteInterface + * @return ErrorMiddleware */ - public function any($pattern, $callable) - { - return $this->map(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], $pattern, $callable); + public function addErrorMiddleware( + bool $displayErrorDetails, + bool $logErrors, + bool $logErrorDetails, + ?LoggerInterface $logger = null + ): ErrorMiddleware { + $errorMiddleware = new ErrorMiddleware( + $this->getCallableResolver(), + $this->getResponseFactory(), + $displayErrorDetails, + $logErrors, + $logErrorDetails, + $logger + ); + $this->add($errorMiddleware); + return $errorMiddleware; } /** - * Add route with multiple methods + * Add the Slim body parsing middleware to the app middleware stack * - * @param string[] $methods Numeric array of HTTP method names - * @param string $pattern The route URI pattern - * @param callable|string $callable The route callback routine + * @param callable[] $bodyParsers * - * @return RouteInterface + * @return BodyParsingMiddleware */ - public function map(array $methods, $pattern, $callable) + public function addBodyParsingMiddleware(array $bodyParsers = []): BodyParsingMiddleware { - if ($callable instanceof Closure) { - $callable = $callable->bindTo($this->container); - } - - $route = $this->container->get('router')->map($methods, $pattern, $callable); - if (is_callable([$route, 'setContainer'])) { - $route->setContainer($this->container); - } - - if (is_callable([$route, 'setOutputBuffering'])) { - $route->setOutputBuffering($this->container->get('settings')['outputBuffering']); - } - - return $route; + $bodyParsingMiddleware = new BodyParsingMiddleware($bodyParsers); + $this->add($bodyParsingMiddleware); + return $bodyParsingMiddleware; } - /** - * Route Groups - * - * This method accepts a route pattern and a callback. All route - * declarations in the callback will be prepended by the group(s) - * that it is in. - * - * @param string $pattern - * @param callable $callable - * - * @return RouteGroupInterface - */ - public function group($pattern, $callable) - { - /** @var RouteGroup $group */ - $group = $this->container->get('router')->pushGroup($pattern, $callable); - $group->setContainer($this->container); - $group($this); - $this->container->get('router')->popGroup(); - return $group; - } - - /******************************************************************************** - * Runner - *******************************************************************************/ - /** * Run application * * This method traverses the application middleware stack and then sends the * resultant Response object to the HTTP client. * - * @param bool|false $silent - * @return ResponseInterface - * - * @throws Exception - * @throws MethodNotAllowedException - * @throws NotFoundException + * @param ServerRequestInterface|null $request + * @return void */ - public function run($silent = false) + public function run(?ServerRequestInterface $request = null): void { - $response = $this->container->get('response'); - - try { - ob_start(); - $response = $this->process($this->container->get('request'), $response); - } catch (InvalidMethodException $e) { - $response = $this->processInvalidMethod($e->getRequest(), $response); - } finally { - $output = ob_get_clean(); + if (!$request) { + $serverRequestCreator = ServerRequestCreatorFactory::create(); + $request = $serverRequestCreator->createServerRequestFromGlobals(); } - if (!empty($output) && $response->getBody()->isWritable()) { - $outputBuffering = $this->container->get('settings')['outputBuffering']; - if ($outputBuffering === 'prepend') { - // prepend output buffer content - $body = new Http\Body(fopen('php://temp', 'r+')); - $body->write($output . $response->getBody()); - $response = $response->withBody($body); - } elseif ($outputBuffering === 'append') { - // append output buffer content - $response->getBody()->write($output); - } - } - - $response = $this->finalize($response); - - if (!$silent) { - $this->respond($response); - } - - return $response; + $response = $this->handle($request); + $responseEmitter = new ResponseEmitter(); + $responseEmitter->emit($response); } /** - * Pull route info for a request with a bad method to decide whether to - * return a not-found error (default) or a bad-method error, then run - * the handler for that error, returning the resulting response. - * - * Used for cases where an incoming request has an unrecognized method, - * rather than throwing an exception and not catching it all the way up. - * - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * @return ResponseInterface - */ - protected function processInvalidMethod(ServerRequestInterface $request, ResponseInterface $response) - { - $router = $this->container->get('router'); - if (is_callable([$request->getUri(), 'getBasePath']) && is_callable([$router, 'setBasePath'])) { - $router->setBasePath($request->getUri()->getBasePath()); - } - - $request = $this->dispatchRouterAndPrepareRoute($request, $router); - $routeInfo = $request->getAttribute('routeInfo', [RouterInterface::DISPATCH_STATUS => Dispatcher::NOT_FOUND]); - - if ($routeInfo[RouterInterface::DISPATCH_STATUS] === Dispatcher::METHOD_NOT_ALLOWED) { - return $this->handleException( - new MethodNotAllowedException($request, $response, $routeInfo[RouterInterface::ALLOWED_METHODS]), - $request, - $response - ); - } - - return $this->handleException(new NotFoundException($request, $response), $request, $response); - } - - /** - * Process a request + * Handle a request * * This method traverses the application middleware stack and then returns the * resultant Response object. * * @param ServerRequestInterface $request - * @param ResponseInterface $response * @return ResponseInterface - * - * @throws Exception - * @throws MethodNotAllowedException - * @throws NotFoundException */ - public function process(ServerRequestInterface $request, ResponseInterface $response) + public function handle(ServerRequestInterface $request): ResponseInterface { - // Ensure basePath is set - $router = $this->container->get('router'); - if (is_callable([$request->getUri(), 'getBasePath']) && is_callable([$router, 'setBasePath'])) { - $router->setBasePath($request->getUri()->getBasePath()); - } + $response = $this->middlewareDispatcher->handle($request); - // Dispatch the Router first if the setting for this is on - if ($this->container->get('settings')['determineRouteBeforeAppMiddleware'] === true) { - // Dispatch router (note: you won't be able to alter routes after this) - $request = $this->dispatchRouterAndPrepareRoute($request, $router); - } - - // Traverse middleware stack - try { - $response = $this->callMiddlewareStack($request, $response); - } catch (Exception $e) { - $response = $this->handleException($e, $request, $response); - } catch (Throwable $e) { - $response = $this->handlePhpError($e, $request, $response); + /** + * This is to be in compliance with RFC 2616, Section 9. + * If the incoming request method is HEAD, we need to ensure that the response body + * is empty as the request may fall back on a GET route handler due to FastRoute's + * routing logic which could potentially append content to the response body + * https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 + */ + $method = strtoupper($request->getMethod()); + if ($method === 'HEAD') { + $emptyBody = $this->responseFactory->createResponse()->getBody(); + return $response->withBody($emptyBody); } return $response; } - - /** - * Send the response to the client - * - * @param ResponseInterface $response - */ - public function respond(ResponseInterface $response) - { - // Send response - if (!headers_sent()) { - // Headers - foreach ($response->getHeaders() as $name => $values) { - foreach ($values as $value) { - header(sprintf('%s: %s', $name, $value), false); - } - } - - // Set the status _after_ the headers, because of PHP's "helpful" behavior with location headers. - // See https://github.com/slimphp/Slim/issues/1730 - - // Status - header(sprintf( - 'HTTP/%s %s %s', - $response->getProtocolVersion(), - $response->getStatusCode(), - $response->getReasonPhrase() - )); - } - - // Body - if (!$this->isEmptyResponse($response)) { - $body = $response->getBody(); - if ($body->isSeekable()) { - $body->rewind(); - } - $settings = $this->container->get('settings'); - $chunkSize = $settings['responseChunkSize']; - - $contentLength = $response->getHeaderLine('Content-Length'); - if (!$contentLength) { - $contentLength = $body->getSize(); - } - - - if (isset($contentLength)) { - $amountToRead = $contentLength; - while ($amountToRead > 0 && !$body->eof()) { - $data = $body->read(min($chunkSize, $amountToRead)); - echo $data; - - $amountToRead -= strlen($data); - - if (connection_status() != CONNECTION_NORMAL) { - break; - } - } - } else { - while (!$body->eof()) { - echo $body->read($chunkSize); - if (connection_status() != CONNECTION_NORMAL) { - break; - } - } - } - } - } - - /** - * Invoke application - * - * This method implements the middleware interface. It receives - * Request and Response objects, and it returns a Response object - * after compiling the routes registered in the Router and dispatching - * the Request object to the appropriate Route callback routine. - * - * @param ServerRequestInterface $request The most recent Request object - * @param ResponseInterface $response The most recent Response object - * - * @return ResponseInterface - * @throws MethodNotAllowedException - * @throws NotFoundException - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response) - { - // Get the route info - $routeInfo = $request->getAttribute('routeInfo'); - - /** @var \Slim\Interfaces\RouterInterface $router */ - $router = $this->container->get('router'); - - // If router hasn't been dispatched or the URI changed then dispatch - if (null === $routeInfo || ($routeInfo['request'] !== [$request->getMethod(), (string) $request->getUri()])) { - $request = $this->dispatchRouterAndPrepareRoute($request, $router); - $routeInfo = $request->getAttribute('routeInfo'); - } - - if ($routeInfo[0] === Dispatcher::FOUND) { - $route = $router->lookupRoute($routeInfo[1]); - return $route->run($request, $response); - } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { - if (!$this->container->has('notAllowedHandler')) { - throw new MethodNotAllowedException($request, $response, $routeInfo[1]); - } - /** @var callable $notAllowedHandler */ - $notAllowedHandler = $this->container->get('notAllowedHandler'); - return $notAllowedHandler($request, $response, $routeInfo[1]); - } - - if (!$this->container->has('notFoundHandler')) { - throw new NotFoundException($request, $response); - } - /** @var callable $notFoundHandler */ - $notFoundHandler = $this->container->get('notFoundHandler'); - return $notFoundHandler($request, $response); - } - - /** - * Perform a sub-request from within an application route - * - * This method allows you to prepare and initiate a sub-request, run within - * the context of the current request. This WILL NOT issue a remote HTTP - * request. Instead, it will route the provided URL, method, headers, - * cookies, body, and server variables against the set of registered - * application routes. The result response object is returned. - * - * @param string $method The request method (e.g., GET, POST, PUT, etc.) - * @param string $path The request URI path - * @param string $query The request URI query string - * @param array $headers The request headers (key-value array) - * @param array $cookies The request cookies (key-value array) - * @param string $bodyContent The request body - * @param ResponseInterface $response The response object (optional) - * @return ResponseInterface - */ - public function subRequest( - $method, - $path, - $query = '', - array $headers = [], - array $cookies = [], - $bodyContent = '', - ResponseInterface $response = null - ) { - $env = $this->container->get('environment'); - $uri = Uri::createFromEnvironment($env)->withPath($path)->withQuery($query); - $headers = new Headers($headers); - $serverParams = $env->all(); - $body = new Body(fopen('php://temp', 'r+')); - $body->write($bodyContent); - $body->rewind(); - $request = new Request($method, $uri, $headers, $cookies, $serverParams, $body); - - if (!$response) { - $response = $this->container->get('response'); - } - - return $this($request, $response); - } - - /** - * Dispatch the router to find the route. Prepare the route for use. - * - * @param ServerRequestInterface $request - * @param RouterInterface $router - * @return ServerRequestInterface - */ - protected function dispatchRouterAndPrepareRoute(ServerRequestInterface $request, RouterInterface $router) - { - $routeInfo = $router->dispatch($request); - - if ($routeInfo[0] === Dispatcher::FOUND) { - $routeArguments = []; - foreach ($routeInfo[2] as $k => $v) { - $routeArguments[$k] = urldecode($v); - } - - $route = $router->lookupRoute($routeInfo[1]); - $route->prepare($request, $routeArguments); - - // add route to the request's attributes in case a middleware or handler needs access to the route - $request = $request->withAttribute('route', $route); - } - - $routeInfo['request'] = [$request->getMethod(), (string) $request->getUri()]; - - return $request->withAttribute('routeInfo', $routeInfo); - } - - /** - * Finalize response - * - * @param ResponseInterface $response - * @return ResponseInterface - */ - protected function finalize(ResponseInterface $response) - { - // stop PHP sending a Content-Type automatically - ini_set('default_mimetype', ''); - - if ($this->isEmptyResponse($response)) { - return $response->withoutHeader('Content-Type')->withoutHeader('Content-Length'); - } - - // Add Content-Length header if `addContentLengthHeader` setting is set - if (isset($this->container->get('settings')['addContentLengthHeader']) && - $this->container->get('settings')['addContentLengthHeader'] == true) { - if (ob_get_length() > 0) { - throw new \RuntimeException("Unexpected data in output buffer. " . - "Maybe you have characters before an opening getBody()->getSize(); - if ($size !== null && !$response->hasHeader('Content-Length')) { - $response = $response->withHeader('Content-Length', (string) $size); - } - } - - return $response; - } - - /** - * Helper method, which returns true if the provided response must not output a body and false - * if the response could have a body. - * - * @see https://tools.ietf.org/html/rfc7231 - * - * @param ResponseInterface $response - * @return bool - */ - protected function isEmptyResponse(ResponseInterface $response) - { - if (method_exists($response, 'isEmpty')) { - return $response->isEmpty(); - } - - return in_array($response->getStatusCode(), [204, 205, 304]); - } - - /** - * Call relevant handler from the Container if needed. If it doesn't exist, - * then just re-throw. - * - * @param Exception $e - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * - * @return ResponseInterface - * @throws Exception if a handler is needed and not found - */ - protected function handleException(Exception $e, ServerRequestInterface $request, ResponseInterface $response) - { - if ($e instanceof MethodNotAllowedException) { - $handler = 'notAllowedHandler'; - $params = [$e->getRequest(), $e->getResponse(), $e->getAllowedMethods()]; - } elseif ($e instanceof NotFoundException) { - $handler = 'notFoundHandler'; - $params = [$e->getRequest(), $e->getResponse(), $e]; - } elseif ($e instanceof SlimException) { - // This is a Stop exception and contains the response - return $e->getResponse(); - } else { - // Other exception, use $request and $response params - $handler = 'errorHandler'; - $params = [$request, $response, $e]; - } - - if ($this->container->has($handler)) { - $callable = $this->container->get($handler); - // Call the registered handler - return call_user_func_array($callable, $params); - } - - // No handlers found, so just throw the exception - throw $e; - } - - /** - * Call relevant handler from the Container if needed. If it doesn't exist, - * then just re-throw. - * - * @param Throwable $e - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * @return ResponseInterface - * @throws Throwable - */ - protected function handlePhpError(Throwable $e, ServerRequestInterface $request, ResponseInterface $response) - { - $handler = 'phpErrorHandler'; - $params = [$request, $response, $e]; - - if ($this->container->has($handler)) { - $callable = $this->container->get($handler); - // Call the registered handler - return call_user_func_array($callable, $params); - } - - // No handlers found, so just throw the exception - throw $e; - } } diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolver.php b/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolver.php index 2211a329..66f225de 100644 --- a/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolver.php +++ b/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolver.php @@ -1,110 +1,193 @@ container = $container; } /** - * Resolve toResolve into a closure so that the router can dispatch. + * {@inheritdoc} + */ + public function resolve($toResolve): callable + { + $toResolve = $this->prepareToResolve($toResolve); + if (is_callable($toResolve)) { + return $this->bindToContainer($toResolve); + } + $resolved = $toResolve; + if (is_string($toResolve)) { + $resolved = $this->resolveSlimNotation($toResolve); + $resolved[1] ??= '__invoke'; + } + $callable = $this->assertCallable($resolved, $toResolve); + return $this->bindToContainer($callable); + } + + /** + * {@inheritdoc} + */ + public function resolveRoute($toResolve): callable + { + return $this->resolveByPredicate($toResolve, [$this, 'isRoute'], 'handle'); + } + + /** + * {@inheritdoc} + */ + public function resolveMiddleware($toResolve): callable + { + return $this->resolveByPredicate($toResolve, [$this, 'isMiddleware'], 'process'); + } + + /** + * @param string|callable $toResolve * - * If toResolve is of the format 'class:method', then try to extract 'class' - * from the container otherwise instantiate it and then dispatch 'method'. + * @throws RuntimeException + */ + private function resolveByPredicate($toResolve, callable $predicate, string $defaultMethod): callable + { + $toResolve = $this->prepareToResolve($toResolve); + if (is_callable($toResolve)) { + return $this->bindToContainer($toResolve); + } + $resolved = $toResolve; + if ($predicate($toResolve)) { + $resolved = [$toResolve, $defaultMethod]; + } + if (is_string($toResolve)) { + [$instance, $method] = $this->resolveSlimNotation($toResolve); + if ($method === null && $predicate($instance)) { + $method = $defaultMethod; + } + $resolved = [$instance, $method ?? '__invoke']; + } + $callable = $this->assertCallable($resolved, $toResolve); + return $this->bindToContainer($callable); + } + + /** + * @param mixed $toResolve + */ + private function isRoute($toResolve): bool + { + return $toResolve instanceof RequestHandlerInterface; + } + + /** + * @param mixed $toResolve + */ + private function isMiddleware($toResolve): bool + { + return $toResolve instanceof MiddlewareInterface; + } + + /** + * @throws RuntimeException * + * @return array{object, string|null} [Instance, Method Name] + */ + private function resolveSlimNotation(string $toResolve): array + { + preg_match(CallableResolver::$callablePattern, $toResolve, $matches); + [$class, $method] = $matches ? [$matches[1], $matches[2]] : [$toResolve, null]; + + /** @var string $class */ + /** @var string|null $method */ + if ($this->container && $this->container->has($class)) { + $instance = $this->container->get($class); + if (!is_object($instance)) { + throw new RuntimeException(sprintf('%s container entry is not an object', $class)); + } + } else { + if (!class_exists($class)) { + if ($method) { + $class .= '::' . $method . '()'; + } + throw new RuntimeException(sprintf('Callable %s does not exist', $class)); + } + $instance = new $class($this->container); + } + return [$instance, $method]; + } + + /** + * @param mixed $resolved * @param mixed $toResolve * - * @return callable - * - * @throws RuntimeException if the callable does not exist - * @throws RuntimeException if the callable is not resolvable + * @throws RuntimeException */ - public function resolve($toResolve) + private function assertCallable($resolved, $toResolve): callable { - if (is_callable($toResolve)) { - return $toResolve; + if (!is_callable($resolved)) { + if (is_callable($toResolve) || is_object($toResolve) || is_array($toResolve)) { + $formatedToResolve = ($toResolveJson = json_encode($toResolve)) !== false ? $toResolveJson : ''; + } else { + $formatedToResolve = is_string($toResolve) ? $toResolve : ''; + } + throw new RuntimeException(sprintf('%s is not resolvable', $formatedToResolve)); } - - if (!is_string($toResolve)) { - $this->assertCallable($toResolve); - } - - // check for slim callable as "class:method" - if (preg_match(self::CALLABLE_PATTERN, $toResolve, $matches)) { - $resolved = $this->resolveCallable($matches[1], $matches[2]); - $this->assertCallable($resolved); - - return $resolved; - } - - $resolved = $this->resolveCallable($toResolve); - $this->assertCallable($resolved); - return $resolved; } - /** - * Check if string is something in the DIC - * that's callable or is a class name which has an __invoke() method. - * - * @param string $class - * @param string $method - * @return callable - * - * @throws \RuntimeException if the callable does not exist - */ - protected function resolveCallable($class, $method = '__invoke') + private function bindToContainer(callable $callable): callable { - if ($this->container->has($class)) { - return [$this->container->get($class), $method]; + if (is_array($callable) && $callable[0] instanceof Closure) { + $callable = $callable[0]; } - - if (!class_exists($class)) { - throw new RuntimeException(sprintf('Callable %s does not exist', $class)); + if ($this->container && $callable instanceof Closure) { + /** @var Closure $callable */ + $callable = $callable->bindTo($this->container); } - - return [new $class($this->container), $method]; + return $callable; } /** - * @param Callable $callable - * - * @throws \RuntimeException if the callable is not resolvable + * @param string|callable $toResolve + * @return string|callable */ - protected function assertCallable($callable) + private function prepareToResolve($toResolve) { - if (!is_callable($callable)) { - throw new RuntimeException(sprintf( - '%s is not resolvable', - is_array($callable) || is_object($callable) ? json_encode($callable) : $callable - )); + if (!is_array($toResolve)) { + return $toResolve; } + $candidate = $toResolve; + $class = array_shift($candidate); + $method = array_shift($candidate); + if (is_string($class) && is_string($method)) { + return $class . ':' . $method; + } + return $toResolve; } } diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolverAwareTrait.php b/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolverAwareTrait.php deleted file mode 100644 index ffb4eb28..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/CallableResolverAwareTrait.php +++ /dev/null @@ -1,47 +0,0 @@ -container instanceof ContainerInterface) { - return $callable; - } - - /** @var CallableResolverInterface $resolver */ - $resolver = $this->container->get('callableResolver'); - - return $resolver->resolve($callable); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Collection.php b/advancedcontentfilter/vendor/slim/slim/Slim/Collection.php deleted file mode 100644 index 728bb73e..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Collection.php +++ /dev/null @@ -1,202 +0,0 @@ -replace($items); - } - - /******************************************************************************** - * Collection interface - *******************************************************************************/ - - /** - * Set collection item - * - * @param string $key The data key - * @param mixed $value The data value - */ - public function set($key, $value) - { - $this->data[$key] = $value; - } - - /** - * Get collection item for key - * - * @param string $key The data key - * @param mixed $default The default value to return if data key does not exist - * - * @return mixed The key's value, or the default value - */ - public function get($key, $default = null) - { - return $this->has($key) ? $this->data[$key] : $default; - } - - /** - * Add item to collection, replacing existing items with the same data key - * - * @param array $items Key-value array of data to append to this collection - */ - public function replace(array $items) - { - foreach ($items as $key => $value) { - $this->set($key, $value); - } - } - - /** - * Get all items in collection - * - * @return array The collection's source data - */ - public function all() - { - return $this->data; - } - - /** - * Get collection keys - * - * @return array The collection's source data keys - */ - public function keys() - { - return array_keys($this->data); - } - - /** - * Does this collection have a given key? - * - * @param string $key The data key - * - * @return bool - */ - public function has($key) - { - return array_key_exists($key, $this->data); - } - - /** - * Remove item from collection - * - * @param string $key The data key - */ - public function remove($key) - { - unset($this->data[$key]); - } - - /** - * Remove all items from collection - */ - public function clear() - { - $this->data = []; - } - - /******************************************************************************** - * ArrayAccess interface - *******************************************************************************/ - - /** - * Does this collection have a given key? - * - * @param string $key The data key - * - * @return bool - */ - public function offsetExists($key) - { - return $this->has($key); - } - - /** - * Get collection item for key - * - * @param string $key The data key - * - * @return mixed The key's value, or the default value - */ - public function offsetGet($key) - { - return $this->get($key); - } - - /** - * Set collection item - * - * @param string $key The data key - * @param mixed $value The data value - */ - public function offsetSet($key, $value) - { - $this->set($key, $value); - } - - /** - * Remove item from collection - * - * @param string $key The data key - */ - public function offsetUnset($key) - { - $this->remove($key); - } - - /** - * Get number of items in collection - * - * @return int - */ - public function count() - { - return count($this->data); - } - - /******************************************************************************** - * IteratorAggregate interface - *******************************************************************************/ - - /** - * Get collection iterator - * - * @return \ArrayIterator - */ - public function getIterator() - { - return new ArrayIterator($this->data); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Container.php b/advancedcontentfilter/vendor/slim/slim/Slim/Container.php deleted file mode 100644 index 1f713ac4..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Container.php +++ /dev/null @@ -1,179 +0,0 @@ - '1.1', - 'responseChunkSize' => 4096, - 'outputBuffering' => 'append', - 'determineRouteBeforeAppMiddleware' => false, - 'displayErrorDetails' => false, - 'addContentLengthHeader' => true, - 'routerCacheFile' => false, - ]; - - /** - * Create new container - * - * @param array $values The parameters or objects. - */ - public function __construct(array $values = []) - { - parent::__construct($values); - - $userSettings = isset($values['settings']) ? $values['settings'] : []; - $this->registerDefaultServices($userSettings); - } - - /** - * This function registers the default services that Slim needs to work. - * - * All services are shared - that is, they are registered such that the - * same instance is returned on subsequent calls. - * - * @param array $userSettings Associative array of application settings - * - * @return void - */ - private function registerDefaultServices($userSettings) - { - $defaultSettings = $this->defaultSettings; - - /** - * This service MUST return an array or an - * instance of \ArrayAccess. - * - * @return array|\ArrayAccess - */ - $this['settings'] = function () use ($userSettings, $defaultSettings) { - return new Collection(array_merge($defaultSettings, $userSettings)); - }; - - $defaultProvider = new DefaultServicesProvider(); - $defaultProvider->register($this); - } - - /******************************************************************************** - * Methods to satisfy Psr\Container\ContainerInterface - *******************************************************************************/ - - /** - * Finds an entry of the container by its identifier and returns it. - * - * @param string $id Identifier of the entry to look for. - * - * @throws ContainerValueNotFoundException No entry was found for this identifier. - * @throws ContainerException Error while retrieving the entry. - * - * @return mixed Entry. - */ - public function get($id) - { - if (!$this->offsetExists($id)) { - throw new ContainerValueNotFoundException(sprintf('Identifier "%s" is not defined.', $id)); - } - try { - return $this->offsetGet($id); - } catch (\InvalidArgumentException $exception) { - if ($this->exceptionThrownByContainer($exception)) { - throw new SlimContainerException( - sprintf('Container error while retrieving "%s"', $id), - null, - $exception - ); - } else { - throw $exception; - } - } - } - - /** - * Tests whether an exception needs to be recast for compliance with Container-Interop. This will be if the - * exception was thrown by Pimple. - * - * @param \InvalidArgumentException $exception - * - * @return bool - */ - private function exceptionThrownByContainer(\InvalidArgumentException $exception) - { - $trace = $exception->getTrace()[0]; - - return $trace['class'] === PimpleContainer::class && $trace['function'] === 'offsetGet'; - } - - /** - * Returns true if the container can return an entry for the given identifier. - * Returns false otherwise. - * - * @param string $id Identifier of the entry to look for. - * - * @return boolean - */ - public function has($id) - { - return $this->offsetExists($id); - } - - - /******************************************************************************** - * Magic methods for convenience - *******************************************************************************/ - - public function __get($name) - { - return $this->get($name); - } - - public function __isset($name) - { - return $this->has($name); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/DefaultServicesProvider.php b/advancedcontentfilter/vendor/slim/slim/Slim/DefaultServicesProvider.php deleted file mode 100644 index 13fe1fb3..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/DefaultServicesProvider.php +++ /dev/null @@ -1,211 +0,0 @@ -get('environment')); - }; - } - - if (!isset($container['response'])) { - /** - * PSR-7 Response object - * - * @param Container $container - * - * @return ResponseInterface - */ - $container['response'] = function ($container) { - $headers = new Headers(['Content-Type' => 'text/html; charset=UTF-8']); - $response = new Response(200, $headers); - - return $response->withProtocolVersion($container->get('settings')['httpVersion']); - }; - } - - if (!isset($container['router'])) { - /** - * This service MUST return a SHARED instance - * of \Slim\Interfaces\RouterInterface. - * - * @param Container $container - * - * @return RouterInterface - */ - $container['router'] = function ($container) { - $routerCacheFile = false; - if (isset($container->get('settings')['routerCacheFile'])) { - $routerCacheFile = $container->get('settings')['routerCacheFile']; - } - - - $router = (new Router)->setCacheFile($routerCacheFile); - if (method_exists($router, 'setContainer')) { - $router->setContainer($container); - } - - return $router; - }; - } - - if (!isset($container['foundHandler'])) { - /** - * This service MUST return a SHARED instance - * of \Slim\Interfaces\InvocationStrategyInterface. - * - * @return InvocationStrategyInterface - */ - $container['foundHandler'] = function () { - return new RequestResponse; - }; - } - - if (!isset($container['phpErrorHandler'])) { - /** - * This service MUST return a callable - * that accepts three arguments: - * - * 1. Instance of \Psr\Http\Message\ServerRequestInterface - * 2. Instance of \Psr\Http\Message\ResponseInterface - * 3. Instance of \Error - * - * The callable MUST return an instance of - * \Psr\Http\Message\ResponseInterface. - * - * @param Container $container - * - * @return callable - */ - $container['phpErrorHandler'] = function ($container) { - return new PhpError($container->get('settings')['displayErrorDetails']); - }; - } - - if (!isset($container['errorHandler'])) { - /** - * This service MUST return a callable - * that accepts three arguments: - * - * 1. Instance of \Psr\Http\Message\ServerRequestInterface - * 2. Instance of \Psr\Http\Message\ResponseInterface - * 3. Instance of \Exception - * - * The callable MUST return an instance of - * \Psr\Http\Message\ResponseInterface. - * - * @param Container $container - * - * @return callable - */ - $container['errorHandler'] = function ($container) { - return new Error( - $container->get('settings')['displayErrorDetails'] - ); - }; - } - - if (!isset($container['notFoundHandler'])) { - /** - * This service MUST return a callable - * that accepts two arguments: - * - * 1. Instance of \Psr\Http\Message\ServerRequestInterface - * 2. Instance of \Psr\Http\Message\ResponseInterface - * - * The callable MUST return an instance of - * \Psr\Http\Message\ResponseInterface. - * - * @return callable - */ - $container['notFoundHandler'] = function () { - return new NotFound; - }; - } - - if (!isset($container['notAllowedHandler'])) { - /** - * This service MUST return a callable - * that accepts three arguments: - * - * 1. Instance of \Psr\Http\Message\ServerRequestInterface - * 2. Instance of \Psr\Http\Message\ResponseInterface - * 3. Array of allowed HTTP methods - * - * The callable MUST return an instance of - * \Psr\Http\Message\ResponseInterface. - * - * @return callable - */ - $container['notAllowedHandler'] = function () { - return new NotAllowed; - }; - } - - if (!isset($container['callableResolver'])) { - /** - * Instance of \Slim\Interfaces\CallableResolverInterface - * - * @param Container $container - * - * @return CallableResolverInterface - */ - $container['callableResolver'] = function ($container) { - return new CallableResolver($container); - }; - } - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/DeferredCallable.php b/advancedcontentfilter/vendor/slim/slim/Slim/DeferredCallable.php deleted file mode 100644 index 22887c0f..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/DeferredCallable.php +++ /dev/null @@ -1,45 +0,0 @@ -callable = $callable; - $this->container = $container; - } - - public function __invoke() - { - $callable = $this->resolveCallable($this->callable); - if ($callable instanceof Closure) { - $callable = $callable->bindTo($this->container); - } - - $args = func_get_args(); - - return call_user_func_array($callable, $args); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Error/AbstractErrorRenderer.php b/advancedcontentfilter/vendor/slim/slim/Slim/Error/AbstractErrorRenderer.php new file mode 100644 index 00000000..90b290d4 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Error/AbstractErrorRenderer.php @@ -0,0 +1,46 @@ +getTitle(); + } + + return $this->defaultErrorTitle; + } + + protected function getErrorDescription(Throwable $exception): string + { + if ($exception instanceof HttpException) { + return $exception->getDescription(); + } + + return $this->defaultErrorDescription; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/HtmlErrorRenderer.php b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/HtmlErrorRenderer.php new file mode 100644 index 00000000..e030522a --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/HtmlErrorRenderer.php @@ -0,0 +1,84 @@ +The application could not run because of the following error:

'; + $html .= '

Details

'; + $html .= $this->renderExceptionFragment($exception); + } else { + $html = "

{$this->getErrorDescription($exception)}

"; + } + + return $this->renderHtmlBody($this->getErrorTitle($exception), $html); + } + + private function renderExceptionFragment(Throwable $exception): string + { + $html = sprintf('
Type: %s
', get_class($exception)); + + /** @var int|string $code */ + $code = $exception->getCode(); + $html .= sprintf('
Code: %s
', $code); + + $html .= sprintf('
Message: %s
', htmlentities($exception->getMessage())); + + $html .= sprintf('
File: %s
', $exception->getFile()); + + $html .= sprintf('
Line: %s
', $exception->getLine()); + + $html .= '

Trace

'; + $html .= sprintf('
%s
', htmlentities($exception->getTraceAsString())); + + return $html; + } + + public function renderHtmlBody(string $title = '', string $html = ''): string + { + return sprintf( + '' . + '' . + ' ' . + ' ' . + ' ' . + ' %s' . + ' ' . + ' ' . + ' ' . + '

%s

' . + '
%s
' . + ' Go Back' . + ' ' . + '', + $title, + $title, + $html + ); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/JsonErrorRenderer.php b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/JsonErrorRenderer.php new file mode 100644 index 00000000..63d905b3 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/JsonErrorRenderer.php @@ -0,0 +1,56 @@ + $this->getErrorTitle($exception)]; + + if ($displayErrorDetails) { + $error['exception'] = []; + do { + $error['exception'][] = $this->formatExceptionFragment($exception); + } while ($exception = $exception->getPrevious()); + } + + return (string) json_encode($error, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + } + + /** + * @return array + */ + private function formatExceptionFragment(Throwable $exception): array + { + /** @var int|string $code */ + $code = $exception->getCode(); + return [ + 'type' => get_class($exception), + 'code' => $code, + 'message' => $exception->getMessage(), + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + ]; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/PlainTextErrorRenderer.php b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/PlainTextErrorRenderer.php new file mode 100644 index 00000000..3d80c74b --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/PlainTextErrorRenderer.php @@ -0,0 +1,59 @@ +getErrorTitle($exception)}\n"; + + if ($displayErrorDetails) { + $text .= $this->formatExceptionFragment($exception); + + while ($exception = $exception->getPrevious()) { + $text .= "\nPrevious Error:\n"; + $text .= $this->formatExceptionFragment($exception); + } + } + + return $text; + } + + private function formatExceptionFragment(Throwable $exception): string + { + $text = sprintf("Type: %s\n", get_class($exception)); + + $code = $exception->getCode(); + /** @var int|string $code */ + $text .= sprintf("Code: %s\n", $code); + + $text .= sprintf("Message: %s\n", htmlentities($exception->getMessage())); + + $text .= sprintf("File: %s\n", $exception->getFile()); + + $text .= sprintf("Line: %s\n", $exception->getLine()); + + $text .= sprintf('Trace: %s', $exception->getTraceAsString()); + + return $text; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/XmlErrorRenderer.php b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/XmlErrorRenderer.php new file mode 100644 index 00000000..1171b79b --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Error/Renderers/XmlErrorRenderer.php @@ -0,0 +1,54 @@ +\n"; + $xml .= "\n " . $this->createCdataSection($this->getErrorTitle($exception)) . "\n"; + + if ($displayErrorDetails) { + do { + $xml .= " \n"; + $xml .= ' ' . get_class($exception) . "\n"; + $xml .= ' ' . $exception->getCode() . "\n"; + $xml .= ' ' . $this->createCdataSection($exception->getMessage()) . "\n"; + $xml .= ' ' . $exception->getFile() . "\n"; + $xml .= ' ' . $exception->getLine() . "\n"; + $xml .= " \n"; + } while ($exception = $exception->getPrevious()); + } + + $xml .= ''; + + return $xml; + } + + /** + * Returns a CDATA section with the given content. + */ + private function createCdataSection(string $content): string + { + return sprintf('', str_replace(']]>', ']]]]>', $content)); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/ContainerException.php b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/ContainerException.php deleted file mode 100644 index 06163f1d..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/ContainerException.php +++ /dev/null @@ -1,20 +0,0 @@ -request = $request; + } + + public function getRequest(): ServerRequestInterface + { + return $this->request; + } + + public function getTitle(): string + { + return $this->title; + } + + public function setTitle(string $title): self + { + $this->title = $title; + return $this; + } + + public function getDescription(): string + { + return $this->description; + } + + public function setDescription(string $description): self + { + $this->description = $description; + return $this; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpForbiddenException.php b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpForbiddenException.php new file mode 100644 index 00000000..dd3bb230 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpForbiddenException.php @@ -0,0 +1,27 @@ +allowedMethods; + } + + /** + * @param string[] $methods + */ + public function setAllowedMethods(array $methods): self + { + $this->allowedMethods = $methods; + $this->message = 'Method not allowed. Must be one of: ' . implode(', ', $methods); + return $this; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpNotFoundException.php b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpNotFoundException.php new file mode 100644 index 00000000..865146d6 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpNotFoundException.php @@ -0,0 +1,27 @@ +message = $message; + } + + parent::__construct($request, $this->message, $this->code, $previous); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpUnauthorizedException.php b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpUnauthorizedException.php new file mode 100644 index 00000000..07bd70d0 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/HttpUnauthorizedException.php @@ -0,0 +1,27 @@ +request = $request; - parent::__construct(sprintf('Unsupported HTTP method "%s" provided', $method)); - } - - public function getRequest() - { - return $this->request; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/MethodNotAllowedException.php b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/MethodNotAllowedException.php deleted file mode 100644 index 951f5dfb..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/MethodNotAllowedException.php +++ /dev/null @@ -1,45 +0,0 @@ -allowedMethods = $allowedMethods; - } - - /** - * Get allowed methods - * - * @return string[] - */ - public function getAllowedMethods() - { - return $this->allowedMethods; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/NotFoundException.php b/advancedcontentfilter/vendor/slim/slim/Slim/Exception/NotFoundException.php deleted file mode 100644 index 9e72e14e..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Exception/NotFoundException.php +++ /dev/null @@ -1,14 +0,0 @@ -request = $request; - $this->response = $response; - } - - /** - * Get request - * - * @return ServerRequestInterface - */ - public function getRequest() - { - return $this->request; - } - - /** - * Get response - * - * @return ResponseInterface - */ - public function getResponse() - { - return $this->response; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Factory/AppFactory.php b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/AppFactory.php new file mode 100644 index 00000000..6fc5f86e --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/AppFactory.php @@ -0,0 +1,206 @@ +has(ResponseFactoryInterface::class) + && ( + $responseFactoryFromContainer = $container->get(ResponseFactoryInterface::class) + ) instanceof ResponseFactoryInterface + ? $responseFactoryFromContainer + : self::determineResponseFactory(); + + $callableResolver = $container->has(CallableResolverInterface::class) + && ( + $callableResolverFromContainer = $container->get(CallableResolverInterface::class) + ) instanceof CallableResolverInterface + ? $callableResolverFromContainer + : null; + + $routeCollector = $container->has(RouteCollectorInterface::class) + && ( + $routeCollectorFromContainer = $container->get(RouteCollectorInterface::class) + ) instanceof RouteCollectorInterface + ? $routeCollectorFromContainer + : null; + + $routeResolver = $container->has(RouteResolverInterface::class) + && ( + $routeResolverFromContainer = $container->get(RouteResolverInterface::class) + ) instanceof RouteResolverInterface + ? $routeResolverFromContainer + : null; + + $middlewareDispatcher = $container->has(MiddlewareDispatcherInterface::class) + && ( + $middlewareDispatcherFromContainer = $container->get(MiddlewareDispatcherInterface::class) + ) instanceof MiddlewareDispatcherInterface + ? $middlewareDispatcherFromContainer + : null; + + return new App( + $responseFactory, + $container, + $callableResolver, + $routeCollector, + $routeResolver, + $middlewareDispatcher + ); + } + + /** + * @throws RuntimeException + */ + public static function determineResponseFactory(): ResponseFactoryInterface + { + if (static::$responseFactory) { + if (static::$streamFactory) { + return static::attemptResponseFactoryDecoration(static::$responseFactory, static::$streamFactory); + } + return static::$responseFactory; + } + + $psr17FactoryProvider = static::$psr17FactoryProvider ?? new Psr17FactoryProvider(); + + /** @var Psr17Factory $psr17factory */ + foreach ($psr17FactoryProvider->getFactories() as $psr17factory) { + if ($psr17factory::isResponseFactoryAvailable()) { + $responseFactory = $psr17factory::getResponseFactory(); + + if (static::$streamFactory || $psr17factory::isStreamFactoryAvailable()) { + $streamFactory = static::$streamFactory ?? $psr17factory::getStreamFactory(); + return static::attemptResponseFactoryDecoration($responseFactory, $streamFactory); + } + + return $responseFactory; + } + } + + throw new RuntimeException( + "Could not detect any PSR-17 ResponseFactory implementations. " . + "Please install a supported implementation in order to use `AppFactory::create()`. " . + "See https://github.com/slimphp/Slim/blob/4.x/README.md for a list of supported implementations." + ); + } + + protected static function attemptResponseFactoryDecoration( + ResponseFactoryInterface $responseFactory, + StreamFactoryInterface $streamFactory + ): ResponseFactoryInterface { + if ( + static::$slimHttpDecoratorsAutomaticDetectionEnabled + && SlimHttpPsr17Factory::isResponseFactoryAvailable() + ) { + return SlimHttpPsr17Factory::createDecoratedResponseFactory($responseFactory, $streamFactory); + } + + return $responseFactory; + } + + public static function setPsr17FactoryProvider(Psr17FactoryProviderInterface $psr17FactoryProvider): void + { + static::$psr17FactoryProvider = $psr17FactoryProvider; + } + + public static function setResponseFactory(ResponseFactoryInterface $responseFactory): void + { + static::$responseFactory = $responseFactory; + } + + public static function setStreamFactory(StreamFactoryInterface $streamFactory): void + { + static::$streamFactory = $streamFactory; + } + + public static function setContainer(ContainerInterface $container): void + { + static::$container = $container; + } + + public static function setCallableResolver(CallableResolverInterface $callableResolver): void + { + static::$callableResolver = $callableResolver; + } + + public static function setRouteCollector(RouteCollectorInterface $routeCollector): void + { + static::$routeCollector = $routeCollector; + } + + public static function setRouteResolver(RouteResolverInterface $routeResolver): void + { + static::$routeResolver = $routeResolver; + } + + public static function setMiddlewareDispatcher(MiddlewareDispatcherInterface $middlewareDispatcher): void + { + static::$middlewareDispatcher = $middlewareDispatcher; + } + + public static function setSlimHttpDecoratorsAutomaticDetection(bool $enabled): void + { + static::$slimHttpDecoratorsAutomaticDetectionEnabled = $enabled; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php new file mode 100644 index 00000000..32a548a6 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/GuzzlePsr17Factory.php @@ -0,0 +1,19 @@ +serverRequestCreator = $serverRequestCreator; + $this->serverRequestCreatorMethod = $serverRequestCreatorMethod; + } + + /** + * {@inheritdoc} + */ + public function createServerRequestFromGlobals(): ServerRequestInterface + { + /** @var callable $callable */ + $callable = [$this->serverRequestCreator, $this->serverRequestCreatorMethod]; + return (Closure::fromCallable($callable))(); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimHttpPsr17Factory.php b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimHttpPsr17Factory.php new file mode 100644 index 00000000..5d636318 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimHttpPsr17Factory.php @@ -0,0 +1,39 @@ +serverRequestCreator = $serverRequestCreator; + } + + /** + * {@inheritdoc} + */ + public function createServerRequestFromGlobals(): ServerRequestInterface + { + if (!static::isServerRequestDecoratorAvailable()) { + throw new RuntimeException('The Slim-Http ServerRequest decorator is not available.'); + } + + $request = $this->serverRequestCreator->createServerRequestFromGlobals(); + + if ( + !(( + $decoratedServerRequest = new static::$serverRequestDecoratorClass($request) + ) instanceof ServerRequestInterface) + ) { + throw new RuntimeException(get_called_class() . ' could not instantiate a decorated server request.'); + } + + return $decoratedServerRequest; + } + + public static function isServerRequestDecoratorAvailable(): bool + { + return class_exists(static::$serverRequestDecoratorClass); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimPsr17Factory.php b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimPsr17Factory.php new file mode 100644 index 00000000..46c46f9c --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Factory/Psr17/SlimPsr17Factory.php @@ -0,0 +1,19 @@ +getFactories() as $psr17Factory) { + if ($psr17Factory::isServerRequestCreatorAvailable()) { + $serverRequestCreator = $psr17Factory::getServerRequestCreator(); + return static::attemptServerRequestCreatorDecoration($serverRequestCreator); + } + } + + throw new RuntimeException( + "Could not detect any ServerRequest creator implementations. " . + "Please install a supported implementation in order to use `App::run()` " . + "without having to pass in a `ServerRequest` object. " . + "See https://github.com/slimphp/Slim/blob/4.x/README.md for a list of supported implementations." + ); + } + + protected static function attemptServerRequestCreatorDecoration( + ServerRequestCreatorInterface $serverRequestCreator + ): ServerRequestCreatorInterface { + if ( + static::$slimHttpDecoratorsAutomaticDetectionEnabled + && SlimHttpServerRequestCreator::isServerRequestDecoratorAvailable() + ) { + return new SlimHttpServerRequestCreator($serverRequestCreator); + } + + return $serverRequestCreator; + } + + public static function setPsr17FactoryProvider(Psr17FactoryProviderInterface $psr17FactoryProvider): void + { + static::$psr17FactoryProvider = $psr17FactoryProvider; + } + + public static function setServerRequestCreator(ServerRequestCreatorInterface $serverRequestCreator): void + { + self::$serverRequestCreator = $serverRequestCreator; + } + + public static function setSlimHttpDecoratorsAutomaticDetection(bool $enabled): void + { + static::$slimHttpDecoratorsAutomaticDetectionEnabled = $enabled; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractError.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractError.php deleted file mode 100644 index 42f8dde3..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractError.php +++ /dev/null @@ -1,99 +0,0 @@ -displayErrorDetails = (bool) $displayErrorDetails; - } - - /** - * Write to the error log if displayErrorDetails is false - * - * @param \Exception|\Throwable $throwable - * - * @return void - */ - protected function writeToErrorLog($throwable) - { - if ($this->displayErrorDetails) { - return; - } - - $message = 'Slim Application Error:' . PHP_EOL; - $message .= $this->renderThrowableAsText($throwable); - while ($throwable = $throwable->getPrevious()) { - $message .= PHP_EOL . 'Previous error:' . PHP_EOL; - $message .= $this->renderThrowableAsText($throwable); - } - - $message .= PHP_EOL . 'View in rendered output by enabling the "displayErrorDetails" setting.' . PHP_EOL; - - $this->logError($message); - } - - /** - * Render error as Text. - * - * @param \Exception|\Throwable $throwable - * - * @return string - */ - protected function renderThrowableAsText($throwable) - { - $text = sprintf('Type: %s' . PHP_EOL, get_class($throwable)); - - if ($code = $throwable->getCode()) { - $text .= sprintf('Code: %s' . PHP_EOL, $code); - } - - if ($message = $throwable->getMessage()) { - $text .= sprintf('Message: %s' . PHP_EOL, htmlentities($message)); - } - - if ($file = $throwable->getFile()) { - $text .= sprintf('File: %s' . PHP_EOL, $file); - } - - if ($line = $throwable->getLine()) { - $text .= sprintf('Line: %s' . PHP_EOL, $line); - } - - if ($trace = $throwable->getTraceAsString()) { - $text .= sprintf('Trace: %s', $trace); - } - - return $text; - } - - /** - * Wraps the error_log function so that this can be easily tested - * - * @param $message - */ - protected function logError($message) - { - error_log($message); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractHandler.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractHandler.php deleted file mode 100644 index b166a156..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/AbstractHandler.php +++ /dev/null @@ -1,59 +0,0 @@ -getHeaderLine('Accept'); - $selectedContentTypes = array_intersect(explode(',', $acceptHeader), $this->knownContentTypes); - - if (count($selectedContentTypes)) { - return current($selectedContentTypes); - } - - // handle +json and +xml specially - if (preg_match('/\+(json|xml)/', $acceptHeader, $matches)) { - $mediaType = 'application/' . $matches[1]; - if (in_array($mediaType, $this->knownContentTypes)) { - return $mediaType; - } - } - - return 'text/html'; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Error.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Error.php deleted file mode 100644 index dd0bc8d4..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Error.php +++ /dev/null @@ -1,224 +0,0 @@ -determineContentType($request); - switch ($contentType) { - case 'application/json': - $output = $this->renderJsonErrorMessage($exception); - break; - - case 'text/xml': - case 'application/xml': - $output = $this->renderXmlErrorMessage($exception); - break; - - case 'text/html': - $output = $this->renderHtmlErrorMessage($exception); - break; - - default: - throw new UnexpectedValueException('Cannot render unknown content type ' . $contentType); - } - - $this->writeToErrorLog($exception); - - $body = new Body(fopen('php://temp', 'r+')); - $body->write($output); - - return $response - ->withStatus(500) - ->withHeader('Content-type', $contentType) - ->withBody($body); - } - - /** - * Render HTML error page - * - * @param \Exception $exception - * - * @return string - */ - protected function renderHtmlErrorMessage(\Exception $exception) - { - $title = 'Slim Application Error'; - - if ($this->displayErrorDetails) { - $html = '

The application could not run because of the following error:

'; - $html .= '

Details

'; - $html .= $this->renderHtmlException($exception); - - while ($exception = $exception->getPrevious()) { - $html .= '

Previous exception

'; - $html .= $this->renderHtmlExceptionOrError($exception); - } - } else { - $html = '

A website error has occurred. Sorry for the temporary inconvenience.

'; - } - - $output = sprintf( - "" . - "%s

%s

%s", - $title, - $title, - $html - ); - - return $output; - } - - /** - * Render exception as HTML. - * - * Provided for backwards compatibility; use renderHtmlExceptionOrError(). - * - * @param \Exception $exception - * - * @return string - */ - protected function renderHtmlException(\Exception $exception) - { - return $this->renderHtmlExceptionOrError($exception); - } - - /** - * Render exception or error as HTML. - * - * @param \Exception|\Error $exception - * - * @return string - */ - protected function renderHtmlExceptionOrError($exception) - { - if (!$exception instanceof \Exception && !$exception instanceof \Error) { - throw new \RuntimeException("Unexpected type. Expected Exception or Error."); - } - - $html = sprintf('
Type: %s
', get_class($exception)); - - if (($code = $exception->getCode())) { - $html .= sprintf('
Code: %s
', $code); - } - - if (($message = $exception->getMessage())) { - $html .= sprintf('
Message: %s
', htmlentities($message)); - } - - if (($file = $exception->getFile())) { - $html .= sprintf('
File: %s
', $file); - } - - if (($line = $exception->getLine())) { - $html .= sprintf('
Line: %s
', $line); - } - - if (($trace = $exception->getTraceAsString())) { - $html .= '

Trace

'; - $html .= sprintf('
%s
', htmlentities($trace)); - } - - return $html; - } - - /** - * Render JSON error - * - * @param \Exception $exception - * - * @return string - */ - protected function renderJsonErrorMessage(\Exception $exception) - { - $error = [ - 'message' => 'Slim Application Error', - ]; - - if ($this->displayErrorDetails) { - $error['exception'] = []; - - do { - $error['exception'][] = [ - 'type' => get_class($exception), - 'code' => $exception->getCode(), - 'message' => $exception->getMessage(), - 'file' => $exception->getFile(), - 'line' => $exception->getLine(), - 'trace' => explode("\n", $exception->getTraceAsString()), - ]; - } while ($exception = $exception->getPrevious()); - } - - return json_encode($error, JSON_PRETTY_PRINT); - } - - /** - * Render XML error - * - * @param \Exception $exception - * - * @return string - */ - protected function renderXmlErrorMessage(\Exception $exception) - { - $xml = "\n Slim Application Error\n"; - if ($this->displayErrorDetails) { - do { - $xml .= " \n"; - $xml .= " " . get_class($exception) . "\n"; - $xml .= " " . $exception->getCode() . "\n"; - $xml .= " " . $this->createCdataSection($exception->getMessage()) . "\n"; - $xml .= " " . $exception->getFile() . "\n"; - $xml .= " " . $exception->getLine() . "\n"; - $xml .= " " . $this->createCdataSection($exception->getTraceAsString()) . "\n"; - $xml .= " \n"; - } while ($exception = $exception->getPrevious()); - } - $xml .= ""; - - return $xml; - } - - /** - * Returns a CDATA section with the given content. - * - * @param string $content - * @return string - */ - private function createCdataSection($content) - { - return sprintf('', str_replace(']]>', ']]]]>', $content)); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/ErrorHandler.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/ErrorHandler.php new file mode 100644 index 00000000..f9606e36 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/ErrorHandler.php @@ -0,0 +1,308 @@ + + */ + protected array $errorRenderers = [ + 'application/json' => JsonErrorRenderer::class, + 'application/xml' => XmlErrorRenderer::class, + 'text/xml' => XmlErrorRenderer::class, + 'text/html' => HtmlErrorRenderer::class, + 'text/plain' => PlainTextErrorRenderer::class, + ]; + + protected bool $displayErrorDetails = false; + + protected bool $logErrors; + + protected bool $logErrorDetails = false; + + protected ?string $contentType = null; + + protected ?string $method = null; + + protected ServerRequestInterface $request; + + protected Throwable $exception; + + protected int $statusCode; + + protected CallableResolverInterface $callableResolver; + + protected ResponseFactoryInterface $responseFactory; + + protected LoggerInterface $logger; + + public function __construct( + CallableResolverInterface $callableResolver, + ResponseFactoryInterface $responseFactory, + ?LoggerInterface $logger = null + ) { + $this->callableResolver = $callableResolver; + $this->responseFactory = $responseFactory; + $this->logger = $logger ?: $this->getDefaultLogger(); + } + + /** + * Invoke error handler + * + * @param ServerRequestInterface $request The most recent Request object + * @param Throwable $exception The caught Exception object + * @param bool $displayErrorDetails Whether or not to display the error details + * @param bool $logErrors Whether or not to log errors + * @param bool $logErrorDetails Whether or not to log error details + */ + public function __invoke( + ServerRequestInterface $request, + Throwable $exception, + bool $displayErrorDetails, + bool $logErrors, + bool $logErrorDetails + ): ResponseInterface { + $this->displayErrorDetails = $displayErrorDetails; + $this->logErrors = $logErrors; + $this->logErrorDetails = $logErrorDetails; + $this->request = $request; + $this->exception = $exception; + $this->method = $request->getMethod(); + $this->statusCode = $this->determineStatusCode(); + if ($this->contentType === null) { + $this->contentType = $this->determineContentType($request); + } + + if ($logErrors) { + $this->writeToErrorLog(); + } + + return $this->respond(); + } + + /** + * Force the content type for all error handler responses. + * + * @param string|null $contentType The content type + */ + public function forceContentType(?string $contentType): void + { + $this->contentType = $contentType; + } + + protected function determineStatusCode(): int + { + if ($this->method === 'OPTIONS') { + return 200; + } + + if ($this->exception instanceof HttpException) { + return $this->exception->getCode(); + } + + return 500; + } + + /** + * Determine which content type we know about is wanted using Accept header + * + * Note: This method is a bare-bones implementation designed specifically for + * Slim's error handling requirements. Consider a fully-feature solution such + * as willdurand/negotiation for any other situation. + */ + protected function determineContentType(ServerRequestInterface $request): ?string + { + $acceptHeader = $request->getHeaderLine('Accept'); + $selectedContentTypes = array_intersect( + explode(',', $acceptHeader), + array_keys($this->errorRenderers) + ); + $count = count($selectedContentTypes); + + if ($count) { + $current = current($selectedContentTypes); + + /** + * Ensure other supported content types take precedence over text/plain + * when multiple content types are provided via Accept header. + */ + if ($current === 'text/plain' && $count > 1) { + $next = next($selectedContentTypes); + if (is_string($next)) { + return $next; + } + } + + if (is_string($current)) { + return $current; + } + } + + if (preg_match('/\+(json|xml)/', $acceptHeader, $matches)) { + $mediaType = 'application/' . $matches[1]; + if (array_key_exists($mediaType, $this->errorRenderers)) { + return $mediaType; + } + } + + return null; + } + + /** + * Determine which renderer to use based on content type + * + * @throws RuntimeException + */ + protected function determineRenderer(): callable + { + if ($this->contentType !== null && array_key_exists($this->contentType, $this->errorRenderers)) { + $renderer = $this->errorRenderers[$this->contentType]; + } else { + $renderer = $this->defaultErrorRenderer; + } + + return $this->callableResolver->resolve($renderer); + } + + /** + * Register an error renderer for a specific content-type + * + * @param string $contentType The content-type this renderer should be registered to + * @param ErrorRendererInterface|string|callable $errorRenderer The error renderer + */ + public function registerErrorRenderer(string $contentType, $errorRenderer): void + { + $this->errorRenderers[$contentType] = $errorRenderer; + } + + /** + * Set the default error renderer + * + * @param string $contentType The content type of the default error renderer + * @param ErrorRendererInterface|string|callable $errorRenderer The default error renderer + */ + public function setDefaultErrorRenderer(string $contentType, $errorRenderer): void + { + $this->defaultErrorRendererContentType = $contentType; + $this->defaultErrorRenderer = $errorRenderer; + } + + /** + * Set the renderer for the error logger + * + * @param ErrorRendererInterface|string|callable $logErrorRenderer + */ + public function setLogErrorRenderer($logErrorRenderer): void + { + $this->logErrorRenderer = $logErrorRenderer; + } + + /** + * Write to the error log if $logErrors has been set to true + */ + protected function writeToErrorLog(): void + { + $renderer = $this->callableResolver->resolve($this->logErrorRenderer); + $error = $renderer($this->exception, $this->logErrorDetails); + if (!$this->displayErrorDetails) { + $error .= "\nTips: To display error details in HTTP response "; + $error .= 'set "displayErrorDetails" to true in the ErrorHandler constructor.'; + } + $this->logError($error); + } + + /** + * Wraps the error_log function so that this can be easily tested + */ + protected function logError(string $error): void + { + $this->logger->error($error); + } + + /** + * Returns a default logger implementation. + */ + protected function getDefaultLogger(): LoggerInterface + { + return new Logger(); + } + + protected function respond(): ResponseInterface + { + $response = $this->responseFactory->createResponse($this->statusCode); + if ($this->contentType !== null && array_key_exists($this->contentType, $this->errorRenderers)) { + $response = $response->withHeader('Content-type', $this->contentType); + } else { + $response = $response->withHeader('Content-type', $this->defaultErrorRendererContentType); + } + + if ($this->exception instanceof HttpMethodNotAllowedException) { + $allowedMethods = implode(', ', $this->exception->getAllowedMethods()); + $response = $response->withHeader('Allow', $allowedMethods); + } + + $renderer = $this->determineRenderer(); + $body = call_user_func($renderer, $this->exception, $this->displayErrorDetails); + if ($body !== false) { + /** @var string $body */ + $response->getBody()->write($body); + } + + return $response; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotAllowed.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotAllowed.php deleted file mode 100644 index 345f0ff8..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotAllowed.php +++ /dev/null @@ -1,147 +0,0 @@ -getMethod() === 'OPTIONS') { - $status = 200; - $contentType = 'text/plain'; - $output = $this->renderPlainOptionsMessage($methods); - } else { - $status = 405; - $contentType = $this->determineContentType($request); - switch ($contentType) { - case 'application/json': - $output = $this->renderJsonNotAllowedMessage($methods); - break; - - case 'text/xml': - case 'application/xml': - $output = $this->renderXmlNotAllowedMessage($methods); - break; - - case 'text/html': - $output = $this->renderHtmlNotAllowedMessage($methods); - break; - default: - throw new UnexpectedValueException('Cannot render unknown content type ' . $contentType); - } - } - - $body = new Body(fopen('php://temp', 'r+')); - $body->write($output); - $allow = implode(', ', $methods); - - return $response - ->withStatus($status) - ->withHeader('Content-type', $contentType) - ->withHeader('Allow', $allow) - ->withBody($body); - } - - /** - * Render PLAIN message for OPTIONS response - * - * @param array $methods - * @return string - */ - protected function renderPlainOptionsMessage($methods) - { - $allow = implode(', ', $methods); - - return 'Allowed methods: ' . $allow; - } - - /** - * Render JSON not allowed message - * - * @param array $methods - * @return string - */ - protected function renderJsonNotAllowedMessage($methods) - { - $allow = implode(', ', $methods); - - return '{"message":"Method not allowed. Must be one of: ' . $allow . '"}'; - } - - /** - * Render XML not allowed message - * - * @param array $methods - * @return string - */ - protected function renderXmlNotAllowedMessage($methods) - { - $allow = implode(', ', $methods); - - return "Method not allowed. Must be one of: $allow"; - } - - /** - * Render HTML not allowed message - * - * @param array $methods - * @return string - */ - protected function renderHtmlNotAllowedMessage($methods) - { - $allow = implode(', ', $methods); - $output = << - - Method not allowed - - - -

Method not allowed

-

Method not allowed. Must be one of: $allow

- - -END; - - return $output; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotFound.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotFound.php deleted file mode 100644 index b3330321..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/NotFound.php +++ /dev/null @@ -1,141 +0,0 @@ -getMethod() === 'OPTIONS') { - $contentType = 'text/plain'; - $output = $this->renderPlainNotFoundOutput(); - } else { - $contentType = $this->determineContentType($request); - switch ($contentType) { - case 'application/json': - $output = $this->renderJsonNotFoundOutput(); - break; - - case 'text/xml': - case 'application/xml': - $output = $this->renderXmlNotFoundOutput(); - break; - - case 'text/html': - $output = $this->renderHtmlNotFoundOutput($request); - break; - - default: - throw new UnexpectedValueException('Cannot render unknown content type ' . $contentType); - } - } - - $body = new Body(fopen('php://temp', 'r+')); - $body->write($output); - - return $response->withStatus(404) - ->withHeader('Content-Type', $contentType) - ->withBody($body); - } - - /** - * Render plain not found message - * - * @return ResponseInterface - */ - protected function renderPlainNotFoundOutput() - { - return 'Not found'; - } - - /** - * Return a response for application/json content not found - * - * @return ResponseInterface - */ - protected function renderJsonNotFoundOutput() - { - return '{"message":"Not found"}'; - } - - /** - * Return a response for xml content not found - * - * @return ResponseInterface - */ - protected function renderXmlNotFoundOutput() - { - return 'Not found'; - } - - /** - * Return a response for text/html content not found - * - * @param ServerRequestInterface $request The most recent Request object - * - * @return ResponseInterface - */ - protected function renderHtmlNotFoundOutput(ServerRequestInterface $request) - { - $homeUrl = (string)($request->getUri()->withPath('')->withQuery('')->withFragment('')); - return << - - Page Not Found - - - -

Page Not Found

-

- The page you are looking for could not be found. Check the address bar - to ensure your URL is spelled correctly. If all else fails, you can - visit our home page at the link below. -

- Visit the Home Page - - -END; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/PhpError.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/PhpError.php deleted file mode 100644 index 3ecce30c..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/PhpError.php +++ /dev/null @@ -1,205 +0,0 @@ -determineContentType($request); - switch ($contentType) { - case 'application/json': - $output = $this->renderJsonErrorMessage($error); - break; - - case 'text/xml': - case 'application/xml': - $output = $this->renderXmlErrorMessage($error); - break; - - case 'text/html': - $output = $this->renderHtmlErrorMessage($error); - break; - default: - throw new UnexpectedValueException('Cannot render unknown content type ' . $contentType); - } - - $this->writeToErrorLog($error); - - $body = new Body(fopen('php://temp', 'r+')); - $body->write($output); - - return $response - ->withStatus(500) - ->withHeader('Content-type', $contentType) - ->withBody($body); - } - - /** - * Render HTML error page - * - * @param \Throwable $error - * - * @return string - */ - protected function renderHtmlErrorMessage(\Throwable $error) - { - $title = 'Slim Application Error'; - - if ($this->displayErrorDetails) { - $html = '

The application could not run because of the following error:

'; - $html .= '

Details

'; - $html .= $this->renderHtmlError($error); - - while ($error = $error->getPrevious()) { - $html .= '

Previous error

'; - $html .= $this->renderHtmlError($error); - } - } else { - $html = '

A website error has occurred. Sorry for the temporary inconvenience.

'; - } - - $output = sprintf( - "" . - "%s

%s

%s", - $title, - $title, - $html - ); - - return $output; - } - - /** - * Render error as HTML. - * - * @param \Throwable $error - * - * @return string - */ - protected function renderHtmlError(\Throwable $error) - { - $html = sprintf('
Type: %s
', get_class($error)); - - if (($code = $error->getCode())) { - $html .= sprintf('
Code: %s
', $code); - } - - if (($message = $error->getMessage())) { - $html .= sprintf('
Message: %s
', htmlentities($message)); - } - - if (($file = $error->getFile())) { - $html .= sprintf('
File: %s
', $file); - } - - if (($line = $error->getLine())) { - $html .= sprintf('
Line: %s
', $line); - } - - if (($trace = $error->getTraceAsString())) { - $html .= '

Trace

'; - $html .= sprintf('
%s
', htmlentities($trace)); - } - - return $html; - } - - /** - * Render JSON error - * - * @param \Throwable $error - * - * @return string - */ - protected function renderJsonErrorMessage(\Throwable $error) - { - $json = [ - 'message' => 'Slim Application Error', - ]; - - if ($this->displayErrorDetails) { - $json['error'] = []; - - do { - $json['error'][] = [ - 'type' => get_class($error), - 'code' => $error->getCode(), - 'message' => $error->getMessage(), - 'file' => $error->getFile(), - 'line' => $error->getLine(), - 'trace' => explode("\n", $error->getTraceAsString()), - ]; - } while ($error = $error->getPrevious()); - } - - return json_encode($json, JSON_PRETTY_PRINT); - } - - /** - * Render XML error - * - * @param \Throwable $error - * - * @return string - */ - protected function renderXmlErrorMessage(\Throwable $error) - { - $xml = "\n Slim Application Error\n"; - if ($this->displayErrorDetails) { - do { - $xml .= " \n"; - $xml .= " " . get_class($error) . "\n"; - $xml .= " " . $error->getCode() . "\n"; - $xml .= " " . $this->createCdataSection($error->getMessage()) . "\n"; - $xml .= " " . $error->getFile() . "\n"; - $xml .= " " . $error->getLine() . "\n"; - $xml .= " " . $this->createCdataSection($error->getTraceAsString()) . "\n"; - $xml .= " \n"; - } while ($error = $error->getPrevious()); - } - $xml .= ""; - - return $xml; - } - - /** - * Returns a CDATA section with the given content. - * - * @param string $content - * @return string - */ - private function createCdataSection($content) - { - return sprintf('', str_replace(']]>', ']]]]>', $content)); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestHandler.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestHandler.php new file mode 100644 index 00000000..ea88a5f1 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestHandler.php @@ -0,0 +1,48 @@ +appendRouteArgumentsToRequestAttributes = $appendRouteArgumentsToRequestAttributes; + } + + /** + * Invoke a route callable that implements RequestHandlerInterface + * + * @param array $routeArguments + */ + public function __invoke( + callable $callable, + ServerRequestInterface $request, + ResponseInterface $response, + array $routeArguments + ): ResponseInterface { + if ($this->appendRouteArgumentsToRequestAttributes) { + foreach ($routeArguments as $k => $v) { + $request = $request->withAttribute($k, $v); + } + } + + return $callable($request); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php index ad99b56e..45b2c05a 100644 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php @@ -1,11 +1,13 @@ $routeArguments */ public function __invoke( callable $callable, ServerRequestInterface $request, ResponseInterface $response, array $routeArguments - ) { + ): ResponseInterface { foreach ($routeArguments as $k => $v) { $request = $request->withAttribute($k, $v); } - return call_user_func($callable, $request, $response, $routeArguments); + return $callable($request, $response, $routeArguments); } } diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseArgs.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseArgs.php index 739cc7ee..c4ab16df 100644 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseArgs.php +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseArgs.php @@ -1,42 +1,38 @@ $routeArguments */ public function __invoke( callable $callable, ServerRequestInterface $request, ResponseInterface $response, array $routeArguments - ) { - array_unshift($routeArguments, $request, $response); - - return call_user_func_array($callable, $routeArguments); + ): ResponseInterface { + return $callable($request, $response, ...array_values($routeArguments)); } } diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseNamedArgs.php b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseNamedArgs.php new file mode 100644 index 00000000..651111dd --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponseNamedArgs.php @@ -0,0 +1,44 @@ += 8.0.0'); + } + } + + /** + * Invoke a route callable with request, response and all route parameters + * as individual arguments. + * + * @param array $routeArguments + */ + public function __invoke( + callable $callable, + ServerRequestInterface $request, + ResponseInterface $response, + array $routeArguments + ): ResponseInterface { + return $callable($request, $response, ...$routeArguments); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Body.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Body.php deleted file mode 100644 index 7a7b4df8..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Body.php +++ /dev/null @@ -1,22 +0,0 @@ - '', - 'domain' => null, - 'hostonly' => null, - 'path' => null, - 'expires' => null, - 'secure' => false, - 'httponly' => false - ]; - - /** - * Create new cookies helper - * - * @param array $cookies - */ - public function __construct(array $cookies = []) - { - $this->requestCookies = $cookies; - } - - /** - * Set default cookie properties - * - * @param array $settings - */ - public function setDefaults(array $settings) - { - $this->defaults = array_replace($this->defaults, $settings); - } - - /** - * Get request cookie - * - * @param string $name Cookie name - * @param mixed $default Cookie default value - * - * @return mixed Cookie value if present, else default - */ - public function get($name, $default = null) - { - return isset($this->requestCookies[$name]) ? $this->requestCookies[$name] : $default; - } - - /** - * Set response cookie - * - * @param string $name Cookie name - * @param string|array $value Cookie value, or cookie properties - */ - public function set($name, $value) - { - if (!is_array($value)) { - $value = ['value' => (string)$value]; - } - $this->responseCookies[$name] = array_replace($this->defaults, $value); - } - - /** - * Convert to `Set-Cookie` headers - * - * @return string[] - */ - public function toHeaders() - { - $headers = []; - foreach ($this->responseCookies as $name => $properties) { - $headers[] = $this->toHeader($name, $properties); - } - - return $headers; - } - - /** - * Convert to `Set-Cookie` header - * - * @param string $name Cookie name - * @param array $properties Cookie properties - * - * @return string - */ - protected function toHeader($name, array $properties) - { - $result = urlencode($name) . '=' . urlencode($properties['value']); - - if (isset($properties['domain'])) { - $result .= '; domain=' . $properties['domain']; - } - - if (isset($properties['path'])) { - $result .= '; path=' . $properties['path']; - } - - if (isset($properties['expires'])) { - if (is_string($properties['expires'])) { - $timestamp = strtotime($properties['expires']); - } else { - $timestamp = (int)$properties['expires']; - } - if ($timestamp !== 0) { - $result .= '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp); - } - } - - if (isset($properties['secure']) && $properties['secure']) { - $result .= '; secure'; - } - - if (isset($properties['hostonly']) && $properties['hostonly']) { - $result .= '; HostOnly'; - } - - if (isset($properties['httponly']) && $properties['httponly']) { - $result .= '; HttpOnly'; - } - - return $result; - } - - /** - * Parse HTTP request `Cookie:` header and extract - * into a PHP associative array. - * - * @param string $header The raw HTTP request `Cookie:` header - * - * @return array Associative array of cookie names and values - * - * @throws InvalidArgumentException if the cookie data cannot be parsed - */ - public static function parseHeader($header) - { - if (is_array($header) === true) { - $header = isset($header[0]) ? $header[0] : ''; - } - - if (is_string($header) === false) { - throw new InvalidArgumentException('Cannot parse Cookie data. Header value must be a string.'); - } - - $header = rtrim($header, "\r\n"); - $pieces = preg_split('@[;]\s*@', $header); - $cookies = []; - - foreach ($pieces as $cookie) { - $cookie = explode('=', $cookie, 2); - - if (count($cookie) === 2) { - $key = urldecode($cookie[0]); - $value = urldecode($cookie[1]); - - if (!isset($cookies[$key])) { - $cookies[$key] = $value; - } - } - } - - return $cookies; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Environment.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Environment.php deleted file mode 100644 index cd452fcf..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Environment.php +++ /dev/null @@ -1,63 +0,0 @@ - 'HTTP/1.1', - 'REQUEST_METHOD' => 'GET', - 'REQUEST_SCHEME' => $defscheme, - 'SCRIPT_NAME' => '', - 'REQUEST_URI' => '', - 'QUERY_STRING' => '', - 'SERVER_NAME' => 'localhost', - 'SERVER_PORT' => $defport, - 'HTTP_HOST' => 'localhost', - 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', - 'HTTP_ACCEPT_LANGUAGE' => 'en-US,en;q=0.8', - 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3', - 'HTTP_USER_AGENT' => 'Slim Framework', - 'REMOTE_ADDR' => '127.0.0.1', - 'REQUEST_TIME' => time(), - 'REQUEST_TIME_FLOAT' => microtime(true), - ], $userData); - - return new static($data); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Headers.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Headers.php deleted file mode 100644 index ef50f84b..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Headers.php +++ /dev/null @@ -1,222 +0,0 @@ - 1, - 'CONTENT_LENGTH' => 1, - 'PHP_AUTH_USER' => 1, - 'PHP_AUTH_PW' => 1, - 'PHP_AUTH_DIGEST' => 1, - 'AUTH_TYPE' => 1, - ]; - - /** - * Create new headers collection with data extracted from - * the application Environment object - * - * @param Environment $environment The Slim application Environment - * - * @return self - */ - public static function createFromEnvironment(Environment $environment) - { - $data = []; - $environment = self::determineAuthorization($environment); - foreach ($environment as $key => $value) { - $key = strtoupper($key); - if (isset(static::$special[$key]) || strpos($key, 'HTTP_') === 0) { - if ($key !== 'HTTP_CONTENT_LENGTH') { - $data[$key] = $value; - } - } - } - - return new static($data); - } - - /** - * If HTTP_AUTHORIZATION does not exist tries to get it from - * getallheaders() when available. - * - * @param Environment $environment The Slim application Environment - * - * @return Environment - */ - - public static function determineAuthorization(Environment $environment) - { - $authorization = $environment->get('HTTP_AUTHORIZATION'); - - if (empty($authorization) && is_callable('getallheaders')) { - $headers = getallheaders(); - $headers = array_change_key_case($headers, CASE_LOWER); - if (isset($headers['authorization'])) { - $environment->set('HTTP_AUTHORIZATION', $headers['authorization']); - } - } - - return $environment; - } - - /** - * Return array of HTTP header names and values. - * This method returns the _original_ header name - * as specified by the end user. - * - * @return array - */ - public function all() - { - $all = parent::all(); - $out = []; - foreach ($all as $key => $props) { - $out[$props['originalKey']] = $props['value']; - } - - return $out; - } - - /** - * Set HTTP header value - * - * This method sets a header value. It replaces - * any values that may already exist for the header name. - * - * @param string $key The case-insensitive header name - * @param string $value The header value - */ - public function set($key, $value) - { - if (!is_array($value)) { - $value = [$value]; - } - parent::set($this->normalizeKey($key), [ - 'value' => $value, - 'originalKey' => $key - ]); - } - - /** - * Get HTTP header value - * - * @param string $key The case-insensitive header name - * @param mixed $default The default value if key does not exist - * - * @return string[] - */ - public function get($key, $default = null) - { - if ($this->has($key)) { - return parent::get($this->normalizeKey($key))['value']; - } - - return $default; - } - - /** - * Get HTTP header key as originally specified - * - * @param string $key The case-insensitive header name - * @param mixed $default The default value if key does not exist - * - * @return string - */ - public function getOriginalKey($key, $default = null) - { - if ($this->has($key)) { - return parent::get($this->normalizeKey($key))['originalKey']; - } - - return $default; - } - - /** - * Add HTTP header value - * - * This method appends a header value. Unlike the set() method, - * this method _appends_ this new value to any values - * that already exist for this header name. - * - * @param string $key The case-insensitive header name - * @param array|string $value The new header value(s) - */ - public function add($key, $value) - { - $oldValues = $this->get($key, []); - $newValues = is_array($value) ? $value : [$value]; - $this->set($key, array_merge($oldValues, array_values($newValues))); - } - - /** - * Does this collection have a given header? - * - * @param string $key The case-insensitive header name - * - * @return bool - */ - public function has($key) - { - return parent::has($this->normalizeKey($key)); - } - - /** - * Remove header from collection - * - * @param string $key The case-insensitive header name - */ - public function remove($key) - { - parent::remove($this->normalizeKey($key)); - } - - /** - * Normalize header name - * - * This method transforms header names into a - * normalized form. This is how we enable case-insensitive - * header names in the other methods in this class. - * - * @param string $key The case-insensitive header name - * - * @return string Normalized header name - */ - public function normalizeKey($key) - { - $key = strtr(strtolower($key), '_', '-'); - if (strpos($key, 'http-') === 0) { - $key = substr($key, 5); - } - - return $key; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Message.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Message.php deleted file mode 100644 index 9195fb5b..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Message.php +++ /dev/null @@ -1,305 +0,0 @@ - true, - '1.1' => true, - '2.0' => true, - '2' => true, - ]; - - /** - * Headers - * - * @var \Slim\Interfaces\Http\HeadersInterface - */ - protected $headers; - - /** - * Body object - * - * @var \Psr\Http\Message\StreamInterface - */ - protected $body; - - - /** - * Disable magic setter to ensure immutability - */ - public function __set($name, $value) - { - // Do nothing - } - - /******************************************************************************* - * Protocol - ******************************************************************************/ - - /** - * Retrieves the HTTP protocol version as a string. - * - * The string MUST contain only the HTTP version number (e.g., "1.1", "1.0"). - * - * @return string HTTP protocol version. - */ - public function getProtocolVersion() - { - return $this->protocolVersion; - } - - /** - * Return an instance with the specified HTTP protocol version. - * - * The version string MUST contain only the HTTP version number (e.g., - * "1.1", "1.0"). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new protocol version. - * - * @param string $version HTTP protocol version - * @return static - * @throws InvalidArgumentException if the http version is an invalid number - */ - public function withProtocolVersion($version) - { - if (!isset(self::$validProtocolVersions[$version])) { - throw new InvalidArgumentException( - 'Invalid HTTP version. Must be one of: ' - . implode(', ', array_keys(self::$validProtocolVersions)) - ); - } - $clone = clone $this; - $clone->protocolVersion = $version; - - return $clone; - } - - /******************************************************************************* - * Headers - ******************************************************************************/ - - /** - * Retrieves all message header values. - * - * The keys represent the header name as it will be sent over the wire, and - * each value is an array of strings associated with the header. - * - * // Represent the headers as a string - * foreach ($message->getHeaders() as $name => $values) { - * echo $name . ": " . implode(", ", $values); - * } - * - * // Emit headers iteratively: - * foreach ($message->getHeaders() as $name => $values) { - * foreach ($values as $value) { - * header(sprintf('%s: %s', $name, $value), false); - * } - * } - * - * While header names are not case-sensitive, getHeaders() will preserve the - * exact case in which headers were originally specified. - * - * @return array Returns an associative array of the message's headers. Each - * key MUST be a header name, and each value MUST be an array of strings - * for that header. - */ - public function getHeaders() - { - return $this->headers->all(); - } - - /** - * Checks if a header exists by the given case-insensitive name. - * - * @param string $name Case-insensitive header field name. - * @return bool Returns true if any header names match the given header - * name using a case-insensitive string comparison. Returns false if - * no matching header name is found in the message. - */ - public function hasHeader($name) - { - return $this->headers->has($name); - } - - /** - * Retrieves a message header value by the given case-insensitive name. - * - * This method returns an array of all the header values of the given - * case-insensitive header name. - * - * If the header does not appear in the message, this method MUST return an - * empty array. - * - * @param string $name Case-insensitive header field name. - * @return string[] An array of string values as provided for the given - * header. If the header does not appear in the message, this method MUST - * return an empty array. - */ - public function getHeader($name) - { - return $this->headers->get($name, []); - } - - /** - * Retrieves a comma-separated string of the values for a single header. - * - * This method returns all of the header values of the given - * case-insensitive header name as a string concatenated together using - * a comma. - * - * NOTE: Not all header values may be appropriately represented using - * comma concatenation. For such headers, use getHeader() instead - * and supply your own delimiter when concatenating. - * - * If the header does not appear in the message, this method MUST return - * an empty string. - * - * @param string $name Case-insensitive header field name. - * @return string A string of values as provided for the given header - * concatenated together using a comma. If the header does not appear in - * the message, this method MUST return an empty string. - */ - public function getHeaderLine($name) - { - return implode(',', $this->headers->get($name, [])); - } - - /** - * Return an instance with the provided value replacing the specified header. - * - * While header names are case-insensitive, the casing of the header will - * be preserved by this function, and returned from getHeaders(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new and/or updated header and value. - * - * @param string $name Case-insensitive header field name. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withHeader($name, $value) - { - $clone = clone $this; - $clone->headers->set($name, $value); - - return $clone; - } - - /** - * Return an instance with the specified header appended with the given value. - * - * Existing values for the specified header will be maintained. The new - * value(s) will be appended to the existing list. If the header did not - * exist previously, it will be added. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new header and/or value. - * - * @param string $name Case-insensitive header field name to add. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withAddedHeader($name, $value) - { - $clone = clone $this; - $clone->headers->add($name, $value); - - return $clone; - } - - /** - * Return an instance without the specified header. - * - * Header resolution MUST be done without case-sensitivity. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the named header. - * - * @param string $name Case-insensitive header field name to remove. - * @return static - */ - public function withoutHeader($name) - { - $clone = clone $this; - $clone->headers->remove($name); - - return $clone; - } - - /******************************************************************************* - * Body - ******************************************************************************/ - - /** - * Gets the body of the message. - * - * @return StreamInterface Returns the body as a stream. - */ - public function getBody() - { - return $this->body; - } - - /** - * Return an instance with the specified message body. - * - * The body MUST be a StreamInterface object. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return a new instance that has the - * new body stream. - * - * @param StreamInterface $body Body. - * @return static - * @throws \InvalidArgumentException When the body is not valid. - */ - public function withBody(StreamInterface $body) - { - // TODO: Test for invalid body? - $clone = clone $this; - $clone->body = $body; - - return $clone; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Request.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Request.php deleted file mode 100644 index 4bea07e9..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Request.php +++ /dev/null @@ -1,1227 +0,0 @@ - 1, - 'DELETE' => 1, - 'GET' => 1, - 'HEAD' => 1, - 'OPTIONS' => 1, - 'PATCH' => 1, - 'POST' => 1, - 'PUT' => 1, - 'TRACE' => 1, - ]; - - /** - * Create new HTTP request with data extracted from the application - * Environment object - * - * @param Environment $environment The Slim application Environment - * - * @return static - */ - public static function createFromEnvironment(Environment $environment) - { - $method = $environment['REQUEST_METHOD']; - $uri = Uri::createFromEnvironment($environment); - $headers = Headers::createFromEnvironment($environment); - $cookies = Cookies::parseHeader($headers->get('Cookie', [])); - $serverParams = $environment->all(); - $body = new RequestBody(); - $uploadedFiles = UploadedFile::createFromEnvironment($environment); - - $request = new static($method, $uri, $headers, $cookies, $serverParams, $body, $uploadedFiles); - - if ($method === 'POST' && - in_array($request->getMediaType(), ['application/x-www-form-urlencoded', 'multipart/form-data']) - ) { - // parsed body must be $_POST - $request = $request->withParsedBody($_POST); - } - return $request; - } - - /** - * Create new HTTP request. - * - * Adds a host header when none was provided and a host is defined in uri. - * - * @param string $method The request method - * @param UriInterface $uri The request URI object - * @param HeadersInterface $headers The request headers collection - * @param array $cookies The request cookies collection - * @param array $serverParams The server environment variables - * @param StreamInterface $body The request body object - * @param array $uploadedFiles The request uploadedFiles collection - * @throws InvalidMethodException on invalid HTTP method - */ - public function __construct( - $method, - UriInterface $uri, - HeadersInterface $headers, - array $cookies, - array $serverParams, - StreamInterface $body, - array $uploadedFiles = [] - ) { - try { - $this->originalMethod = $this->filterMethod($method); - } catch (InvalidMethodException $e) { - $this->originalMethod = $method; - } - - $this->uri = $uri; - $this->headers = $headers; - $this->cookies = $cookies; - $this->serverParams = $serverParams; - $this->attributes = new Collection(); - $this->body = $body; - $this->uploadedFiles = $uploadedFiles; - - if (isset($serverParams['SERVER_PROTOCOL'])) { - $this->protocolVersion = str_replace('HTTP/', '', $serverParams['SERVER_PROTOCOL']); - } - - if (!$this->headers->has('Host') || $this->uri->getHost() !== '') { - $this->headers->set('Host', $this->uri->getHost()); - } - - $this->registerMediaTypeParser('application/json', function ($input) { - $result = json_decode($input, true); - if (!is_array($result)) { - return null; - } - return $result; - }); - - $this->registerMediaTypeParser('application/xml', function ($input) { - $backup = libxml_disable_entity_loader(true); - $backup_errors = libxml_use_internal_errors(true); - $result = simplexml_load_string($input); - libxml_disable_entity_loader($backup); - libxml_clear_errors(); - libxml_use_internal_errors($backup_errors); - if ($result === false) { - return null; - } - return $result; - }); - - $this->registerMediaTypeParser('text/xml', function ($input) { - $backup = libxml_disable_entity_loader(true); - $backup_errors = libxml_use_internal_errors(true); - $result = simplexml_load_string($input); - libxml_disable_entity_loader($backup); - libxml_clear_errors(); - libxml_use_internal_errors($backup_errors); - if ($result === false) { - return null; - } - return $result; - }); - - $this->registerMediaTypeParser('application/x-www-form-urlencoded', function ($input) { - parse_str($input, $data); - return $data; - }); - - // if the request had an invalid method, we can throw it now - if (isset($e) && $e instanceof InvalidMethodException) { - throw $e; - } - } - - /** - * This method is applied to the cloned object - * after PHP performs an initial shallow-copy. This - * method completes a deep-copy by creating new objects - * for the cloned object's internal reference pointers. - */ - public function __clone() - { - $this->headers = clone $this->headers; - $this->attributes = clone $this->attributes; - $this->body = clone $this->body; - } - - /******************************************************************************* - * Method - ******************************************************************************/ - - /** - * Retrieves the HTTP method of the request. - * - * @return string Returns the request method. - */ - public function getMethod() - { - if ($this->method === null) { - $this->method = $this->originalMethod; - $customMethod = $this->getHeaderLine('X-Http-Method-Override'); - - if ($customMethod) { - $this->method = $this->filterMethod($customMethod); - } elseif ($this->originalMethod === 'POST') { - $overrideMethod = $this->filterMethod($this->getParsedBodyParam('_METHOD')); - if ($overrideMethod !== null) { - $this->method = $overrideMethod; - } - - if ($this->getBody()->eof()) { - $this->getBody()->rewind(); - } - } - } - - return $this->method; - } - - /** - * Get the original HTTP method (ignore override). - * - * Note: This method is not part of the PSR-7 standard. - * - * @return string - */ - public function getOriginalMethod() - { - return $this->originalMethod; - } - - /** - * Return an instance with the provided HTTP method. - * - * While HTTP method names are typically all uppercase characters, HTTP - * method names are case-sensitive and thus implementations SHOULD NOT - * modify the given string. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * changed request method. - * - * @param string $method Case-sensitive method. - * @return static - * @throws \InvalidArgumentException for invalid HTTP methods. - */ - public function withMethod($method) - { - $method = $this->filterMethod($method); - $clone = clone $this; - $clone->originalMethod = $method; - $clone->method = $method; - - return $clone; - } - - /** - * Validate the HTTP method - * - * @param null|string $method - * @return null|string - * @throws \InvalidArgumentException on invalid HTTP method. - */ - protected function filterMethod($method) - { - if ($method === null) { - return $method; - } - - if (!is_string($method)) { - throw new InvalidArgumentException(sprintf( - 'Unsupported HTTP method; must be a string, received %s', - (is_object($method) ? get_class($method) : gettype($method)) - )); - } - - $method = strtoupper($method); - if (preg_match("/^[!#$%&'*+.^_`|~0-9a-z-]+$/i", $method) !== 1) { - throw new InvalidMethodException($this, $method); - } - - return $method; - } - - /** - * Does this request use a given method? - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $method HTTP method - * @return bool - */ - public function isMethod($method) - { - return $this->getMethod() === $method; - } - - /** - * Is this a GET request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isGet() - { - return $this->isMethod('GET'); - } - - /** - * Is this a POST request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isPost() - { - return $this->isMethod('POST'); - } - - /** - * Is this a PUT request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isPut() - { - return $this->isMethod('PUT'); - } - - /** - * Is this a PATCH request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isPatch() - { - return $this->isMethod('PATCH'); - } - - /** - * Is this a DELETE request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isDelete() - { - return $this->isMethod('DELETE'); - } - - /** - * Is this a HEAD request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isHead() - { - return $this->isMethod('HEAD'); - } - - /** - * Is this a OPTIONS request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isOptions() - { - return $this->isMethod('OPTIONS'); - } - - /** - * Is this an XHR request? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isXhr() - { - return $this->getHeaderLine('X-Requested-With') === 'XMLHttpRequest'; - } - - /******************************************************************************* - * URI - ******************************************************************************/ - - /** - * Retrieves the message's request target. - * - * Retrieves the message's request-target either as it will appear (for - * clients), as it appeared at request (for servers), or as it was - * specified for the instance (see withRequestTarget()). - * - * In most cases, this will be the origin-form of the composed URI, - * unless a value was provided to the concrete implementation (see - * withRequestTarget() below). - * - * If no URI is available, and no request-target has been specifically - * provided, this method MUST return the string "/". - * - * @return string - */ - public function getRequestTarget() - { - if ($this->requestTarget) { - return $this->requestTarget; - } - - if ($this->uri === null) { - return '/'; - } - - $basePath = $this->uri->getBasePath(); - $path = $this->uri->getPath(); - $path = $basePath . '/' . ltrim($path, '/'); - - $query = $this->uri->getQuery(); - if ($query) { - $path .= '?' . $query; - } - $this->requestTarget = $path; - - return $this->requestTarget; - } - - /** - * Return an instance with the specific request-target. - * - * If the request needs a non-origin-form request-target — e.g., for - * specifying an absolute-form, authority-form, or asterisk-form — - * this method may be used to create an instance with the specified - * request-target, verbatim. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * changed request target. - * - * @link http://tools.ietf.org/html/rfc7230#section-2.7 (for the various - * request-target forms allowed in request messages) - * @param mixed $requestTarget - * @return static - * @throws InvalidArgumentException if the request target is invalid - */ - public function withRequestTarget($requestTarget) - { - if (preg_match('#\s#', $requestTarget)) { - throw new InvalidArgumentException( - 'Invalid request target provided; must be a string and cannot contain whitespace' - ); - } - $clone = clone $this; - $clone->requestTarget = $requestTarget; - - return $clone; - } - - /** - * Retrieves the URI instance. - * - * This method MUST return a UriInterface instance. - * - * @link http://tools.ietf.org/html/rfc3986#section-4.3 - * @return UriInterface Returns a UriInterface instance - * representing the URI of the request. - */ - public function getUri() - { - return $this->uri; - } - - /** - * Returns an instance with the provided URI. - * - * This method MUST update the Host header of the returned request by - * default if the URI contains a host component. If the URI does not - * contain a host component, any pre-existing Host header MUST be carried - * over to the returned request. - * - * You can opt-in to preserving the original state of the Host header by - * setting `$preserveHost` to `true`. When `$preserveHost` is set to - * `true`, this method interacts with the Host header in the following ways: - * - * - If the the Host header is missing or empty, and the new URI contains - * a host component, this method MUST update the Host header in the returned - * request. - * - If the Host header is missing or empty, and the new URI does not contain a - * host component, this method MUST NOT update the Host header in the returned - * request. - * - If a Host header is present and non-empty, this method MUST NOT update - * the Host header in the returned request. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * new UriInterface instance. - * - * @link http://tools.ietf.org/html/rfc3986#section-4.3 - * @param UriInterface $uri New request URI to use. - * @param bool $preserveHost Preserve the original state of the Host header. - * @return static - */ - public function withUri(UriInterface $uri, $preserveHost = false) - { - $clone = clone $this; - $clone->uri = $uri; - - if (!$preserveHost) { - if ($uri->getHost() !== '') { - $clone->headers->set('Host', $uri->getHost()); - } - } else { - if ($uri->getHost() !== '' && (!$this->hasHeader('Host') || $this->getHeaderLine('Host') === '')) { - $clone->headers->set('Host', $uri->getHost()); - } - } - - return $clone; - } - - /** - * Get request content type. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return string|null The request content type, if known - */ - public function getContentType() - { - $result = $this->getHeader('Content-Type'); - - return $result ? $result[0] : null; - } - - /** - * Get request media type, if known. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return string|null The request media type, minus content-type params - */ - public function getMediaType() - { - $contentType = $this->getContentType(); - if ($contentType) { - $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType); - - return strtolower($contentTypeParts[0]); - } - - return null; - } - - /** - * Get request media type params, if known. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return array - */ - public function getMediaTypeParams() - { - $contentType = $this->getContentType(); - $contentTypeParams = []; - if ($contentType) { - $contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType); - $contentTypePartsLength = count($contentTypeParts); - for ($i = 1; $i < $contentTypePartsLength; $i++) { - $paramParts = explode('=', $contentTypeParts[$i]); - $contentTypeParams[strtolower($paramParts[0])] = $paramParts[1]; - } - } - - return $contentTypeParams; - } - - /** - * Get request content character set, if known. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return string|null - */ - public function getContentCharset() - { - $mediaTypeParams = $this->getMediaTypeParams(); - if (isset($mediaTypeParams['charset'])) { - return $mediaTypeParams['charset']; - } - - return null; - } - - /** - * Get request content length, if known. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return int|null - */ - public function getContentLength() - { - $result = $this->headers->get('Content-Length'); - - return $result ? (int)$result[0] : null; - } - - /******************************************************************************* - * Cookies - ******************************************************************************/ - - /** - * Retrieve cookies. - * - * Retrieves cookies sent by the client to the server. - * - * The data MUST be compatible with the structure of the $_COOKIE - * superglobal. - * - * @return array - */ - public function getCookieParams() - { - return $this->cookies; - } - - /** - * Fetch cookie value from cookies sent by the client to the server. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $key The attribute name. - * @param mixed $default Default value to return if the attribute does not exist. - * - * @return mixed - */ - public function getCookieParam($key, $default = null) - { - $cookies = $this->getCookieParams(); - $result = $default; - if (isset($cookies[$key])) { - $result = $cookies[$key]; - } - - return $result; - } - - /** - * Return an instance with the specified cookies. - * - * The data IS NOT REQUIRED to come from the $_COOKIE superglobal, but MUST - * be compatible with the structure of $_COOKIE. Typically, this data will - * be injected at instantiation. - * - * This method MUST NOT update the related Cookie header of the request - * instance, nor related values in the server params. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated cookie values. - * - * @param array $cookies Array of key/value pairs representing cookies. - * @return static - */ - public function withCookieParams(array $cookies) - { - $clone = clone $this; - $clone->cookies = $cookies; - - return $clone; - } - - /******************************************************************************* - * Query Params - ******************************************************************************/ - - /** - * Retrieve query string arguments. - * - * Retrieves the deserialized query string arguments, if any. - * - * Note: the query params might not be in sync with the URI or server - * params. If you need to ensure you are only getting the original - * values, you may need to parse the query string from `getUri()->getQuery()` - * or from the `QUERY_STRING` server param. - * - * @return array - */ - public function getQueryParams() - { - if (is_array($this->queryParams)) { - return $this->queryParams; - } - - if ($this->uri === null) { - return []; - } - - parse_str($this->uri->getQuery(), $this->queryParams); // <-- URL decodes data - - return $this->queryParams; - } - - /** - * Return an instance with the specified query string arguments. - * - * These values SHOULD remain immutable over the course of the incoming - * request. They MAY be injected during instantiation, such as from PHP's - * $_GET superglobal, or MAY be derived from some other value such as the - * URI. In cases where the arguments are parsed from the URI, the data - * MUST be compatible with what PHP's parse_str() would return for - * purposes of how duplicate query parameters are handled, and how nested - * sets are handled. - * - * Setting query string arguments MUST NOT change the URI stored by the - * request, nor the values in the server params. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated query string arguments. - * - * @param array $query Array of query string arguments, typically from - * $_GET. - * @return static - */ - public function withQueryParams(array $query) - { - $clone = clone $this; - $clone->queryParams = $query; - - return $clone; - } - - /******************************************************************************* - * File Params - ******************************************************************************/ - - /** - * Retrieve normalized file upload data. - * - * This method returns upload metadata in a normalized tree, with each leaf - * an instance of Psr\Http\Message\UploadedFileInterface. - * - * These values MAY be prepared from $_FILES or the message body during - * instantiation, or MAY be injected via withUploadedFiles(). - * - * @return array An array tree of UploadedFileInterface instances; an empty - * array MUST be returned if no data is present. - */ - public function getUploadedFiles() - { - return $this->uploadedFiles; - } - - /** - * Create a new instance with the specified uploaded files. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated body parameters. - * - * @param array $uploadedFiles An array tree of UploadedFileInterface instances. - * @return static - * @throws \InvalidArgumentException if an invalid structure is provided. - */ - public function withUploadedFiles(array $uploadedFiles) - { - $clone = clone $this; - $clone->uploadedFiles = $uploadedFiles; - - return $clone; - } - - /******************************************************************************* - * Server Params - ******************************************************************************/ - - /** - * Retrieve server parameters. - * - * Retrieves data related to the incoming request environment, - * typically derived from PHP's $_SERVER superglobal. The data IS NOT - * REQUIRED to originate from $_SERVER. - * - * @return array - */ - public function getServerParams() - { - return $this->serverParams; - } - - /** - * Retrieve a server parameter. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $key - * @param mixed $default - * @return mixed - */ - public function getServerParam($key, $default = null) - { - $serverParams = $this->getServerParams(); - - return isset($serverParams[$key]) ? $serverParams[$key] : $default; - } - - /******************************************************************************* - * Attributes - ******************************************************************************/ - - /** - * Retrieve attributes derived from the request. - * - * The request "attributes" may be used to allow injection of any - * parameters derived from the request: e.g., the results of path - * match operations; the results of decrypting cookies; the results of - * deserializing non-form-encoded message bodies; etc. Attributes - * will be application and request specific, and CAN be mutable. - * - * @return array Attributes derived from the request. - */ - public function getAttributes() - { - return $this->attributes->all(); - } - - /** - * Retrieve a single derived request attribute. - * - * Retrieves a single derived request attribute as described in - * getAttributes(). If the attribute has not been previously set, returns - * the default value as provided. - * - * This method obviates the need for a hasAttribute() method, as it allows - * specifying a default value to return if the attribute is not found. - * - * @see getAttributes() - * @param string $name The attribute name. - * @param mixed $default Default value to return if the attribute does not exist. - * @return mixed - */ - public function getAttribute($name, $default = null) - { - return $this->attributes->get($name, $default); - } - - /** - * Return an instance with the specified derived request attribute. - * - * This method allows setting a single derived request attribute as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated attribute. - * - * @see getAttributes() - * @param string $name The attribute name. - * @param mixed $value The value of the attribute. - * @return static - */ - public function withAttribute($name, $value) - { - $clone = clone $this; - $clone->attributes->set($name, $value); - - return $clone; - } - - /** - * Create a new instance with the specified derived request attributes. - * - * Note: This method is not part of the PSR-7 standard. - * - * This method allows setting all new derived request attributes as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return a new instance that has the - * updated attributes. - * - * @param array $attributes New attributes - * @return static - */ - public function withAttributes(array $attributes) - { - $clone = clone $this; - $clone->attributes = new Collection($attributes); - - return $clone; - } - - /** - * Return an instance that removes the specified derived request attribute. - * - * This method allows removing a single derived request attribute as - * described in getAttributes(). - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that removes - * the attribute. - * - * @see getAttributes() - * @param string $name The attribute name. - * @return static - */ - public function withoutAttribute($name) - { - $clone = clone $this; - $clone->attributes->remove($name); - - return $clone; - } - - /******************************************************************************* - * Body - ******************************************************************************/ - - /** - * Retrieve any parameters provided in the request body. - * - * If the request Content-Type is either application/x-www-form-urlencoded - * or multipart/form-data, and the request method is POST, this method MUST - * return the contents of $_POST. - * - * Otherwise, this method may return any results of deserializing - * the request body content; as parsing returns structured content, the - * potential types MUST be arrays or objects only. A null value indicates - * the absence of body content. - * - * @return null|array|object The deserialized body parameters, if any. - * These will typically be an array or object. - * @throws RuntimeException if the request body media type parser returns an invalid value - */ - public function getParsedBody() - { - if ($this->bodyParsed !== false) { - return $this->bodyParsed; - } - - if (!$this->body) { - return null; - } - - $mediaType = $this->getMediaType(); - - // look for a media type with a structured syntax suffix (RFC 6839) - $parts = explode('+', $mediaType); - if (count($parts) >= 2) { - $mediaType = 'application/' . $parts[count($parts)-1]; - } - - if (isset($this->bodyParsers[$mediaType]) === true) { - $body = (string)$this->getBody(); - $parsed = $this->bodyParsers[$mediaType]($body); - - if (!is_null($parsed) && !is_object($parsed) && !is_array($parsed)) { - throw new RuntimeException( - 'Request body media type parser return value must be an array, an object, or null' - ); - } - $this->bodyParsed = $parsed; - return $this->bodyParsed; - } - - return null; - } - - /** - * Return an instance with the specified body parameters. - * - * These MAY be injected during instantiation. - * - * If the request Content-Type is either application/x-www-form-urlencoded - * or multipart/form-data, and the request method is POST, use this method - * ONLY to inject the contents of $_POST. - * - * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of - * deserializing the request body content. Deserialization/parsing returns - * structured data, and, as such, this method ONLY accepts arrays or objects, - * or a null value if nothing was available to parse. - * - * As an example, if content negotiation determines that the request data - * is a JSON payload, this method could be used to create a request - * instance with the deserialized parameters. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated body parameters. - * - * @param null|array|object $data The deserialized body data. This will - * typically be in an array or object. - * @return static - * @throws \InvalidArgumentException if an unsupported argument type is - * provided. - */ - public function withParsedBody($data) - { - if (!is_null($data) && !is_object($data) && !is_array($data)) { - throw new InvalidArgumentException('Parsed body value must be an array, an object, or null'); - } - - $clone = clone $this; - $clone->bodyParsed = $data; - - return $clone; - } - - /** - * Force Body to be parsed again. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return $this - */ - public function reparseBody() - { - $this->bodyParsed = false; - - return $this; - } - - /** - * Register media type parser. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $mediaType A HTTP media type (excluding content-type - * params). - * @param callable $callable A callable that returns parsed contents for - * media type. - */ - public function registerMediaTypeParser($mediaType, callable $callable) - { - if ($callable instanceof Closure) { - $callable = $callable->bindTo($this); - } - $this->bodyParsers[(string)$mediaType] = $callable; - } - - /******************************************************************************* - * Parameters (e.g., POST and GET data) - ******************************************************************************/ - - /** - * Fetch request parameter value from body or query string (in that order). - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $key The parameter key. - * @param string $default The default value. - * - * @return mixed The parameter value. - */ - public function getParam($key, $default = null) - { - $postParams = $this->getParsedBody(); - $getParams = $this->getQueryParams(); - $result = $default; - if (is_array($postParams) && isset($postParams[$key])) { - $result = $postParams[$key]; - } elseif (is_object($postParams) && property_exists($postParams, $key)) { - $result = $postParams->$key; - } elseif (isset($getParams[$key])) { - $result = $getParams[$key]; - } - - return $result; - } - - /** - * Fetch parameter value from request body. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $key - * @param mixed $default - * - * @return mixed - */ - public function getParsedBodyParam($key, $default = null) - { - $postParams = $this->getParsedBody(); - $result = $default; - if (is_array($postParams) && isset($postParams[$key])) { - $result = $postParams[$key]; - } elseif (is_object($postParams) && property_exists($postParams, $key)) { - $result = $postParams->$key; - } - - return $result; - } - - /** - * Fetch parameter value from query string. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $key - * @param mixed $default - * - * @return mixed - */ - public function getQueryParam($key, $default = null) - { - $getParams = $this->getQueryParams(); - $result = $default; - if (isset($getParams[$key])) { - $result = $getParams[$key]; - } - - return $result; - } - - /** - * Fetch associative array of body and query string parameters. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param array|null $only list the keys to retrieve. - * @return array|null - */ - public function getParams(array $only = null) - { - $params = $this->getQueryParams(); - $postParams = $this->getParsedBody(); - if ($postParams) { - $params = array_merge($params, (array)$postParams); - } - - if ($only) { - $onlyParams = []; - foreach ($only as $key) { - if (array_key_exists($key, $params)) { - $onlyParams[$key] = $params[$key]; - } - } - return $onlyParams; - } - - return $params; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/RequestBody.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/RequestBody.php deleted file mode 100644 index 50887fdd..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/RequestBody.php +++ /dev/null @@ -1,27 +0,0 @@ - 'Continue', - 101 => 'Switching Protocols', - 102 => 'Processing', - //Successful 2xx - 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', - 226 => 'IM Used', - //Redirection 3xx - 300 => 'Multiple Choices', - 301 => 'Moved Permanently', - 302 => 'Found', - 303 => 'See Other', - 304 => 'Not Modified', - 305 => 'Use Proxy', - 306 => '(Unused)', - 307 => 'Temporary Redirect', - 308 => 'Permanent Redirect', - //Client Error 4xx - 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 Timeout', - 409 => 'Conflict', - 410 => 'Gone', - 411 => 'Length Required', - 412 => 'Precondition Failed', - 413 => 'Request Entity Too Large', - 414 => 'Request-URI Too Long', - 415 => 'Unsupported Media Type', - 416 => 'Requested Range Not Satisfiable', - 417 => 'Expectation Failed', - 418 => 'I\'m a teapot', - 421 => 'Misdirected Request', - 422 => 'Unprocessable Entity', - 423 => 'Locked', - 424 => 'Failed Dependency', - 426 => 'Upgrade Required', - 428 => 'Precondition Required', - 429 => 'Too Many Requests', - 431 => 'Request Header Fields Too Large', - 444 => 'Connection Closed Without Response', - 451 => 'Unavailable For Legal Reasons', - 499 => 'Client Closed Request', - //Server Error 5xx - 500 => 'Internal Server Error', - 501 => 'Not Implemented', - 502 => 'Bad Gateway', - 503 => 'Service Unavailable', - 504 => 'Gateway Timeout', - 505 => 'HTTP Version Not Supported', - 506 => 'Variant Also Negotiates', - 507 => 'Insufficient Storage', - 508 => 'Loop Detected', - 510 => 'Not Extended', - 511 => 'Network Authentication Required', - 599 => 'Network Connect Timeout Error', - ]; - - /** - * EOL characters used for HTTP response. - * - * @var string - */ - const EOL = "\r\n"; - - /** - * Create new HTTP response. - * - * @param int $status The response status code. - * @param HeadersInterface|null $headers The response headers. - * @param StreamInterface|null $body The response body. - */ - public function __construct($status = 200, HeadersInterface $headers = null, StreamInterface $body = null) - { - $this->status = $this->filterStatus($status); - $this->headers = $headers ? $headers : new Headers(); - $this->body = $body ? $body : new Body(fopen('php://temp', 'r+')); - } - - /** - * This method is applied to the cloned object - * after PHP performs an initial shallow-copy. This - * method completes a deep-copy by creating new objects - * for the cloned object's internal reference pointers. - */ - public function __clone() - { - $this->headers = clone $this->headers; - } - - /******************************************************************************* - * Status - ******************************************************************************/ - - /** - * Gets the response status code. - * - * The status code is a 3-digit integer result code of the server's attempt - * to understand and satisfy the request. - * - * @return int Status code. - */ - public function getStatusCode() - { - return $this->status; - } - - /** - * Return an instance with the specified status code and, optionally, reason phrase. - * - * If no reason phrase is specified, implementations MAY choose to default - * to the RFC 7231 or IANA recommended reason phrase for the response's - * status code. - * - * This method MUST be implemented in such a way as to retain the - * immutability of the message, and MUST return an instance that has the - * updated status and reason phrase. - * - * @link http://tools.ietf.org/html/rfc7231#section-6 - * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml - * @param int $code The 3-digit integer result code to set. - * @param string $reasonPhrase The reason phrase to use with the - * provided status code; if none is provided, implementations MAY - * use the defaults as suggested in the HTTP specification. - * @return static - * @throws \InvalidArgumentException For invalid status code arguments. - */ - public function withStatus($code, $reasonPhrase = '') - { - $code = $this->filterStatus($code); - - if (!is_string($reasonPhrase) && !method_exists($reasonPhrase, '__toString')) { - throw new InvalidArgumentException('ReasonPhrase must be a string'); - } - - $clone = clone $this; - $clone->status = $code; - if ($reasonPhrase === '' && isset(static::$messages[$code])) { - $reasonPhrase = static::$messages[$code]; - } - - if ($reasonPhrase === '') { - throw new InvalidArgumentException('ReasonPhrase must be supplied for this code'); - } - - $clone->reasonPhrase = $reasonPhrase; - - return $clone; - } - - /** - * Filter HTTP status code. - * - * @param int $status HTTP status code. - * @return int - * @throws \InvalidArgumentException If an invalid HTTP status code is provided. - */ - protected function filterStatus($status) - { - if (!is_integer($status) || $status<100 || $status>599) { - throw new InvalidArgumentException('Invalid HTTP status code'); - } - - return $status; - } - - /** - * Gets the response reason phrase associated with the status code. - * - * Because a reason phrase is not a required element in a response - * status line, the reason phrase value MAY be null. Implementations MAY - * choose to return the default RFC 7231 recommended reason phrase (or those - * listed in the IANA HTTP Status Code Registry) for the response's - * status code. - * - * @link http://tools.ietf.org/html/rfc7231#section-6 - * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml - * @return string Reason phrase; must return an empty string if none present. - */ - public function getReasonPhrase() - { - if ($this->reasonPhrase) { - return $this->reasonPhrase; - } - if (isset(static::$messages[$this->status])) { - return static::$messages[$this->status]; - } - return ''; - } - - /******************************************************************************* - * Headers - ******************************************************************************/ - - /** - * Return an instance with the provided value replacing the specified header. - * - * If a Location header is set and the status code is 200, then set the status - * code to 302 to mimic what PHP does. See https://github.com/slimphp/Slim/issues/1730 - * - * @param string $name Case-insensitive header field name. - * @param string|string[] $value Header value(s). - * @return static - * @throws \InvalidArgumentException for invalid header names or values. - */ - public function withHeader($name, $value) - { - $clone = clone $this; - $clone->headers->set($name, $value); - - if ($clone->getStatusCode() === 200 && strtolower($name) === 'location') { - $clone = $clone->withStatus(302); - } - - return $clone; - } - - - /******************************************************************************* - * Body - ******************************************************************************/ - - /** - * Write data to the response body. - * - * Note: This method is not part of the PSR-7 standard. - * - * Proxies to the underlying stream and writes the provided data to it. - * - * @param string $data - * @return $this - */ - public function write($data) - { - $this->getBody()->write($data); - - return $this; - } - - /******************************************************************************* - * Response Helpers - ******************************************************************************/ - - /** - * Redirect. - * - * Note: This method is not part of the PSR-7 standard. - * - * This method prepares the response object to return an HTTP Redirect - * response to the client. - * - * @param string|UriInterface $url The redirect destination. - * @param int|null $status The redirect HTTP status code. - * @return static - */ - public function withRedirect($url, $status = null) - { - $responseWithRedirect = $this->withHeader('Location', (string)$url); - - if (is_null($status) && $this->getStatusCode() === 200) { - $status = 302; - } - - if (!is_null($status)) { - return $responseWithRedirect->withStatus($status); - } - - return $responseWithRedirect; - } - - /** - * Json. - * - * Note: This method is not part of the PSR-7 standard. - * - * This method prepares the response object to return an HTTP Json - * response to the client. - * - * @param mixed $data The data - * @param int $status The HTTP status code. - * @param int $encodingOptions Json encoding options - * @throws \RuntimeException - * @return static - */ - public function withJson($data, $status = null, $encodingOptions = 0) - { - $response = $this->withBody(new Body(fopen('php://temp', 'r+'))); - $response->body->write($json = json_encode($data, $encodingOptions)); - - // Ensure that the json encoding passed successfully - if ($json === false) { - throw new \RuntimeException(json_last_error_msg(), json_last_error()); - } - - $responseWithJson = $response->withHeader('Content-Type', 'application/json;charset=utf-8'); - if (isset($status)) { - return $responseWithJson->withStatus($status); - } - return $responseWithJson; - } - - /** - * Is this response empty? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isEmpty() - { - return in_array($this->getStatusCode(), [204, 205, 304]); - } - - /** - * Is this response informational? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isInformational() - { - return $this->getStatusCode() >= 100 && $this->getStatusCode() < 200; - } - - /** - * Is this response OK? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isOk() - { - return $this->getStatusCode() === 200; - } - - /** - * Is this response successful? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isSuccessful() - { - return $this->getStatusCode() >= 200 && $this->getStatusCode() < 300; - } - - /** - * Is this response a redirect? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isRedirect() - { - return in_array($this->getStatusCode(), [301, 302, 303, 307]); - } - - /** - * Is this response a redirection? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isRedirection() - { - return $this->getStatusCode() >= 300 && $this->getStatusCode() < 400; - } - - /** - * Is this response forbidden? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - * @api - */ - public function isForbidden() - { - return $this->getStatusCode() === 403; - } - - /** - * Is this response not Found? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isNotFound() - { - return $this->getStatusCode() === 404; - } - - /** - * Is this response a client error? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isClientError() - { - return $this->getStatusCode() >= 400 && $this->getStatusCode() < 500; - } - - /** - * Is this response a server error? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - public function isServerError() - { - return $this->getStatusCode() >= 500 && $this->getStatusCode() < 600; - } - - /** - * Convert response to string. - * - * Note: This method is not part of the PSR-7 standard. - * - * @return string - */ - public function __toString() - { - $output = sprintf( - 'HTTP/%s %s %s', - $this->getProtocolVersion(), - $this->getStatusCode(), - $this->getReasonPhrase() - ); - $output .= Response::EOL; - foreach ($this->getHeaders() as $name => $values) { - $output .= sprintf('%s: %s', $name, $this->getHeaderLine($name)) . Response::EOL; - } - $output .= Response::EOL; - $output .= (string)$this->getBody(); - - return $output; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Stream.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Stream.php deleted file mode 100644 index 27c7a764..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Stream.php +++ /dev/null @@ -1,450 +0,0 @@ - ['r', 'r+', 'w+', 'a+', 'x+', 'c+'], - 'writable' => ['r+', 'w', 'w+', 'a', 'a+', 'x', 'x+', 'c', 'c+'], - ]; - - /** - * The underlying stream resource - * - * @var resource - */ - protected $stream; - - /** - * Stream metadata - * - * @var array - */ - protected $meta; - - /** - * Is this stream readable? - * - * @var bool - */ - protected $readable; - - /** - * Is this stream writable? - * - * @var bool - */ - protected $writable; - - /** - * Is this stream seekable? - * - * @var bool - */ - protected $seekable; - - /** - * The size of the stream if known - * - * @var null|int - */ - protected $size; - - /** - * Is this stream a pipe? - * - * @var bool - */ - protected $isPipe; - - /** - * Create a new Stream. - * - * @param resource $stream A PHP resource handle. - * - * @throws InvalidArgumentException If argument is not a resource. - */ - public function __construct($stream) - { - $this->attach($stream); - } - - /** - * Get stream metadata as an associative array or retrieve a specific key. - * - * The keys returned are identical to the keys returned from PHP's - * stream_get_meta_data() function. - * - * @link http://php.net/manual/en/function.stream-get-meta-data.php - * - * @param string $key Specific metadata to retrieve. - * - * @return array|mixed|null Returns an associative array if no key is - * provided. Returns a specific key value if a key is provided and the - * value is found, or null if the key is not found. - */ - public function getMetadata($key = null) - { - $this->meta = stream_get_meta_data($this->stream); - if (is_null($key) === true) { - return $this->meta; - } - - return isset($this->meta[$key]) ? $this->meta[$key] : null; - } - - /** - * Is a resource attached to this stream? - * - * Note: This method is not part of the PSR-7 standard. - * - * @return bool - */ - protected function isAttached() - { - return is_resource($this->stream); - } - - /** - * Attach new resource to this object. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param resource $newStream A PHP resource handle. - * - * @throws InvalidArgumentException If argument is not a valid PHP resource. - */ - protected function attach($newStream) - { - if (is_resource($newStream) === false) { - throw new InvalidArgumentException(__METHOD__ . ' argument must be a valid PHP resource'); - } - - if ($this->isAttached() === true) { - $this->detach(); - } - - $this->stream = $newStream; - } - - /** - * Separates any underlying resources from the stream. - * - * After the stream has been detached, the stream is in an unusable state. - * - * @return resource|null Underlying PHP stream, if any - */ - public function detach() - { - $oldResource = $this->stream; - $this->stream = null; - $this->meta = null; - $this->readable = null; - $this->writable = null; - $this->seekable = null; - $this->size = null; - $this->isPipe = null; - - return $oldResource; - } - - /** - * Reads all data from the stream into a string, from the beginning to end. - * - * This method MUST attempt to seek to the beginning of the stream before - * reading data and read the stream until the end is reached. - * - * Warning: This could attempt to load a large amount of data into memory. - * - * This method MUST NOT raise an exception in order to conform with PHP's - * string casting operations. - * - * @see http://php.net/manual/en/language.oop5.magic.php#object.tostring - * @return string - */ - public function __toString() - { - if (!$this->isAttached()) { - return ''; - } - - try { - $this->rewind(); - return $this->getContents(); - } catch (RuntimeException $e) { - return ''; - } - } - - /** - * Closes the stream and any underlying resources. - */ - public function close() - { - if ($this->isAttached() === true) { - if ($this->isPipe()) { - pclose($this->stream); - } else { - fclose($this->stream); - } - } - - $this->detach(); - } - - /** - * Get the size of the stream if known. - * - * @return int|null Returns the size in bytes if known, or null if unknown. - */ - public function getSize() - { - if (!$this->size && $this->isAttached() === true) { - $stats = fstat($this->stream); - $this->size = isset($stats['size']) && !$this->isPipe() ? $stats['size'] : null; - } - - return $this->size; - } - - /** - * Returns the current position of the file read/write pointer - * - * @return int Position of the file pointer - * - * @throws RuntimeException on error. - */ - public function tell() - { - if (!$this->isAttached() || ($position = ftell($this->stream)) === false || $this->isPipe()) { - throw new RuntimeException('Could not get the position of the pointer in stream'); - } - - return $position; - } - - /** - * Returns true if the stream is at the end of the stream. - * - * @return bool - */ - public function eof() - { - return $this->isAttached() ? feof($this->stream) : true; - } - - /** - * Returns whether or not the stream is readable. - * - * @return bool - */ - public function isReadable() - { - if ($this->readable === null) { - if ($this->isPipe()) { - $this->readable = true; - } else { - $this->readable = false; - if ($this->isAttached()) { - $meta = $this->getMetadata(); - foreach (self::$modes['readable'] as $mode) { - if (strpos($meta['mode'], $mode) === 0) { - $this->readable = true; - break; - } - } - } - } - } - - return $this->readable; - } - - /** - * Returns whether or not the stream is writable. - * - * @return bool - */ - public function isWritable() - { - if ($this->writable === null) { - $this->writable = false; - if ($this->isAttached()) { - $meta = $this->getMetadata(); - foreach (self::$modes['writable'] as $mode) { - if (strpos($meta['mode'], $mode) === 0) { - $this->writable = true; - break; - } - } - } - } - - return $this->writable; - } - - /** - * Returns whether or not the stream is seekable. - * - * @return bool - */ - public function isSeekable() - { - if ($this->seekable === null) { - $this->seekable = false; - if ($this->isAttached()) { - $meta = $this->getMetadata(); - $this->seekable = !$this->isPipe() && $meta['seekable']; - } - } - - return $this->seekable; - } - - /** - * Seek to a position in the stream. - * - * @link http://www.php.net/manual/en/function.fseek.php - * - * @param int $offset Stream offset - * @param int $whence Specifies how the cursor position will be calculated - * based on the seek offset. Valid values are identical to the built-in - * PHP $whence values for `fseek()`. SEEK_SET: Set position equal to - * offset bytes SEEK_CUR: Set position to current location plus offset - * SEEK_END: Set position to end-of-stream plus offset. - * - * @throws RuntimeException on failure. - */ - public function seek($offset, $whence = SEEK_SET) - { - // Note that fseek returns 0 on success! - if (!$this->isSeekable() || fseek($this->stream, $offset, $whence) === -1) { - throw new RuntimeException('Could not seek in stream'); - } - } - - /** - * Seek to the beginning of the stream. - * - * If the stream is not seekable, this method will raise an exception; - * otherwise, it will perform a seek(0). - * - * @see seek() - * - * @link http://www.php.net/manual/en/function.fseek.php - * - * @throws RuntimeException on failure. - */ - public function rewind() - { - if (!$this->isSeekable() || rewind($this->stream) === false) { - throw new RuntimeException('Could not rewind stream'); - } - } - - /** - * Read data from the stream. - * - * @param int $length Read up to $length bytes from the object and return - * them. Fewer than $length bytes may be returned if underlying stream - * call returns fewer bytes. - * - * @return string Returns the data read from the stream, or an empty string - * if no bytes are available. - * - * @throws RuntimeException if an error occurs. - */ - public function read($length) - { - if (!$this->isReadable() || ($data = fread($this->stream, $length)) === false) { - throw new RuntimeException('Could not read from stream'); - } - - return $data; - } - - /** - * Write data to the stream. - * - * @param string $string The string that is to be written. - * - * @return int Returns the number of bytes written to the stream. - * - * @throws RuntimeException on failure. - */ - public function write($string) - { - if (!$this->isWritable() || ($written = fwrite($this->stream, $string)) === false) { - throw new RuntimeException('Could not write to stream'); - } - - // reset size so that it will be recalculated on next call to getSize() - $this->size = null; - - return $written; - } - - /** - * Returns the remaining contents in a string - * - * @return string - * - * @throws RuntimeException if unable to read or an error occurs while - * reading. - */ - public function getContents() - { - if (!$this->isReadable() || ($contents = stream_get_contents($this->stream)) === false) { - throw new RuntimeException('Could not get contents of stream'); - } - - return $contents; - } - - /** - * Returns whether or not the stream is a pipe. - * - * @return bool - */ - public function isPipe() - { - if ($this->isPipe === null) { - $this->isPipe = false; - if ($this->isAttached()) { - $mode = fstat($this->stream)['mode']; - $this->isPipe = ($mode & self::FSTAT_MODE_S_IFIFO) !== 0; - } - } - - return $this->isPipe; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/UploadedFile.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/UploadedFile.php deleted file mode 100644 index ae5dfb65..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/UploadedFile.php +++ /dev/null @@ -1,327 +0,0 @@ -has('slim.files')) { - return $env['slim.files']; - } elseif (isset($_FILES)) { - return static::parseUploadedFiles($_FILES); - } - - return []; - } - - /** - * Parse a non-normalized, i.e. $_FILES superglobal, tree of uploaded file data. - * - * @param array $uploadedFiles The non-normalized tree of uploaded file data. - * - * @return array A normalized tree of UploadedFile instances. - */ - private static function parseUploadedFiles(array $uploadedFiles) - { - $parsed = []; - foreach ($uploadedFiles as $field => $uploadedFile) { - if (!isset($uploadedFile['error'])) { - if (is_array($uploadedFile)) { - $parsed[$field] = static::parseUploadedFiles($uploadedFile); - } - continue; - } - - $parsed[$field] = []; - if (!is_array($uploadedFile['error'])) { - $parsed[$field] = new static( - $uploadedFile['tmp_name'], - isset($uploadedFile['name']) ? $uploadedFile['name'] : null, - isset($uploadedFile['type']) ? $uploadedFile['type'] : null, - isset($uploadedFile['size']) ? $uploadedFile['size'] : null, - $uploadedFile['error'], - true - ); - } else { - $subArray = []; - foreach ($uploadedFile['error'] as $fileIdx => $error) { - // normalise subarray and re-parse to move the input's keyname up a level - $subArray[$fileIdx]['name'] = $uploadedFile['name'][$fileIdx]; - $subArray[$fileIdx]['type'] = $uploadedFile['type'][$fileIdx]; - $subArray[$fileIdx]['tmp_name'] = $uploadedFile['tmp_name'][$fileIdx]; - $subArray[$fileIdx]['error'] = $uploadedFile['error'][$fileIdx]; - $subArray[$fileIdx]['size'] = $uploadedFile['size'][$fileIdx]; - - $parsed[$field] = static::parseUploadedFiles($subArray); - } - } - } - - return $parsed; - } - - /** - * Construct a new UploadedFile instance. - * - * @param string $file The full path to the uploaded file provided by the client. - * @param string|null $name The file name. - * @param string|null $type The file media type. - * @param int|null $size The file size in bytes. - * @param int $error The UPLOAD_ERR_XXX code representing the status of the upload. - * @param bool $sapi Indicates if the upload is in a SAPI environment. - */ - public function __construct($file, $name = null, $type = null, $size = null, $error = UPLOAD_ERR_OK, $sapi = false) - { - $this->file = $file; - $this->name = $name; - $this->type = $type; - $this->size = $size; - $this->error = $error; - $this->sapi = $sapi; - } - - /** - * Retrieve a stream representing the uploaded file. - * - * This method MUST return a StreamInterface instance, representing the - * uploaded file. The purpose of this method is to allow utilizing native PHP - * stream functionality to manipulate the file upload, such as - * stream_copy_to_stream() (though the result will need to be decorated in a - * native PHP stream wrapper to work with such functions). - * - * If the moveTo() method has been called previously, this method MUST raise - * an exception. - * - * @return StreamInterface Stream representation of the uploaded file. - * @throws \RuntimeException in cases when no stream is available or can be - * created. - */ - public function getStream() - { - if ($this->moved) { - throw new \RuntimeException(sprintf('Uploaded file %1s has already been moved', $this->name)); - } - if ($this->stream === null) { - $this->stream = new Stream(fopen($this->file, 'r')); - } - - return $this->stream; - } - - /** - * Move the uploaded file to a new location. - * - * Use this method as an alternative to move_uploaded_file(). This method is - * guaranteed to work in both SAPI and non-SAPI environments. - * Implementations must determine which environment they are in, and use the - * appropriate method (move_uploaded_file(), rename(), or a stream - * operation) to perform the operation. - * - * $targetPath may be an absolute path, or a relative path. If it is a - * relative path, resolution should be the same as used by PHP's rename() - * function. - * - * The original file or stream MUST be removed on completion. - * - * If this method is called more than once, any subsequent calls MUST raise - * an exception. - * - * When used in an SAPI environment where $_FILES is populated, when writing - * files via moveTo(), is_uploaded_file() and move_uploaded_file() SHOULD be - * used to ensure permissions and upload status are verified correctly. - * - * If you wish to move to a stream, use getStream(), as SAPI operations - * cannot guarantee writing to stream destinations. - * - * @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 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) - { - if ($this->moved) { - throw new RuntimeException('Uploaded file already moved'); - } - - $targetIsStream = strpos($targetPath, '://') > 0; - if (!$targetIsStream && !is_writable(dirname($targetPath))) { - throw new InvalidArgumentException('Upload target path is not writable'); - } - - if ($targetIsStream) { - if (!copy($this->file, $targetPath)) { - throw new RuntimeException(sprintf('Error moving uploaded file %1s to %2s', $this->name, $targetPath)); - } - if (!unlink($this->file)) { - throw new RuntimeException(sprintf('Error removing uploaded file %1s', $this->name)); - } - } elseif ($this->sapi) { - if (!is_uploaded_file($this->file)) { - throw new RuntimeException(sprintf('%1s is not a valid uploaded file', $this->file)); - } - - if (!move_uploaded_file($this->file, $targetPath)) { - throw new RuntimeException(sprintf('Error moving uploaded file %1s to %2s', $this->name, $targetPath)); - } - } else { - if (!rename($this->file, $targetPath)) { - throw new RuntimeException(sprintf('Error moving uploaded file %1s to %2s', $this->name, $targetPath)); - } - } - - $this->moved = true; - } - - /** - * Retrieve the error associated with the uploaded file. - * - * The return value MUST be one of PHP's UPLOAD_ERR_XXX constants. - * - * If the file was uploaded successfully, this method MUST return - * UPLOAD_ERR_OK. - * - * Implementations SHOULD return the value stored in the "error" key of - * the file in the $_FILES array. - * - * @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; - } - - /** - * Retrieve the filename sent by the client. - * - * Do not trust the value returned by this method. A client could send - * a malicious filename with the intention to corrupt or hack your - * application. - * - * Implementations SHOULD return the value stored in the "name" key of - * the file in the $_FILES array. - * - * @return string|null The filename sent by the client or null if none - * was provided. - */ - public function getClientFilename() - { - return $this->name; - } - - /** - * Retrieve the media type sent by the client. - * - * Do not trust the value returned by this method. A client could send - * a malicious media type with the intention to corrupt or hack your - * application. - * - * Implementations SHOULD return the value stored in the "type" key of - * the file in the $_FILES array. - * - * @return string|null The media type sent by the client or null if none - * was provided. - */ - public function getClientMediaType() - { - return $this->type; - } - - /** - * Retrieve the file size. - * - * Implementations SHOULD return the value stored in the "size" key of - * the file in the $_FILES array if available, as PHP calculates this based - * on the actual size transmitted. - * - * @return int|null The file size in bytes or null if unknown. - */ - public function getSize() - { - return $this->size; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Uri.php b/advancedcontentfilter/vendor/slim/slim/Slim/Http/Uri.php deleted file mode 100644 index fb0f04b5..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Http/Uri.php +++ /dev/null @@ -1,845 +0,0 @@ -scheme = $this->filterScheme($scheme); - $this->host = $host; - $this->port = $this->filterPort($port); - $this->path = empty($path) ? '/' : $this->filterPath($path); - $this->query = $this->filterQuery($query); - $this->fragment = $this->filterQuery($fragment); - $this->user = $user; - $this->password = $password; - } - - /** - * Create new Uri from string. - * - * @param string $uri Complete Uri string - * (i.e., https://user:pass@host:443/path?query). - * - * @return self - */ - public static function createFromString($uri) - { - if (!is_string($uri) && !method_exists($uri, '__toString')) { - throw new InvalidArgumentException('Uri must be a string'); - } - - $parts = parse_url($uri); - $scheme = isset($parts['scheme']) ? $parts['scheme'] : ''; - $user = isset($parts['user']) ? $parts['user'] : ''; - $pass = isset($parts['pass']) ? $parts['pass'] : ''; - $host = isset($parts['host']) ? $parts['host'] : ''; - $port = isset($parts['port']) ? $parts['port'] : null; - $path = isset($parts['path']) ? $parts['path'] : ''; - $query = isset($parts['query']) ? $parts['query'] : ''; - $fragment = isset($parts['fragment']) ? $parts['fragment'] : ''; - - return new static($scheme, $host, $port, $path, $query, $fragment, $user, $pass); - } - - /** - * Create new Uri from environment. - * - * @param Environment $env - * - * @return self - */ - public static function createFromEnvironment(Environment $env) - { - // Scheme - $isSecure = $env->get('HTTPS'); - $scheme = (empty($isSecure) || $isSecure === 'off') ? 'http' : 'https'; - - // Authority: Username and password - $username = $env->get('PHP_AUTH_USER', ''); - $password = $env->get('PHP_AUTH_PW', ''); - - // Authority: Host - if ($env->has('HTTP_HOST')) { - $host = $env->get('HTTP_HOST'); - } else { - $host = $env->get('SERVER_NAME'); - } - - // Authority: Port - $port = (int)$env->get('SERVER_PORT', 80); - if (preg_match('/^(\[[a-fA-F0-9:.]+\])(:\d+)?\z/', $host, $matches)) { - $host = $matches[1]; - - if (isset($matches[2])) { - $port = (int) substr($matches[2], 1); - } - } else { - $pos = strpos($host, ':'); - if ($pos !== false) { - $port = (int) substr($host, $pos + 1); - $host = strstr($host, ':', true); - } - } - - // Path - $requestScriptName = parse_url($env->get('SCRIPT_NAME'), PHP_URL_PATH); - $requestScriptDir = dirname($requestScriptName); - - // parse_url() requires a full URL. As we don't extract the domain name or scheme, - // we use a stand-in. - $requestUri = parse_url('http://example.com' . $env->get('REQUEST_URI'), PHP_URL_PATH); - - $basePath = ''; - $virtualPath = $requestUri; - if (stripos($requestUri, $requestScriptName) === 0) { - $basePath = $requestScriptName; - } elseif ($requestScriptDir !== '/' && stripos($requestUri, $requestScriptDir) === 0) { - $basePath = $requestScriptDir; - } - - if ($basePath) { - $virtualPath = ltrim(substr($requestUri, strlen($basePath)), '/'); - } - - // Query string - $queryString = $env->get('QUERY_STRING', ''); - if ($queryString === '') { - $queryString = parse_url('http://example.com' . $env->get('REQUEST_URI'), PHP_URL_QUERY); - } - - // Fragment - $fragment = ''; - - // Build Uri - $uri = new static($scheme, $host, $port, $virtualPath, $queryString, $fragment, $username, $password); - if ($basePath) { - $uri = $uri->withBasePath($basePath); - } - - return $uri; - } - - /******************************************************************************** - * Scheme - *******************************************************************************/ - - /** - * Retrieve the scheme component of the URI. - * - * If no scheme is present, this method MUST return an empty string. - * - * The value returned MUST be normalized to lowercase, per RFC 3986 - * Section 3.1. - * - * The trailing ":" character is not part of the scheme and MUST NOT be - * added. - * - * @see https://tools.ietf.org/html/rfc3986#section-3.1 - * @return string The URI scheme. - */ - public function getScheme() - { - return $this->scheme; - } - - /** - * Return an instance with the specified scheme. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified scheme. - * - * Implementations MUST support the schemes "http" and "https" case - * insensitively, and MAY accommodate other schemes if required. - * - * An empty scheme is equivalent to removing the scheme. - * - * @param string $scheme The scheme to use with the new instance. - * @return self A new instance with the specified scheme. - * @throws \InvalidArgumentException for invalid or unsupported schemes. - */ - public function withScheme($scheme) - { - $scheme = $this->filterScheme($scheme); - $clone = clone $this; - $clone->scheme = $scheme; - - return $clone; - } - - /** - * Filter Uri scheme. - * - * @param string $scheme Raw Uri scheme. - * @return string - * - * @throws InvalidArgumentException If the Uri scheme is not a string. - * @throws InvalidArgumentException If Uri scheme is not "", "https", or "http". - */ - protected function filterScheme($scheme) - { - static $valid = [ - '' => true, - 'https' => true, - 'http' => true, - ]; - - if (!is_string($scheme) && !method_exists($scheme, '__toString')) { - throw new InvalidArgumentException('Uri scheme must be a string'); - } - - $scheme = str_replace('://', '', strtolower((string)$scheme)); - if (!isset($valid[$scheme])) { - throw new InvalidArgumentException('Uri scheme must be one of: "", "https", "http"'); - } - - return $scheme; - } - - /******************************************************************************** - * Authority - *******************************************************************************/ - - /** - * Retrieve the authority component of the URI. - * - * If no authority information is present, this method MUST return an empty - * string. - * - * The authority syntax of the URI is: - * - *
-     * [user-info@]host[:port]
-     * 
- * - * If the port component is not set or is the standard port for the current - * scheme, it SHOULD NOT be included. - * - * @see https://tools.ietf.org/html/rfc3986#section-3.2 - * @return string The URI authority, in "[user-info@]host[:port]" format. - */ - public function getAuthority() - { - $userInfo = $this->getUserInfo(); - $host = $this->getHost(); - $port = $this->getPort(); - - return ($userInfo ? $userInfo . '@' : '') . $host . ($port !== null ? ':' . $port : ''); - } - - /** - * Retrieve the user information component of the URI. - * - * If no user information is present, this method MUST return an empty - * string. - * - * If a user is present in the URI, this will return that value; - * additionally, if the password is also present, it will be appended to the - * user value, with a colon (":") separating the values. - * - * The trailing "@" character is not part of the user information and MUST - * NOT be added. - * - * @return string The URI user information, in "username[:password]" format. - */ - public function getUserInfo() - { - return $this->user . ($this->password ? ':' . $this->password : ''); - } - - /** - * Return an instance with the specified user information. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified user information. - * - * Password is optional, but the user information MUST include the - * user; an empty string for the user is equivalent to removing user - * information. - * - * @param string $user The user name to use for authority. - * @param null|string $password The password associated with $user. - * @return self A new instance with the specified user information. - */ - public function withUserInfo($user, $password = null) - { - $clone = clone $this; - $clone->user = $this->filterUserInfo($user); - if ($clone->user) { - $clone->password = $password ? $this->filterUserInfo($password) : ''; - } else { - $clone->password = ''; - } - - return $clone; - } - - /** - * Filters the user info string. - * - * @param string $query The raw uri query string. - * @return string The percent-encoded query string. - */ - protected function filterUserInfo($query) - { - return preg_replace_callback( - '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=]+|%(?![A-Fa-f0-9]{2}))/u', - function ($match) { - return rawurlencode($match[0]); - }, - $query - ); - } - - /** - * Retrieve the host component of the URI. - * - * If no host is present, this method MUST return an empty string. - * - * The value returned MUST be normalized to lowercase, per RFC 3986 - * Section 3.2.2. - * - * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 - * @return string The URI host. - */ - public function getHost() - { - return $this->host; - } - - /** - * Return an instance with the specified host. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified host. - * - * An empty host value is equivalent to removing the host. - * - * @param string $host The hostname to use with the new instance. - * @return self A new instance with the specified host. - * @throws \InvalidArgumentException for invalid hostnames. - */ - public function withHost($host) - { - $clone = clone $this; - $clone->host = $host; - - return $clone; - } - - /** - * Retrieve the port component of the URI. - * - * If a port is present, and it is non-standard for the current scheme, - * this method MUST return it as an integer. If the port is the standard port - * used with the current scheme, this method SHOULD return null. - * - * If no port is present, and no scheme is present, this method MUST return - * a null value. - * - * If no port is present, but a scheme is present, this method MAY return - * the standard port for that scheme, but SHOULD return null. - * - * @return null|int The URI port. - */ - public function getPort() - { - return $this->port && !$this->hasStandardPort() ? $this->port : null; - } - - /** - * Return an instance with the specified port. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified port. - * - * Implementations MUST raise an exception for ports outside the - * established TCP and UDP port ranges. - * - * A null value provided for the port is equivalent to removing the port - * information. - * - * @param null|int $port The port to use with the new instance; a null value - * removes the port information. - * @return self A new instance with the specified port. - * @throws \InvalidArgumentException for invalid ports. - */ - public function withPort($port) - { - $port = $this->filterPort($port); - $clone = clone $this; - $clone->port = $port; - - return $clone; - } - - /** - * Does this Uri use a standard port? - * - * @return bool - */ - protected function hasStandardPort() - { - return ($this->scheme === 'http' && $this->port === 80) || ($this->scheme === 'https' && $this->port === 443); - } - - /** - * Filter Uri port. - * - * @param null|int $port The Uri port number. - * @return null|int - * - * @throws InvalidArgumentException If the port is invalid. - */ - protected function filterPort($port) - { - if (is_null($port) || (is_integer($port) && ($port >= 1 && $port <= 65535))) { - return $port; - } - - throw new InvalidArgumentException('Uri port must be null or an integer between 1 and 65535 (inclusive)'); - } - - /******************************************************************************** - * Path - *******************************************************************************/ - - /** - * Retrieve the path component of the URI. - * - * The path can either be empty or absolute (starting with a slash) or - * rootless (not starting with a slash). Implementations MUST support all - * three syntaxes. - * - * Normally, the empty path "" and absolute path "/" are considered equal as - * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically - * do this normalization because in contexts with a trimmed base path, e.g. - * the front controller, this difference becomes significant. It's the task - * of the user to handle both "" and "/". - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.3. - * - * As an example, if the value should include a slash ("/") not intended as - * delimiter between path segments, that value MUST be passed in encoded - * form (e.g., "%2F") to the instance. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.3 - * @return string The URI path. - */ - public function getPath() - { - return $this->path; - } - - /** - * Return an instance with the specified path. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified path. - * - * The path can either be empty or absolute (starting with a slash) or - * rootless (not starting with a slash). Implementations MUST support all - * three syntaxes. - * - * If the path is intended to be domain-relative rather than path relative then - * it must begin with a slash ("/"). Paths not starting with a slash ("/") - * are assumed to be relative to some base path known to the application or - * consumer. - * - * Users can provide both encoded and decoded path characters. - * Implementations ensure the correct encoding as outlined in getPath(). - * - * @param string $path The path to use with the new instance. - * @return self A new instance with the specified path. - * @throws \InvalidArgumentException for invalid paths. - */ - public function withPath($path) - { - if (!is_string($path)) { - throw new InvalidArgumentException('Uri path must be a string'); - } - - $clone = clone $this; - $clone->path = $this->filterPath($path); - - // if the path is absolute, then clear basePath - if (substr($path, 0, 1) == '/') { - $clone->basePath = ''; - } - - return $clone; - } - - /** - * Retrieve the base path segment of the URI. - * - * Note: This method is not part of the PSR-7 standard. - * - * This method MUST return a string; if no path is present it MUST return - * an empty string. - * - * @return string The base path segment of the URI. - */ - public function getBasePath() - { - return $this->basePath; - } - - /** - * Set base path. - * - * Note: This method is not part of the PSR-7 standard. - * - * @param string $basePath - * @return self - */ - public function withBasePath($basePath) - { - if (!is_string($basePath)) { - throw new InvalidArgumentException('Uri path must be a string'); - } - if (!empty($basePath)) { - $basePath = '/' . trim($basePath, '/'); // <-- Trim on both sides - } - $clone = clone $this; - - if ($basePath !== '/') { - $clone->basePath = $this->filterPath($basePath); - } - - return $clone; - } - - /** - * Filter Uri path. - * - * This method percent-encodes all reserved - * characters in the provided path string. This method - * will NOT double-encode characters that are already - * percent-encoded. - * - * @param string $path The raw uri path. - * @return string The RFC 3986 percent-encoded uri path. - * @link http://www.faqs.org/rfcs/rfc3986.html - */ - protected function filterPath($path) - { - return preg_replace_callback( - '/(?:[^a-zA-Z0-9_\-\.~:@&=\+\$,\/;%]+|%(?![A-Fa-f0-9]{2}))/', - function ($match) { - return rawurlencode($match[0]); - }, - $path - ); - } - - /******************************************************************************** - * Query - *******************************************************************************/ - - /** - * Retrieve the query string of the URI. - * - * If no query string is present, this method MUST return an empty string. - * - * The leading "?" character is not part of the query and MUST NOT be - * added. - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.4. - * - * As an example, if a value in a key/value pair of the query string should - * include an ampersand ("&") not intended as a delimiter between values, - * that value MUST be passed in encoded form (e.g., "%26") to the instance. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.4 - * @return string The URI query string. - */ - public function getQuery() - { - return $this->query; - } - - /** - * Return an instance with the specified query string. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified query string. - * - * Users can provide both encoded and decoded query characters. - * Implementations ensure the correct encoding as outlined in getQuery(). - * - * An empty query string value is equivalent to removing the query string. - * - * @param string $query The query string to use with the new instance. - * @return self A new instance with the specified query string. - * @throws \InvalidArgumentException for invalid query strings. - */ - public function withQuery($query) - { - if (!is_string($query) && !method_exists($query, '__toString')) { - throw new InvalidArgumentException('Uri query must be a string'); - } - $query = ltrim((string)$query, '?'); - $clone = clone $this; - $clone->query = $this->filterQuery($query); - - return $clone; - } - - /** - * Filters the query string or fragment of a URI. - * - * @param string $query The raw uri query string. - * @return string The percent-encoded query string. - */ - protected function filterQuery($query) - { - return preg_replace_callback( - '/(?:[^a-zA-Z0-9_\-\.~!\$&\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))/', - function ($match) { - return rawurlencode($match[0]); - }, - $query - ); - } - - /******************************************************************************** - * Fragment - *******************************************************************************/ - - /** - * Retrieve the fragment component of the URI. - * - * If no fragment is present, this method MUST return an empty string. - * - * The leading "#" character is not part of the fragment and MUST NOT be - * added. - * - * The value returned MUST be percent-encoded, but MUST NOT double-encode - * any characters. To determine what characters to encode, please refer to - * RFC 3986, Sections 2 and 3.5. - * - * @see https://tools.ietf.org/html/rfc3986#section-2 - * @see https://tools.ietf.org/html/rfc3986#section-3.5 - * @return string The URI fragment. - */ - public function getFragment() - { - return $this->fragment; - } - - /** - * Return an instance with the specified URI fragment. - * - * This method MUST retain the state of the current instance, and return - * an instance that contains the specified URI fragment. - * - * Users can provide both encoded and decoded fragment characters. - * Implementations ensure the correct encoding as outlined in getFragment(). - * - * An empty fragment value is equivalent to removing the fragment. - * - * @param string $fragment The fragment to use with the new instance. - * @return self A new instance with the specified fragment. - */ - public function withFragment($fragment) - { - if (!is_string($fragment) && !method_exists($fragment, '__toString')) { - throw new InvalidArgumentException('Uri fragment must be a string'); - } - $fragment = ltrim((string)$fragment, '#'); - $clone = clone $this; - $clone->fragment = $this->filterQuery($fragment); - - return $clone; - } - - /******************************************************************************** - * Helpers - *******************************************************************************/ - - /** - * Return the string representation as a URI reference. - * - * Depending on which components of the URI are present, the resulting - * string is either a full URI or relative reference according to RFC 3986, - * Section 4.1. The method concatenates the various components of the URI, - * using the appropriate delimiters: - * - * - If a scheme is present, it MUST be suffixed by ":". - * - If an authority is present, it MUST be prefixed by "//". - * - The path can be concatenated without delimiters. But there are two - * cases where the path has to be adjusted to make the URI reference - * valid as PHP does not allow to throw an exception in __toString(): - * - If the path is rootless and an authority is present, the path MUST - * be prefixed by "/". - * - If the path is starting with more than one "/" and no authority is - * present, the starting slashes MUST be reduced to one. - * - If a query is present, it MUST be prefixed by "?". - * - If a fragment is present, it MUST be prefixed by "#". - * - * @see http://tools.ietf.org/html/rfc3986#section-4.1 - * @return string - */ - public function __toString() - { - $scheme = $this->getScheme(); - $authority = $this->getAuthority(); - $basePath = $this->getBasePath(); - $path = $this->getPath(); - $query = $this->getQuery(); - $fragment = $this->getFragment(); - - $path = $basePath . '/' . ltrim($path, '/'); - - return ($scheme ? $scheme . ':' : '') - . ($authority ? '//' . $authority : '') - . $path - . ($query ? '?' . $query : '') - . ($fragment ? '#' . $fragment : ''); - } - - /** - * Return the fully qualified base URL. - * - * Note that this method never includes a trailing / - * - * This method is not part of PSR-7. - * - * @return string - */ - public function getBaseUrl() - { - $scheme = $this->getScheme(); - $authority = $this->getAuthority(); - $basePath = $this->getBasePath(); - - if ($authority && substr($basePath, 0, 1) !== '/') { - $basePath = $basePath . '/' . $basePath; - } - - return ($scheme ? $scheme . ':' : '') - . ($authority ? '//' . $authority : '') - . rtrim($basePath, '/'); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/AdvancedCallableResolverInterface.php b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/AdvancedCallableResolverInterface.php new file mode 100644 index 00000000..aa1d897d --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/AdvancedCallableResolverInterface.php @@ -0,0 +1,28 @@ + $routeArguments The route's placeholder arguments * - * @return ResponseInterface|string The response from the callable. + * @return ResponseInterface The response from the callable. */ public function __invoke( callable $callable, ServerRequestInterface $request, ResponseInterface $response, array $routeArguments - ); + ): ResponseInterface; } diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/MiddlewareDispatcherInterface.php b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/MiddlewareDispatcherInterface.php new file mode 100644 index 00000000..aa7a26ad --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/MiddlewareDispatcherInterface.php @@ -0,0 +1,42 @@ + + */ + public function getArguments(): array; + + /** + * Set a route argument + */ + public function setArgument(string $name, string $value): RouteInterface; + + /** + * Replace route arguments + * + * @param array $arguments + */ + public function setArguments(array $arguments): self; + + /** + * @param MiddlewareInterface|string|callable $middleware + */ + public function add($middleware): self; + + public function addMiddleware(MiddlewareInterface $middleware): self; /** * Prepare the route for use * - * @param ServerRequestInterface $request - * @param array $arguments + * @param array $arguments */ - public function prepare(ServerRequestInterface $request, array $arguments); + public function prepare(array $arguments): self; /** * Run route @@ -117,24 +118,6 @@ interface RouteInterface * This method traverses the middleware stack, including the route's callable * and captures the resultant HTTP response object. It then sends the response * back to the Application. - * - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * @return ResponseInterface */ - public function run(ServerRequestInterface $request, ResponseInterface $response); - - /** - * Dispatch route callable against current Request and Response objects - * - * This method invokes the route object's callable. If middleware is - * registered for the route, each callable middleware is invoked in - * the order specified. - * - * @param ServerRequestInterface $request The current Request object - * @param ResponseInterface $response The current Response object - * - * @return ResponseInterface - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response); + public function run(ServerRequestInterface $request): ResponseInterface; } diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteParserInterface.php b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteParserInterface.php new file mode 100644 index 00000000..03d93266 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteParserInterface.php @@ -0,0 +1,52 @@ + $data Named argument replacement data + * @param array $queryParams Optional query string parameters + * + * @throws RuntimeException If named route does not exist + * @throws InvalidArgumentException If required data not provided + */ + public function relativeUrlFor(string $routeName, array $data = [], array $queryParams = []): string; + + /** + * Build the path for a named route including the base path + * + * @param string $routeName Route name + * @param array $data Named argument replacement data + * @param array $queryParams Optional query string parameters + * + * @throws RuntimeException If named route does not exist + * @throws InvalidArgumentException If required data not provided + */ + public function urlFor(string $routeName, array $data = [], array $queryParams = []): string; + + /** + * Get fully qualified URL for named route + * + * @param UriInterface $uri + * @param string $routeName Route name + * @param array $data Named argument replacement data + * @param array $queryParams Optional query string parameters + */ + public function fullUrlFor(UriInterface $uri, string $routeName, array $data = [], array $queryParams = []): string; +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteResolverInterface.php b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteResolverInterface.php new file mode 100644 index 00000000..256a3599 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouteResolverInterface.php @@ -0,0 +1,17 @@ +getPath() + */ + public function computeRoutingResults(string $uri, string $method): RoutingResults; + + public function resolveRoute(string $identifier): RouteInterface; +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouterInterface.php b/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouterInterface.php deleted file mode 100644 index 2ab8b678..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Interfaces/RouterInterface.php +++ /dev/null @@ -1,111 +0,0 @@ - $context + * + * @throws InvalidArgumentException + */ + public function log($level, $message, array $context = []): void + { + error_log((string) $message); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/BodyParsingMiddleware.php b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/BodyParsingMiddleware.php new file mode 100644 index 00000000..9a90f30c --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/BodyParsingMiddleware.php @@ -0,0 +1,196 @@ + callable + */ + public function __construct(array $bodyParsers = []) + { + $this->registerDefaultBodyParsers(); + + foreach ($bodyParsers as $mediaType => $parser) { + $this->registerBodyParser($mediaType, $parser); + } + } + + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $parsedBody = $request->getParsedBody(); + + if (empty($parsedBody)) { + $parsedBody = $this->parseBody($request); + $request = $request->withParsedBody($parsedBody); + } + + return $handler->handle($request); + } + + /** + * @param string $mediaType A HTTP media type (excluding content-type params). + * @param callable $callable A callable that returns parsed contents for media type. + */ + public function registerBodyParser(string $mediaType, callable $callable): self + { + $this->bodyParsers[$mediaType] = $callable; + return $this; + } + + /** + * @param string $mediaType A HTTP media type (excluding content-type params). + */ + public function hasBodyParser(string $mediaType): bool + { + return isset($this->bodyParsers[$mediaType]); + } + + /** + * @param string $mediaType A HTTP media type (excluding content-type params). + * @throws RuntimeException + */ + public function getBodyParser(string $mediaType): callable + { + if (!isset($this->bodyParsers[$mediaType])) { + throw new RuntimeException('No parser for type ' . $mediaType); + } + return $this->bodyParsers[$mediaType]; + } + + protected function registerDefaultBodyParsers(): void + { + $this->registerBodyParser('application/json', static function ($input) { + $result = json_decode($input, true); + + if (!is_array($result)) { + return null; + } + + return $result; + }); + + $this->registerBodyParser('application/x-www-form-urlencoded', static function ($input) { + parse_str($input, $data); + return $data; + }); + + $xmlCallable = static function ($input) { + $backup = self::disableXmlEntityLoader(true); + $backup_errors = libxml_use_internal_errors(true); + $result = simplexml_load_string($input); + + self::disableXmlEntityLoader($backup); + libxml_clear_errors(); + libxml_use_internal_errors($backup_errors); + + if ($result === false) { + return null; + } + + return $result; + }; + + $this->registerBodyParser('application/xml', $xmlCallable); + $this->registerBodyParser('text/xml', $xmlCallable); + } + + /** + * @return null|array|object + */ + protected function parseBody(ServerRequestInterface $request) + { + $mediaType = $this->getMediaType($request); + if ($mediaType === null) { + return null; + } + + // Check if this specific media type has a parser registered first + if (!isset($this->bodyParsers[$mediaType])) { + // If not, look for a media type with a structured syntax suffix (RFC 6839) + $parts = explode('+', $mediaType); + if (count($parts) >= 2) { + $mediaType = 'application/' . $parts[count($parts) - 1]; + } + } + + if (isset($this->bodyParsers[$mediaType])) { + $body = (string)$request->getBody(); + $parsed = $this->bodyParsers[$mediaType]($body); + + if ($parsed !== null && !is_object($parsed) && !is_array($parsed)) { + throw new RuntimeException( + 'Request body media type parser return value must be an array, an object, or null' + ); + } + + return $parsed; + } + + return null; + } + + /** + * @return string|null The serverRequest media type, minus content-type params + */ + protected function getMediaType(ServerRequestInterface $request): ?string + { + $contentType = $request->getHeader('Content-Type')[0] ?? null; + + if (is_string($contentType) && trim($contentType) !== '') { + $contentTypeParts = explode(';', $contentType); + return strtolower(trim($contentTypeParts[0])); + } + + return null; + } + + protected static function disableXmlEntityLoader(bool $disable): bool + { + if (LIBXML_VERSION >= 20900) { + // libxml >= 2.9.0 disables entity loading by default, so it is + // safe to skip the real call (deprecated in PHP 8). + return true; + } + + // @codeCoverageIgnoreStart + return libxml_disable_entity_loader($disable); + // @codeCoverageIgnoreEnd + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ContentLengthMiddleware.php b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ContentLengthMiddleware.php new file mode 100644 index 00000000..8fa13bcf --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ContentLengthMiddleware.php @@ -0,0 +1,32 @@ +handle($request); + + // Add Content-Length header if not already added + $size = $response->getBody()->getSize(); + if ($size !== null && !$response->hasHeader('Content-Length')) { + $response = $response->withHeader('Content-Length', (string) $size); + } + + return $response; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php new file mode 100644 index 00000000..2eb5cc96 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php @@ -0,0 +1,212 @@ +callableResolver = $callableResolver; + $this->responseFactory = $responseFactory; + $this->displayErrorDetails = $displayErrorDetails; + $this->logErrors = $logErrors; + $this->logErrorDetails = $logErrorDetails; + $this->logger = $logger; + } + + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + try { + return $handler->handle($request); + } catch (Throwable $e) { + return $this->handleException($request, $e); + } + } + + public function handleException(ServerRequestInterface $request, Throwable $exception): ResponseInterface + { + if ($exception instanceof HttpException) { + $request = $exception->getRequest(); + } + + $exceptionType = get_class($exception); + $handler = $this->getErrorHandler($exceptionType); + + return $handler($request, $exception, $this->displayErrorDetails, $this->logErrors, $this->logErrorDetails); + } + + /** + * Get callable to handle scenarios where an error + * occurs when processing the current request. + * + * @param string $type Exception/Throwable name. ie: RuntimeException::class + * @return callable|ErrorHandler + */ + public function getErrorHandler(string $type) + { + if (isset($this->handlers[$type])) { + return $this->callableResolver->resolve($this->handlers[$type]); + } + + if (isset($this->subClassHandlers[$type])) { + return $this->callableResolver->resolve($this->subClassHandlers[$type]); + } + + foreach ($this->subClassHandlers as $class => $handler) { + if (is_subclass_of($type, $class)) { + return $this->callableResolver->resolve($handler); + } + } + + return $this->getDefaultErrorHandler(); + } + + /** + * Get default error handler + * + * @return ErrorHandler|callable + */ + public function getDefaultErrorHandler() + { + if ($this->defaultErrorHandler === null) { + $this->defaultErrorHandler = new ErrorHandler( + $this->callableResolver, + $this->responseFactory, + $this->logger + ); + } + + return $this->callableResolver->resolve($this->defaultErrorHandler); + } + + /** + * Set callable as the default Slim application error handler. + * + * The callable signature MUST match the ErrorHandlerInterface + * + * @see \Slim\Interfaces\ErrorHandlerInterface + * + * 1. Instance of \Psr\Http\Message\ServerRequestInterface + * 2. Instance of \Throwable + * 3. Boolean $displayErrorDetails + * 4. Boolean $logErrors + * 5. Boolean $logErrorDetails + * + * The callable MUST return an instance of + * \Psr\Http\Message\ResponseInterface. + * + * @param string|callable|ErrorHandler $handler + */ + public function setDefaultErrorHandler($handler): self + { + $this->defaultErrorHandler = $handler; + return $this; + } + + /** + * Set callable to handle scenarios where an error + * occurs when processing the current request. + * + * The callable signature MUST match the ErrorHandlerInterface + * + * Pass true to $handleSubclasses to make the handler handle all subclasses of + * the type as well. Pass an array of classes to make the same function handle multiple exceptions. + * + * @see \Slim\Interfaces\ErrorHandlerInterface + * + * 1. Instance of \Psr\Http\Message\ServerRequestInterface + * 2. Instance of \Throwable + * 3. Boolean $displayErrorDetails + * 4. Boolean $logErrors + * 5. Boolean $logErrorDetails + * + * The callable MUST return an instance of + * \Psr\Http\Message\ResponseInterface. + * + * @param string|string[] $typeOrTypes Exception/Throwable name. + * ie: RuntimeException::class or an array of classes + * ie: [HttpNotFoundException::class, HttpMethodNotAllowedException::class] + * @param string|callable|ErrorHandlerInterface $handler + */ + public function setErrorHandler($typeOrTypes, $handler, bool $handleSubclasses = false): self + { + if (is_array($typeOrTypes)) { + foreach ($typeOrTypes as $type) { + $this->addErrorHandler($type, $handler, $handleSubclasses); + } + } else { + $this->addErrorHandler($typeOrTypes, $handler, $handleSubclasses); + } + + return $this; + } + + /** + * Used internally to avoid code repetition when passing multiple exceptions to setErrorHandler(). + * @param string|callable|ErrorHandlerInterface $handler + */ + private function addErrorHandler(string $type, $handler, bool $handleSubclasses): void + { + if ($handleSubclasses) { + $this->subClassHandlers[$type] = $handler; + } else { + $this->handlers[$type] = $handler; + } + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/MethodOverrideMiddleware.php b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/MethodOverrideMiddleware.php new file mode 100644 index 00000000..079a1f18 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/MethodOverrideMiddleware.php @@ -0,0 +1,43 @@ +getHeaderLine('X-Http-Method-Override'); + + if ($methodHeader) { + $request = $request->withMethod($methodHeader); + } elseif (strtoupper($request->getMethod()) === 'POST') { + $body = $request->getParsedBody(); + + if (is_array($body) && !empty($body['_METHOD'])) { + $request = $request->withMethod($body['_METHOD']); + } + + if ($request->getBody()->eof()) { + $request->getBody()->rewind(); + } + } + + return $handler->handle($request); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/OutputBufferingMiddleware.php b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/OutputBufferingMiddleware.php new file mode 100644 index 00000000..69ee1f6f --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/OutputBufferingMiddleware.php @@ -0,0 +1,74 @@ +streamFactory = $streamFactory; + $this->style = $style; + + if (!in_array($style, [static::APPEND, static::PREPEND], true)) { + throw new InvalidArgumentException("Invalid style `{$style}`. Must be `append` or `prepend`"); + } + } + + /** + * @throws Throwable + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + try { + ob_start(); + $response = $handler->handle($request); + $output = ob_get_clean(); + } catch (Throwable $e) { + ob_end_clean(); + throw $e; + } + + if (!empty($output)) { + if ($this->style === static::PREPEND) { + $body = $this->streamFactory->createStream(); + $body->write($output . $response->getBody()); + $response = $response->withBody($body); + } elseif ($this->style === static::APPEND && $response->getBody()->isWritable()) { + $response->getBody()->write($output); + } + } + + return $response; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php new file mode 100644 index 00000000..a3d3085b --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Middleware/RoutingMiddleware.php @@ -0,0 +1,98 @@ +routeResolver = $routeResolver; + $this->routeParser = $routeParser; + } + + /** + * @throws HttpNotFoundException + * @throws HttpMethodNotAllowedException + * @throws RuntimeException + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $request = $this->performRouting($request); + return $handler->handle($request); + } + + /** + * Perform routing + * + * @param ServerRequestInterface $request PSR7 Server Request + * + * @throws HttpNotFoundException + * @throws HttpMethodNotAllowedException + * @throws RuntimeException + */ + public function performRouting(ServerRequestInterface $request): ServerRequestInterface + { + $request = $request->withAttribute(RouteContext::ROUTE_PARSER, $this->routeParser); + + $routingResults = $this->resolveRoutingResultsFromRequest($request); + $routeStatus = $routingResults->getRouteStatus(); + + $request = $request->withAttribute(RouteContext::ROUTING_RESULTS, $routingResults); + + switch ($routeStatus) { + case RoutingResults::FOUND: + $routeArguments = $routingResults->getRouteArguments(); + $routeIdentifier = $routingResults->getRouteIdentifier() ?? ''; + $route = $this->routeResolver + ->resolveRoute($routeIdentifier) + ->prepare($routeArguments); + return $request->withAttribute(RouteContext::ROUTE, $route); + + case RoutingResults::NOT_FOUND: + throw new HttpNotFoundException($request); + + case RoutingResults::METHOD_NOT_ALLOWED: + $exception = new HttpMethodNotAllowedException($request); + $exception->setAllowedMethods($routingResults->getAllowedMethods()); + throw $exception; + + default: + throw new RuntimeException('An unexpected error occurred while performing routing.'); + } + } + + /** + * Resolves the route from the given request + */ + protected function resolveRoutingResultsFromRequest(ServerRequestInterface $request): RoutingResults + { + return $this->routeResolver->computeRoutingResults( + $request->getUri()->getPath(), + $request->getMethod() + ); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareAwareTrait.php b/advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareAwareTrait.php deleted file mode 100644 index 8b8a1755..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareAwareTrait.php +++ /dev/null @@ -1,121 +0,0 @@ -middlewareLock) { - throw new RuntimeException('Middleware can’t be added once the stack is dequeuing'); - } - - if (is_null($this->tip)) { - $this->seedMiddlewareStack(); - } - $next = $this->tip; - $this->tip = function ( - ServerRequestInterface $request, - ResponseInterface $response - ) use ( - $callable, - $next - ) { - $result = call_user_func($callable, $request, $response, $next); - if ($result instanceof ResponseInterface === false) { - throw new UnexpectedValueException( - 'Middleware must return instance of \Psr\Http\Message\ResponseInterface' - ); - } - - return $result; - }; - - return $this; - } - - /** - * Seed middleware stack with first callable - * - * @param callable $kernel The last item to run as middleware - * - * @throws RuntimeException if the stack is seeded more than once - */ - protected function seedMiddlewareStack(callable $kernel = null) - { - if (!is_null($this->tip)) { - throw new RuntimeException('MiddlewareStack can only be seeded once.'); - } - if ($kernel === null) { - $kernel = $this; - } - $this->tip = $kernel; - } - - /** - * Call middleware stack - * - * @param ServerRequestInterface $request A request object - * @param ResponseInterface $response A response object - * - * @return ResponseInterface - */ - public function callMiddlewareStack(ServerRequestInterface $request, ResponseInterface $response) - { - if (is_null($this->tip)) { - $this->seedMiddlewareStack(); - } - /** @var callable $start */ - $start = $this->tip; - $this->middlewareLock = true; - $response = $start($request, $response); - $this->middlewareLock = false; - return $response; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareDispatcher.php b/advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareDispatcher.php new file mode 100644 index 00000000..7e056441 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/MiddlewareDispatcher.php @@ -0,0 +1,275 @@ +seedMiddlewareStack($kernel); + $this->callableResolver = $callableResolver; + $this->container = $container; + } + + /** + * {@inheritdoc} + */ + public function seedMiddlewareStack(RequestHandlerInterface $kernel): void + { + $this->tip = $kernel; + } + + /** + * Invoke the middleware stack + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + return $this->tip->handle($request); + } + + /** + * Add a new middleware to the stack + * + * Middleware are organized as a stack. That means middleware + * that have been added before will be executed after the newly + * added one (last in, first out). + * + * @param MiddlewareInterface|string|callable $middleware + */ + public function add($middleware): MiddlewareDispatcherInterface + { + if ($middleware instanceof MiddlewareInterface) { + return $this->addMiddleware($middleware); + } + + if (is_string($middleware)) { + return $this->addDeferred($middleware); + } + + if (is_callable($middleware)) { + return $this->addCallable($middleware); + } + + /** @phpstan-ignore-next-line */ + throw new RuntimeException( + 'A middleware must be an object/class name referencing an implementation of ' . + 'MiddlewareInterface or a callable with a matching signature.' + ); + } + + /** + * Add a new middleware to the stack + * + * Middleware are organized as a stack. That means middleware + * that have been added before will be executed after the newly + * added one (last in, first out). + */ + public function addMiddleware(MiddlewareInterface $middleware): MiddlewareDispatcherInterface + { + $next = $this->tip; + $this->tip = new class ($middleware, $next) implements RequestHandlerInterface { + private MiddlewareInterface $middleware; + + private RequestHandlerInterface $next; + + public function __construct(MiddlewareInterface $middleware, RequestHandlerInterface $next) + { + $this->middleware = $middleware; + $this->next = $next; + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + return $this->middleware->process($request, $this->next); + } + }; + + return $this; + } + + /** + * Add a new middleware by class name + * + * Middleware are organized as a stack. That means middleware + * that have been added before will be executed after the newly + * added one (last in, first out). + */ + public function addDeferred(string $middleware): self + { + $next = $this->tip; + $this->tip = new class ( + $middleware, + $next, + $this->container, + $this->callableResolver + ) implements RequestHandlerInterface { + private string $middleware; + + private RequestHandlerInterface $next; + + private ?ContainerInterface $container; + + private ?CallableResolverInterface $callableResolver; + + public function __construct( + string $middleware, + RequestHandlerInterface $next, + ?ContainerInterface $container = null, + ?CallableResolverInterface $callableResolver = null + ) { + $this->middleware = $middleware; + $this->next = $next; + $this->container = $container; + $this->callableResolver = $callableResolver; + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + if ($this->callableResolver instanceof AdvancedCallableResolverInterface) { + $callable = $this->callableResolver->resolveMiddleware($this->middleware); + return $callable($request, $this->next); + } + + $callable = null; + + if ($this->callableResolver instanceof CallableResolverInterface) { + try { + $callable = $this->callableResolver->resolve($this->middleware); + } catch (RuntimeException $e) { + // Do Nothing + } + } + + if (!$callable) { + $resolved = $this->middleware; + $instance = null; + $method = null; + + // Check for Slim callable as `class:method` + if (preg_match(CallableResolver::$callablePattern, $resolved, $matches)) { + $resolved = $matches[1]; + $method = $matches[2]; + } + + if ($this->container && $this->container->has($resolved)) { + $instance = $this->container->get($resolved); + if ($instance instanceof MiddlewareInterface) { + return $instance->process($request, $this->next); + } + } elseif (!function_exists($resolved)) { + if (!class_exists($resolved)) { + throw new RuntimeException(sprintf('Middleware %s does not exist', $resolved)); + } + $instance = new $resolved($this->container); + } + + if ($instance && $instance instanceof MiddlewareInterface) { + return $instance->process($request, $this->next); + } + + $callable = $instance ?? $resolved; + if ($instance && $method) { + $callable = [$instance, $method]; + } + + if ($this->container && $callable instanceof Closure) { + $callable = $callable->bindTo($this->container); + } + } + + if (!is_callable($callable)) { + throw new RuntimeException( + sprintf( + 'Middleware %s is not resolvable', + $this->middleware + ) + ); + } + + return $callable($request, $this->next); + } + }; + + return $this; + } + + /** + * Add a (non-standard) callable middleware to the stack + * + * Middleware are organized as a stack. That means middleware + * that have been added before will be executed after the newly + * added one (last in, first out). + */ + public function addCallable(callable $middleware): self + { + $next = $this->tip; + + if ($this->container && $middleware instanceof Closure) { + /** @var Closure $middleware */ + $middleware = $middleware->bindTo($this->container); + } + + $this->tip = new class ($middleware, $next) implements RequestHandlerInterface { + /** + * @var callable + */ + private $middleware; + + /** + * @var RequestHandlerInterface + */ + private $next; + + public function __construct(callable $middleware, RequestHandlerInterface $next) + { + $this->middleware = $middleware; + $this->next = $next; + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + return ($this->middleware)($request, $this->next); + } + }; + + return $this; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/ResponseEmitter.php b/advancedcontentfilter/vendor/slim/slim/Slim/ResponseEmitter.php new file mode 100644 index 00000000..fac36e9e --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/ResponseEmitter.php @@ -0,0 +1,136 @@ +responseChunkSize = $responseChunkSize; + } + + /** + * Send the response the client + */ + public function emit(ResponseInterface $response): void + { + $isEmpty = $this->isResponseEmpty($response); + if (headers_sent() === false) { + $this->emitHeaders($response); + + // Set the status _after_ the headers, because of PHP's "helpful" behavior with location headers. + // See https://github.com/slimphp/Slim/issues/1730 + + $this->emitStatusLine($response); + } + + if (!$isEmpty) { + $this->emitBody($response); + } + } + + /** + * Emit Response Headers + */ + private function emitHeaders(ResponseInterface $response): void + { + foreach ($response->getHeaders() as $name => $values) { + $first = strtolower($name) !== 'set-cookie'; + foreach ($values as $value) { + $header = sprintf('%s: %s', $name, $value); + header($header, $first); + $first = false; + } + } + } + + /** + * Emit Status Line + */ + private function emitStatusLine(ResponseInterface $response): void + { + $statusLine = sprintf( + 'HTTP/%s %s %s', + $response->getProtocolVersion(), + $response->getStatusCode(), + $response->getReasonPhrase() + ); + header($statusLine, true, $response->getStatusCode()); + } + + /** + * Emit Body + */ + private function emitBody(ResponseInterface $response): void + { + $body = $response->getBody(); + if ($body->isSeekable()) { + $body->rewind(); + } + + $amountToRead = (int) $response->getHeaderLine('Content-Length'); + if (!$amountToRead) { + $amountToRead = $body->getSize(); + } + + if ($amountToRead) { + while ($amountToRead > 0 && !$body->eof()) { + $length = min($this->responseChunkSize, $amountToRead); + $data = $body->read($length); + echo $data; + + $amountToRead -= strlen($data); + + if (connection_status() !== CONNECTION_NORMAL) { + break; + } + } + } else { + while (!$body->eof()) { + echo $body->read($this->responseChunkSize); + if (connection_status() !== CONNECTION_NORMAL) { + break; + } + } + } + } + + /** + * Asserts response body is empty or status code is 204, 205 or 304 + */ + public function isResponseEmpty(ResponseInterface $response): bool + { + if (in_array($response->getStatusCode(), [204, 205, 304], true)) { + return true; + } + $stream = $response->getBody(); + $seekable = $stream->isSeekable(); + if ($seekable) { + $stream->rewind(); + } + return $seekable ? $stream->read(1) === '' : $stream->eof(); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routable.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routable.php deleted file mode 100644 index c912db43..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Routable.php +++ /dev/null @@ -1,106 +0,0 @@ -middleware; - } - - /** - * Get the route pattern - * - * @return string - */ - public function getPattern() - { - return $this->pattern; - } - - /** - * Set container for use with resolveCallable - * - * @param ContainerInterface $container - * - * @return self - */ - public function setContainer(ContainerInterface $container) - { - $this->container = $container; - return $this; - } - - /** - * Prepend middleware to the middleware collection - * - * @param callable|string $callable The callback routine - * - * @return static - */ - public function add($callable) - { - $this->middleware[] = new DeferredCallable($callable, $this->container); - return $this; - } - - /** - * Set the route pattern - * - * @param string $newPattern - */ - public function setPattern($newPattern) - { - $this->pattern = $newPattern; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Route.php b/advancedcontentfilter/vendor/slim/slim/Slim/Route.php deleted file mode 100644 index fa8be4e4..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Route.php +++ /dev/null @@ -1,349 +0,0 @@ -methods = is_string($methods) ? [$methods] : $methods; - $this->pattern = $pattern; - $this->callable = $callable; - $this->groups = $groups; - $this->identifier = 'route' . $identifier; - } - - /** - * Finalize the route in preparation for dispatching - */ - public function finalize() - { - if ($this->finalized) { - return; - } - - $groupMiddleware = []; - foreach ($this->getGroups() as $group) { - $groupMiddleware = array_merge($group->getMiddleware(), $groupMiddleware); - } - - $this->middleware = array_merge($this->middleware, $groupMiddleware); - - foreach ($this->getMiddleware() as $middleware) { - $this->addMiddleware($middleware); - } - - $this->finalized = true; - } - - /** - * Get route callable - * - * @return callable - */ - public function getCallable() - { - return $this->callable; - } - - /** - * This method enables you to override the Route's callable - * - * @param string|\Closure $callable - */ - public function setCallable($callable) - { - $this->callable = $callable; - } - - /** - * Get route methods - * - * @return string[] - */ - public function getMethods() - { - return $this->methods; - } - - /** - * Get parent route groups - * - * @return RouteGroup[] - */ - public function getGroups() - { - return $this->groups; - } - - /** - * Get route name - * - * @return null|string - */ - public function getName() - { - return $this->name; - } - - /** - * Get route identifier - * - * @return string - */ - public function getIdentifier() - { - return $this->identifier; - } - - /** - * Get output buffering mode - * - * @return boolean|string - */ - public function getOutputBuffering() - { - return $this->outputBuffering; - } - - /** - * Set output buffering mode - * - * One of: false, 'prepend' or 'append' - * - * @param boolean|string $mode - * - * @throws InvalidArgumentException If an unknown buffering mode is specified - */ - public function setOutputBuffering($mode) - { - if (!in_array($mode, [false, 'prepend', 'append'], true)) { - throw new InvalidArgumentException('Unknown output buffering mode'); - } - $this->outputBuffering = $mode; - } - - /** - * Set route name - * - * @param string $name - * - * @return self - * - * @throws InvalidArgumentException if the route name is not a string - */ - public function setName($name) - { - if (!is_string($name)) { - throw new InvalidArgumentException('Route name must be a string'); - } - $this->name = $name; - return $this; - } - - /** - * Set a route argument - * - * @param string $name - * @param string $value - * - * @return self - */ - public function setArgument($name, $value) - { - $this->arguments[$name] = $value; - return $this; - } - - /** - * Replace route arguments - * - * @param array $arguments - * - * @return self - */ - public function setArguments(array $arguments) - { - $this->arguments = $arguments; - return $this; - } - - /** - * Retrieve route arguments - * - * @return array - */ - public function getArguments() - { - return $this->arguments; - } - - /** - * Retrieve a specific route argument - * - * @param string $name - * @param string|null $default - * - * @return mixed - */ - public function getArgument($name, $default = null) - { - if (array_key_exists($name, $this->arguments)) { - return $this->arguments[$name]; - } - return $default; - } - - /******************************************************************************** - * Route Runner - *******************************************************************************/ - - /** - * Prepare the route for use - * - * @param ServerRequestInterface $request - * @param array $arguments - */ - public function prepare(ServerRequestInterface $request, array $arguments) - { - // Add the arguments - foreach ($arguments as $k => $v) { - $this->setArgument($k, $v); - } - } - - /** - * Run route - * - * This method traverses the middleware stack, including the route's callable - * and captures the resultant HTTP response object. It then sends the response - * back to the Application. - * - * @param ServerRequestInterface $request - * @param ResponseInterface $response - * - * @return ResponseInterface - */ - public function run(ServerRequestInterface $request, ResponseInterface $response) - { - // Finalise route now that we are about to run it - $this->finalize(); - - // Traverse middleware stack and fetch updated response - return $this->callMiddlewareStack($request, $response); - } - - /** - * Dispatch route callable against current Request and Response objects - * - * This method invokes the route object's callable. If middleware is - * registered for the route, each callable middleware is invoked in - * the order specified. - * - * @param ServerRequestInterface $request The current Request object - * @param ResponseInterface $response The current Response object - * @return \Psr\Http\Message\ResponseInterface - * @throws \Exception if the route callable throws an exception - */ - public function __invoke(ServerRequestInterface $request, ResponseInterface $response) - { - $this->callable = $this->resolveCallable($this->callable); - - /** @var InvocationStrategyInterface $handler */ - $handler = isset($this->container) ? $this->container->get('foundHandler') : new RequestResponse(); - - $newResponse = $handler($this->callable, $request, $response, $this->arguments); - - if ($newResponse instanceof ResponseInterface) { - // if route callback returns a ResponseInterface, then use it - $response = $newResponse; - } elseif (is_string($newResponse)) { - // if route callback returns a string, then append it to the response - if ($response->getBody()->isWritable()) { - $response->getBody()->write($newResponse); - } - } - - return $response; - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/RouteGroup.php b/advancedcontentfilter/vendor/slim/slim/Slim/RouteGroup.php deleted file mode 100644 index 8260bbd6..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/RouteGroup.php +++ /dev/null @@ -1,47 +0,0 @@ -pattern = $pattern; - $this->callable = $callable; - } - - /** - * Invoke the group to register any Routable objects within it. - * - * @param App $app The App instance to bind/pass to the group callable - */ - public function __invoke(App $app = null) - { - $callable = $this->resolveCallable($this->callable); - if ($callable instanceof Closure && $app !== null) { - $callable = $callable->bindTo($app); - } - - $callable($app); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Router.php b/advancedcontentfilter/vendor/slim/slim/Slim/Router.php deleted file mode 100644 index 83116288..00000000 --- a/advancedcontentfilter/vendor/slim/slim/Slim/Router.php +++ /dev/null @@ -1,455 +0,0 @@ -routeParser = $parser ?: new StdParser; - } - - /** - * Set the base path used in pathFor() - * - * @param string $basePath - * - * @return self - */ - public function setBasePath($basePath) - { - if (!is_string($basePath)) { - throw new InvalidArgumentException('Router basePath must be a string'); - } - - $this->basePath = $basePath; - - return $this; - } - - /** - * Set path to fast route cache file. If this is false then route caching is disabled. - * - * @param string|false $cacheFile - * - * @return self - */ - public function setCacheFile($cacheFile) - { - if (!is_string($cacheFile) && $cacheFile !== false) { - throw new InvalidArgumentException('Router cacheFile must be a string or false'); - } - - $this->cacheFile = $cacheFile; - - if ($cacheFile !== false && !is_writable(dirname($cacheFile))) { - throw new RuntimeException('Router cacheFile directory must be writable'); - } - - - return $this; - } - - /** - * @param ContainerInterface $container - */ - public function setContainer(ContainerInterface $container) - { - $this->container = $container; - } - - /** - * Add route - * - * @param string[] $methods Array of HTTP methods - * @param string $pattern The route pattern - * @param callable $handler The route callable - * - * @return RouteInterface - * - * @throws InvalidArgumentException if the route pattern isn't a string - */ - public function map($methods, $pattern, $handler) - { - if (!is_string($pattern)) { - throw new InvalidArgumentException('Route pattern must be a string'); - } - - // Prepend parent group pattern(s) - if ($this->routeGroups) { - $pattern = $this->processGroups() . $pattern; - } - - // According to RFC methods are defined in uppercase (See RFC 7231) - $methods = array_map("strtoupper", $methods); - - // Add route - $route = $this->createRoute($methods, $pattern, $handler); - $this->routes[$route->getIdentifier()] = $route; - $this->routeCounter++; - - return $route; - } - - /** - * Dispatch router for HTTP request - * - * @param ServerRequestInterface $request The current HTTP request object - * - * @return array - * - * @link https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php - */ - public function dispatch(ServerRequestInterface $request) - { - $uri = '/' . ltrim($request->getUri()->getPath(), '/'); - - return $this->createDispatcher()->dispatch( - $request->getMethod(), - $uri - ); - } - - /** - * Create a new Route object - * - * @param string[] $methods Array of HTTP methods - * @param string $pattern The route pattern - * @param callable $callable The route callable - * - * @return \Slim\Interfaces\RouteInterface - */ - protected function createRoute($methods, $pattern, $callable) - { - $route = new Route($methods, $pattern, $callable, $this->routeGroups, $this->routeCounter); - if (!empty($this->container)) { - $route->setContainer($this->container); - } - - return $route; - } - - /** - * @return \FastRoute\Dispatcher - */ - protected function createDispatcher() - { - if ($this->dispatcher) { - return $this->dispatcher; - } - - $routeDefinitionCallback = function (RouteCollector $r) { - foreach ($this->getRoutes() as $route) { - $r->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier()); - } - }; - - if ($this->cacheFile) { - $this->dispatcher = \FastRoute\cachedDispatcher($routeDefinitionCallback, [ - 'routeParser' => $this->routeParser, - 'cacheFile' => $this->cacheFile, - ]); - } else { - $this->dispatcher = \FastRoute\simpleDispatcher($routeDefinitionCallback, [ - 'routeParser' => $this->routeParser, - ]); - } - - return $this->dispatcher; - } - - /** - * @param \FastRoute\Dispatcher $dispatcher - */ - public function setDispatcher(Dispatcher $dispatcher) - { - $this->dispatcher = $dispatcher; - } - - /** - * Get route objects - * - * @return Route[] - */ - public function getRoutes() - { - return $this->routes; - } - - /** - * Get named route object - * - * @param string $name Route name - * - * @return Route - * - * @throws RuntimeException If named route does not exist - */ - public function getNamedRoute($name) - { - foreach ($this->routes as $route) { - if ($name == $route->getName()) { - return $route; - } - } - throw new RuntimeException('Named route does not exist for name: ' . $name); - } - - /** - * Remove named route - * - * @param string $name Route name - * - * @throws RuntimeException If named route does not exist - */ - public function removeNamedRoute($name) - { - $route = $this->getNamedRoute($name); - - // no exception, route exists, now remove by id - unset($this->routes[$route->getIdentifier()]); - } - - /** - * Process route groups - * - * @return string A group pattern to prefix routes with - */ - protected function processGroups() - { - $pattern = ""; - foreach ($this->routeGroups as $group) { - $pattern .= $group->getPattern(); - } - return $pattern; - } - - /** - * Add a route group to the array - * - * @param string $pattern - * @param callable $callable - * - * @return RouteGroupInterface - */ - public function pushGroup($pattern, $callable) - { - $group = new RouteGroup($pattern, $callable); - array_push($this->routeGroups, $group); - return $group; - } - - /** - * Removes the last route group from the array - * - * @return RouteGroup|bool The RouteGroup if successful, else False - */ - public function popGroup() - { - $group = array_pop($this->routeGroups); - return $group instanceof RouteGroup ? $group : false; - } - - /** - * @param $identifier - * @return \Slim\Interfaces\RouteInterface - */ - public function lookupRoute($identifier) - { - if (!isset($this->routes[$identifier])) { - throw new RuntimeException('Route not found, looks like your route cache is stale.'); - } - return $this->routes[$identifier]; - } - - /** - * Build the path for a named route excluding the base path - * - * @param string $name Route name - * @param array $data Named argument replacement data - * @param array $queryParams Optional query string parameters - * - * @return string - * - * @throws RuntimeException If named route does not exist - * @throws InvalidArgumentException If required data not provided - */ - public function relativePathFor($name, array $data = [], array $queryParams = []) - { - $route = $this->getNamedRoute($name); - $pattern = $route->getPattern(); - - $routeDatas = $this->routeParser->parse($pattern); - // $routeDatas is an array of all possible routes that can be made. There is - // one routedata for each optional parameter plus one for no optional parameters. - // - // The most specific is last, so we look for that first. - $routeDatas = array_reverse($routeDatas); - - $segments = []; - foreach ($routeDatas as $routeData) { - foreach ($routeData as $item) { - if (is_string($item)) { - // this segment is a static string - $segments[] = $item; - continue; - } - - // This segment has a parameter: first element is the name - if (!array_key_exists($item[0], $data)) { - // we don't have a data element for this segment: cancel - // testing this routeData item, so that we can try a less - // specific routeData item. - $segments = []; - $segmentName = $item[0]; - break; - } - $segments[] = $data[$item[0]]; - } - if (!empty($segments)) { - // we found all the parameters for this route data, no need to check - // less specific ones - break; - } - } - - if (empty($segments)) { - throw new InvalidArgumentException('Missing data for URL segment: ' . $segmentName); - } - $url = implode('', $segments); - - if ($queryParams) { - $url .= '?' . http_build_query($queryParams); - } - - return $url; - } - - - /** - * Build the path for a named route including the base path - * - * @param string $name Route name - * @param array $data Named argument replacement data - * @param array $queryParams Optional query string parameters - * - * @return string - * - * @throws RuntimeException If named route does not exist - * @throws InvalidArgumentException If required data not provided - */ - public function pathFor($name, array $data = [], array $queryParams = []) - { - $url = $this->relativePathFor($name, $data, $queryParams); - - if ($this->basePath) { - $url = $this->basePath . $url; - } - - return $url; - } - - /** - * Build the path for a named route. - * - * This method is deprecated. Use pathFor() from now on. - * - * @param string $name Route name - * @param array $data Named argument replacement data - * @param array $queryParams Optional query string parameters - * - * @return string - * - * @throws RuntimeException If named route does not exist - * @throws InvalidArgumentException If required data not provided - */ - public function urlFor($name, array $data = [], array $queryParams = []) - { - trigger_error('urlFor() is deprecated. Use pathFor() instead.', E_USER_DEPRECATED); - return $this->pathFor($name, $data, $queryParams); - } -} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/Dispatcher.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/Dispatcher.php new file mode 100644 index 00000000..e33eac39 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/Dispatcher.php @@ -0,0 +1,78 @@ +routeCollector = $routeCollector; + } + + protected function createDispatcher(): FastRouteDispatcher + { + if ($this->dispatcher) { + return $this->dispatcher; + } + + $routeDefinitionCallback = function (FastRouteCollector $r): void { + $basePath = $this->routeCollector->getBasePath(); + + foreach ($this->routeCollector->getRoutes() as $route) { + $r->addRoute($route->getMethods(), $basePath . $route->getPattern(), $route->getIdentifier()); + } + }; + + $cacheFile = $this->routeCollector->getCacheFile(); + if ($cacheFile) { + /** @var FastRouteDispatcher $dispatcher */ + $dispatcher = \FastRoute\cachedDispatcher($routeDefinitionCallback, [ + 'dataGenerator' => GroupCountBased::class, + 'dispatcher' => FastRouteDispatcher::class, + 'routeParser' => new Std(), + 'cacheFile' => $cacheFile, + ]); + } else { + /** @var FastRouteDispatcher $dispatcher */ + $dispatcher = \FastRoute\simpleDispatcher($routeDefinitionCallback, [ + 'dataGenerator' => GroupCountBased::class, + 'dispatcher' => FastRouteDispatcher::class, + 'routeParser' => new Std(), + ]); + } + + $this->dispatcher = $dispatcher; + return $this->dispatcher; + } + + /** + * {@inheritdoc} + */ + public function dispatch(string $method, string $uri): RoutingResults + { + $dispatcher = $this->createDispatcher(); + $results = $dispatcher->dispatch($method, $uri); + return new RoutingResults($this, $method, $uri, $results[0], $results[1], $results[2]); + } + + /** + * {@inheritdoc} + */ + public function getAllowedMethods(string $uri): array + { + $dispatcher = $this->createDispatcher(); + return $dispatcher->getAllowedMethods($uri); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/FastRouteDispatcher.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/FastRouteDispatcher.php new file mode 100644 index 00000000..797746bb --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/FastRouteDispatcher.php @@ -0,0 +1,109 @@ +} + */ + public function dispatch($httpMethod, $uri): array + { + $routingResults = $this->routingResults($httpMethod, $uri); + if ($routingResults[0] === self::FOUND) { + return $routingResults; + } + + // For HEAD requests, attempt fallback to GET + if ($httpMethod === 'HEAD') { + $routingResults = $this->routingResults('GET', $uri); + if ($routingResults[0] === self::FOUND) { + return $routingResults; + } + } + + // If nothing else matches, try fallback routes + $routingResults = $this->routingResults('*', $uri); + if ($routingResults[0] === self::FOUND) { + return $routingResults; + } + + if (!empty($this->getAllowedMethods($uri))) { + return [self::METHOD_NOT_ALLOWED, null, []]; + } + + return [self::NOT_FOUND, null, []]; + } + + /** + * @param string $httpMethod + * @param string $uri + * + * @return array{int, string|null, array} + */ + private function routingResults(string $httpMethod, string $uri): array + { + if (isset($this->staticRouteMap[$httpMethod][$uri])) { + /** @var string $routeIdentifier */ + $routeIdentifier = $this->staticRouteMap[$httpMethod][$uri]; + return [self::FOUND, $routeIdentifier, []]; + } + + if (isset($this->variableRouteData[$httpMethod])) { + /** @var array{0: int, 1?: string, 2?: array} $result */ + $result = $this->dispatchVariableRoute($this->variableRouteData[$httpMethod], $uri); + if ($result[0] === self::FOUND) { + /** @var array{int, string, array} $result */ + return [self::FOUND, $result[1], $result[2]]; + } + } + + return [self::NOT_FOUND, null, []]; + } + + /** + * @param string $uri + * + * @return string[] + */ + public function getAllowedMethods(string $uri): array + { + if (isset($this->allowedMethods[$uri])) { + return $this->allowedMethods[$uri]; + } + + $allowedMethods = []; + foreach ($this->staticRouteMap as $method => $uriMap) { + if (isset($uriMap[$uri])) { + $allowedMethods[$method] = true; + } + } + + foreach ($this->variableRouteData as $method => $routeData) { + $result = $this->dispatchVariableRoute($routeData, $uri); + if ($result[0] === self::FOUND) { + $allowedMethods[$method] = true; + } + } + + return $this->allowedMethods[$uri] = array_keys($allowedMethods); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/Route.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/Route.php new file mode 100644 index 00000000..2cd9fa56 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/Route.php @@ -0,0 +1,360 @@ + + */ + protected array $arguments = []; + + /** + * Route arguments parameters + * + * @var string[] + */ + protected array $savedArguments = []; + + /** + * Container + */ + protected ?ContainerInterface $container = null; + + protected MiddlewareDispatcher $middlewareDispatcher; + + /** + * Route callable + * + * @var callable|string + */ + protected $callable; + + protected CallableResolverInterface $callableResolver; + + protected ResponseFactoryInterface $responseFactory; + + /** + * Route pattern + */ + protected string $pattern; + + protected bool $groupMiddlewareAppended = false; + + /** + * @param string[] $methods The route HTTP methods + * @param string $pattern The route pattern + * @param callable|string $callable The route callable + * @param ResponseFactoryInterface $responseFactory + * @param CallableResolverInterface $callableResolver + * @param ContainerInterface|null $container + * @param InvocationStrategyInterface|null $invocationStrategy + * @param RouteGroupInterface[] $groups The parent route groups + * @param int $identifier The route identifier + */ + public function __construct( + array $methods, + string $pattern, + $callable, + ResponseFactoryInterface $responseFactory, + CallableResolverInterface $callableResolver, + ?ContainerInterface $container = null, + ?InvocationStrategyInterface $invocationStrategy = null, + array $groups = [], + int $identifier = 0 + ) { + $this->methods = $methods; + $this->pattern = $pattern; + $this->callable = $callable; + $this->responseFactory = $responseFactory; + $this->callableResolver = $callableResolver; + $this->container = $container; + $this->invocationStrategy = $invocationStrategy ?? new RequestResponse(); + $this->groups = $groups; + $this->identifier = 'route' . $identifier; + $this->middlewareDispatcher = new MiddlewareDispatcher($this, $callableResolver, $container); + } + + public function getCallableResolver(): CallableResolverInterface + { + return $this->callableResolver; + } + + /** + * {@inheritdoc} + */ + public function getInvocationStrategy(): InvocationStrategyInterface + { + return $this->invocationStrategy; + } + + /** + * {@inheritdoc} + */ + public function setInvocationStrategy(InvocationStrategyInterface $invocationStrategy): RouteInterface + { + $this->invocationStrategy = $invocationStrategy; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getMethods(): array + { + return $this->methods; + } + + /** + * {@inheritdoc} + */ + public function getPattern(): string + { + return $this->pattern; + } + + /** + * {@inheritdoc} + */ + public function setPattern(string $pattern): RouteInterface + { + $this->pattern = $pattern; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCallable() + { + return $this->callable; + } + + /** + * {@inheritdoc} + */ + public function setCallable($callable): RouteInterface + { + $this->callable = $callable; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * {@inheritdoc} + */ + public function setName(string $name): RouteInterface + { + $this->name = $name; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getIdentifier(): string + { + return $this->identifier; + } + + /** + * {@inheritdoc} + */ + public function getArgument(string $name, ?string $default = null): ?string + { + if (array_key_exists($name, $this->arguments)) { + return $this->arguments[$name]; + } + return $default; + } + + /** + * {@inheritdoc} + */ + public function getArguments(): array + { + return $this->arguments; + } + + /** + * {@inheritdoc} + */ + public function setArguments(array $arguments, bool $includeInSavedArguments = true): RouteInterface + { + if ($includeInSavedArguments) { + $this->savedArguments = $arguments; + } + + $this->arguments = $arguments; + return $this; + } + + /** + * @return RouteGroupInterface[] + */ + public function getGroups(): array + { + return $this->groups; + } + + /** + * {@inheritdoc} + */ + public function add($middleware): RouteInterface + { + $this->middlewareDispatcher->add($middleware); + return $this; + } + + /** + * {@inheritdoc} + */ + public function addMiddleware(MiddlewareInterface $middleware): RouteInterface + { + $this->middlewareDispatcher->addMiddleware($middleware); + return $this; + } + + /** + * {@inheritdoc} + */ + public function prepare(array $arguments): RouteInterface + { + $this->arguments = array_replace($this->savedArguments, $arguments); + return $this; + } + + /** + * {@inheritdoc} + */ + public function setArgument(string $name, string $value, bool $includeInSavedArguments = true): RouteInterface + { + if ($includeInSavedArguments) { + $this->savedArguments[$name] = $value; + } + + $this->arguments[$name] = $value; + return $this; + } + + /** + * {@inheritdoc} + */ + public function run(ServerRequestInterface $request): ResponseInterface + { + if (!$this->groupMiddlewareAppended) { + $this->appendGroupMiddlewareToRoute(); + } + + return $this->middlewareDispatcher->handle($request); + } + + /** + * @return void + */ + protected function appendGroupMiddlewareToRoute(): void + { + $inner = $this->middlewareDispatcher; + $this->middlewareDispatcher = new MiddlewareDispatcher($inner, $this->callableResolver, $this->container); + + /** @var RouteGroupInterface $group */ + foreach (array_reverse($this->groups) as $group) { + $group->appendMiddlewareToDispatcher($this->middlewareDispatcher); + } + + $this->groupMiddlewareAppended = true; + } + + /** + * {@inheritdoc} + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + if ($this->callableResolver instanceof AdvancedCallableResolverInterface) { + $callable = $this->callableResolver->resolveRoute($this->callable); + } else { + $callable = $this->callableResolver->resolve($this->callable); + } + $strategy = $this->invocationStrategy; + + /** @var string[] $strategyImplements */ + $strategyImplements = class_implements($strategy); + + if ( + is_array($callable) + && $callable[0] instanceof RequestHandlerInterface + && !in_array(RequestHandlerInvocationStrategyInterface::class, $strategyImplements) + ) { + $strategy = new RequestHandler(); + } + + $response = $this->responseFactory->createResponse(); + return $strategy($callable, $request, $response, $this->arguments); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollector.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollector.php new file mode 100644 index 00000000..61b45030 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollector.php @@ -0,0 +1,293 @@ +responseFactory = $responseFactory; + $this->callableResolver = $callableResolver; + $this->container = $container; + $this->defaultInvocationStrategy = $defaultInvocationStrategy ?? new RequestResponse(); + $this->routeParser = $routeParser ?? new RouteParser($this); + + if ($cacheFile) { + $this->setCacheFile($cacheFile); + } + } + + public function getRouteParser(): RouteParserInterface + { + return $this->routeParser; + } + + /** + * Get default route invocation strategy + */ + public function getDefaultInvocationStrategy(): InvocationStrategyInterface + { + return $this->defaultInvocationStrategy; + } + + public function setDefaultInvocationStrategy(InvocationStrategyInterface $strategy): RouteCollectorInterface + { + $this->defaultInvocationStrategy = $strategy; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getCacheFile(): ?string + { + return $this->cacheFile; + } + + /** + * {@inheritdoc} + */ + public function setCacheFile(string $cacheFile): RouteCollectorInterface + { + if (file_exists($cacheFile) && !is_readable($cacheFile)) { + throw new RuntimeException( + sprintf('Route collector cache file `%s` is not readable', $cacheFile) + ); + } + + if (!file_exists($cacheFile) && !is_writable(dirname($cacheFile))) { + throw new RuntimeException( + sprintf('Route collector cache file directory `%s` is not writable', dirname($cacheFile)) + ); + } + + $this->cacheFile = $cacheFile; + return $this; + } + + /** + * {@inheritdoc} + */ + public function getBasePath(): string + { + return $this->basePath; + } + + /** + * Set the base path used in urlFor() + */ + public function setBasePath(string $basePath): RouteCollectorInterface + { + $this->basePath = $basePath; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getRoutes(): array + { + return $this->routes; + } + + /** + * {@inheritdoc} + */ + public function removeNamedRoute(string $name): RouteCollectorInterface + { + $route = $this->getNamedRoute($name); + + unset($this->routesByName[$route->getName()], $this->routes[$route->getIdentifier()]); + return $this; + } + + /** + * {@inheritdoc} + */ + public function getNamedRoute(string $name): RouteInterface + { + if (isset($this->routesByName[$name])) { + $route = $this->routesByName[$name]; + if ($route->getName() === $name) { + return $route; + } + + unset($this->routesByName[$name]); + } + + foreach ($this->routes as $route) { + if ($name === $route->getName()) { + $this->routesByName[$name] = $route; + return $route; + } + } + + throw new RuntimeException('Named route does not exist for name: ' . $name); + } + + /** + * {@inheritdoc} + */ + public function lookupRoute(string $identifier): RouteInterface + { + if (!isset($this->routes[$identifier])) { + throw new RuntimeException('Route not found, looks like your route cache is stale.'); + } + return $this->routes[$identifier]; + } + + /** + * {@inheritdoc} + */ + public function group(string $pattern, $callable): RouteGroupInterface + { + $routeGroup = $this->createGroup($pattern, $callable); + $this->routeGroups[] = $routeGroup; + + $routeGroup->collectRoutes(); + array_pop($this->routeGroups); + + return $routeGroup; + } + + /** + * @param string|callable $callable + */ + protected function createGroup(string $pattern, $callable): RouteGroupInterface + { + $routeCollectorProxy = $this->createProxy($pattern); + return new RouteGroup($pattern, $callable, $this->callableResolver, $routeCollectorProxy); + } + + protected function createProxy(string $pattern): RouteCollectorProxyInterface + { + return new RouteCollectorProxy( + $this->responseFactory, + $this->callableResolver, + $this->container, + $this, + $pattern + ); + } + + /** + * {@inheritdoc} + */ + public function map(array $methods, string $pattern, $handler): RouteInterface + { + $route = $this->createRoute($methods, $pattern, $handler); + $this->routes[$route->getIdentifier()] = $route; + + $routeName = $route->getName(); + if ($routeName !== null && !isset($this->routesByName[$routeName])) { + $this->routesByName[$routeName] = $route; + } + + $this->routeCounter++; + + return $route; + } + + /** + * @param string[] $methods + * @param callable|string $callable + */ + protected function createRoute(array $methods, string $pattern, $callable): RouteInterface + { + return new Route( + $methods, + $pattern, + $callable, + $this->responseFactory, + $this->callableResolver, + $this->container, + $this->defaultInvocationStrategy, + $this->routeGroups, + $this->routeCounter + ); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollectorProxy.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollectorProxy.php new file mode 100644 index 00000000..f8bc232b --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteCollectorProxy.php @@ -0,0 +1,187 @@ +responseFactory = $responseFactory; + $this->callableResolver = $callableResolver; + $this->container = $container; + $this->routeCollector = $routeCollector ?? new RouteCollector($responseFactory, $callableResolver, $container); + $this->groupPattern = $groupPattern; + } + + /** + * {@inheritdoc} + */ + public function getResponseFactory(): ResponseFactoryInterface + { + return $this->responseFactory; + } + + /** + * {@inheritdoc} + */ + public function getCallableResolver(): CallableResolverInterface + { + return $this->callableResolver; + } + + /** + * {@inheritdoc} + */ + public function getContainer(): ?ContainerInterface + { + return $this->container; + } + + /** + * {@inheritdoc} + */ + public function getRouteCollector(): RouteCollectorInterface + { + return $this->routeCollector; + } + + /** + * {@inheritdoc} + */ + public function getBasePath(): string + { + return $this->routeCollector->getBasePath(); + } + + /** + * {@inheritdoc} + */ + public function setBasePath(string $basePath): RouteCollectorProxyInterface + { + $this->routeCollector->setBasePath($basePath); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function get(string $pattern, $callable): RouteInterface + { + return $this->map(['GET'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function post(string $pattern, $callable): RouteInterface + { + return $this->map(['POST'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function put(string $pattern, $callable): RouteInterface + { + return $this->map(['PUT'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function patch(string $pattern, $callable): RouteInterface + { + return $this->map(['PATCH'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function delete(string $pattern, $callable): RouteInterface + { + return $this->map(['DELETE'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function options(string $pattern, $callable): RouteInterface + { + return $this->map(['OPTIONS'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function any(string $pattern, $callable): RouteInterface + { + return $this->map(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function map(array $methods, string $pattern, $callable): RouteInterface + { + $pattern = $this->groupPattern . $pattern; + + return $this->routeCollector->map($methods, $pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function group(string $pattern, $callable): RouteGroupInterface + { + $pattern = $this->groupPattern . $pattern; + + return $this->routeCollector->group($pattern, $callable); + } + + /** + * {@inheritdoc} + */ + public function redirect(string $from, $to, int $status = 302): RouteInterface + { + $responseFactory = $this->responseFactory; + + $handler = function () use ($to, $status, $responseFactory) { + $response = $responseFactory->createResponse($status); + return $response->withHeader('Location', (string) $to); + }; + + return $this->get($from, $handler); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteContext.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteContext.php new file mode 100644 index 00000000..3ba5e23a --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteContext.php @@ -0,0 +1,88 @@ +getAttribute(self::ROUTE); + $routeParser = $serverRequest->getAttribute(self::ROUTE_PARSER); + $routingResults = $serverRequest->getAttribute(self::ROUTING_RESULTS); + $basePath = $serverRequest->getAttribute(self::BASE_PATH); + + if ($routeParser === null || $routingResults === null) { + throw new RuntimeException('Cannot create RouteContext before routing has been completed'); + } + + /** @var RouteInterface|null $route */ + /** @var RouteParserInterface $routeParser */ + /** @var RoutingResults $routingResults */ + /** @var string|null $basePath */ + return new self($route, $routeParser, $routingResults, $basePath); + } + + private ?RouteInterface $route; + + private RouteParserInterface $routeParser; + + private RoutingResults $routingResults; + + private ?string $basePath; + + private function __construct( + ?RouteInterface $route, + RouteParserInterface $routeParser, + RoutingResults $routingResults, + ?string $basePath = null + ) { + $this->route = $route; + $this->routeParser = $routeParser; + $this->routingResults = $routingResults; + $this->basePath = $basePath; + } + + public function getRoute(): ?RouteInterface + { + return $this->route; + } + + public function getRouteParser(): RouteParserInterface + { + return $this->routeParser; + } + + public function getRoutingResults(): RoutingResults + { + return $this->routingResults; + } + + public function getBasePath(): string + { + if ($this->basePath === null) { + throw new RuntimeException('No base path defined.'); + } + return $this->basePath; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteGroup.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteGroup.php new file mode 100644 index 00000000..cd2f4e79 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteGroup.php @@ -0,0 +1,104 @@ +pattern = $pattern; + $this->callable = $callable; + $this->callableResolver = $callableResolver; + $this->routeCollectorProxy = $routeCollectorProxy; + } + + /** + * {@inheritdoc} + */ + public function collectRoutes(): RouteGroupInterface + { + if ($this->callableResolver instanceof AdvancedCallableResolverInterface) { + $callable = $this->callableResolver->resolveRoute($this->callable); + } else { + $callable = $this->callableResolver->resolve($this->callable); + } + $callable($this->routeCollectorProxy); + return $this; + } + + /** + * {@inheritdoc} + */ + public function add($middleware): RouteGroupInterface + { + $this->middleware[] = $middleware; + return $this; + } + + /** + * {@inheritdoc} + */ + public function addMiddleware(MiddlewareInterface $middleware): RouteGroupInterface + { + $this->middleware[] = $middleware; + return $this; + } + + /** + * {@inheritdoc} + */ + public function appendMiddlewareToDispatcher(MiddlewareDispatcher $dispatcher): RouteGroupInterface + { + foreach ($this->middleware as $middleware) { + $dispatcher->add($middleware); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getPattern(): string + { + return $this->pattern; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteParser.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteParser.php new file mode 100644 index 00000000..afb533cc --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteParser.php @@ -0,0 +1,127 @@ +routeCollector = $routeCollector; + $this->routeParser = new Std(); + } + + /** + * {@inheritdoc} + */ + public function relativeUrlFor(string $routeName, array $data = [], array $queryParams = []): string + { + $route = $this->routeCollector->getNamedRoute($routeName); + $pattern = $route->getPattern(); + + $segments = []; + $segmentName = ''; + + /* + * $routes is an associative array of expressions representing a route as multiple segments + * There is an expression for each optional parameter plus one without the optional parameters + * The most specific is last, hence why we reverse the array before iterating over it + */ + $expressions = array_reverse($this->routeParser->parse($pattern)); + foreach ($expressions as $expression) { + foreach ($expression as $segment) { + /* + * Each $segment is either a string or an array of strings + * containing optional parameters of an expression + */ + if (is_string($segment)) { + $segments[] = $segment; + continue; + } + + /** @var string[] $segment */ + /* + * If we don't have a data element for this segment in the provided $data + * we cancel testing to move onto the next expression with a less specific item + */ + if (!array_key_exists($segment[0], $data)) { + $segments = []; + $segmentName = $segment[0]; + break; + } + + $segments[] = $data[$segment[0]]; + } + + /* + * If we get to this logic block we have found all the parameters + * for the provided $data which means we don't need to continue testing + * less specific expressions + */ + if (!empty($segments)) { + break; + } + } + + if (empty($segments)) { + throw new InvalidArgumentException('Missing data for URL segment: ' . $segmentName); + } + + $url = implode('', $segments); + if ($queryParams) { + $url .= '?' . http_build_query($queryParams); + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function urlFor(string $routeName, array $data = [], array $queryParams = []): string + { + $basePath = $this->routeCollector->getBasePath(); + $url = $this->relativeUrlFor($routeName, $data, $queryParams); + + if ($basePath) { + $url = $basePath . $url; + } + + return $url; + } + + /** + * {@inheritdoc} + */ + public function fullUrlFor(UriInterface $uri, string $routeName, array $data = [], array $queryParams = []): string + { + $path = $this->urlFor($routeName, $data, $queryParams); + $scheme = $uri->getScheme(); + $authority = $uri->getAuthority(); + $protocol = ($scheme ? $scheme . ':' : '') . ($authority ? '//' . $authority : ''); + return $protocol . $path; + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteResolver.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteResolver.php new file mode 100644 index 00000000..d4f4eafa --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteResolver.php @@ -0,0 +1,56 @@ +routeCollector = $routeCollector; + $this->dispatcher = $dispatcher ?? new Dispatcher($routeCollector); + } + + /** + * @param string $uri Should be $request->getUri()->getPath() + */ + public function computeRoutingResults(string $uri, string $method): RoutingResults + { + $uri = rawurldecode($uri); + if ($uri === '' || $uri[0] !== '/') { + $uri = '/' . $uri; + } + return $this->dispatcher->dispatch($method, $uri); + } + + /** + * @throws RuntimeException + */ + public function resolveRoute(string $identifier): RouteInterface + { + return $this->routeCollector->lookupRoute($identifier); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteRunner.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteRunner.php new file mode 100644 index 00000000..40946af5 --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RouteRunner.php @@ -0,0 +1,70 @@ +routeResolver = $routeResolver; + $this->routeParser = $routeParser; + $this->routeCollectorProxy = $routeCollectorProxy; + } + + /** + * This request handler is instantiated automatically in App::__construct() + * It is at the very tip of the middleware queue meaning it will be executed + * last and it detects whether or not routing has been performed in the user + * defined middleware stack. In the event that the user did not perform routing + * it is done here + * + * @throws HttpNotFoundException + * @throws HttpMethodNotAllowedException + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + // If routing hasn't been done, then do it now so we can dispatch + if ($request->getAttribute(RouteContext::ROUTING_RESULTS) === null) { + $routingMiddleware = new RoutingMiddleware($this->routeResolver, $this->routeParser); + $request = $routingMiddleware->performRouting($request); + } + + if ($this->routeCollectorProxy !== null) { + $request = $request->withAttribute( + RouteContext::BASE_PATH, + $this->routeCollectorProxy->getBasePath() + ); + } + + /** @var Route $route */ + $route = $request->getAttribute(RouteContext::ROUTE); + return $route->run($request); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RoutingResults.php b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RoutingResults.php new file mode 100644 index 00000000..ac2fa64f --- /dev/null +++ b/advancedcontentfilter/vendor/slim/slim/Slim/Routing/RoutingResults.php @@ -0,0 +1,112 @@ + + */ + protected array $routeArguments; + + /** + * @param array $routeArguments + */ + public function __construct( + DispatcherInterface $dispatcher, + string $method, + string $uri, + int $routeStatus, + ?string $routeIdentifier = null, + array $routeArguments = [] + ) { + $this->dispatcher = $dispatcher; + $this->method = $method; + $this->uri = $uri; + $this->routeStatus = $routeStatus; + $this->routeIdentifier = $routeIdentifier; + $this->routeArguments = $routeArguments; + } + + public function getDispatcher(): DispatcherInterface + { + return $this->dispatcher; + } + + public function getMethod(): string + { + return $this->method; + } + + public function getUri(): string + { + return $this->uri; + } + + public function getRouteStatus(): int + { + return $this->routeStatus; + } + + public function getRouteIdentifier(): ?string + { + return $this->routeIdentifier; + } + + /** + * @return array + */ + public function getRouteArguments(bool $urlDecode = true): array + { + if (!$urlDecode) { + return $this->routeArguments; + } + + $routeArguments = []; + foreach ($this->routeArguments as $key => $value) { + $routeArguments[$key] = rawurldecode($value); + } + + return $routeArguments; + } + + /** + * @return string[] + */ + public function getAllowedMethods(): array + { + return $this->dispatcher->getAllowedMethods($this->uri); + } +} diff --git a/advancedcontentfilter/vendor/slim/slim/composer.json b/advancedcontentfilter/vendor/slim/slim/composer.json index 554a838a..36c0c1d1 100644 --- a/advancedcontentfilter/vendor/slim/slim/composer.json +++ b/advancedcontentfilter/vendor/slim/slim/composer.json @@ -3,7 +3,7 @@ "type": "library", "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", "keywords": ["framework","micro","api","router"], - "homepage": "https://slimframework.com", + "homepage": "https://www.slimframework.com", "license": "MIT", "authors": [ { @@ -21,38 +21,82 @@ "email": "rob@akrabat.com", "homepage": "http://akrabat.com" }, + { + "name": "Pierre Berube", + "email": "pierre@lgse.com", + "homepage": "http://www.lgse.com" + }, { "name": "Gabriel Manricks", "email": "gmanricks@me.com", "homepage": "http://gabrielmanricks.com" } ], + "support": { + "docs": "https://www.slimframework.com/docs/v4/", + "forum": "https://discourse.slimframework.com/", + "irc": "irc://irc.freenode.net:6667/slimphp", + "issues": "https://github.com/slimphp/Slim/issues", + "rss": "https://www.slimframework.com/blog/feed.rss", + "slack": "https://slimphp.slack.com/", + "source": "https://github.com/slimphp/Slim", + "wiki": "https://github.com/slimphp/Slim/wiki" + }, "require": { - "php": ">=5.5.0", - "pimple/pimple": "^3.0", - "psr/http-message": "^1.0", - "nikic/fast-route": "^1.0", - "container-interop/container-interop": "^1.2", - "psr/container": "^1.0" + "php": "^7.4 || ^8.0", + "ext-json": "*", + "nikic/fast-route": "^1.3", + "psr/container": "^1.0 || ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.1 || ^2.0 || ^3.0" }, "require-dev": { - "squizlabs/php_codesniffer": "^2.5", - "phpunit/phpunit": "^4.0" - }, - "provide": { - "psr/http-message-implementation": "1.0" + "ext-simplexml": "*", + "adriansuter/php-autoload-override": "^1.4", + "guzzlehttp/psr7": "^2.5", + "httpsoft/http-message": "^1.1", + "httpsoft/http-server-request": "^1.1", + "laminas/laminas-diactoros": "^2.17", + "nyholm/psr7": "^1.8", + "nyholm/psr7-server": "^1.0", + "phpspec/prophecy": "^1.17", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "slim/http": "^1.3", + "slim/psr7": "^1.6", + "squizlabs/php_codesniffer": "^3.7" }, "autoload": { "psr-4": { "Slim\\": "Slim" } }, + "autoload-dev": { + "psr-4": { + "Slim\\Tests\\": "tests" + } + }, "scripts": { "test": [ "@phpunit", - "@phpcs" + "@phpcs", + "@phpstan" ], - "phpunit": "php vendor/bin/phpunit", - "phpcs": "php vendor/bin/phpcs" + "phpunit": "phpunit", + "phpcs": "phpcs", + "phpstan": "phpstan --memory-limit=-1" + }, + "suggest": { + "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", + "ext-xml": "Needed to support XML format in BodyParsingMiddleware", + "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information.", + "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim" + }, + "config": { + "sort-packages": true } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/AbstractAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/AbstractAdapter.php index 727fc84c..ab7dc960 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/AbstractAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/AbstractAdapter.php @@ -14,7 +14,6 @@ namespace Symfony\Component\Cache\Adapter; use Psr\Cache\CacheItemInterface; use Psr\Log\LoggerAwareInterface; use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\ResettableInterface; @@ -25,6 +24,11 @@ use Symfony\Component\Cache\Traits\AbstractTrait; */ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface, ResettableInterface { + /** + * @internal + */ + const NS_SEPARATOR = ':'; + use AbstractTrait; private static $apcuSupported; @@ -39,17 +43,16 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface */ protected function __construct($namespace = '', $defaultLifetime = 0) { - $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; - if (null !== $this->maxIdLength && strlen($namespace) > $this->maxIdLength - 24) { - throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, strlen($namespace), $namespace)); + $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).static::NS_SEPARATOR; + if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { + throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); } $this->createCacheItem = \Closure::bind( - function ($key, $value, $isHit) use ($defaultLifetime) { + static function ($key, $value, $isHit) { $item = new CacheItem(); $item->key = $key; $item->value = $value; $item->isHit = $isHit; - $item->defaultLifetime = $defaultLifetime; return $item; }, @@ -58,14 +61,16 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface ); $getId = function ($key) { return $this->getId((string) $key); }; $this->mergeByLifetime = \Closure::bind( - function ($deferred, $namespace, &$expiredIds) use ($getId) { - $byLifetime = array(); + static function ($deferred, $namespace, &$expiredIds) use ($getId, $defaultLifetime) { + $byLifetime = []; $now = time(); - $expiredIds = array(); + $expiredIds = []; foreach ($deferred as $key => $item) { if (null === $item->expiry) { - $byLifetime[0 < $item->defaultLifetime ? $item->defaultLifetime : 0][$getId($key)] = $item->value; + $byLifetime[0 < $defaultLifetime ? $defaultLifetime : 0][$getId($key)] = $item->value; + } elseif (0 === $item->expiry) { + $byLifetime[0][$getId($key)] = $item->value; } elseif ($item->expiry > $now) { $byLifetime[$item->expiry - $now][$getId($key)] = $item->value; } else { @@ -81,11 +86,10 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface } /** - * @param string $namespace - * @param int $defaultLifetime - * @param string $version - * @param string $directory - * @param LoggerInterface|null $logger + * @param string $namespace + * @param int $defaultLifetime + * @param string $version + * @param string $directory * * @return AdapterInterface */ @@ -112,24 +116,22 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface if (null !== $logger) { $fs->setLogger($logger); } - if (!self::$apcuSupported) { + if (!self::$apcuSupported || (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { return $fs; } $apcu = new ApcuAdapter($namespace, (int) $defaultLifetime / 5, $version); - if ('cli' === \PHP_SAPI && !ini_get('apc.enable_cli')) { - $apcu->setLogger(new NullLogger()); - } elseif (null !== $logger) { + if (null !== $logger) { $apcu->setLogger($logger); } - return new ChainAdapter(array($apcu, $fs)); + return new ChainAdapter([$apcu, $fs]); } - public static function createConnection($dsn, array $options = array()) + public static function createConnection($dsn, array $options = []) { - if (!is_string($dsn)) { - throw new InvalidArgumentException(sprintf('The %s() method expect argument #1 to be string, %s given.', __METHOD__, gettype($dsn))); + if (!\is_string($dsn)) { + throw new InvalidArgumentException(sprintf('The "%s()" method expect argument #1 to be string, "%s" given.', __METHOD__, \gettype($dsn))); } if (0 === strpos($dsn, 'redis://')) { return RedisAdapter::createConnection($dsn, $options); @@ -138,7 +140,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface return MemcachedAdapter::createConnection($dsn, $options); } - throw new InvalidArgumentException(sprintf('Unsupported DSN: %s.', $dsn)); + throw new InvalidArgumentException(sprintf('Unsupported DSN: "%s".', $dsn)); } /** @@ -156,11 +158,11 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface $value = null; try { - foreach ($this->doFetch(array($id)) as $value) { + foreach ($this->doFetch([$id]) as $value) { $isHit = true; } } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to fetch key "{key}"', array('key' => $key, 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]); } return $f($key, $value, $isHit); @@ -169,12 +171,12 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { if ($this->deferred) { $this->commit(); } - $ids = array(); + $ids = []; foreach ($keys as $key) { $ids[] = $this->getId($key); @@ -182,8 +184,8 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface try { $items = $this->doFetch($ids); } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to fetch requested items', array('keys' => $keys, 'exception' => $e)); - $items = array(); + CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => $keys, 'exception' => $e]); + $items = []; } $ids = array_combine($ids, $keys); @@ -224,7 +226,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface $ok = true; $byLifetime = $this->mergeByLifetime; $byLifetime = $byLifetime($this->deferred, $this->namespace, $expiredIds); - $retry = $this->deferred = array(); + $retry = $this->deferred = []; if ($expiredIds) { $this->doDelete($expiredIds); @@ -234,15 +236,15 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface $e = $this->doSave($values, $lifetime); } catch (\Exception $e) { } - if (true === $e || array() === $e) { + if (true === $e || [] === $e) { continue; } - if (is_array($e) || 1 === count($values)) { - foreach (is_array($e) ? $e : array_keys($values) as $id) { + if (\is_array($e) || 1 === \count($values)) { + foreach (\is_array($e) ? $e : array_keys($values) as $id) { $ok = false; $v = $values[$id]; - $type = is_object($v) ? get_class($v) : gettype($v); - CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', array('key' => substr($id, strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null)); + $type = \is_object($v) ? \get_class($v) : \gettype($v); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]); } } else { foreach ($values as $id => $v) { @@ -256,21 +258,31 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface foreach ($ids as $id) { try { $v = $byLifetime[$lifetime][$id]; - $e = $this->doSave(array($id => $v), $lifetime); + $e = $this->doSave([$id => $v], $lifetime); } catch (\Exception $e) { } - if (true === $e || array() === $e) { + if (true === $e || [] === $e) { continue; } $ok = false; - $type = is_object($v) ? get_class($v) : gettype($v); - CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', array('key' => substr($id, strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null)); + $type = \is_object($v) ? \get_class($v) : \gettype($v); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => substr($id, \strlen($this->namespace)), 'type' => $type, 'exception' => $e instanceof \Exception ? $e : null]); } } return $ok; } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { if ($this->deferred) { @@ -292,7 +304,7 @@ abstract class AbstractAdapter implements AdapterInterface, LoggerAwareInterface yield $key => $f($key, $value, true); } } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to fetch requested items', array('keys' => array_values($keys), 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to fetch requested items', ['keys' => array_values($keys), 'exception' => $e]); } foreach ($keys as $key) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/AdapterInterface.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/AdapterInterface.php index 41222c1a..85fe0768 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/AdapterInterface.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/AdapterInterface.php @@ -33,5 +33,5 @@ interface AdapterInterface extends CacheItemPoolInterface * * @return \Traversable|CacheItem[] */ - public function getItems(array $keys = array()); + public function getItems(array $keys = []); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/ArrayAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/ArrayAdapter.php index 2118e9c6..33f55a86 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/ArrayAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/ArrayAdapter.php @@ -25,6 +25,7 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable use ArrayTrait; private $createCacheItem; + private $defaultLifetime; /** * @param int $defaultLifetime @@ -32,14 +33,14 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable */ public function __construct($defaultLifetime = 0, $storeSerialized = true) { + $this->defaultLifetime = $defaultLifetime; $this->storeSerialized = $storeSerialized; $this->createCacheItem = \Closure::bind( - function ($key, $value, $isHit) use ($defaultLifetime) { + static function ($key, $value, $isHit) { $item = new CacheItem(); $item->key = $key; $item->value = $value; $item->isHit = $isHit; - $item->defaultLifetime = $defaultLifetime; return $item; }, @@ -66,7 +67,7 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable $isHit = false; } } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', array('key' => $key, 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]); $this->values[$key] = $value = null; $isHit = false; } @@ -78,7 +79,7 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { foreach ($keys as $key) { CacheItem::validateKey($key); @@ -112,6 +113,10 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable $value = $item["\0*\0value"]; $expiry = $item["\0*\0expiry"]; + if (0 === $expiry) { + $expiry = \PHP_INT_MAX; + } + if (null !== $expiry && $expiry <= time()) { $this->deleteItem($key); @@ -121,18 +126,18 @@ class ArrayAdapter implements AdapterInterface, LoggerAwareInterface, Resettable try { $value = serialize($value); } catch (\Exception $e) { - $type = is_object($value) ? get_class($value) : gettype($value); - CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', array('key' => $key, 'type' => $type, 'exception' => $e)); + $type = \is_object($value) ? \get_class($value) : \gettype($value); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]); return false; } } - if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) { - $expiry = time() + $item["\0*\0defaultLifetime"]; + if (null === $expiry && 0 < $this->defaultLifetime) { + $expiry = time() + $this->defaultLifetime; } $this->values[$key] = $value; - $this->expiries[$key] = null !== $expiry ? $expiry : PHP_INT_MAX; + $this->expiries[$key] = null !== $expiry ? $expiry : \PHP_INT_MAX; return true; } diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/ChainAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/ChainAdapter.php index 6bdf6b2d..fdb28846 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/ChainAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/ChainAdapter.php @@ -28,15 +28,15 @@ use Symfony\Component\Cache\ResettableInterface; */ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableInterface { - private $adapters = array(); + private $adapters = []; private $adapterCount; - private $saveUp; + private $syncItem; /** - * @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items - * @param int $maxLifetime The max lifetime of items propagated from lower adapters to upper ones + * @param CacheItemPoolInterface[] $adapters The ordered list of adapters used to fetch cached items + * @param int $defaultLifetime The default lifetime of items propagated from lower adapters to upper ones */ - public function __construct(array $adapters, $maxLifetime = 0) + public function __construct(array $adapters, $defaultLifetime = 0) { if (!$adapters) { throw new InvalidArgumentException('At least one adapter must be specified.'); @@ -44,7 +44,10 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn foreach ($adapters as $adapter) { if (!$adapter instanceof CacheItemPoolInterface) { - throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', get_class($adapter), CacheItemPoolInterface::class)); + throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($adapter), CacheItemPoolInterface::class)); + } + if (\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && $adapter instanceof ApcuAdapter && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { + continue; // skip putting APCu in the chain when the backend is disabled } if ($adapter instanceof AdapterInterface) { @@ -53,18 +56,18 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn $this->adapters[] = new ProxyAdapter($adapter); } } - $this->adapterCount = count($this->adapters); + $this->adapterCount = \count($this->adapters); - $this->saveUp = \Closure::bind( - function ($adapter, $item) use ($maxLifetime) { - $origDefaultLifetime = $item->defaultLifetime; + $this->syncItem = \Closure::bind( + static function ($sourceItem, $item) use ($defaultLifetime) { + $item->value = $sourceItem->value; + $item->isHit = $sourceItem->isHit; - if (0 < $maxLifetime && ($origDefaultLifetime <= 0 || $maxLifetime < $origDefaultLifetime)) { - $item->defaultLifetime = $maxLifetime; + if (0 < $defaultLifetime) { + $item->expiresAfter($defaultLifetime); } - $adapter->save($item); - $item->defaultLifetime = $origDefaultLifetime; + return $item; }, null, CacheItem::class @@ -76,18 +79,21 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn */ public function getItem($key) { - $saveUp = $this->saveUp; + $syncItem = $this->syncItem; + $misses = []; foreach ($this->adapters as $i => $adapter) { $item = $adapter->getItem($key); if ($item->isHit()) { while (0 <= --$i) { - $saveUp($this->adapters[$i], $item); + $this->adapters[$i]->save($syncItem($item, $misses[$i])); } return $item; } + + $misses[$i] = $item; } return $item; @@ -96,14 +102,15 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { return $this->generateItems($this->adapters[0]->getItems($keys), 0); } private function generateItems($items, $adapterIndex) { - $missing = array(); + $missing = []; + $misses = []; $nextAdapterIndex = $adapterIndex + 1; $nextAdapter = isset($this->adapters[$nextAdapterIndex]) ? $this->adapters[$nextAdapterIndex] : null; @@ -112,17 +119,18 @@ class ChainAdapter implements AdapterInterface, PruneableInterface, ResettableIn yield $k => $item; } else { $missing[] = $k; + $misses[$k] = $item; } } if ($missing) { - $saveUp = $this->saveUp; + $syncItem = $this->syncItem; $adapter = $this->adapters[$adapterIndex]; $items = $this->generateItems($nextAdapter->getItems($missing), $nextAdapterIndex); foreach ($items as $k => $item) { if ($item->isHit()) { - $saveUp($adapter, $item); + $adapter->save($syncItem($item, $misses[$k])); } yield $k => $item; diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/DoctrineAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/DoctrineAdapter.php index 972d2b41..8081d7dc 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/DoctrineAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/DoctrineAdapter.php @@ -19,9 +19,8 @@ class DoctrineAdapter extends AbstractAdapter use DoctrineTrait; /** - * @param CacheProvider $provider - * @param string $namespace - * @param int $defaultLifetime + * @param string $namespace + * @param int $defaultLifetime */ public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/NullAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/NullAdapter.php index f58f81e5..c81a1cd6 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/NullAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/NullAdapter.php @@ -49,7 +49,7 @@ class NullAdapter implements AdapterInterface /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { return $this->generateItems($keys); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/PdoAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/PdoAdapter.php index c3fc45b6..59038679 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/PdoAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/PdoAdapter.php @@ -35,7 +35,7 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface * * db_time_col: The column where to store the timestamp [default: item_time] * * db_username: The username when lazy-connect [default: ''] * * db_password: The password when lazy-connect [default: ''] - * * db_connection_options: An array of driver-specific connection options [default: array()] + * * db_connection_options: An array of driver-specific connection options [default: []] * * @param \PDO|Connection|string $connOrDsn A \PDO or Connection instance or DSN string or null * @param string $namespace @@ -46,7 +46,7 @@ class PdoAdapter extends AbstractAdapter implements PruneableInterface * @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION * @throws InvalidArgumentException When namespace contains invalid characters */ - public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = array()) + public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = []) { $this->init($connOrDsn, $namespace, $defaultLifetime, $options); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpArrayAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpArrayAdapter.php index d3b9d77d..47a259c1 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpArrayAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpArrayAdapter.php @@ -40,9 +40,9 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl { $this->file = $file; $this->pool = $fallbackPool; - $this->zendDetectUnicode = ini_get('zend.detect_unicode'); + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); $this->createCacheItem = \Closure::bind( - function ($key, $value, $isHit) { + static function ($key, $value, $isHit) { $item = new CacheItem(); $item->key = $key; $item->value = $value; @@ -61,14 +61,13 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl * fallback pool with this adapter only if the current PHP version is supported. * * @param string $file The PHP file were values are cached - * @param CacheItemPoolInterface $fallbackPool Fallback for old PHP versions or opcache disabled + * @param CacheItemPoolInterface $fallbackPool A pool to fallback on when an item is not hit * * @return CacheItemPoolInterface */ public static function create($file, CacheItemPoolInterface $fallbackPool) { - // Shared memory is available in PHP 7.0+ with OPCache enabled and in HHVM - if ((\PHP_VERSION_ID >= 70000 && ini_get('opcache.enable')) || defined('HHVM_VERSION')) { + if (\PHP_VERSION_ID >= 70000) { if (!$fallbackPool instanceof AdapterInterface) { $fallbackPool = new ProxyAdapter($fallbackPool); } @@ -84,8 +83,8 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl */ public function getItem($key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -99,7 +98,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl if ('N;' === $value) { $value = null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { $e = null; $value = unserialize($value); @@ -120,11 +119,11 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { foreach ($keys as $key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } } if (null === $this->values) { @@ -139,8 +138,8 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl */ public function hasItem($key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -154,8 +153,8 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl */ public function deleteItem($key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -170,11 +169,11 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl public function deleteItems(array $keys) { $deleted = true; - $fallbackKeys = array(); + $fallbackKeys = []; foreach ($keys as $key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (isset($this->values[$key])) { @@ -232,7 +231,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl private function generateItems(array $keys) { $f = $this->createCacheItem; - $fallbackKeys = array(); + $fallbackKeys = []; foreach ($keys as $key) { if (isset($this->values[$key])) { @@ -240,7 +239,7 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl if ('N;' === $value) { yield $key => $f($key, null, true); - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { yield $key => $f($key, unserialize($value), true); } catch (\Error $e) { @@ -266,20 +265,27 @@ class PhpArrayAdapter implements AdapterInterface, PruneableInterface, Resettabl /** * @throws \ReflectionException When $class is not found and is required * - * @internal + * @internal to be removed in Symfony 5.0 */ public static function throwOnRequiredClass($class) { $e = new \ReflectionException("Class $class does not exist"); - $trace = $e->getTrace(); - $autoloadFrame = array( + $trace = debug_backtrace(); + $autoloadFrame = [ 'function' => 'spl_autoload_call', - 'args' => array($class), - ); - $i = 1 + array_search($autoloadFrame, $trace, true); + 'args' => [$class], + ]; - if (isset($trace[$i]['function']) && !isset($trace[$i]['class'])) { - switch ($trace[$i]['function']) { + if (\PHP_VERSION_ID >= 80000 && isset($trace[1])) { + $callerFrame = $trace[1]; + } elseif (false !== $i = array_search($autoloadFrame, $trace, true)) { + $callerFrame = $trace[++$i]; + } else { + throw $e; + } + + if (isset($callerFrame['function']) && !isset($callerFrame['class'])) { + switch ($callerFrame['function']) { case 'get_class_methods': case 'get_class_vars': case 'get_parent_class': diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpFilesAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpFilesAdapter.php index 528d9c01..b56143c2 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpFilesAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/PhpFilesAdapter.php @@ -29,13 +29,13 @@ class PhpFilesAdapter extends AbstractAdapter implements PruneableInterface public function __construct($namespace = '', $defaultLifetime = 0, $directory = null) { if (!static::isSupported()) { - throw new CacheException('OPcache is not enabled'); + throw new CacheException('OPcache is not enabled.'); } parent::__construct('', $defaultLifetime); $this->init($namespace, $directory); $e = new \Exception(); $this->includeHandler = function () use ($e) { throw $e; }; - $this->zendDetectUnicode = ini_get('zend.detect_unicode'); + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/ProxyAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/ProxyAdapter.php index 82c95c5b..c89a760e 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/ProxyAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/ProxyAdapter.php @@ -29,28 +29,31 @@ class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableIn private $namespaceLen; private $createCacheItem; private $poolHash; + private $defaultLifetime; /** - * @param CacheItemPoolInterface $pool - * @param string $namespace - * @param int $defaultLifetime + * @param string $namespace + * @param int $defaultLifetime */ public function __construct(CacheItemPoolInterface $pool, $namespace = '', $defaultLifetime = 0) { $this->pool = $pool; $this->poolHash = $poolHash = spl_object_hash($pool); $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace); - $this->namespaceLen = strlen($namespace); + $this->namespaceLen = \strlen($namespace); + $this->defaultLifetime = $defaultLifetime; $this->createCacheItem = \Closure::bind( - function ($key, $innerItem) use ($defaultLifetime, $poolHash) { + static function ($key, $innerItem) use ($poolHash) { $item = new CacheItem(); $item->key = $key; - $item->value = $innerItem->get(); - $item->isHit = $innerItem->isHit(); - $item->defaultLifetime = $defaultLifetime; - $item->innerItem = $innerItem; $item->poolHash = $poolHash; - $innerItem->set(null); + + if (null !== $innerItem) { + $item->value = $innerItem->get(); + $item->isHit = $innerItem->isHit(); + $item->innerItem = $innerItem; + $innerItem->set(null); + } return $item; }, @@ -73,7 +76,7 @@ class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableIn /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { if ($this->namespaceLen) { foreach ($keys as $i => $key) { @@ -153,10 +156,21 @@ class ProxyAdapter implements AdapterInterface, PruneableInterface, ResettableIn } $item = (array) $item; $expiry = $item["\0*\0expiry"]; - if (null === $expiry && 0 < $item["\0*\0defaultLifetime"]) { - $expiry = time() + $item["\0*\0defaultLifetime"]; + if (null === $expiry && 0 < $this->defaultLifetime) { + $expiry = time() + $this->defaultLifetime; } - $innerItem = $item["\0*\0poolHash"] === $this->poolHash ? $item["\0*\0innerItem"] : $this->pool->getItem($this->namespace.$item["\0*\0key"]); + + if ($item["\0*\0poolHash"] === $this->poolHash && $item["\0*\0innerItem"]) { + $innerItem = $item["\0*\0innerItem"]; + } elseif ($this->pool instanceof AdapterInterface) { + // this is an optimization specific for AdapterInterface implementations + // so we can save a round-trip to the backend by just creating a new item + $f = $this->createCacheItem; + $innerItem = $f($this->namespace.$item["\0*\0key"], null); + } else { + $innerItem = $this->pool->getItem($this->namespace.$item["\0*\0key"]); + } + $innerItem->set($item["\0*\0value"]); $innerItem->expiresAt(null !== $expiry ? \DateTime::createFromFormat('U', $expiry) : null); diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php index 24db5d50..d3d0ede6 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/SimpleCacheAdapter.php @@ -13,14 +13,18 @@ namespace Symfony\Component\Cache\Adapter; use Psr\SimpleCache\CacheInterface; use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\ResettableInterface; use Symfony\Component\Cache\Traits\ProxyTrait; /** * @author Nicolas Grekas */ -class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface, ResettableInterface +class SimpleCacheAdapter extends AbstractAdapter implements PruneableInterface { + /** + * @internal + */ + const NS_SEPARATOR = '_'; + use ProxyTrait; private $miss; diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/TagAwareAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/TagAwareAdapter.php index 72bbc143..febe5090 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/TagAwareAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/TagAwareAdapter.php @@ -27,25 +27,26 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R use ProxyTrait; - private $deferred = array(); + private $deferred = []; private $createCacheItem; private $setCacheItemTags; private $getTagsByKey; private $invalidateTags; private $tags; + private $knownTagVersions = []; + private $knownTagVersionsTtl; - public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null) + public function __construct(AdapterInterface $itemsPool, AdapterInterface $tagsPool = null, $knownTagVersionsTtl = 0.15) { $this->pool = $itemsPool; $this->tags = $tagsPool ?: $itemsPool; + $this->knownTagVersionsTtl = $knownTagVersionsTtl; $this->createCacheItem = \Closure::bind( - function ($key, $value, CacheItem $protoItem) { + static function ($key, $value, CacheItem $protoItem) { $item = new CacheItem(); $item->key = $key; $item->value = $value; - $item->defaultLifetime = $protoItem->defaultLifetime; $item->expiry = $protoItem->expiry; - $item->innerItem = $protoItem->innerItem; $item->poolHash = $protoItem->poolHash; return $item; @@ -54,7 +55,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R CacheItem::class ); $this->setCacheItemTags = \Closure::bind( - function (CacheItem $item, $key, array &$itemTags) { + static function (CacheItem $item, $key, array &$itemTags) { if (!$item->isHit) { return $item; } @@ -74,8 +75,8 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R CacheItem::class ); $this->getTagsByKey = \Closure::bind( - function ($deferred) { - $tagsByKey = array(); + static function ($deferred) { + $tagsByKey = []; foreach ($deferred as $key => $item) { $tagsByKey[$key] = $item->tags; } @@ -86,11 +87,9 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R CacheItem::class ); $this->invalidateTags = \Closure::bind( - function (AdapterInterface $tagsAdapter, array $tags) { - foreach ($tagsAdapter->getItems($tags) as $v) { - $v->set(1 + (int) $v->get()); - $v->defaultLifetime = 0; - $v->expiry = null; + static function (AdapterInterface $tagsAdapter, array $tags) { + foreach ($tags as $v) { + $v->expiry = 0; $tagsAdapter->saveDeferred($v); } @@ -106,14 +105,42 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R */ public function invalidateTags(array $tags) { - foreach ($tags as $k => $tag) { - if ('' !== $tag && is_string($tag)) { - $tags[$k] = $tag.static::TAGS_PREFIX; - } + $ok = true; + $tagsByKey = []; + $invalidatedTags = []; + foreach ($tags as $tag) { + CacheItem::validateKey($tag); + $invalidatedTags[$tag] = 0; } - $f = $this->invalidateTags; - return $f($this->tags, $tags); + if ($this->deferred) { + $items = $this->deferred; + foreach ($items as $key => $item) { + if (!$this->pool->saveDeferred($item)) { + unset($this->deferred[$key]); + $ok = false; + } + } + + $f = $this->getTagsByKey; + $tagsByKey = $f($items); + $this->deferred = []; + } + + $tagVersions = $this->getTagVersions($tagsByKey, $invalidatedTags); + $f = $this->createCacheItem; + + foreach ($tagsByKey as $key => $tags) { + $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key])); + } + $ok = $this->pool->commit() && $ok; + + if ($invalidatedTags) { + $f = $this->invalidateTags; + $ok = $f($this->tags, $invalidatedTags) && $ok; + } + + return $ok; } /** @@ -127,12 +154,19 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R if (!$this->pool->hasItem($key)) { return false; } - if (!$itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key)->get()) { + + $itemTags = $this->pool->getItem(static::TAGS_PREFIX.$key); + + if (!$itemTags->isHit()) { + return false; + } + + if (!$itemTags = $itemTags->get()) { return true; } - foreach ($this->getTagVersions(array($itemTags)) as $tag => $version) { - if ($itemTags[$tag] !== $version) { + foreach ($this->getTagVersions([$itemTags]) as $tag => $version) { + if ($itemTags[$tag] !== $version && 1 !== $itemTags[$tag] - $version) { return false; } } @@ -145,23 +179,25 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R */ public function getItem($key) { - foreach ($this->getItems(array($key)) as $item) { + foreach ($this->getItems([$key]) as $item) { return $item; } + + return null; } /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { if ($this->deferred) { $this->commit(); } - $tagKeys = array(); + $tagKeys = []; foreach ($keys as $key) { - if ('' !== $key && is_string($key)) { + if ('' !== $key && \is_string($key)) { $key = static::TAGS_PREFIX.$key; $tagKeys[$key] = $key; } @@ -183,7 +219,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R */ public function clear() { - $this->deferred = array(); + $this->deferred = []; return $this->pool->clear(); } @@ -193,7 +229,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R */ public function deleteItem($key) { - return $this->deleteItems(array($key)); + return $this->deleteItems([$key]); } /** @@ -202,7 +238,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R public function deleteItems(array $keys) { foreach ($keys as $key) { - if ('' !== $key && is_string($key)) { + if ('' !== $key && \is_string($key)) { $keys[] = static::TAGS_PREFIX.$key; } } @@ -241,29 +277,17 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R */ public function commit() { - $ok = true; + return $this->invalidateTags([]); + } - if ($this->deferred) { - $items = $this->deferred; - foreach ($items as $key => $item) { - if (!$this->pool->saveDeferred($item)) { - unset($this->deferred[$key]); - $ok = false; - } - } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } - $f = $this->getTagsByKey; - $tagsByKey = $f($items); - $this->deferred = array(); - $tagVersions = $this->getTagVersions($tagsByKey); - $f = $this->createCacheItem; - - foreach ($tagsByKey as $key => $tags) { - $this->pool->saveDeferred($f(static::TAGS_PREFIX.$key, array_intersect_key($tagVersions, $tags), $items[$key])); - } - } - - return $this->pool->commit() && $ok; + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); } public function __destruct() @@ -273,7 +297,7 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R private function generateItems($items, array $tagKeys) { - $bufferedItems = $itemTags = array(); + $bufferedItems = $itemTags = []; $f = $this->setCacheItemTags; foreach ($items as $key => $item) { @@ -287,14 +311,17 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R } unset($tagKeys[$key]); - $itemTags[$key] = $item->get() ?: array(); + + if ($item->isHit()) { + $itemTags[$key] = $item->get() ?: []; + } if (!$tagKeys) { $tagVersions = $this->getTagVersions($itemTags); foreach ($itemTags as $key => $tags) { foreach ($tags as $tag => $version) { - if ($tagVersions[$tag] !== $version) { + if ($tagVersions[$tag] !== $version && 1 !== $version - $tagVersions[$tag]) { unset($itemTags[$key]); continue 2; } @@ -310,23 +337,55 @@ class TagAwareAdapter implements TagAwareAdapterInterface, PruneableInterface, R } } - private function getTagVersions(array $tagsByKey) + private function getTagVersions(array $tagsByKey, array &$invalidatedTags = []) { - $tagVersions = array(); + $tagVersions = $invalidatedTags; foreach ($tagsByKey as $tags) { $tagVersions += $tags; } - if ($tagVersions) { - $tags = array(); - foreach ($tagVersions as $tag => $version) { - $tagVersions[$tag] = $tag.static::TAGS_PREFIX; - $tags[$tag.static::TAGS_PREFIX] = $tag; + if (!$tagVersions) { + return []; + } + + if (!$fetchTagVersions = 1 !== \func_num_args()) { + foreach ($tagsByKey as $tags) { + foreach ($tags as $tag => $version) { + if ($tagVersions[$tag] > $version) { + $tagVersions[$tag] = $version; + } + } } - foreach ($this->tags->getItems($tagVersions) as $tag => $version) { - $tagVersions[$tags[$tag]] = $version->get() ?: 0; + } + + $now = microtime(true); + $tags = []; + foreach ($tagVersions as $tag => $version) { + $tags[$tag.static::TAGS_PREFIX] = $tag; + if ($fetchTagVersions || !isset($this->knownTagVersions[$tag])) { + $fetchTagVersions = true; + continue; } + $version -= $this->knownTagVersions[$tag][1]; + if ((0 !== $version && 1 !== $version) || $now - $this->knownTagVersions[$tag][0] >= $this->knownTagVersionsTtl) { + // reuse previously fetched tag versions up to the ttl, unless we are storing items or a potential miss arises + $fetchTagVersions = true; + } else { + $this->knownTagVersions[$tag][1] += $version; + } + } + + if (!$fetchTagVersions) { + return $tagVersions; + } + + foreach ($this->tags->getItems(array_keys($tags)) as $tag => $version) { + $tagVersions[$tag = $tags[$tag]] = $version->get() ?: 0; + if (isset($invalidatedTags[$tag])) { + $invalidatedTags[$tag] = $version->set(++$tagVersions[$tag]); + } + $this->knownTagVersions[$tag] = [$now, $tagVersions[$tag]]; } return $tagVersions; diff --git a/advancedcontentfilter/vendor/symfony/cache/Adapter/TraceableAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Adapter/TraceableAdapter.php index 98d0e526..cc855c13 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Adapter/TraceableAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Adapter/TraceableAdapter.php @@ -25,7 +25,7 @@ use Symfony\Component\Cache\ResettableInterface; class TraceableAdapter implements AdapterInterface, PruneableInterface, ResettableInterface { protected $pool; - private $calls = array(); + private $calls = []; public function __construct(AdapterInterface $pool) { @@ -107,7 +107,7 @@ class TraceableAdapter implements AdapterInterface, PruneableInterface, Resettab /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { $event = $this->start(__FUNCTION__); try { @@ -116,7 +116,7 @@ class TraceableAdapter implements AdapterInterface, PruneableInterface, Resettab $event->end = microtime(true); } $f = function () use ($result, $event) { - $event->result = array(); + $event->result = []; foreach ($result as $key => $item) { if ($event->result[$key] = $item->isHit()) { ++$event->hits; @@ -191,15 +191,11 @@ class TraceableAdapter implements AdapterInterface, PruneableInterface, Resettab */ public function reset() { - if (!$this->pool instanceof ResettableInterface) { - return; - } - $event = $this->start(__FUNCTION__); - try { + if ($this->pool instanceof ResettableInterface) { $this->pool->reset(); - } finally { - $event->end = microtime(true); } + + $this->clearCalls(); } public function getCalls() @@ -209,7 +205,7 @@ class TraceableAdapter implements AdapterInterface, PruneableInterface, Resettab public function clearCalls() { - $this->calls = array(); + $this->calls = []; } protected function start($name) diff --git a/advancedcontentfilter/vendor/symfony/cache/CacheItem.php b/advancedcontentfilter/vendor/symfony/cache/CacheItem.php index 93ffea49..7ae6568c 100644 --- a/advancedcontentfilter/vendor/symfony/cache/CacheItem.php +++ b/advancedcontentfilter/vendor/symfony/cache/CacheItem.php @@ -24,9 +24,8 @@ final class CacheItem implements CacheItemInterface protected $value; protected $isHit = false; protected $expiry; - protected $defaultLifetime; - protected $tags = array(); - protected $prevTags = array(); + protected $tags = []; + protected $prevTags = []; protected $innerItem; protected $poolHash; @@ -56,6 +55,8 @@ final class CacheItem implements CacheItemInterface /** * {@inheritdoc} + * + * @return $this */ public function set($value) { @@ -66,15 +67,17 @@ final class CacheItem implements CacheItemInterface /** * {@inheritdoc} + * + * @return $this */ public function expiresAt($expiration) { if (null === $expiration) { - $this->expiry = $this->defaultLifetime > 0 ? time() + $this->defaultLifetime : null; + $this->expiry = null; } elseif ($expiration instanceof \DateTimeInterface) { $this->expiry = (int) $expiration->format('U'); } else { - throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given', is_object($expiration) ? get_class($expiration) : gettype($expiration))); + throw new InvalidArgumentException(sprintf('Expiration date must implement DateTimeInterface or be null, "%s" given.', \is_object($expiration) ? \get_class($expiration) : \gettype($expiration))); } return $this; @@ -82,17 +85,19 @@ final class CacheItem implements CacheItemInterface /** * {@inheritdoc} + * + * @return $this */ public function expiresAfter($time) { if (null === $time) { - $this->expiry = $this->defaultLifetime > 0 ? time() + $this->defaultLifetime : null; + $this->expiry = null; } elseif ($time instanceof \DateInterval) { $this->expiry = (int) \DateTime::createFromFormat('U', time())->add($time)->format('U'); - } elseif (is_int($time)) { + } elseif (\is_int($time)) { $this->expiry = $time + time(); } else { - throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', is_object($time) ? get_class($time) : gettype($time))); + throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($time) ? \get_class($time) : \gettype($time))); } return $this; @@ -103,27 +108,27 @@ final class CacheItem implements CacheItemInterface * * @param string|string[] $tags A tag or array of tags * - * @return static + * @return $this * * @throws InvalidArgumentException When $tag is not valid */ public function tag($tags) { - if (!is_array($tags)) { - $tags = array($tags); + if (!\is_array($tags)) { + $tags = [$tags]; } foreach ($tags as $tag) { - if (!is_string($tag)) { - throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given', is_object($tag) ? get_class($tag) : gettype($tag))); + if (!\is_string($tag)) { + throw new InvalidArgumentException(sprintf('Cache tag must be string, "%s" given.', \is_object($tag) ? \get_class($tag) : \gettype($tag))); } if (isset($this->tags[$tag])) { continue; } - if (!isset($tag[0])) { - throw new InvalidArgumentException('Cache tag length must be greater than zero'); + if ('' === $tag) { + throw new InvalidArgumentException('Cache tag length must be greater than zero.'); } if (false !== strpbrk($tag, '{}()/\@:')) { - throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:', $tag)); + throw new InvalidArgumentException(sprintf('Cache tag "%s" contains reserved characters {}()/\@:.', $tag)); } $this->tags[$tag] = $tag; } @@ -152,14 +157,14 @@ final class CacheItem implements CacheItemInterface */ public static function validateKey($key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } - if (!isset($key[0])) { - throw new InvalidArgumentException('Cache key length must be greater than zero'); + if ('' === $key) { + throw new InvalidArgumentException('Cache key length must be greater than zero.'); } if (false !== strpbrk($key, '{}()/\@:')) { - throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:', $key)); + throw new InvalidArgumentException(sprintf('Cache key "%s" contains reserved characters {}()/\@:.', $key)); } return $key; @@ -170,18 +175,18 @@ final class CacheItem implements CacheItemInterface * * @internal */ - public static function log(LoggerInterface $logger = null, $message, $context = array()) + public static function log(LoggerInterface $logger = null, $message, $context = []) { if ($logger) { $logger->warning($message, $context); } else { - $replace = array(); + $replace = []; foreach ($context as $k => $v) { if (is_scalar($v)) { $replace['{'.$k.'}'] = $v; } } - @trigger_error(strtr($message, $replace), E_USER_WARNING); + @trigger_error(strtr($message, $replace), \E_USER_WARNING); } } } diff --git a/advancedcontentfilter/vendor/symfony/cache/DataCollector/CacheDataCollector.php b/advancedcontentfilter/vendor/symfony/cache/DataCollector/CacheDataCollector.php index ceef45aa..c9e87d5c 100644 --- a/advancedcontentfilter/vendor/symfony/cache/DataCollector/CacheDataCollector.php +++ b/advancedcontentfilter/vendor/symfony/cache/DataCollector/CacheDataCollector.php @@ -27,11 +27,10 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter /** * @var TraceableAdapter[] */ - private $instances = array(); + private $instances = []; /** - * @param string $name - * @param TraceableAdapter $instance + * @param string $name */ public function addInstance($name, TraceableAdapter $instance) { @@ -43,8 +42,8 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter */ public function collect(Request $request, Response $response, \Exception $exception = null) { - $empty = array('calls' => array(), 'config' => array(), 'options' => array(), 'statistics' => array()); - $this->data = array('instances' => $empty, 'total' => $empty); + $empty = ['calls' => [], 'config' => [], 'options' => [], 'statistics' => []]; + $this->data = ['instances' => $empty, 'total' => $empty]; foreach ($this->instances as $name => $instance) { $this->data['instances']['calls'][$name] = $instance->getCalls(); } @@ -55,7 +54,7 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter public function reset() { - $this->data = array(); + $this->data = []; foreach ($this->instances as $instance) { $instance->clearCalls(); } @@ -109,9 +108,9 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter */ private function calculateStatistics() { - $statistics = array(); + $statistics = []; foreach ($this->data['instances']['calls'] as $name => $calls) { - $statistics[$name] = array( + $statistics[$name] = [ 'calls' => 0, 'time' => 0, 'reads' => 0, @@ -119,34 +118,33 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter 'deletes' => 0, 'hits' => 0, 'misses' => 0, - ); + ]; /** @var TraceableAdapterEvent $call */ foreach ($calls as $call) { - $statistics[$name]['calls'] += 1; + ++$statistics[$name]['calls']; $statistics[$name]['time'] += $call->end - $call->start; if ('getItem' === $call->name) { - $statistics[$name]['reads'] += 1; + ++$statistics[$name]['reads']; if ($call->hits) { - $statistics[$name]['hits'] += 1; + ++$statistics[$name]['hits']; } else { - $statistics[$name]['misses'] += 1; + ++$statistics[$name]['misses']; } } elseif ('getItems' === $call->name) { - $count = $call->hits + $call->misses; - $statistics[$name]['reads'] += $count; + $statistics[$name]['reads'] += $call->hits + $call->misses; $statistics[$name]['hits'] += $call->hits; - $statistics[$name]['misses'] += $count - $call->misses; + $statistics[$name]['misses'] += $call->misses; } elseif ('hasItem' === $call->name) { - $statistics[$name]['reads'] += 1; + ++$statistics[$name]['reads']; if (false === $call->result) { - $statistics[$name]['misses'] += 1; + ++$statistics[$name]['misses']; } else { - $statistics[$name]['hits'] += 1; + ++$statistics[$name]['hits']; } } elseif ('save' === $call->name) { - $statistics[$name]['writes'] += 1; + ++$statistics[$name]['writes']; } elseif ('deleteItem' === $call->name) { - $statistics[$name]['deletes'] += 1; + ++$statistics[$name]['deletes']; } } if ($statistics[$name]['reads']) { @@ -165,7 +163,7 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter private function calculateTotalStatistics() { $statistics = $this->getStatistics(); - $totals = array( + $totals = [ 'calls' => 0, 'time' => 0, 'reads' => 0, @@ -173,7 +171,7 @@ class CacheDataCollector extends DataCollector implements LateDataCollectorInter 'deletes' => 0, 'hits' => 0, 'misses' => 0, - ); + ]; foreach ($statistics as $name => $values) { foreach ($totals as $key => $value) { $totals[$key] += $statistics[$name][$key]; diff --git a/advancedcontentfilter/vendor/symfony/cache/DoctrineProvider.php b/advancedcontentfilter/vendor/symfony/cache/DoctrineProvider.php index cebe95fb..4c5cd0cb 100644 --- a/advancedcontentfilter/vendor/symfony/cache/DoctrineProvider.php +++ b/advancedcontentfilter/vendor/symfony/cache/DoctrineProvider.php @@ -90,7 +90,7 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese */ protected function doFlush() { - $this->pool->clear(); + return $this->pool->clear(); } /** @@ -98,5 +98,6 @@ class DoctrineProvider extends CacheProvider implements PruneableInterface, Rese */ protected function doGetStats() { + return null; } } diff --git a/advancedcontentfilter/vendor/symfony/cache/LICENSE b/advancedcontentfilter/vendor/symfony/cache/LICENSE index fcd3fa76..a7ec7080 100644 --- a/advancedcontentfilter/vendor/symfony/cache/LICENSE +++ b/advancedcontentfilter/vendor/symfony/cache/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016-2018 Fabien Potencier +Copyright (c) 2016-2020 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/AbstractCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/AbstractCache.php index e666effa..baedb737 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/AbstractCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/AbstractCache.php @@ -15,14 +15,19 @@ use Psr\Log\LoggerAwareInterface; use Psr\SimpleCache\CacheInterface; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Traits\AbstractTrait; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\AbstractTrait; /** * @author Nicolas Grekas */ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, ResettableInterface { + /** + * @internal + */ + const NS_SEPARATOR = ':'; + use AbstractTrait { deleteItems as private; AbstractTrait::deleteItem as delete; @@ -39,8 +44,8 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re { $this->defaultLifetime = max(0, (int) $defaultLifetime); $this->namespace = '' === $namespace ? '' : CacheItem::validateKey($namespace).':'; - if (null !== $this->maxIdLength && strlen($namespace) > $this->maxIdLength - 24) { - throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s")', $this->maxIdLength - 24, strlen($namespace), $namespace)); + if (null !== $this->maxIdLength && \strlen($namespace) > $this->maxIdLength - 24) { + throw new InvalidArgumentException(sprintf('Namespace must be %d chars max, %d given ("%s").', $this->maxIdLength - 24, \strlen($namespace), $namespace)); } } @@ -52,11 +57,11 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re $id = $this->getId($key); try { - foreach ($this->doFetch(array($id)) as $value) { + foreach ($this->doFetch([$id]) as $value) { return $value; } } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to fetch key "{key}"', array('key' => $key, 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to fetch key "{key}"', ['key' => $key, 'exception' => $e]); } return $default; @@ -69,7 +74,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re { CacheItem::validateKey($key); - return $this->setMultiple(array($key => $value), $ttl); + return $this->setMultiple([$key => $value], $ttl); } /** @@ -79,10 +84,10 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } - $ids = array(); + $ids = []; foreach ($keys as $key) { $ids[] = $this->getId($key); @@ -90,8 +95,8 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re try { $values = $this->doFetch($ids); } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to fetch requested values', array('keys' => $keys, 'exception' => $e)); - $values = array(); + CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => $keys, 'exception' => $e]); + $values = []; } $ids = array_combine($ids, $keys); @@ -103,13 +108,13 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re */ public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); + if (!\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); } - $valuesById = array(); + $valuesById = []; foreach ($values as $key => $value) { - if (is_int($key)) { + if (\is_int($key)) { $key = (string) $key; } $valuesById[$this->getId($key)] = $value; @@ -122,14 +127,14 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re $e = $this->doSave($valuesById, $ttl); } catch (\Exception $e) { } - if (true === $e || array() === $e) { + if (true === $e || [] === $e) { return true; } - $keys = array(); - foreach (is_array($e) ? $e : array_keys($valuesById) as $id) { - $keys[] = substr($id, strlen($this->namespace)); + $keys = []; + foreach (\is_array($e) ? $e : array_keys($valuesById) as $id) { + $keys[] = substr($id, \strlen($this->namespace)); } - CacheItem::log($this->logger, 'Failed to save values', array('keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null)); + CacheItem::log($this->logger, 'Failed to save values', ['keys' => $keys, 'exception' => $e instanceof \Exception ? $e : null]); return false; } @@ -141,8 +146,8 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } return $this->deleteItems($keys); @@ -156,11 +161,11 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re if ($ttl instanceof \DateInterval) { $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U'); } - if (is_int($ttl)) { + if (\is_int($ttl)) { return 0 < $ttl ? $ttl : false; } - throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', is_object($ttl) ? get_class($ttl) : gettype($ttl))); + throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl))); } private function generateValues($values, &$keys, $default) @@ -175,7 +180,7 @@ abstract class AbstractCache implements CacheInterface, LoggerAwareInterface, Re yield $key => $value; } } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to fetch requested values', array('keys' => array_values($keys), 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to fetch requested values', ['keys' => array_values($keys), 'exception' => $e]); } foreach ($keys as $key) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/ArrayCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/ArrayCache.php index 8d027cd2..6013f0ad 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/ArrayCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/ArrayCache.php @@ -45,7 +45,7 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte */ public function get($key, $default = null) { - foreach ($this->getMultiple(array($key), $default) as $v) { + foreach ($this->getMultiple([$key], $default) as $v) { return $v; } } @@ -57,8 +57,8 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } foreach ($keys as $key) { CacheItem::validateKey($key); @@ -72,8 +72,8 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte */ public function deleteMultiple($keys) { - if (!is_array($keys) && !$keys instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + if (!\is_array($keys) && !$keys instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } foreach ($keys as $key) { $this->delete($key); @@ -89,7 +89,7 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte { CacheItem::validateKey($key); - return $this->setMultiple(array($key => $value), $ttl); + return $this->setMultiple([$key => $value], $ttl); } /** @@ -97,13 +97,13 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte */ public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); + if (!\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); } - $valuesArray = array(); + $valuesArray = []; foreach ($values as $key => $value) { - is_int($key) || CacheItem::validateKey($key); + \is_int($key) || CacheItem::validateKey($key); $valuesArray[$key] = $value; } if (false === $ttl = $this->normalizeTtl($ttl)) { @@ -114,14 +114,14 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte try { $valuesArray[$key] = serialize($value); } catch (\Exception $e) { - $type = is_object($value) ? get_class($value) : gettype($value); - CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', array('key' => $key, 'type' => $type, 'exception' => $e)); + $type = \is_object($value) ? \get_class($value) : \gettype($value); + CacheItem::log($this->logger, 'Failed to save key "{key}" ({type})', ['key' => $key, 'type' => $type, 'exception' => $e]); return false; } } } - $expiry = 0 < $ttl ? time() + $ttl : PHP_INT_MAX; + $expiry = 0 < $ttl ? time() + $ttl : \PHP_INT_MAX; foreach ($valuesArray as $key => $value) { $this->values[$key] = $value; @@ -139,10 +139,10 @@ class ArrayCache implements CacheInterface, LoggerAwareInterface, ResettableInte if ($ttl instanceof \DateInterval) { $ttl = (int) \DateTime::createFromFormat('U', 0)->add($ttl)->format('U'); } - if (is_int($ttl)) { + if (\is_int($ttl)) { return 0 < $ttl ? $ttl : false; } - throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given', is_object($ttl) ? get_class($ttl) : gettype($ttl))); + throw new InvalidArgumentException(sprintf('Expiration date must be an integer, a DateInterval or null, "%s" given.', \is_object($ttl) ? \get_class($ttl) : \gettype($ttl))); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/ChainCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/ChainCache.php index 9d0c7587..2e6c7277 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/ChainCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/ChainCache.php @@ -27,7 +27,7 @@ use Symfony\Component\Cache\ResettableInterface; class ChainCache implements CacheInterface, PruneableInterface, ResettableInterface { private $miss; - private $caches = array(); + private $caches = []; private $defaultLifetime; private $cacheCount; @@ -43,13 +43,13 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf foreach ($caches as $cache) { if (!$cache instanceof CacheInterface) { - throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', get_class($cache), CacheInterface::class)); + throw new InvalidArgumentException(sprintf('The class "%s" does not implement the "%s" interface.', \get_class($cache), CacheInterface::class)); } } $this->miss = new \stdClass(); $this->caches = array_values($caches); - $this->cacheCount = count($this->caches); + $this->cacheCount = \count($this->caches); $this->defaultLifetime = 0 < $defaultLifetime ? (int) $defaultLifetime : null; } @@ -58,7 +58,7 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf */ public function get($key, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; foreach ($this->caches as $i => $cache) { $value = $cache->get($key, $miss); @@ -80,14 +80,14 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf */ public function getMultiple($keys, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; return $this->generateItems($this->caches[0]->getMultiple($keys, $miss), 0, $miss, $default); } private function generateItems($values, $cacheIndex, $miss, $default) { - $missing = array(); + $missing = []; $nextCacheIndex = $cacheIndex + 1; $nextCache = isset($this->caches[$nextCacheIndex]) ? $this->caches[$nextCacheIndex] : null; @@ -201,7 +201,7 @@ class ChainCache implements CacheInterface, PruneableInterface, ResettableInterf if ($values instanceof \Traversable) { $valuesIterator = $values; $values = function () use ($valuesIterator, &$values) { - $generatedValues = array(); + $generatedValues = []; foreach ($valuesIterator as $key => $value) { yield $key => $value; diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/DoctrineCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/DoctrineCache.php index 00f0b9c6..ea1a4eda 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/DoctrineCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/DoctrineCache.php @@ -19,9 +19,8 @@ class DoctrineCache extends AbstractCache use DoctrineTrait; /** - * @param CacheProvider $provider - * @param string $namespace - * @param int $defaultLifetime + * @param string $namespace + * @param int $defaultLifetime */ public function __construct(CacheProvider $provider, $namespace = '', $defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/MemcachedCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/MemcachedCache.php index 77177406..94a9f297 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/MemcachedCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/MemcachedCache.php @@ -20,9 +20,8 @@ class MemcachedCache extends AbstractCache protected $maxIdLength = 250; /** - * @param \Memcached $client - * @param string $namespace - * @param int $defaultLifetime + * @param string $namespace + * @param int $defaultLifetime */ public function __construct(\Memcached $client, $namespace = '', $defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/PdoCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/PdoCache.php index 931a3b1f..c92e049a 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/PdoCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/PdoCache.php @@ -33,7 +33,7 @@ class PdoCache extends AbstractCache implements PruneableInterface * * db_time_col: The column where to store the timestamp [default: item_time] * * db_username: The username when lazy-connect [default: ''] * * db_password: The password when lazy-connect [default: ''] - * * db_connection_options: An array of driver-specific connection options [default: array()] + * * db_connection_options: An array of driver-specific connection options [default: []] * * @param \PDO|Connection|string $connOrDsn A \PDO or Connection instance or DSN string or null * @param string $namespace @@ -44,7 +44,7 @@ class PdoCache extends AbstractCache implements PruneableInterface * @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION * @throws InvalidArgumentException When namespace contains invalid characters */ - public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = array()) + public function __construct($connOrDsn, $namespace = '', $defaultLifetime = 0, array $options = []) { $this->init($connOrDsn, $namespace, $defaultLifetime, $options); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/PhpArrayCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/PhpArrayCache.php index 3db8a2ac..7bb25ff8 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/PhpArrayCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/PhpArrayCache.php @@ -13,9 +13,9 @@ namespace Symfony\Component\Cache\Simple; use Psr\SimpleCache\CacheInterface; use Symfony\Component\Cache\Exception\InvalidArgumentException; -use Symfony\Component\Cache\Traits\PhpArrayTrait; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\ResettableInterface; +use Symfony\Component\Cache\Traits\PhpArrayTrait; /** * Caches items at warm up time using a PHP array that is stored in shared memory by OPCache since PHP 7.0. @@ -36,7 +36,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt { $this->file = $file; $this->pool = $fallbackPool; - $this->zendDetectUnicode = ini_get('zend.detect_unicode'); + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); } /** @@ -44,14 +44,14 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt * stores arrays in its latest versions. This factory method decorates the given * fallback pool with this adapter only if the current PHP version is supported. * - * @param string $file The PHP file were values are cached + * @param string $file The PHP file were values are cached + * @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit * * @return CacheInterface */ public static function create($file, CacheInterface $fallbackPool) { - // Shared memory is available in PHP 7.0+ with OPCache enabled and in HHVM - if ((\PHP_VERSION_ID >= 70000 && ini_get('opcache.enable')) || defined('HHVM_VERSION')) { + if (\PHP_VERSION_ID >= 70000) { return new static($file, $fallbackPool); } @@ -63,8 +63,8 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt */ public function get($key, $default = null) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -77,7 +77,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt if ('N;' === $value) { $value = null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { $e = null; $value = unserialize($value); @@ -99,12 +99,12 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } foreach ($keys as $key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } } if (null === $this->values) { @@ -119,8 +119,8 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt */ public function has($key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -134,8 +134,8 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt */ public function delete($key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -149,16 +149,16 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt */ public function deleteMultiple($keys) { - if (!is_array($keys) && !$keys instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + if (!\is_array($keys) && !$keys instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } $deleted = true; - $fallbackKeys = array(); + $fallbackKeys = []; foreach ($keys as $key) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (isset($this->values[$key])) { @@ -183,8 +183,8 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt */ public function set($key, $value, $ttl = null) { - if (!is_string($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (null === $this->values) { $this->initialize(); @@ -198,16 +198,16 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt */ public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); + if (!\is_array($values) && !$values instanceof \Traversable) { + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); } $saved = true; - $fallbackValues = array(); + $fallbackValues = []; foreach ($values as $key => $value) { - if (!is_string($key) && !is_int($key)) { - throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + if (!\is_string($key) && !\is_int($key)) { + throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key))); } if (isset($this->values[$key])) { @@ -226,7 +226,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt private function generateItems(array $keys, $default) { - $fallbackKeys = array(); + $fallbackKeys = []; foreach ($keys as $key) { if (isset($this->values[$key])) { @@ -234,7 +234,7 @@ class PhpArrayCache implements CacheInterface, PruneableInterface, ResettableInt if ('N;' === $value) { yield $key => null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { try { yield $key => unserialize($value); } catch (\Error $e) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/PhpFilesCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/PhpFilesCache.php index 9231c8cd..50c19034 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/PhpFilesCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/PhpFilesCache.php @@ -29,13 +29,13 @@ class PhpFilesCache extends AbstractCache implements PruneableInterface public function __construct($namespace = '', $defaultLifetime = 0, $directory = null) { if (!static::isSupported()) { - throw new CacheException('OPcache is not enabled'); + throw new CacheException('OPcache is not enabled.'); } parent::__construct('', $defaultLifetime); $this->init($namespace, $directory); $e = new \Exception(); $this->includeHandler = function () use ($e) { throw $e; }; - $this->zendDetectUnicode = ini_get('zend.detect_unicode'); + $this->zendDetectUnicode = filter_var(ini_get('zend.detect_unicode'), \FILTER_VALIDATE_BOOLEAN); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/Psr6Cache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/Psr6Cache.php index 81f14d4a..6b3de205 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/Psr6Cache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/Psr6Cache.php @@ -11,11 +11,11 @@ namespace Symfony\Component\Cache\Simple; -use Psr\Cache\CacheItemPoolInterface; use Psr\Cache\CacheException as Psr6CacheException; -use Psr\SimpleCache\CacheInterface; +use Psr\Cache\CacheItemPoolInterface; use Psr\SimpleCache\CacheException as SimpleCacheException; -use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Psr\SimpleCache\CacheInterface; +use Symfony\Component\Cache\Adapter\AdapterInterface; use Symfony\Component\Cache\CacheItem; use Symfony\Component\Cache\Exception\InvalidArgumentException; use Symfony\Component\Cache\PruneableInterface; @@ -30,27 +30,36 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa use ProxyTrait; private $createCacheItem; + private $cacheItemPrototype; public function __construct(CacheItemPoolInterface $pool) { $this->pool = $pool; - if ($pool instanceof AbstractAdapter) { - $this->createCacheItem = \Closure::bind( - function ($key, $value, $allowInt = false) { - if ($allowInt && is_int($key)) { - $key = (string) $key; - } else { - CacheItem::validateKey($key); - } - $f = $this->createCacheItem; - - return $f($key, $value, false); - }, - $pool, - AbstractAdapter::class - ); + if (!$pool instanceof AdapterInterface) { + return; } + $cacheItemPrototype = &$this->cacheItemPrototype; + $createCacheItem = \Closure::bind( + static function ($key, $value, $allowInt = false) use (&$cacheItemPrototype) { + $item = clone $cacheItemPrototype; + $item->key = $allowInt && \is_int($key) ? (string) $key : CacheItem::validateKey($key); + $item->value = $value; + $item->isHit = false; + + return $item; + }, + null, + CacheItem::class + ); + $this->createCacheItem = function ($key, $value, $allowInt = false) use ($createCacheItem) { + if (null === $this->cacheItemPrototype) { + $this->get($allowInt && \is_int($key) ? (string) $key : $key); + } + $this->createCacheItem = $createCacheItem; + + return $createCacheItem($key, $value, $allowInt); + }; } /** @@ -65,6 +74,10 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa } catch (Psr6CacheException $e) { throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); } + if (null === $this->cacheItemPrototype) { + $this->cacheItemPrototype = clone $item; + $this->cacheItemPrototype->set(null); + } return $item->isHit() ? $item->get() : $default; } @@ -121,8 +134,8 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } try { @@ -132,7 +145,7 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa } catch (Psr6CacheException $e) { throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); } - $values = array(); + $values = []; foreach ($items as $key => $item) { $values[$key] = $item->isHit() ? $item->get() : $default; @@ -146,11 +159,11 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa */ public function setMultiple($values, $ttl = null) { - $valuesIsArray = is_array($values); + $valuesIsArray = \is_array($values); if (!$valuesIsArray && !$values instanceof \Traversable) { - throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given', is_object($values) ? get_class($values) : gettype($values))); + throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values))); } - $items = array(); + $items = []; try { if (null !== $f = $this->createCacheItem) { @@ -159,14 +172,14 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa $items[$key] = $f($key, $value, true); } } elseif ($valuesIsArray) { - $items = array(); + $items = []; foreach ($values as $key => $value) { $items[] = (string) $key; } $items = $this->pool->getItems($items); } else { foreach ($values as $key => $value) { - if (is_int($key)) { + if (\is_int($key)) { $key = (string) $key; } $items[$key] = $this->pool->getItem($key)->set($value); @@ -199,8 +212,8 @@ class Psr6Cache implements CacheInterface, PruneableInterface, ResettableInterfa { if ($keys instanceof \Traversable) { $keys = iterator_to_array($keys, false); - } elseif (!is_array($keys)) { - throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given', is_object($keys) ? get_class($keys) : gettype($keys))); + } elseif (!\is_array($keys)) { + throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys))); } try { diff --git a/advancedcontentfilter/vendor/symfony/cache/Simple/TraceableCache.php b/advancedcontentfilter/vendor/symfony/cache/Simple/TraceableCache.php index 756403bf..61b22963 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Simple/TraceableCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Simple/TraceableCache.php @@ -24,7 +24,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn { private $pool; private $miss; - private $calls = array(); + private $calls = []; public function __construct(CacheInterface $pool) { @@ -37,7 +37,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn */ public function get($key, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; $event = $this->start(__FUNCTION__); try { $value = $this->pool->get($key, $miss); @@ -99,7 +99,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn public function setMultiple($values, $ttl = null) { $event = $this->start(__FUNCTION__); - $event->result['keys'] = array(); + $event->result['keys'] = []; if ($values instanceof \Traversable) { $values = function () use ($values, $event) { @@ -109,7 +109,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn } }; $values = $values(); - } elseif (is_array($values)) { + } elseif (\is_array($values)) { $event->result['keys'] = array_keys($values); } @@ -125,7 +125,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn */ public function getMultiple($keys, $default = null) { - $miss = null !== $default && is_object($default) ? $default : $this->miss; + $miss = null !== $default && \is_object($default) ? $default : $this->miss; $event = $this->start(__FUNCTION__); try { $result = $this->pool->getMultiple($keys, $miss); @@ -133,7 +133,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn $event->end = microtime(true); } $f = function () use ($result, $event, $miss, $default) { - $event->result = array(); + $event->result = []; foreach ($result as $key => $value) { if ($event->result[$key] = $miss !== $value) { ++$event->hits; @@ -216,7 +216,7 @@ class TraceableCache implements CacheInterface, PruneableInterface, ResettableIn try { return $this->calls; } finally { - $this->calls = array(); + $this->calls = []; } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php index d9353821..0e8ed001 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php @@ -15,11 +15,11 @@ use Symfony\Component\Cache\Adapter\RedisAdapter; abstract class AbstractRedisAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testExpiration' => 'Testing expiration slows down the test suite', 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ); + ]; protected static $redis; @@ -28,14 +28,15 @@ abstract class AbstractRedisAdapterTest extends AdapterTestCase return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); } - public static function setupBeforeClass() + public static function setUpBeforeClass() { - if (!extension_loaded('redis')) { + if (!\extension_loaded('redis')) { self::markTestSkipped('Extension redis required.'); } - if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) { - $e = error_get_last(); - self::markTestSkipped($e['message']); + try { + (new \Redis())->connect(getenv('REDIS_HOST')); + } catch (\Exception $e) { + self::markTestSkipped($e->getMessage()); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php index a0b74b47..5758a286 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php @@ -21,11 +21,11 @@ abstract class AdapterTestCase extends CachePoolTest { parent::setUp(); - if (!array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && defined('HHVM_VERSION')) { + if (!\array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && \defined('HHVM_VERSION')) { $this->skippedTests['testDeferredSaveWithoutCommit'] = 'Destructors are called late on HHVM.'; } - if (!array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) { + if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) { $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; } } @@ -85,11 +85,11 @@ abstract class AdapterTestCase extends CachePoolTest $item = $cache->getItem('foo'); $this->assertFalse($item->isHit()); - foreach ($cache->getItems(array('foo')) as $item) { + foreach ($cache->getItems(['foo']) as $item) { } $cache->save($item->set(new NotUnserializable())); - foreach ($cache->getItems(array('foo')) as $item) { + foreach ($cache->getItems(['foo']) as $item) { } $this->assertFalse($item->isHit()); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php index 72df12e4..f55a1b9b 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php @@ -16,23 +16,23 @@ use Symfony\Component\Cache\Adapter\ApcuAdapter; class ApcuAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testExpiration' => 'Testing expiration slows down the test suite', 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ); + ]; public function createCachePool($defaultLifetime = 0) { - if (!function_exists('apcu_fetch') || !ini_get('apc.enabled')) { + if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN)) { $this->markTestSkipped('APCu extension is required.'); } - if ('cli' === PHP_SAPI && !ini_get('apc.enable_cli')) { + if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { if ('testWithCliSapi' !== $this->getName()) { $this->markTestSkipped('apc.enable_cli=1 is required.'); } } - if ('\\' === DIRECTORY_SEPARATOR) { + if ('\\' === \DIRECTORY_SEPARATOR) { $this->markTestSkipped('Fails transiently on Windows.'); } @@ -54,7 +54,7 @@ class ApcuAdapterTest extends AdapterTestCase public function testVersion() { - $namespace = str_replace('\\', '.', get_class($this)); + $namespace = str_replace('\\', '.', static::class); $pool1 = new ApcuAdapter($namespace, 0, 'p1'); @@ -79,7 +79,7 @@ class ApcuAdapterTest extends AdapterTestCase public function testNamespace() { - $namespace = str_replace('\\', '.', get_class($this)); + $namespace = str_replace('\\', '.', static::class); $pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1'); diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php index 725d7901..e6adc9d0 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php @@ -18,10 +18,10 @@ use Symfony\Component\Cache\Adapter\ArrayAdapter; */ class ArrayAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', - ); + ]; public function createCachePool($defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php index 293a90cc..be811d6f 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php @@ -11,10 +11,11 @@ namespace Symfony\Component\Cache\Tests\Adapter; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Adapter\ChainAdapter; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter; @@ -26,25 +27,21 @@ class ChainAdapterTest extends AdapterTestCase { public function createCachePool($defaultLifetime = 0) { - return new ChainAdapter(array(new ArrayAdapter($defaultLifetime), new ExternalAdapter(), new FilesystemAdapter('', $defaultLifetime)), $defaultLifetime); + return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime); } - /** - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage At least one adapter must be specified. - */ public function testEmptyAdaptersException() { - new ChainAdapter(array()); + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('At least one adapter must be specified.'); + new ChainAdapter([]); } - /** - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage The class "stdClass" does not implement - */ public function testInvalidAdapterException() { - new ChainAdapter(array(new \stdClass())); + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The class "stdClass" does not implement'); + new ChainAdapter([new \stdClass()]); } public function testPrune() @@ -53,23 +50,141 @@ class ChainAdapterTest extends AdapterTestCase $this->markTestSkipped($this->skippedTests[__FUNCTION__]); } - $cache = new ChainAdapter(array( + $cache = new ChainAdapter([ $this->getPruneableMock(), $this->getNonPruneableMock(), $this->getPruneableMock(), - )); + ]); $this->assertTrue($cache->prune()); - $cache = new ChainAdapter(array( + $cache = new ChainAdapter([ $this->getPruneableMock(), $this->getFailingPruneableMock(), $this->getPruneableMock(), - )); + ]); $this->assertFalse($cache->prune()); } + public function testMultipleCachesExpirationWhenCommonTtlIsNotSet() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $adapter1 = new ArrayAdapter(4); + $adapter2 = new ArrayAdapter(2); + + $cache = new ChainAdapter([$adapter1, $adapter2]); + + $cache->save($cache->getItem('key')->set('value')); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertFalse($item->isHit()); + + $adapter2->save($adapter2->getItem('key1')->set('value1')); + + $item = $cache->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + $item = $adapter2->getItem('key1'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertFalse($item->isHit()); + } + + public function testMultipleCachesExpirationWhenCommonTtlIsSet() + { + if (isset($this->skippedTests[__FUNCTION__])) { + $this->markTestSkipped($this->skippedTests[__FUNCTION__]); + } + + $adapter1 = new ArrayAdapter(4); + $adapter2 = new ArrayAdapter(2); + + $cache = new ChainAdapter([$adapter1, $adapter2], 6); + + $cache->save($cache->getItem('key')->set('value')); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value', $item->get()); + + $item = $adapter2->getItem('key'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key'); + $this->assertFalse($item->isHit()); + + $adapter2->save($adapter2->getItem('key1')->set('value1')); + + $item = $cache->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + $item = $adapter2->getItem('key1'); + $this->assertFalse($item->isHit()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertTrue($item->isHit()); + $this->assertEquals('value1', $item->get()); + + sleep(2); + + $item = $adapter1->getItem('key1'); + $this->assertFalse($item->isHit()); + } + /** - * @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface + * @return MockObject|PruneableCacheInterface */ private function getPruneableMock() { @@ -80,13 +195,13 @@ class ChainAdapterTest extends AdapterTestCase $pruneable ->expects($this->atLeastOnce()) ->method('prune') - ->will($this->returnValue(true)); + ->willReturn(true); return $pruneable; } /** - * @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface + * @return MockObject|PruneableCacheInterface */ private function getFailingPruneableMock() { @@ -97,13 +212,13 @@ class ChainAdapterTest extends AdapterTestCase $pruneable ->expects($this->atLeastOnce()) ->method('prune') - ->will($this->returnValue(false)); + ->willReturn(false); return $pruneable; } /** - * @return \PHPUnit_Framework_MockObject_MockObject|AdapterInterface + * @return MockObject|AdapterInterface */ private function getNonPruneableMock() { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php index 8d4dfe28..8f520cb5 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php @@ -19,11 +19,11 @@ use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; */ class DoctrineAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayCache is not.', 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayCache is not.', 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', - ); + ]; public function createCachePool($defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php index b6757514..fa830682 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php @@ -34,7 +34,7 @@ class FilesystemAdapterTest extends AdapterTestCase if (!file_exists($dir)) { return; } - if (!$dir || 0 !== strpos(dirname($dir), sys_get_temp_dir())) { + if (!$dir || 0 !== strpos(\dirname($dir), sys_get_temp_dir())) { throw new \Exception(__METHOD__."() operates only on subdirs of system's temp dir"); } $children = new \RecursiveIteratorIterator( diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php index cf2384c5..536e2c2d 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php @@ -19,29 +19,59 @@ class MaxIdLengthAdapterTest extends TestCase public function testLongKey() { $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs(array(str_repeat('-', 10))) - ->setMethods(array('doHave', 'doFetch', 'doDelete', 'doSave', 'doClear')) + ->setConstructorArgs([str_repeat('-', 10)]) + ->setMethods(['doHave', 'doFetch', 'doDelete', 'doSave', 'doClear']) ->getMock(); $cache->expects($this->exactly(2)) ->method('doHave') ->withConsecutive( - array($this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')), - array($this->equalTo('----------:---------------------------------------')) + [$this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')], + [$this->equalTo('----------:---------------------------------------')] ); $cache->hasItem(str_repeat('-', 40)); $cache->hasItem(str_repeat('-', 39)); } - /** - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Namespace must be 26 chars max, 40 given ("----------------------------------------") - */ - public function testTooLongNamespace() + public function testLongKeyVersioning() { $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs(array(str_repeat('-', 40))) + ->setConstructorArgs([str_repeat('-', 26)]) + ->getMock(); + + $cache + ->method('doFetch') + ->willReturn(['2:']); + + $reflectionClass = new \ReflectionClass(AbstractAdapter::class); + + $reflectionMethod = $reflectionClass->getMethod('getId'); + $reflectionMethod->setAccessible(true); + + // No versioning enabled + $this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); + + $reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled'); + $reflectionProperty->setAccessible(true); + $reflectionProperty->setValue($cache, true); + + // Versioning enabled + $this->assertEquals('--------------------------:2:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); + $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); + } + + public function testTooLongNamespace() + { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Namespace must be 26 chars max, 40 given ("----------------------------------------")'); + $this->getMockBuilder(MaxIdLengthAdapter::class) + ->setConstructorArgs([str_repeat('-', 40)]) ->getMock(); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php index 76e06080..a9a397dd 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php @@ -16,19 +16,19 @@ use Symfony\Component\Cache\Adapter\MemcachedAdapter; class MemcachedAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ); + ]; protected static $client; - public static function setupBeforeClass() + public static function setUpBeforeClass() { if (!MemcachedAdapter::isSupported()) { self::markTestSkipped('Extension memcached >=2.2.0 required.'); } - self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), array('binary_protocol' => false)); + self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); self::$client->get('foo'); $code = self::$client->getResultCode(); @@ -46,13 +46,13 @@ class MemcachedAdapterTest extends AdapterTestCase public function testOptions() { - $client = MemcachedAdapter::createConnection(array(), array( + $client = MemcachedAdapter::createConnection([], [ 'libketama_compatible' => false, 'distribution' => 'modula', 'compression' => true, 'serializer' => 'php', 'hash' => 'md5', - )); + ]); $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); @@ -63,46 +63,51 @@ class MemcachedAdapterTest extends AdapterTestCase /** * @dataProvider provideBadOptions - * @expectedException \ErrorException - * @expectedExceptionMessage constant(): Couldn't find constant Memcached:: */ public function testBadOptions($name, $value) { - MemcachedAdapter::createConnection(array(), array($name => $value)); + if (\PHP_VERSION_ID < 80000) { + $this->expectException('ErrorException'); + $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); + } else { + $this->expectException('Error'); + $this->expectExceptionMessage('Undefined constant Memcached::'); + } + + MemcachedAdapter::createConnection([], [$name => $value]); } public function provideBadOptions() { - return array( - array('foo', 'bar'), - array('hash', 'zyx'), - array('serializer', 'zyx'), - array('distribution', 'zyx'), - ); + return [ + ['foo', 'bar'], + ['hash', 'zyx'], + ['serializer', 'zyx'], + ['distribution', 'zyx'], + ]; } public function testDefaultOptions() { $this->assertTrue(MemcachedAdapter::isSupported()); - $client = MemcachedAdapter::createConnection(array()); + $client = MemcachedAdapter::createConnection([]); $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); + $this->assertSame(1, $client->getOption(\Memcached::OPT_TCP_NODELAY)); $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); } - /** - * @expectedException \Symfony\Component\Cache\Exception\CacheException - * @expectedExceptionMessage MemcachedAdapter: "serializer" option must be "php" or "igbinary". - */ public function testOptionSerializer() { + $this->expectException('Symfony\Component\Cache\Exception\CacheException'); + $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); if (!\Memcached::HAVE_JSON) { $this->markTestSkipped('Memcached::HAVE_JSON required'); } - new MemcachedAdapter(MemcachedAdapter::createConnection(array(), array('serializer' => 'json'))); + new MemcachedAdapter(MemcachedAdapter::createConnection([], ['serializer' => 'json'])); } /** @@ -111,54 +116,54 @@ class MemcachedAdapterTest extends AdapterTestCase public function testServersSetting($dsn, $host, $port) { $client1 = MemcachedAdapter::createConnection($dsn); - $client2 = MemcachedAdapter::createConnection(array($dsn)); - $client3 = MemcachedAdapter::createConnection(array(array($host, $port))); - $expect = array( + $client2 = MemcachedAdapter::createConnection([$dsn]); + $client3 = MemcachedAdapter::createConnection([[$host, $port]]); + $expect = [ 'host' => $host, 'port' => $port, - ); + ]; - $f = function ($s) { return array('host' => $s['host'], 'port' => $s['port']); }; - $this->assertSame(array($expect), array_map($f, $client1->getServerList())); - $this->assertSame(array($expect), array_map($f, $client2->getServerList())); - $this->assertSame(array($expect), array_map($f, $client3->getServerList())); + $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; + $this->assertSame([$expect], array_map($f, $client1->getServerList())); + $this->assertSame([$expect], array_map($f, $client2->getServerList())); + $this->assertSame([$expect], array_map($f, $client3->getServerList())); } public function provideServersSetting() { - yield array( + yield [ 'memcached://127.0.0.1/50', '127.0.0.1', 11211, - ); - yield array( + ]; + yield [ 'memcached://localhost:11222?weight=25', 'localhost', 11222, - ); - if (ini_get('memcached.use_sasl')) { - yield array( + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ 'memcached://user:password@127.0.0.1?weight=50', '127.0.0.1', 11211, - ); + ]; } - yield array( + yield [ 'memcached:///var/run/memcached.sock?weight=25', '/var/run/memcached.sock', 0, - ); - yield array( + ]; + yield [ 'memcached:///var/local/run/memcached.socket?weight=25', '/var/local/run/memcached.socket', 0, - ); - if (ini_get('memcached.use_sasl')) { - yield array( + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ 'memcached://user:password@/var/local/run/memcached.socket?weight=25', '/var/local/run/memcached.socket', 0, - ); + ]; } } @@ -180,15 +185,20 @@ class MemcachedAdapterTest extends AdapterTestCase self::markTestSkipped('Extension memcached required.'); } - yield array( + yield [ 'memcached://localhost:11222?retry_timeout=10', - array(\Memcached::OPT_RETRY_TIMEOUT => 8), - array(\Memcached::OPT_RETRY_TIMEOUT => 10), - ); - yield array( + [\Memcached::OPT_RETRY_TIMEOUT => 8], + [\Memcached::OPT_RETRY_TIMEOUT => 10], + ]; + yield [ 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2', - array(\Memcached::OPT_RETRY_TIMEOUT => 8), - array(\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8), - ); + [\Memcached::OPT_RETRY_TIMEOUT => 8], + [\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8], + ]; + } + + public function testClear() + { + $this->assertTrue($this->createCachePool()->clear()); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php index 73e5cad5..b771fa0e 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php @@ -43,7 +43,7 @@ class NullAdapterTest extends TestCase { $adapter = $this->createCachePool(); - $keys = array('foo', 'bar', 'baz', 'biz'); + $keys = ['foo', 'bar', 'baz', 'biz']; /** @var CacheItemInterface[] $items */ $items = $adapter->getItems($keys); @@ -89,7 +89,7 @@ class NullAdapterTest extends TestCase public function testDeleteItems() { - $this->assertTrue($this->createCachePool()->deleteItems(array('key', 'foo', 'bar'))); + $this->assertTrue($this->createCachePool()->deleteItems(['key', 'foo', 'bar'])); } public function testSave() diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php index 24e3f9bb..dd2a9118 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php @@ -23,9 +23,9 @@ class PdoAdapterTest extends AdapterTestCase protected static $dbFile; - public static function setupBeforeClass() + public static function setUpBeforeClass() { - if (!extension_loaded('pdo_sqlite')) { + if (!\extension_loaded('pdo_sqlite')) { self::markTestSkipped('Extension pdo_sqlite required.'); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php index 1e8c6155..aa53958c 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php @@ -24,15 +24,15 @@ class PdoDbalAdapterTest extends AdapterTestCase protected static $dbFile; - public static function setupBeforeClass() + public static function setUpBeforeClass() { - if (!extension_loaded('pdo_sqlite')) { + if (!\extension_loaded('pdo_sqlite')) { self::markTestSkipped('Extension pdo_sqlite required.'); } self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - $pool = new PdoAdapter(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile))); + $pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); $pool->createTable(); } @@ -43,6 +43,6 @@ class PdoDbalAdapterTest extends AdapterTestCase public function createCachePool($defaultLifetime = 0) { - return new PdoAdapter(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile)), '', $defaultLifetime); + return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php index 14b61263..f88a7187 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php @@ -20,7 +20,7 @@ use Symfony\Component\Cache\Adapter\PhpArrayAdapter; */ class PhpArrayAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testBasicUsage' => 'PhpArrayAdapter is read-only.', 'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.', 'testClear' => 'PhpArrayAdapter is read-only.', @@ -51,17 +51,19 @@ class PhpArrayAdapterTest extends AdapterTestCase 'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.', 'testPrune' => 'PhpArrayAdapter just proxies', - ); + ]; protected static $file; - public static function setupBeforeClass() + public static function setUpBeforeClass() { self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; } protected function tearDown() { + $this->createCachePool()->clear(); + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); } @@ -74,22 +76,22 @@ class PhpArrayAdapterTest extends AdapterTestCase public function testStore() { - $arrayWithRefs = array(); + $arrayWithRefs = []; $arrayWithRefs[0] = 123; $arrayWithRefs[1] = &$arrayWithRefs[0]; - $object = (object) array( + $object = (object) [ 'foo' => 'bar', 'foo2' => 'bar2', - ); + ]; - $expected = array( + $expected = [ 'null' => null, 'serializedString' => serialize($object), 'arrayWithRefs' => $arrayWithRefs, 'object' => $object, - 'arrayWithObject' => array('bar' => $object), - ); + 'arrayWithObject' => ['bar' => $object], + ]; $adapter = $this->createCachePool(); $adapter->warmUp($expected); @@ -101,13 +103,13 @@ class PhpArrayAdapterTest extends AdapterTestCase public function testStoredFile() { - $expected = array( + $expected = [ 'integer' => 42, 'float' => 42.42, 'boolean' => true, - 'array_simple' => array('foo', 'bar'), - 'array_associative' => array('foo' => 'bar', 'foo2' => 'bar2'), - ); + 'array_simple' => ['foo', 'bar'], + 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], + ]; $adapter = $this->createCachePool(); $adapter->warmUp($expected); @@ -122,7 +124,7 @@ class PhpArrayAdapterWrapper extends PhpArrayAdapter { public function save(CacheItemInterface $item) { - call_user_func(\Closure::bind(function () use ($item) { + \call_user_func(\Closure::bind(function () use ($item) { $this->values[$item->getKey()] = $item->get(); $this->warmUp($this->values); $this->values = eval(substr(file_get_contents($this->file), 6)); diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php index 1a23198c..0bfd5c39 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php @@ -19,24 +19,26 @@ use Symfony\Component\Cache\Adapter\PhpArrayAdapter; */ class PhpArrayAdapterWithFallbackTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', 'testPrune' => 'PhpArrayAdapter just proxies', - ); + ]; protected static $file; - public static function setupBeforeClass() + public static function setUpBeforeClass() { self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; } protected function tearDown() { + $this->createCachePool()->clear(); + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php index 8e93c937..247160d5 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php @@ -19,9 +19,9 @@ use Symfony\Component\Cache\Adapter\PhpFilesAdapter; */ class PhpFilesAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testDefaultLifeTime' => 'PhpFilesAdapter does not allow configuring a default lifetime.', - ); + ]; public function createCachePool() { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php index c005d64a..6aadbf26 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php @@ -16,23 +16,23 @@ use Symfony\Component\Cache\Adapter\RedisAdapter; class PredisAdapterTest extends AbstractRedisAdapterTest { - public static function setupBeforeClass() + public static function setUpBeforeClass() { - parent::setupBeforeClass(); - self::$redis = new \Predis\Client(array('host' => getenv('REDIS_HOST'))); + parent::setUpBeforeClass(); + self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]); } public function testCreateConnection() { $redisHost = getenv('REDIS_HOST'); - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', array('class' => \Predis\Client::class, 'timeout' => 3)); + $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', ['class' => \Predis\Client::class, 'timeout' => 3]); $this->assertInstanceOf(\Predis\Client::class, $redis); $connection = $redis->getConnection(); $this->assertInstanceOf(StreamConnection::class, $connection); - $params = array( + $params = [ 'scheme' => 'tcp', 'host' => $redisHost, 'path' => '', @@ -47,7 +47,7 @@ class PredisAdapterTest extends AbstractRedisAdapterTest 'lazy' => false, 'database' => '1', 'password' => null, - ); + ]; $this->assertSame($params, $connection->getParameters()->toArray()); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php index 38915397..1afabaf1 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php @@ -13,10 +13,10 @@ namespace Symfony\Component\Cache\Tests\Adapter; class PredisClusterAdapterTest extends AbstractRedisAdapterTest { - public static function setupBeforeClass() + public static function setUpBeforeClass() { - parent::setupBeforeClass(); - self::$redis = new \Predis\Client(array(array('host' => getenv('REDIS_HOST')))); + parent::setUpBeforeClass(); + self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]); } public static function tearDownAfterClass() diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php new file mode 100644 index 00000000..5b09919e --- /dev/null +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + self::$redis = new \Predis\Client(explode(' ', $hosts), ['cluster' => 'redis']); + } + + public static function tearDownAfterClass() + { + self::$redis = null; + } +} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php index ff4b9d34..810cb31a 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php @@ -21,23 +21,21 @@ use Symfony\Component\Cache\CacheItem; */ class ProxyAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', 'testPrune' => 'ProxyAdapter just proxies', - ); + ]; public function createCachePool($defaultLifetime = 0) { return new ProxyAdapter(new ArrayAdapter(), '', $defaultLifetime); } - /** - * @expectedException \Exception - * @expectedExceptionMessage OK bar - */ public function testProxyfiedItem() { + $this->expectException('Exception'); + $this->expectExceptionMessage('OK bar'); $item = new CacheItem(); $pool = new ProxyAdapter(new TestingArrayAdapter($item)); diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php index 28c310fb..6ec6321a 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php @@ -17,10 +17,10 @@ use Symfony\Component\Cache\Traits\RedisProxy; class RedisAdapterTest extends AbstractRedisAdapterTest { - public static function setupBeforeClass() + public static function setUpBeforeClass() { - parent::setupBeforeClass(); - self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), array('lazy' => true)); + parent::setUpBeforeClass(); + self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]); } public function createCachePool($defaultLifetime = 0) @@ -43,50 +43,50 @@ class RedisAdapterTest extends AbstractRedisAdapterTest $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2'); $this->assertSame(2, $redis->getDbNum()); - $redis = RedisAdapter::createConnection('redis://'.$redisHost, array('timeout' => 3)); + $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]); $this->assertEquals(3, $redis->getTimeout()); $redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4'); $this->assertEquals(4, $redis->getTimeout()); - $redis = RedisAdapter::createConnection('redis://'.$redisHost, array('read_timeout' => 5)); + $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); $this->assertEquals(5, $redis->getReadTimeout()); } /** * @dataProvider provideFailedCreateConnection - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Redis connection failed */ public function testFailedCreateConnection($dsn) { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Redis connection '); RedisAdapter::createConnection($dsn); } public function provideFailedCreateConnection() { - return array( - array('redis://localhost:1234'), - array('redis://foo@localhost'), - array('redis://localhost/123'), - ); + return [ + ['redis://localhost:1234'], + ['redis://foo@localhost'], + ['redis://localhost/123'], + ]; } /** * @dataProvider provideInvalidCreateConnection - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Invalid Redis DSN */ public function testInvalidCreateConnection($dsn) { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid Redis DSN'); RedisAdapter::createConnection($dsn); } public function provideInvalidCreateConnection() { - return array( - array('foo://localhost'), - array('redis://'), - ); + return [ + ['foo://localhost'], + ['redis://'], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php index bef3eb88..bd9def32 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php @@ -13,12 +13,12 @@ namespace Symfony\Component\Cache\Tests\Adapter; class RedisArrayAdapterTest extends AbstractRedisAdapterTest { - public static function setupBeforeClass() + public static function setUpBeforeClass() { parent::setupBeforeClass(); if (!class_exists('RedisArray')) { self::markTestSkipped('The RedisArray class is required.'); } - self::$redis = new \RedisArray(array(getenv('REDIS_HOST')), array('lazy_connect' => true)); + self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php new file mode 100644 index 00000000..9c339d2d --- /dev/null +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Adapter; + +class RedisClusterAdapterTest extends AbstractRedisAdapterTest +{ + public static function setUpBeforeClass() + { + if (!class_exists('RedisCluster')) { + self::markTestSkipped('The RedisCluster class is required.'); + } + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + + self::$redis = new \RedisCluster(null, explode(' ', $hosts)); + } +} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php index d5795d52..d8470a2e 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php @@ -11,20 +11,31 @@ namespace Symfony\Component\Cache\Tests\Adapter; -use Symfony\Component\Cache\Simple\FilesystemCache; use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; +use Symfony\Component\Cache\Simple\ArrayCache; +use Symfony\Component\Cache\Simple\FilesystemCache; /** * @group time-sensitive */ class SimpleCacheAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testPrune' => 'SimpleCache just proxies', - ); + ]; public function createCachePool($defaultLifetime = 0) { return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime); } + + public function testValidCacheKeyWithNamespace() + { + $cache = new SimpleCacheAdapter(new ArrayCache(), 'some_namespace', 0); + $item = $cache->getItem('my_key'); + $item->set('someValue'); + $cache->save($item); + + $this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.'); + } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php index 0e4e07a1..11907a03 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php @@ -11,7 +11,10 @@ namespace Symfony\Component\Cache\Tests\Adapter; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Cache\CacheItemInterface; use Symfony\Component\Cache\Adapter\AdapterInterface; +use Symfony\Component\Cache\Adapter\ArrayAdapter; use Symfony\Component\Cache\Adapter\FilesystemAdapter; use Symfony\Component\Cache\Adapter\TagAwareAdapter; @@ -30,11 +33,9 @@ class TagAwareAdapterTest extends AdapterTestCase FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); } - /** - * @expectedException \Psr\Cache\InvalidArgumentException - */ public function testInvalidTag() { + $this->expectException('Psr\Cache\InvalidArgumentException'); $pool = $this->createCachePool(); $item = $pool->getItem('foo'); $item->tag(':'); @@ -56,7 +57,7 @@ class TagAwareAdapterTest extends AdapterTestCase $pool->save($i3->tag('foo')->tag('baz')); $pool->save($foo); - $pool->invalidateTags(array('bar')); + $pool->invalidateTags(['bar']); $this->assertFalse($pool->getItem('i0')->isHit()); $this->assertTrue($pool->getItem('i1')->isHit()); @@ -64,11 +65,33 @@ class TagAwareAdapterTest extends AdapterTestCase $this->assertTrue($pool->getItem('i3')->isHit()); $this->assertTrue($pool->getItem('foo')->isHit()); - $pool->invalidateTags(array('foo')); + $pool->invalidateTags(['foo']); $this->assertFalse($pool->getItem('i1')->isHit()); $this->assertFalse($pool->getItem('i3')->isHit()); $this->assertTrue($pool->getItem('foo')->isHit()); + + $anotherPoolInstance = $this->createCachePool(); + + $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit()); + $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit()); + $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit()); + } + + public function testInvalidateCommits() + { + $pool1 = $this->createCachePool(); + + $foo = $pool1->getItem('foo'); + $foo->tag('tag'); + + $pool1->saveDeferred($foo->set('foo')); + $pool1->invalidateTags(['tag']); + + $pool2 = $this->createCachePool(); + $foo = $pool2->getItem('foo'); + + $this->assertTrue($foo->isHit()); } public function testTagsAreCleanedOnSave() @@ -81,7 +104,7 @@ class TagAwareAdapterTest extends AdapterTestCase $i = $pool->getItem('k'); $pool->save($i->tag('bar')); - $pool->invalidateTags(array('foo')); + $pool->invalidateTags(['foo']); $this->assertTrue($pool->getItem('k')->isHit()); } @@ -94,7 +117,7 @@ class TagAwareAdapterTest extends AdapterTestCase $pool->deleteItem('k'); $pool->save($pool->getItem('k')); - $pool->invalidateTags(array('foo')); + $pool->invalidateTags(['foo']); $this->assertTrue($pool->getItem('k')->isHit()); } @@ -104,11 +127,11 @@ class TagAwareAdapterTest extends AdapterTestCase $pool = $this->createCachePool(10); $item = $pool->getItem('foo'); - $item->tag(array('baz')); + $item->tag(['baz']); $item->expiresAfter(100); $pool->save($item); - $pool->invalidateTags(array('baz')); + $pool->invalidateTags(['baz']); $this->assertFalse($pool->getItem('foo')->isHit()); sleep(20); @@ -124,7 +147,7 @@ class TagAwareAdapterTest extends AdapterTestCase $pool->save($i->tag('foo')); $i = $pool->getItem('k'); - $this->assertSame(array('foo' => 'foo'), $i->getPreviousTags()); + $this->assertSame(['foo' => 'foo'], $i->getPreviousTags()); } public function testPrune() @@ -139,8 +162,138 @@ class TagAwareAdapterTest extends AdapterTestCase $this->assertFalse($cache->prune()); } + public function testKnownTagVersionsTtl() + { + $itemsPool = new FilesystemAdapter('', 10); + $tagsPool = $this + ->getMockBuilder(AdapterInterface::class) + ->getMock(); + + $pool = new TagAwareAdapter($itemsPool, $tagsPool, 10); + + $item = $pool->getItem('foo'); + $item->tag(['baz']); + $item->expiresAfter(100); + + $tag = $this->getMockBuilder(CacheItemInterface::class)->getMock(); + $tag->expects(self::exactly(2))->method('get')->willReturn(10); + + $tagsPool->expects(self::exactly(2))->method('getItems')->willReturn([ + 'baz'.TagAwareAdapter::TAGS_PREFIX => $tag, + ]); + + $pool->save($item); + $this->assertTrue($pool->getItem('foo')->isHit()); + $this->assertTrue($pool->getItem('foo')->isHit()); + + sleep(20); + + $this->assertTrue($pool->getItem('foo')->isHit()); + + sleep(5); + + $this->assertTrue($pool->getItem('foo')->isHit()); + } + + public function testTagEntryIsCreatedForItemWithoutTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $adapter = new FilesystemAdapter(); + $this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey)); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + + public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $this->assertFalse($anotherPool->hasItem($itemKey)); + } + + public function testInvalidateTagsWithArrayAdapter() + { + $adapter = new TagAwareAdapter(new ArrayAdapter()); + + $item = $adapter->getItem('foo'); + + $this->assertFalse($item->isHit()); + + $item->tag('bar'); + $item->expiresAfter(100); + $adapter->save($item); + + $this->assertTrue($adapter->getItem('foo')->isHit()); + + $adapter->invalidateTags(['bar']); + + $this->assertFalse($adapter->getItem('foo')->isHit()); + } + + public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags() + { + $pool = $this->createCachePool(); + + $itemKey = 'foo'; + $item = $pool->getItem($itemKey); + $pool->save($item); + + $anotherPool = $this->createCachePool(); + + $adapter = new FilesystemAdapter(); + $adapter->deleteItem($itemKey); //simulate losing item but keeping tags + + $item = $anotherPool->getItem($itemKey); + $this->assertFalse($item->isHit()); + } + /** - * @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface + * @return MockObject|PruneableCacheInterface */ private function getPruneableMock() { @@ -151,13 +304,13 @@ class TagAwareAdapterTest extends AdapterTestCase $pruneable ->expects($this->atLeastOnce()) ->method('prune') - ->will($this->returnValue(true)); + ->willReturn(true); return $pruneable; } /** - * @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface + * @return MockObject|PruneableCacheInterface */ private function getFailingPruneableMock() { @@ -168,13 +321,13 @@ class TagAwareAdapterTest extends AdapterTestCase $pruneable ->expects($this->atLeastOnce()) ->method('prune') - ->will($this->returnValue(false)); + ->willReturn(false); return $pruneable; } /** - * @return \PHPUnit_Framework_MockObject_MockObject|AdapterInterface + * @return MockObject|AdapterInterface */ private function getNonPruneableMock() { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php new file mode 100644 index 00000000..b11c1f28 --- /dev/null +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php @@ -0,0 +1,38 @@ +getItem('foo'); + $item->tag(['tag1', 'tag2']); + $item->set('bar'); + $cache->save($item); + + $this->assertSame('bar', $cache->getItem('foo')->get()); + } + + public function dataProvider() + { + return [ + [new ArrayAdapter()], + // also testing with a non-AdapterInterface implementation + // because the ProxyAdapter behaves slightly different for those + [new ExternalAdapter()], + ]; + } +} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php index 3755e88d..35eba7d7 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php @@ -19,9 +19,9 @@ use Symfony\Component\Cache\Adapter\TraceableAdapter; */ class TraceableAdapterTest extends AdapterTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testPrune' => 'TraceableAdapter just proxies', - ); + ]; public function createCachePool($defaultLifetime = 0) { @@ -37,7 +37,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[0]; $this->assertSame('getItem', $call->name); - $this->assertSame(array('k' => false), $call->result); + $this->assertSame(['k' => false], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(1, $call->misses); $this->assertNotEmpty($call->start); @@ -61,7 +61,7 @@ class TraceableAdapterTest extends AdapterTestCase public function testGetItemsMissTrace() { $pool = $this->createCachePool(); - $arg = array('k0', 'k1'); + $arg = ['k0', 'k1']; $items = $pool->getItems($arg); foreach ($items as $item) { } @@ -70,7 +70,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[0]; $this->assertSame('getItems', $call->name); - $this->assertSame(array('k0' => false, 'k1' => false), $call->result); + $this->assertSame(['k0' => false, 'k1' => false], $call->result); $this->assertSame(2, $call->misses); $this->assertNotEmpty($call->start); $this->assertNotEmpty($call->end); @@ -85,7 +85,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[0]; $this->assertSame('hasItem', $call->name); - $this->assertSame(array('k' => false), $call->result); + $this->assertSame(['k' => false], $call->result); $this->assertNotEmpty($call->start); $this->assertNotEmpty($call->end); } @@ -101,7 +101,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[2]; $this->assertSame('hasItem', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertNotEmpty($call->start); $this->assertNotEmpty($call->end); } @@ -115,7 +115,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[0]; $this->assertSame('deleteItem', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); @@ -125,14 +125,14 @@ class TraceableAdapterTest extends AdapterTestCase public function testDeleteItemsTrace() { $pool = $this->createCachePool(); - $arg = array('k0', 'k1'); + $arg = ['k0', 'k1']; $pool->deleteItems($arg); $calls = $pool->getCalls(); $this->assertCount(1, $calls); $call = $calls[0]; $this->assertSame('deleteItems', $call->name); - $this->assertSame(array('keys' => $arg, 'result' => true), $call->result); + $this->assertSame(['keys' => $arg, 'result' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); @@ -149,7 +149,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[1]; $this->assertSame('save', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); @@ -166,7 +166,7 @@ class TraceableAdapterTest extends AdapterTestCase $call = $calls[1]; $this->assertSame('saveDeferred', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php index 9b50bfab..5cd4185c 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php @@ -23,7 +23,7 @@ class TraceableTagAwareAdapterTest extends TraceableAdapterTest public function testInvalidateTags() { $pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter())); - $pool->invalidateTags(array('foo')); + $pool->invalidateTags(['foo']); $calls = $pool->getCalls(); $this->assertCount(1, $calls); diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php index daca925f..28c681d1 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php @@ -23,33 +23,33 @@ class CacheItemTest extends TestCase /** * @dataProvider provideInvalidKey - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Cache key */ public function testInvalidKey($key) { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Cache key'); CacheItem::validateKey($key); } public function provideInvalidKey() { - return array( - array(''), - array('{'), - array('}'), - array('('), - array(')'), - array('/'), - array('\\'), - array('@'), - array(':'), - array(true), - array(null), - array(1), - array(1.1), - array(array(array())), - array(new \Exception('foo')), - ); + return [ + [''], + ['{'], + ['}'], + ['('], + [')'], + ['/'], + ['\\'], + ['@'], + [':'], + [true], + [null], + [1], + [1.1], + [[[]]], + [new \Exception('foo')], + ]; } public function testTag() @@ -57,20 +57,20 @@ class CacheItemTest extends TestCase $item = new CacheItem(); $this->assertSame($item, $item->tag('foo')); - $this->assertSame($item, $item->tag(array('bar', 'baz'))); + $this->assertSame($item, $item->tag(['bar', 'baz'])); - call_user_func(\Closure::bind(function () use ($item) { - $this->assertSame(array('foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'), $item->tags); + \call_user_func(\Closure::bind(function () use ($item) { + $this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->tags); }, $this, CacheItem::class)); } /** * @dataProvider provideInvalidKey - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Cache tag */ public function testInvalidTag($tag) { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Cache tag'); $item = new CacheItem(); $item->tag($tag); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php index 1a6157e8..13b4f330 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php @@ -6,7 +6,7 @@ use Doctrine\Common\Cache\CacheProvider; class ArrayCache extends CacheProvider { - private $data = array(); + private $data = []; protected function doFetch($id) { @@ -21,12 +21,12 @@ class ArrayCache extends CacheProvider $expiry = $this->data[$id][1]; - return !$expiry || time() <= $expiry || !$this->doDelete($id); + return !$expiry || time() < $expiry || !$this->doDelete($id); } protected function doSave($id, $data, $lifeTime = 0) { - $this->data[$id] = array($data, $lifeTime ? time() + $lifeTime : false); + $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false]; return true; } @@ -40,7 +40,7 @@ class ArrayCache extends CacheProvider protected function doFlush() { - $this->data = array(); + $this->data = []; return true; } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php index 493906ea..be1f9901 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php @@ -24,9 +24,9 @@ class ExternalAdapter implements CacheItemPoolInterface { private $cache; - public function __construct() + public function __construct($defaultLifetime = 0) { - $this->cache = new ArrayAdapter(); + $this->cache = new ArrayAdapter($defaultLifetime); } public function getItem($key) @@ -34,7 +34,7 @@ class ExternalAdapter implements CacheItemPoolInterface return $this->cache->getItem($key); } - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { return $this->cache->getItems($keys); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php index f70f49d5..7a6cabe8 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php @@ -15,11 +15,11 @@ use Symfony\Component\Cache\Simple\RedisCache; abstract class AbstractRedisCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testSetTtl' => 'Testing expiration slows down the test suite', 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ); + ]; protected static $redis; @@ -28,14 +28,15 @@ abstract class AbstractRedisCacheTest extends CacheTestCase return new RedisCache(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); } - public static function setupBeforeClass() + public static function setUpBeforeClass() { - if (!extension_loaded('redis')) { + if (!\extension_loaded('redis')) { self::markTestSkipped('Extension redis required.'); } - if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) { - $e = error_get_last(); - self::markTestSkipped($e['message']); + try { + (new \Redis())->connect(getenv('REDIS_HOST')); + } catch (\Exception $e) { + self::markTestSkipped($e->getMessage()); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php index 297a4175..fad0c043 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php @@ -15,18 +15,18 @@ use Symfony\Component\Cache\Simple\ApcuCache; class ApcuCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testSetTtl' => 'Testing expiration slows down the test suite', 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ); + ]; public function createSimpleCache($defaultLifetime = 0) { - if (!function_exists('apcu_fetch') || !ini_get('apc.enabled') || ('cli' === PHP_SAPI && !ini_get('apc.enable_cli'))) { + if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { $this->markTestSkipped('APCu extension is required.'); } - if ('\\' === DIRECTORY_SEPARATOR) { + if ('\\' === \DIRECTORY_SEPARATOR) { $this->markTestSkipped('Fails transiently on Windows.'); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php index 48b97282..ff9944a3 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php @@ -21,18 +21,18 @@ abstract class CacheTestCase extends SimpleCacheTest { parent::setUp(); - if (!array_key_exists('testPrune', $this->skippedTests) && !$this->createSimpleCache() instanceof PruneableInterface) { + if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createSimpleCache() instanceof PruneableInterface) { $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; } } public static function validKeys() { - if (defined('HHVM_VERSION')) { + if (\defined('HHVM_VERSION')) { return parent::validKeys(); } - return array_merge(parent::validKeys(), array(array("a\0b"))); + return array_merge(parent::validKeys(), [["a\0b"]]); } public function testDefaultLifeTime() @@ -42,6 +42,7 @@ abstract class CacheTestCase extends SimpleCacheTest } $cache = $this->createSimpleCache(2); + $cache->clear(); $cache->set('key.dlt', 'value'); sleep(1); @@ -50,6 +51,8 @@ abstract class CacheTestCase extends SimpleCacheTest sleep(2); $this->assertNull($cache->get('key.dlt')); + + $cache->clear(); } public function testNotUnserializable() @@ -59,16 +62,19 @@ abstract class CacheTestCase extends SimpleCacheTest } $cache = $this->createSimpleCache(); + $cache->clear(); $cache->set('foo', new NotUnserializable()); $this->assertNull($cache->get('foo')); - $cache->setMultiple(array('foo' => new NotUnserializable())); + $cache->setMultiple(['foo' => new NotUnserializable()]); - foreach ($cache->getMultiple(array('foo')) as $value) { + foreach ($cache->getMultiple(['foo']) as $value) { } $this->assertNull($value); + + $cache->clear(); } public function testPrune() @@ -83,6 +89,7 @@ abstract class CacheTestCase extends SimpleCacheTest /** @var PruneableInterface|CacheInterface $cache */ $cache = $this->createSimpleCache(); + $cache->clear(); $cache->set('foo', 'foo-val', new \DateInterval('PT05S')); $cache->set('bar', 'bar-val', new \DateInterval('PT10S')); @@ -124,6 +131,8 @@ abstract class CacheTestCase extends SimpleCacheTest $cache->prune(); $this->assertFalse($this->isPruned($cache, 'foo')); $this->assertTrue($this->isPruned($cache, 'qux')); + + $cache->clear(); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php index ab28e3bc..f216bc1f 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php @@ -11,6 +11,7 @@ namespace Symfony\Component\Cache\Tests\Simple; +use PHPUnit\Framework\MockObject\MockObject; use Psr\SimpleCache\CacheInterface; use Symfony\Component\Cache\PruneableInterface; use Symfony\Component\Cache\Simple\ArrayCache; @@ -24,25 +25,21 @@ class ChainCacheTest extends CacheTestCase { public function createSimpleCache($defaultLifetime = 0) { - return new ChainCache(array(new ArrayCache($defaultLifetime), new FilesystemCache('', $defaultLifetime)), $defaultLifetime); + return new ChainCache([new ArrayCache($defaultLifetime), new FilesystemCache('', $defaultLifetime)], $defaultLifetime); } - /** - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage At least one cache must be specified. - */ public function testEmptyCachesException() { - new ChainCache(array()); + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('At least one cache must be specified.'); + new ChainCache([]); } - /** - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage The class "stdClass" does not implement - */ public function testInvalidCacheException() { - new ChainCache(array(new \stdClass())); + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('The class "stdClass" does not implement'); + new ChainCache([new \stdClass()]); } public function testPrune() @@ -51,23 +48,23 @@ class ChainCacheTest extends CacheTestCase $this->markTestSkipped($this->skippedTests[__FUNCTION__]); } - $cache = new ChainCache(array( + $cache = new ChainCache([ $this->getPruneableMock(), $this->getNonPruneableMock(), $this->getPruneableMock(), - )); + ]); $this->assertTrue($cache->prune()); - $cache = new ChainCache(array( + $cache = new ChainCache([ $this->getPruneableMock(), $this->getFailingPruneableMock(), $this->getPruneableMock(), - )); + ]); $this->assertFalse($cache->prune()); } /** - * @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface + * @return MockObject|PruneableCacheInterface */ private function getPruneableMock() { @@ -78,13 +75,13 @@ class ChainCacheTest extends CacheTestCase $pruneable ->expects($this->atLeastOnce()) ->method('prune') - ->will($this->returnValue(true)); + ->willReturn(true); return $pruneable; } /** - * @return \PHPUnit_Framework_MockObject_MockObject|PruneableCacheInterface + * @return MockObject|PruneableCacheInterface */ private function getFailingPruneableMock() { @@ -95,13 +92,13 @@ class ChainCacheTest extends CacheTestCase $pruneable ->expects($this->atLeastOnce()) ->method('prune') - ->will($this->returnValue(false)); + ->willReturn(false); return $pruneable; } /** - * @return \PHPUnit_Framework_MockObject_MockObject|CacheInterface + * @return MockObject|CacheInterface */ private function getNonPruneableMock() { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php index 127c9685..af4331d6 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php @@ -19,10 +19,10 @@ use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; */ class DoctrineCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testObjectDoesNotChangeInCache' => 'ArrayCache does not use serialize/unserialize', 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', - ); + ]; public function createSimpleCache($defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php index c4af891a..6df682e9 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php @@ -16,15 +16,15 @@ use Symfony\Component\Cache\Simple\MemcachedCache; class MemcachedCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testSetTtl' => 'Testing expiration slows down the test suite', 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ); + ]; protected static $client; - public static function setupBeforeClass() + public static function setUpBeforeClass() { if (!MemcachedCache::isSupported()) { self::markTestSkipped('Extension memcached >=2.2.0 required.'); @@ -40,20 +40,29 @@ class MemcachedCacheTest extends CacheTestCase public function createSimpleCache($defaultLifetime = 0) { - $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), array('binary_protocol' => false)) : self::$client; + $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]) : self::$client; return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); } + public function testCreatePersistentConnectionShouldNotDupServerList() + { + $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); + $this->assertCount(1, $instance->getServerList()); + + $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); + $this->assertCount(1, $instance->getServerList()); + } + public function testOptions() { - $client = MemcachedCache::createConnection(array(), array( + $client = MemcachedCache::createConnection([], [ 'libketama_compatible' => false, 'distribution' => 'modula', 'compression' => true, 'serializer' => 'php', 'hash' => 'md5', - )); + ]); $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); @@ -64,46 +73,50 @@ class MemcachedCacheTest extends CacheTestCase /** * @dataProvider provideBadOptions - * @expectedException \ErrorException - * @expectedExceptionMessage constant(): Couldn't find constant Memcached:: */ public function testBadOptions($name, $value) { - MemcachedCache::createConnection(array(), array($name => $value)); + if (\PHP_VERSION_ID < 80000) { + $this->expectException('ErrorException'); + $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); + } else { + $this->expectException('Error'); + $this->expectExceptionMessage('Undefined constant Memcached::'); + } + + MemcachedCache::createConnection([], [$name => $value]); } public function provideBadOptions() { - return array( - array('foo', 'bar'), - array('hash', 'zyx'), - array('serializer', 'zyx'), - array('distribution', 'zyx'), - ); + return [ + ['foo', 'bar'], + ['hash', 'zyx'], + ['serializer', 'zyx'], + ['distribution', 'zyx'], + ]; } public function testDefaultOptions() { $this->assertTrue(MemcachedCache::isSupported()); - $client = MemcachedCache::createConnection(array()); + $client = MemcachedCache::createConnection([]); $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); } - /** - * @expectedException \Symfony\Component\Cache\Exception\CacheException - * @expectedExceptionMessage MemcachedAdapter: "serializer" option must be "php" or "igbinary". - */ public function testOptionSerializer() { + $this->expectException('Symfony\Component\Cache\Exception\CacheException'); + $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); if (!\Memcached::HAVE_JSON) { $this->markTestSkipped('Memcached::HAVE_JSON required'); } - new MemcachedCache(MemcachedCache::createConnection(array(), array('serializer' => 'json'))); + new MemcachedCache(MemcachedCache::createConnection([], ['serializer' => 'json'])); } /** @@ -112,54 +125,54 @@ class MemcachedCacheTest extends CacheTestCase public function testServersSetting($dsn, $host, $port) { $client1 = MemcachedCache::createConnection($dsn); - $client2 = MemcachedCache::createConnection(array($dsn)); - $client3 = MemcachedCache::createConnection(array(array($host, $port))); - $expect = array( + $client2 = MemcachedCache::createConnection([$dsn]); + $client3 = MemcachedCache::createConnection([[$host, $port]]); + $expect = [ 'host' => $host, 'port' => $port, - ); + ]; - $f = function ($s) { return array('host' => $s['host'], 'port' => $s['port']); }; - $this->assertSame(array($expect), array_map($f, $client1->getServerList())); - $this->assertSame(array($expect), array_map($f, $client2->getServerList())); - $this->assertSame(array($expect), array_map($f, $client3->getServerList())); + $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; + $this->assertSame([$expect], array_map($f, $client1->getServerList())); + $this->assertSame([$expect], array_map($f, $client2->getServerList())); + $this->assertSame([$expect], array_map($f, $client3->getServerList())); } public function provideServersSetting() { - yield array( + yield [ 'memcached://127.0.0.1/50', '127.0.0.1', 11211, - ); - yield array( + ]; + yield [ 'memcached://localhost:11222?weight=25', 'localhost', 11222, - ); - if (ini_get('memcached.use_sasl')) { - yield array( + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ 'memcached://user:password@127.0.0.1?weight=50', '127.0.0.1', 11211, - ); + ]; } - yield array( + yield [ 'memcached:///var/run/memcached.sock?weight=25', '/var/run/memcached.sock', 0, - ); - yield array( + ]; + yield [ 'memcached:///var/local/run/memcached.socket?weight=25', '/var/local/run/memcached.socket', 0, - ); - if (ini_get('memcached.use_sasl')) { - yield array( + ]; + if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { + yield [ 'memcached://user:password@/var/local/run/memcached.socket?weight=25', '/var/local/run/memcached.socket', 0, - ); + ]; } } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php new file mode 100644 index 00000000..13865a60 --- /dev/null +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +use Symfony\Component\Cache\Adapter\AbstractAdapter; +use Symfony\Component\Cache\Simple\MemcachedCache; + +class MemcachedCacheTextModeTest extends MemcachedCacheTest +{ + public function createSimpleCache($defaultLifetime = 0) + { + $client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); + + return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); + } +} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php index 7b760fd3..31f42c32 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php @@ -40,7 +40,7 @@ class NullCacheTest extends TestCase { $cache = $this->createCachePool(); - $keys = array('foo', 'bar', 'baz', 'biz'); + $keys = ['foo', 'bar', 'baz', 'biz']; $default = new \stdClass(); $items = $cache->getMultiple($keys, $default); @@ -75,7 +75,7 @@ class NullCacheTest extends TestCase public function testDeleteMultiple() { - $this->assertTrue($this->createCachePool()->deleteMultiple(array('key', 'foo', 'bar'))); + $this->assertTrue($this->createCachePool()->deleteMultiple(['key', 'foo', 'bar'])); } public function testSet() @@ -90,7 +90,7 @@ class NullCacheTest extends TestCase { $cache = $this->createCachePool(); - $this->assertFalse($cache->setMultiple(array('key' => 'val'))); + $this->assertFalse($cache->setMultiple(['key' => 'val'])); $this->assertNull($cache->get('key')); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php index cf573095..f5a26341 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php @@ -23,9 +23,9 @@ class PdoCacheTest extends CacheTestCase protected static $dbFile; - public static function setupBeforeClass() + public static function setUpBeforeClass() { - if (!extension_loaded('pdo_sqlite')) { + if (!\extension_loaded('pdo_sqlite')) { self::markTestSkipped('Extension pdo_sqlite required.'); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php index 0c40c04a..4da2b603 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php @@ -24,15 +24,15 @@ class PdoDbalCacheTest extends CacheTestCase protected static $dbFile; - public static function setupBeforeClass() + public static function setUpBeforeClass() { - if (!extension_loaded('pdo_sqlite')) { + if (!\extension_loaded('pdo_sqlite')) { self::markTestSkipped('Extension pdo_sqlite required.'); } self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - $pool = new PdoCache(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile))); + $pool = new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); $pool->createTable(); } @@ -43,6 +43,6 @@ class PdoDbalCacheTest extends CacheTestCase public function createSimpleCache($defaultLifetime = 0) { - return new PdoCache(DriverManager::getConnection(array('driver' => 'pdo_sqlite', 'path' => self::$dbFile)), '', $defaultLifetime); + return new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php index 1bd0ca27..bcd7dea5 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php @@ -11,16 +11,16 @@ namespace Symfony\Component\Cache\Tests\Simple; -use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; use Symfony\Component\Cache\Simple\NullCache; use Symfony\Component\Cache\Simple\PhpArrayCache; +use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; /** * @group time-sensitive */ class PhpArrayCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testBasicUsageWithLongKey' => 'PhpArrayCache does no writes', 'testDelete' => 'PhpArrayCache does no writes', @@ -45,17 +45,19 @@ class PhpArrayCacheTest extends CacheTestCase 'testDefaultLifeTime' => 'PhpArrayCache does not allow configuring a default lifetime.', 'testPrune' => 'PhpArrayCache just proxies', - ); + ]; protected static $file; - public static function setupBeforeClass() + public static function setUpBeforeClass() { self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; } protected function tearDown() { + $this->createSimpleCache()->clear(); + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); } @@ -68,22 +70,22 @@ class PhpArrayCacheTest extends CacheTestCase public function testStore() { - $arrayWithRefs = array(); + $arrayWithRefs = []; $arrayWithRefs[0] = 123; $arrayWithRefs[1] = &$arrayWithRefs[0]; - $object = (object) array( + $object = (object) [ 'foo' => 'bar', 'foo2' => 'bar2', - ); + ]; - $expected = array( + $expected = [ 'null' => null, 'serializedString' => serialize($object), 'arrayWithRefs' => $arrayWithRefs, 'object' => $object, - 'arrayWithObject' => array('bar' => $object), - ); + 'arrayWithObject' => ['bar' => $object], + ]; $cache = new PhpArrayCache(self::$file, new NullCache()); $cache->warmUp($expected); @@ -95,13 +97,13 @@ class PhpArrayCacheTest extends CacheTestCase public function testStoredFile() { - $expected = array( + $expected = [ 'integer' => 42, 'float' => 42.42, 'boolean' => true, - 'array_simple' => array('foo', 'bar'), - 'array_associative' => array('foo' => 'bar', 'foo2' => 'bar2'), - ); + 'array_simple' => ['foo', 'bar'], + 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], + ]; $cache = new PhpArrayCache(self::$file, new NullCache()); $cache->warmUp($expected); @@ -116,7 +118,7 @@ class PhpArrayCacheWrapper extends PhpArrayCache { public function set($key, $value, $ttl = null) { - call_user_func(\Closure::bind(function () use ($key, $value) { + \call_user_func(\Closure::bind(function () use ($key, $value) { $this->values[$key] = $value; $this->warmUp($this->values); $this->values = eval(substr(file_get_contents($this->file), 6)); @@ -127,10 +129,10 @@ class PhpArrayCacheWrapper extends PhpArrayCache public function setMultiple($values, $ttl = null) { - if (!is_array($values) && !$values instanceof \Traversable) { + if (!\is_array($values) && !$values instanceof \Traversable) { return parent::setMultiple($values, $ttl); } - call_user_func(\Closure::bind(function () use ($values) { + \call_user_func(\Closure::bind(function () use ($values) { foreach ($values as $key => $value) { $this->values[$key] = $value; } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php index 4b6a94f7..b08c1604 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php @@ -20,7 +20,7 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; */ class PhpArrayCacheWithFallbackTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testGetInvalidKeys' => 'PhpArrayCache does no validation', 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', @@ -32,17 +32,19 @@ class PhpArrayCacheWithFallbackTest extends CacheTestCase 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', 'testHasInvalidKeys' => 'PhpArrayCache does no validation', 'testPrune' => 'PhpArrayCache just proxies', - ); + ]; protected static $file; - public static function setupBeforeClass() + public static function setUpBeforeClass() { self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; } protected function tearDown() { + $this->createSimpleCache()->clear(); + if (file_exists(sys_get_temp_dir().'/symfony-cache')) { FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php index 7a402682..936f29a4 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php @@ -19,9 +19,9 @@ use Symfony\Component\Cache\Simple\PhpFilesCache; */ class PhpFilesCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testDefaultLifeTime' => 'PhpFilesCache does not allow configuring a default lifetime.', - ); + ]; public function createSimpleCache() { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php index 78582894..1bc75c90 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php @@ -19,9 +19,9 @@ use Symfony\Component\Cache\Simple\Psr6Cache; */ class Psr6CacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testPrune' => 'Psr6Cache just proxies', - ); + ]; public function createSimpleCache($defaultLifetime = 0) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php index 3c903c8a..ec5e4c06 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php @@ -13,12 +13,12 @@ namespace Symfony\Component\Cache\Tests\Simple; class RedisArrayCacheTest extends AbstractRedisCacheTest { - public static function setupBeforeClass() + public static function setUpBeforeClass() { parent::setupBeforeClass(); if (!class_exists('RedisArray')) { self::markTestSkipped('The RedisArray class is required.'); } - self::$redis = new \RedisArray(array(getenv('REDIS_HOST')), array('lazy_connect' => true)); + self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php index d33421f9..8e3f6088 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php @@ -15,7 +15,7 @@ use Symfony\Component\Cache\Simple\RedisCache; class RedisCacheTest extends AbstractRedisCacheTest { - public static function setupBeforeClass() + public static function setUpBeforeClass() { parent::setupBeforeClass(); self::$redis = RedisCache::createConnection('redis://'.getenv('REDIS_HOST')); @@ -33,50 +33,50 @@ class RedisCacheTest extends AbstractRedisCacheTest $redis = RedisCache::createConnection('redis://'.$redisHost.'/2'); $this->assertSame(2, $redis->getDbNum()); - $redis = RedisCache::createConnection('redis://'.$redisHost, array('timeout' => 3)); + $redis = RedisCache::createConnection('redis://'.$redisHost, ['timeout' => 3]); $this->assertEquals(3, $redis->getTimeout()); $redis = RedisCache::createConnection('redis://'.$redisHost.'?timeout=4'); $this->assertEquals(4, $redis->getTimeout()); - $redis = RedisCache::createConnection('redis://'.$redisHost, array('read_timeout' => 5)); + $redis = RedisCache::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); $this->assertEquals(5, $redis->getReadTimeout()); } /** * @dataProvider provideFailedCreateConnection - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Redis connection failed */ public function testFailedCreateConnection($dsn) { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Redis connection '); RedisCache::createConnection($dsn); } public function provideFailedCreateConnection() { - return array( - array('redis://localhost:1234'), - array('redis://foo@localhost'), - array('redis://localhost/123'), - ); + return [ + ['redis://localhost:1234'], + ['redis://foo@localhost'], + ['redis://localhost/123'], + ]; } /** * @dataProvider provideInvalidCreateConnection - * @expectedException \Symfony\Component\Cache\Exception\InvalidArgumentException - * @expectedExceptionMessage Invalid Redis DSN */ public function testInvalidCreateConnection($dsn) { + $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); + $this->expectExceptionMessage('Invalid Redis DSN'); RedisCache::createConnection($dsn); } public function provideInvalidCreateConnection() { - return array( - array('foo://localhost'), - array('redis://'), - ); + return [ + ['foo://localhost'], + ['redis://'], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php new file mode 100644 index 00000000..6b7f8039 --- /dev/null +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Cache\Tests\Simple; + +class RedisClusterCacheTest extends AbstractRedisCacheTest +{ + public static function setUpBeforeClass() + { + if (!class_exists('RedisCluster')) { + self::markTestSkipped('The RedisCluster class is required.'); + } + if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { + self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); + } + + self::$redis = new \RedisCluster(null, explode(' ', $hosts)); + } +} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php index 535f93da..e684caf3 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php @@ -19,9 +19,9 @@ use Symfony\Component\Cache\Simple\TraceableCache; */ class TraceableCacheTest extends CacheTestCase { - protected $skippedTests = array( + protected $skippedTests = [ 'testPrune' => 'TraceableCache just proxies', - ); + ]; public function createSimpleCache($defaultLifetime = 0) { @@ -37,7 +37,7 @@ class TraceableCacheTest extends CacheTestCase $call = $calls[0]; $this->assertSame('get', $call->name); - $this->assertSame(array('k' => false), $call->result); + $this->assertSame(['k' => false], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(1, $call->misses); $this->assertNotEmpty($call->start); @@ -61,7 +61,7 @@ class TraceableCacheTest extends CacheTestCase { $pool = $this->createSimpleCache(); $pool->set('k1', 123); - $values = $pool->getMultiple(array('k0', 'k1')); + $values = $pool->getMultiple(['k0', 'k1']); foreach ($values as $value) { } $calls = $pool->getCalls(); @@ -69,7 +69,7 @@ class TraceableCacheTest extends CacheTestCase $call = $calls[1]; $this->assertSame('getMultiple', $call->name); - $this->assertSame(array('k1' => true, 'k0' => false), $call->result); + $this->assertSame(['k1' => true, 'k0' => false], $call->result); $this->assertSame(1, $call->misses); $this->assertNotEmpty($call->start); $this->assertNotEmpty($call->end); @@ -84,7 +84,7 @@ class TraceableCacheTest extends CacheTestCase $call = $calls[0]; $this->assertSame('has', $call->name); - $this->assertSame(array('k' => false), $call->result); + $this->assertSame(['k' => false], $call->result); $this->assertNotEmpty($call->start); $this->assertNotEmpty($call->end); } @@ -99,7 +99,7 @@ class TraceableCacheTest extends CacheTestCase $call = $calls[1]; $this->assertSame('has', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertNotEmpty($call->start); $this->assertNotEmpty($call->end); } @@ -113,7 +113,7 @@ class TraceableCacheTest extends CacheTestCase $call = $calls[0]; $this->assertSame('delete', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); @@ -123,14 +123,14 @@ class TraceableCacheTest extends CacheTestCase public function testDeleteMultipleTrace() { $pool = $this->createSimpleCache(); - $arg = array('k0', 'k1'); + $arg = ['k0', 'k1']; $pool->deleteMultiple($arg); $calls = $pool->getCalls(); $this->assertCount(1, $calls); $call = $calls[0]; $this->assertSame('deleteMultiple', $call->name); - $this->assertSame(array('keys' => $arg, 'result' => true), $call->result); + $this->assertSame(['keys' => $arg, 'result' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); @@ -146,7 +146,7 @@ class TraceableCacheTest extends CacheTestCase $call = $calls[0]; $this->assertSame('set', $call->name); - $this->assertSame(array('k' => true), $call->result); + $this->assertSame(['k' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); @@ -156,13 +156,13 @@ class TraceableCacheTest extends CacheTestCase public function testSetMultipleTrace() { $pool = $this->createSimpleCache(); - $pool->setMultiple(array('k' => 'foo')); + $pool->setMultiple(['k' => 'foo']); $calls = $pool->getCalls(); $this->assertCount(1, $calls); $call = $calls[0]; $this->assertSame('setMultiple', $call->name); - $this->assertSame(array('keys' => array('k'), 'result' => true), $call->result); + $this->assertSame(['keys' => ['k'], 'result' => true], $call->result); $this->assertSame(0, $call->hits); $this->assertSame(0, $call->misses); $this->assertNotEmpty($call->start); diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php index a9c459fb..c405de70 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php @@ -24,11 +24,11 @@ trait PdoPruneableTrait $getPdoConn = $o->getMethod('getConnection'); $getPdoConn->setAccessible(true); - /** @var \Doctrine\DBAL\Statement $select */ + /** @var \Doctrine\DBAL\Statement|\PDOStatement $select */ $select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id'); $select->bindValue(':id', sprintf('%%%s', $name)); - $select->execute(); + $result = $select->execute(); - return 0 === count($select->fetchAll(\PDO::FETCH_COLUMN)); + return 1 !== (int) (\is_object($result) ? $result->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN)); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/AbstractTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/AbstractTrait.php index d7af3b55..dc291e10 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/AbstractTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/AbstractTrait.php @@ -26,7 +26,7 @@ trait AbstractTrait private $namespace; private $namespaceVersion = ''; private $versioningIsEnabled = false; - private $deferred = array(); + private $deferred = []; /** * @var int|null The maximum length to enforce for identifiers or null when no limit applies @@ -54,7 +54,7 @@ trait AbstractTrait /** * Deletes all items in the pool. * - * @param string The prefix used for all identifiers managed by this pool + * @param string $namespace The prefix used for all identifiers managed by this pool * * @return bool True if the pool was successfully cleared, false otherwise */ @@ -93,7 +93,7 @@ trait AbstractTrait try { return $this->doHave($id); } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', array('key' => $key, 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to check if key "{key}" is cached', ['key' => $key, 'exception' => $e]); return false; } @@ -104,20 +104,23 @@ trait AbstractTrait */ public function clear() { + $this->deferred = []; if ($cleared = $this->versioningIsEnabled) { - $this->namespaceVersion = 2; - foreach ($this->doFetch(array('@'.$this->namespace)) as $v) { - $this->namespaceVersion = 1 + (int) $v; + $namespaceVersion = substr_replace(base64_encode(pack('V', mt_rand())), static::NS_SEPARATOR, 5); + try { + $cleared = $this->doSave([static::NS_SEPARATOR.$this->namespace => $namespaceVersion], 0); + } catch (\Exception $e) { + $cleared = false; + } + if ($cleared = true === $cleared || [] === $cleared) { + $this->namespaceVersion = $namespaceVersion; } - $this->namespaceVersion .= ':'; - $cleared = $this->doSave(array('@'.$this->namespace => $this->namespaceVersion), 0); } - $this->deferred = array(); try { return $this->doClear($this->namespace) || $cleared; } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to clear the cache', array('exception' => $e)); + CacheItem::log($this->logger, 'Failed to clear the cache', ['exception' => $e]); return false; } @@ -128,7 +131,7 @@ trait AbstractTrait */ public function deleteItem($key) { - return $this->deleteItems(array($key)); + return $this->deleteItems([$key]); } /** @@ -136,7 +139,7 @@ trait AbstractTrait */ public function deleteItems(array $keys) { - $ids = array(); + $ids = []; foreach ($keys as $key) { $ids[$key] = $this->getId($key); @@ -156,12 +159,12 @@ trait AbstractTrait foreach ($ids as $key => $id) { try { $e = null; - if ($this->doDelete(array($id))) { + if ($this->doDelete([$id])) { continue; } } catch (\Exception $e) { } - CacheItem::log($this->logger, 'Failed to delete key "{key}"', array('key' => $key, 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to delete key "{key}"', ['key' => $key, 'exception' => $e]); $ok = false; } @@ -219,9 +222,9 @@ trait AbstractTrait if (false !== $value = unserialize($value)) { return $value; } - throw new \DomainException('Failed to unserialize cached value'); + throw new \DomainException('Failed to unserialize cached value.'); } catch (\Error $e) { - throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); } finally { ini_set('unserialize_callback_func', $unserializeCallbackHandler); } @@ -232,17 +235,24 @@ trait AbstractTrait CacheItem::validateKey($key); if ($this->versioningIsEnabled && '' === $this->namespaceVersion) { - $this->namespaceVersion = '1:'; - foreach ($this->doFetch(array('@'.$this->namespace)) as $v) { - $this->namespaceVersion = $v; + $this->namespaceVersion = '1'.static::NS_SEPARATOR; + try { + foreach ($this->doFetch([static::NS_SEPARATOR.$this->namespace]) as $v) { + $this->namespaceVersion = $v; + } + if ('1'.static::NS_SEPARATOR === $this->namespaceVersion) { + $this->namespaceVersion = substr_replace(base64_encode(pack('V', time())), static::NS_SEPARATOR, 5); + $this->doSave([static::NS_SEPARATOR.$this->namespace => $this->namespaceVersion], 0); + } + } catch (\Exception $e) { } } if (null === $this->maxIdLength) { return $this->namespace.$this->namespaceVersion.$key; } - if (strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { - $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), ':', -22); + if (\strlen($id = $this->namespace.$this->namespaceVersion.$key) > $this->maxIdLength) { + $id = $this->namespace.$this->namespaceVersion.substr_replace(base64_encode(hash('sha256', $key, true)), static::NS_SEPARATOR, -(\strlen($this->namespaceVersion) + 22)); } return $id; diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/ApcuTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/ApcuTrait.php index fe7dfbab..2f47f8e6 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/ApcuTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/ApcuTrait.php @@ -23,15 +23,15 @@ trait ApcuTrait { public static function isSupported() { - return function_exists('apcu_fetch') && ini_get('apc.enabled'); + return \function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN); } private function init($namespace, $defaultLifetime, $version) { if (!static::isSupported()) { - throw new CacheException('APCu is not enabled'); + throw new CacheException('APCu is not enabled.'); } - if ('cli' === PHP_SAPI) { + if ('cli' === \PHP_SAPI) { ini_set('apc.use_request_time', 0); } parent::__construct($namespace, $defaultLifetime); @@ -52,13 +52,13 @@ trait ApcuTrait protected function doFetch(array $ids) { try { - foreach (apcu_fetch($ids, $ok) ?: array() as $k => $v) { + foreach (apcu_fetch($ids, $ok) ?: [] as $k => $v) { if (null !== $v || $ok) { yield $k => $v; } } } catch (\Error $e) { - throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); } } @@ -75,8 +75,8 @@ trait ApcuTrait */ protected function doClear($namespace) { - return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== PHP_SAPI || ini_get('apc.enable_cli')) - ? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), APC_ITER_KEY)) + return isset($namespace[0]) && class_exists('APCuIterator', false) && ('cli' !== \PHP_SAPI || filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) + ? apcu_delete(new \APCuIterator(sprintf('/^%s/', preg_quote($namespace, '/')), \APC_ITER_KEY)) : apcu_clear_cache(); } @@ -107,7 +107,7 @@ trait ApcuTrait } catch (\Exception $e) { } - if (1 === count($values)) { + if (1 === \count($values)) { // Workaround https://github.com/krakjoe/apcu/issues/170 apcu_delete(key($values)); } diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/ArrayTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/ArrayTrait.php index b7d2ad6d..0a60968e 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/ArrayTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/ArrayTrait.php @@ -24,8 +24,8 @@ trait ArrayTrait use LoggerAwareTrait; private $storeSerialized; - private $values = array(); - private $expiries = array(); + private $values = []; + private $expiries = []; /** * Returns all cached values, with cache miss as null. @@ -44,7 +44,7 @@ trait ArrayTrait { CacheItem::validateKey($key); - return isset($this->expiries[$key]) && ($this->expiries[$key] >= time() || !$this->deleteItem($key)); + return isset($this->expiries[$key]) && ($this->expiries[$key] > time() || !$this->deleteItem($key)); } /** @@ -52,7 +52,7 @@ trait ArrayTrait */ public function clear() { - $this->values = $this->expiries = array(); + $this->values = $this->expiries = []; return true; } @@ -81,7 +81,7 @@ trait ArrayTrait { foreach ($keys as $i => $key) { try { - if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] >= $now || !$this->deleteItem($key))) { + if (!$isHit = isset($this->expiries[$key]) && ($this->expiries[$key] > $now || !$this->deleteItem($key))) { $this->values[$key] = $value = null; } elseif (!$this->storeSerialized) { $value = $this->values[$key]; @@ -92,7 +92,7 @@ trait ArrayTrait $isHit = false; } } catch (\Exception $e) { - CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', array('key' => $key, 'exception' => $e)); + CacheItem::log($this->logger, 'Failed to unserialize key "{key}"', ['key' => $key, 'exception' => $e]); $this->values[$key] = $value = null; $isHit = false; } diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/DoctrineTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/DoctrineTrait.php index c87ecaba..48623e67 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/DoctrineTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/DoctrineTrait.php @@ -45,7 +45,7 @@ trait DoctrineTrait case 'unserialize': case 'apcu_fetch': case 'apc_fetch': - throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemCommonTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemCommonTrait.php index b0f495e4..8071a382 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemCommonTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemCommonTrait.php @@ -34,15 +34,15 @@ trait FilesystemCommonTrait if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); } - $directory .= DIRECTORY_SEPARATOR.$namespace; + $directory .= \DIRECTORY_SEPARATOR.$namespace; } if (!file_exists($directory)) { @mkdir($directory, 0777, true); } - $directory .= DIRECTORY_SEPARATOR; + $directory .= \DIRECTORY_SEPARATOR; // On Windows the whole path is limited to 258 chars - if ('\\' === DIRECTORY_SEPARATOR && strlen($directory) > 234) { - throw new InvalidArgumentException(sprintf('Cache directory too long (%s)', $directory)); + if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) { + throw new InvalidArgumentException(sprintf('Cache directory too long (%s).', $directory)); } $this->directory = $directory; @@ -99,7 +99,7 @@ trait FilesystemCommonTrait private function getFile($id, $mkdir = false) { $hash = str_replace('/', '-', base64_encode(hash('sha256', static::class.$id, true))); - $dir = $this->directory.strtoupper($hash[0].DIRECTORY_SEPARATOR.$hash[1].DIRECTORY_SEPARATOR); + $dir = $this->directory.strtoupper($hash[0].\DIRECTORY_SEPARATOR.$hash[1].\DIRECTORY_SEPARATOR); if ($mkdir && !file_exists($dir)) { @mkdir($dir, 0777, true); @@ -116,6 +116,16 @@ trait FilesystemCommonTrait throw new \ErrorException($message, 0, $type, $file, $line); } + public function __sleep() + { + throw new \BadMethodCallException('Cannot serialize '.__CLASS__); + } + + public function __wakeup() + { + throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); + } + public function __destruct() { if (method_exists(parent::class, '__destruct')) { diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemTrait.php index 23974b3b..9d7f5578 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/FilesystemTrait.php @@ -52,7 +52,7 @@ trait FilesystemTrait */ protected function doFetch(array $ids) { - $values = array(); + $values = []; $now = time(); foreach ($ids as $id) { @@ -83,7 +83,7 @@ trait FilesystemTrait { $file = $this->getFile($id); - return file_exists($file) && (@filemtime($file) > time() || $this->doFetch(array($id))); + return file_exists($file) && (@filemtime($file) > time() || $this->doFetch([$id])); } /** @@ -99,7 +99,7 @@ trait FilesystemTrait } if (!$ok && !is_writable($this->directory)) { - throw new CacheException(sprintf('Cache directory is not writable (%s)', $this->directory)); + throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); } return $ok; diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/MemcachedTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/MemcachedTrait.php index 9b877efb..34d0208e 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/MemcachedTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/MemcachedTrait.php @@ -22,32 +22,32 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException; */ trait MemcachedTrait { - private static $defaultClientOptions = array( + private static $defaultClientOptions = [ 'persistent_id' => null, 'username' => null, 'password' => null, - 'serializer' => 'php', - ); + \Memcached::OPT_SERIALIZER => \Memcached::SERIALIZER_PHP, + ]; private $client; private $lazyClient; public static function isSupported() { - return extension_loaded('memcached') && version_compare(phpversion('memcached'), '2.2.0', '>='); + return \extension_loaded('memcached') && version_compare(phpversion('memcached'), '2.2.0', '>='); } private function init(\Memcached $client, $namespace, $defaultLifetime) { if (!static::isSupported()) { - throw new CacheException('Memcached >= 2.2.0 is required'); + throw new CacheException('Memcached >= 2.2.0 is required.'); } - if ('Memcached' === get_class($client)) { + if ('Memcached' === \get_class($client)) { $opt = $client->getOption(\Memcached::OPT_SERIALIZER); if (\Memcached::SERIALIZER_PHP !== $opt && \Memcached::SERIALIZER_IGBINARY !== $opt) { throw new CacheException('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); } - $this->maxIdLength -= strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); + $this->maxIdLength -= \strlen($client->getOption(\Memcached::OPT_PREFIX_KEY)); $this->client = $client; } else { $this->lazyClient = $client; @@ -64,24 +64,24 @@ trait MemcachedTrait * * Examples for servers: * - 'memcached://user:pass@localhost?weight=33' - * - array(array('localhost', 11211, 33)) + * - [['localhost', 11211, 33]] * - * @param array[]|string|string[] An array of servers, a DSN, or an array of DSNs - * @param array An array of options + * @param array[]|string|string[] $servers An array of servers, a DSN, or an array of DSNs + * @param array $options An array of options * * @return \Memcached * * @throws \ErrorException When invalid options or servers are provided */ - public static function createConnection($servers, array $options = array()) + public static function createConnection($servers, array $options = []) { - if (is_string($servers)) { - $servers = array($servers); - } elseif (!is_array($servers)) { - throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, %s given.', gettype($servers))); + if (\is_string($servers)) { + $servers = [$servers]; + } elseif (!\is_array($servers)) { + throw new InvalidArgumentException(sprintf('MemcachedAdapter::createClient() expects array or string as first argument, "%s" given.', \gettype($servers))); } if (!static::isSupported()) { - throw new CacheException('Memcached >= 2.2.0 is required'); + throw new CacheException('Memcached >= 2.2.0 is required.'); } set_error_handler(function ($type, $msg, $file, $line) { throw new \ErrorException($msg, 0, $type, $file, $line); }); try { @@ -92,59 +92,60 @@ trait MemcachedTrait // parse any DSN in $servers foreach ($servers as $i => $dsn) { - if (is_array($dsn)) { + if (\is_array($dsn)) { continue; } if (0 !== strpos($dsn, 'memcached://')) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s does not start with "memcached://"', $dsn)); + throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s" does not start with "memcached://".', $dsn)); } $params = preg_replace_callback('#^memcached://(?:([^@]*+)@)?#', function ($m) use (&$username, &$password) { if (!empty($m[1])) { - list($username, $password) = explode(':', $m[1], 2) + array(1 => null); + list($username, $password) = explode(':', $m[1], 2) + [1 => null]; } return 'file://'; }, $dsn); if (false === $params = parse_url($params)) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $dsn)); + throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); } if (!isset($params['host']) && !isset($params['path'])) { - throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: %s', $dsn)); + throw new InvalidArgumentException(sprintf('Invalid Memcached DSN: "%s".', $dsn)); } if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) { $params['weight'] = $m[1]; - $params['path'] = substr($params['path'], 0, -strlen($m[0])); + $params['path'] = substr($params['path'], 0, -\strlen($m[0])); } - $params += array( + $params += [ 'host' => isset($params['host']) ? $params['host'] : $params['path'], 'port' => isset($params['host']) ? 11211 : null, 'weight' => 0, - ); + ]; if (isset($params['query'])) { parse_str($params['query'], $query); $params += $query; $options = $query + $options; } - $servers[$i] = array($params['host'], $params['port'], $params['weight']); + $servers[$i] = [$params['host'], $params['port'], $params['weight']]; } // set client's options unset($options['persistent_id'], $options['username'], $options['password'], $options['weight'], $options['lazy']); - $options = array_change_key_case($options, CASE_UPPER); + $options = array_change_key_case($options, \CASE_UPPER); $client->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); $client->setOption(\Memcached::OPT_NO_BLOCK, true); - if (!array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) { + $client->setOption(\Memcached::OPT_TCP_NODELAY, true); + if (!\array_key_exists('LIBKETAMA_COMPATIBLE', $options) && !\array_key_exists(\Memcached::OPT_LIBKETAMA_COMPATIBLE, $options)) { $client->setOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE, true); } foreach ($options as $name => $value) { - if (is_int($name)) { + if (\is_int($name)) { continue; } if ('HASH' === $name || 'SERIALIZER' === $name || 'DISTRIBUTION' === $name) { - $value = constant('Memcached::'.$name.'_'.strtoupper($value)); + $value = \constant('Memcached::'.$name.'_'.strtoupper($value)); } - $opt = constant('Memcached::OPT_'.$name); + $opt = \constant('Memcached::OPT_'.$name); unset($options[$name]); $options[$opt] = $value; @@ -153,14 +154,14 @@ trait MemcachedTrait // set client's servers, taking care of persistent connections if (!$client->isPristine()) { - $oldServers = array(); + $oldServers = []; foreach ($client->getServerList() as $server) { - $oldServers[] = array($server['host'], $server['port']); + $oldServers[] = [$server['host'], $server['port']]; } - $newServers = array(); + $newServers = []; foreach ($servers as $server) { - if (1 < count($server)) { + if (1 < \count($server)) { $server = array_values($server); unset($server[2]); $server[1] = (int) $server[1]; @@ -169,12 +170,12 @@ trait MemcachedTrait } if ($oldServers !== $newServers) { - // before resetting, ensure $servers is valid - $client->addServers($servers); $client->resetServerList(); + $client->addServers($servers); } + } else { + $client->addServers($servers); } - $client->addServers($servers); if (null !== $username || null !== $password) { if (!method_exists($client, 'setSaslAuthData')) { @@ -198,7 +199,12 @@ trait MemcachedTrait $lifetime += time(); } - return $this->checkResultCode($this->getClient()->setMulti($values, $lifetime)); + $encodedValues = []; + foreach ($values as $key => $value) { + $encodedValues[rawurlencode($key)] = $value; + } + + return $this->checkResultCode($this->getClient()->setMulti($encodedValues, $lifetime)); } /** @@ -208,9 +214,18 @@ trait MemcachedTrait { $unserializeCallbackHandler = ini_set('unserialize_callback_func', __CLASS__.'::handleUnserializeCallback'); try { - return $this->checkResultCode($this->getClient()->getMulti($ids)); + $encodedIds = array_map('rawurlencode', $ids); + + $encodedResult = $this->checkResultCode($this->getClient()->getMulti($encodedIds)); + + $result = []; + foreach ($encodedResult as $key => $value) { + $result[rawurldecode($key)] = $value; + } + + return $result; } catch (\Error $e) { - throw new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()); + throw new \ErrorException($e->getMessage(), $e->getCode(), \E_ERROR, $e->getFile(), $e->getLine()); } finally { ini_set('unserialize_callback_func', $unserializeCallbackHandler); } @@ -221,7 +236,7 @@ trait MemcachedTrait */ protected function doHave($id) { - return false !== $this->getClient()->get($id) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode()); + return false !== $this->getClient()->get(rawurlencode($id)) || $this->checkResultCode(\Memcached::RES_SUCCESS === $this->client->getResultCode()); } /** @@ -230,9 +245,11 @@ trait MemcachedTrait protected function doDelete(array $ids) { $ok = true; - foreach ($this->checkResultCode($this->getClient()->deleteMulti($ids)) as $result) { + $encodedIds = array_map('rawurlencode', $ids); + foreach ($this->checkResultCode($this->getClient()->deleteMulti($encodedIds)) as $result) { if (\Memcached::RES_SUCCESS !== $result && \Memcached::RES_NOTFOUND !== $result) { $ok = false; + break; } } @@ -244,7 +261,7 @@ trait MemcachedTrait */ protected function doClear($namespace) { - return false; + return '' === $namespace && $this->getClient()->flush(); } private function checkResultCode($result) @@ -255,7 +272,7 @@ trait MemcachedTrait return $result; } - throw new CacheException(sprintf('MemcachedAdapter client error: %s.', strtolower($this->client->getResultMessage()))); + throw new CacheException('MemcachedAdapter client error: '.strtolower($this->client->getResultMessage())); } /** diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/PdoTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/PdoTrait.php index a88099ec..917e8dd1 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/PdoTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/PdoTrait.php @@ -12,8 +12,8 @@ namespace Symfony\Component\Cache\Traits; use Doctrine\DBAL\Connection; -use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\DBALException; +use Doctrine\DBAL\Driver\ServerInfoAwareConnection; use Doctrine\DBAL\Schema\Schema; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -33,7 +33,7 @@ trait PdoTrait private $timeCol = 'item_time'; private $username = ''; private $password = ''; - private $connectionOptions = array(); + private $connectionOptions = []; private $namespace; private function init($connOrDsn, $namespace, $defaultLifetime, array $options) @@ -44,16 +44,16 @@ trait PdoTrait if ($connOrDsn instanceof \PDO) { if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) { - throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__)); + throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__)); } $this->conn = $connOrDsn; } elseif ($connOrDsn instanceof Connection) { $this->conn = $connOrDsn; - } elseif (is_string($connOrDsn)) { + } elseif (\is_string($connOrDsn)) { $this->dsn = $connOrDsn; } else { - throw new InvalidArgumentException(sprintf('"%s" requires PDO or Doctrine\DBAL\Connection instance or DSN string as first argument, "%s" given.', __CLASS__, is_object($connOrDsn) ? get_class($connOrDsn) : gettype($connOrDsn))); + throw new InvalidArgumentException(sprintf('"%s" requires PDO or Doctrine\DBAL\Connection instance or DSN string as first argument, "%s" given.', __CLASS__, \is_object($connOrDsn) ? \get_class($connOrDsn) : \gettype($connOrDsn))); } $this->table = isset($options['db_table']) ? $options['db_table'] : $this->table; @@ -85,27 +85,31 @@ trait PdoTrait $conn = $this->getConnection(); if ($conn instanceof Connection) { - $types = array( + $types = [ 'mysql' => 'binary', 'sqlite' => 'text', 'pgsql' => 'string', 'oci' => 'string', 'sqlsrv' => 'string', - ); + ]; if (!isset($types[$this->driver])) { throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver)); } $schema = new Schema(); $table = $schema->createTable($this->table); - $table->addColumn($this->idCol, $types[$this->driver], array('length' => 255)); - $table->addColumn($this->dataCol, 'blob', array('length' => 16777215)); - $table->addColumn($this->lifetimeCol, 'integer', array('unsigned' => true, 'notnull' => false)); - $table->addColumn($this->timeCol, 'integer', array('unsigned' => true)); - $table->setPrimaryKey(array($this->idCol)); + $table->addColumn($this->idCol, $types[$this->driver], ['length' => 255]); + $table->addColumn($this->dataCol, 'blob', ['length' => 16777215]); + $table->addColumn($this->lifetimeCol, 'integer', ['unsigned' => true, 'notnull' => false]); + $table->addColumn($this->timeCol, 'integer', ['unsigned' => true]); + $table->setPrimaryKey([$this->idCol]); foreach ($schema->toSql($conn->getDatabasePlatform()) as $sql) { - $conn->exec($sql); + if (method_exists($conn, 'executeStatement')) { + $conn->executeStatement($sql); + } else { + $conn->exec($sql); + } } return; @@ -136,7 +140,11 @@ trait PdoTrait throw new \DomainException(sprintf('Creating the cache table is currently not implemented for PDO driver "%s".', $this->driver)); } - $conn->exec($sql); + if (method_exists($conn, 'executeStatement')) { + $conn->executeStatement($sql); + } else { + $conn->exec($sql); + } } /** @@ -166,27 +174,34 @@ trait PdoTrait protected function doFetch(array $ids) { $now = time(); - $expired = array(); + $expired = []; - $sql = str_pad('', (count($ids) << 1) - 1, '?,'); + $sql = str_pad('', (\count($ids) << 1) - 1, '?,'); $sql = "SELECT $this->idCol, CASE WHEN $this->lifetimeCol IS NULL OR $this->lifetimeCol + $this->timeCol > ? THEN $this->dataCol ELSE NULL END FROM $this->table WHERE $this->idCol IN ($sql)"; $stmt = $this->getConnection()->prepare($sql); $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT); foreach ($ids as $id) { $stmt->bindValue(++$i, $id); } - $stmt->execute(); + $result = $stmt->execute(); - while ($row = $stmt->fetch(\PDO::FETCH_NUM)) { + if (\is_object($result)) { + $result = $result->iterateNumeric(); + } else { + $stmt->setFetchMode(\PDO::FETCH_NUM); + $result = $stmt; + } + + foreach ($result as $row) { if (null === $row[1]) { $expired[] = $row[0]; } else { - yield $row[0] => parent::unserialize(is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]); + yield $row[0] => parent::unserialize(\is_resource($row[1]) ? stream_get_contents($row[1]) : $row[1]); } } if ($expired) { - $sql = str_pad('', (count($expired) << 1) - 1, '?,'); + $sql = str_pad('', (\count($expired) << 1) - 1, '?,'); $sql = "DELETE FROM $this->table WHERE $this->lifetimeCol + $this->timeCol <= ? AND $this->idCol IN ($sql)"; $stmt = $this->getConnection()->prepare($sql); $stmt->bindValue($i = 1, $now, \PDO::PARAM_INT); @@ -207,9 +222,9 @@ trait PdoTrait $stmt->bindValue(':id', $id); $stmt->bindValue(':time', time(), \PDO::PARAM_INT); - $stmt->execute(); + $result = $stmt->execute(); - return (bool) $stmt->fetchColumn(); + return (bool) (\is_object($result) ? $result->fetchOne() : $stmt->fetchColumn()); } /** @@ -229,7 +244,11 @@ trait PdoTrait $sql = "DELETE FROM $this->table WHERE $this->idCol LIKE '$namespace%'"; } - $conn->exec($sql); + if (method_exists($conn, 'executeStatement')) { + $conn->executeStatement($sql); + } else { + $conn->exec($sql); + } return true; } @@ -239,7 +258,7 @@ trait PdoTrait */ protected function doDelete(array $ids) { - $sql = str_pad('', (count($ids) << 1) - 1, '?,'); + $sql = str_pad('', (\count($ids) << 1) - 1, '?,'); $sql = "DELETE FROM $this->table WHERE $this->idCol IN ($sql)"; $stmt = $this->getConnection()->prepare($sql); $stmt->execute(array_values($ids)); @@ -252,8 +271,8 @@ trait PdoTrait */ protected function doSave(array $values, $lifetime) { - $serialized = array(); - $failed = array(); + $serialized = []; + $failed = []; foreach ($values as $id => $value) { try { @@ -329,9 +348,9 @@ trait PdoTrait } foreach ($serialized as $id => $data) { - $stmt->execute(); + $result = $stmt->execute(); - if (null === $driver && !$stmt->rowCount()) { + if (null === $driver && !(\is_object($result) ? $result->rowCount() : $stmt->rowCount())) { try { $insertStmt->execute(); } catch (DBALException $e) { @@ -357,25 +376,37 @@ trait PdoTrait if ($this->conn instanceof \PDO) { $this->driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME); } else { - switch ($this->driver = $this->conn->getDriver()->getName()) { - case 'mysqli': - case 'pdo_mysql': - case 'drizzle_pdo_mysql': + $driver = $this->conn->getDriver(); + + switch (true) { + case $driver instanceof \Doctrine\DBAL\Driver\AbstractMySQLDriver: + case $driver instanceof \Doctrine\DBAL\Driver\DrizzlePDOMySql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\Mysqli\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOMySql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\MySQL\Driver: $this->driver = 'mysql'; break; - case 'pdo_sqlite': + case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLite\Driver: $this->driver = 'sqlite'; break; - case 'pdo_pgsql': + case $driver instanceof \Doctrine\DBAL\Driver\PDOPgSql\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\PgSQL\Driver: $this->driver = 'pgsql'; break; - case 'oci8': - case 'pdo_oracle': + case $driver instanceof \Doctrine\DBAL\Driver\OCI8\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOOracle\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\OCI\Driver: $this->driver = 'oci'; break; - case 'pdo_sqlsrv': + case $driver instanceof \Doctrine\DBAL\Driver\SQLSrv\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDOSqlsrv\Driver: + case $driver instanceof \Doctrine\DBAL\Driver\PDO\SQLSrv\Driver: $this->driver = 'sqlsrv'; break; + default: + $this->driver = \get_class($driver); + break; } } } diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/PhpArrayTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/PhpArrayTrait.php index ae634d6b..972c7512 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/PhpArrayTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/PhpArrayTrait.php @@ -28,6 +28,8 @@ trait PhpArrayTrait private $values; private $zendDetectUnicode; + private static $valuesCache = []; + /** * Store an array of cached values. * @@ -37,21 +39,21 @@ trait PhpArrayTrait { if (file_exists($this->file)) { if (!is_file($this->file)) { - throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: %s.', $this->file)); + throw new InvalidArgumentException(sprintf('Cache path exists and is not a file: "%s".', $this->file)); } if (!is_writable($this->file)) { - throw new InvalidArgumentException(sprintf('Cache file is not writable: %s.', $this->file)); + throw new InvalidArgumentException(sprintf('Cache file is not writable: "%s".', $this->file)); } } else { - $directory = dirname($this->file); + $directory = \dirname($this->file); if (!is_dir($directory) && !@mkdir($directory, 0777, true)) { - throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: %s.', $directory)); + throw new InvalidArgumentException(sprintf('Cache directory does not exist and cannot be created: "%s".', $directory)); } if (!is_writable($directory)) { - throw new InvalidArgumentException(sprintf('Cache directory is not writable: %s.', $directory)); + throw new InvalidArgumentException(sprintf('Cache directory is not writable: "%s".', $directory)); } } @@ -60,21 +62,21 @@ trait PhpArrayTrait // This file has been auto-generated by the Symfony Cache Component. -return array( +return [ EOF; foreach ($values as $key => $value) { - CacheItem::validateKey(is_int($key) ? (string) $key : $key); + CacheItem::validateKey(\is_int($key) ? (string) $key : $key); - if (null === $value || is_object($value)) { + if (null === $value || \is_object($value)) { try { $value = serialize($value); } catch (\Exception $e) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, get_class($value)), 0, $e); + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, \get_class($value)), 0, $e); } - } elseif (is_array($value)) { + } elseif (\is_array($value)) { try { $serialized = serialize($value); $unserialized = unserialize($serialized); @@ -85,19 +87,19 @@ EOF; if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) { $value = $serialized; } - } elseif (is_string($value)) { + } elseif (\is_string($value)) { // Serialize strings if they could be confused with serialized objects or arrays if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { $value = serialize($value); } } elseif (!is_scalar($value)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value))); + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, \gettype($value))); } $dump .= var_export($key, true).' => '.var_export($value, true).",\n"; } - $dump .= "\n);\n"; + $dump .= "\n];\n"; $dump = str_replace("' . \"\\0\" . '", "\0", $dump); $tmpFile = uniqid($this->file, true); @@ -107,6 +109,7 @@ EOF; unset($serialized, $unserialized, $value, $dump); @rename($tmpFile, $this->file); + unset(self::$valuesCache[$this->file]); $this->initialize(); } @@ -116,9 +119,10 @@ EOF; */ public function clear() { - $this->values = array(); + $this->values = []; $cleared = @unlink($this->file) || !file_exists($this->file); + unset(self::$valuesCache[$this->file]); return $this->pool->clear() && $cleared; } @@ -128,11 +132,17 @@ EOF; */ private function initialize() { + if (isset(self::$valuesCache[$this->file])) { + $this->values = self::$valuesCache[$this->file]; + + return; + } + if ($this->zendDetectUnicode) { $zmb = ini_set('zend.detect_unicode', 0); } try { - $this->values = file_exists($this->file) ? (include $this->file ?: array()) : array(); + $this->values = self::$valuesCache[$this->file] = file_exists($this->file) ? (include $this->file ?: []) : []; } finally { if ($this->zendDetectUnicode) { ini_set('zend.detect_unicode', $zmb); diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/PhpFilesTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/PhpFilesTrait.php index c800e1a1..2668b26c 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/PhpFilesTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/PhpFilesTrait.php @@ -30,7 +30,7 @@ trait PhpFilesTrait public static function isSupported() { - return function_exists('opcache_invalidate') && ini_get('opcache.enable'); + return \function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), \FILTER_VALIDATE_BOOLEAN); } /** @@ -40,7 +40,7 @@ trait PhpFilesTrait { $time = time(); $pruned = true; - $allowCompile = 'cli' !== PHP_SAPI || ini_get('opcache.enable_cli'); + $allowCompile = 'cli' !== \PHP_SAPI || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN); set_error_handler($this->includeHandler); try { @@ -67,7 +67,7 @@ trait PhpFilesTrait */ protected function doFetch(array $ids) { - $values = array(); + $values = []; $now = time(); if ($this->zendDetectUnicode) { @@ -96,7 +96,7 @@ trait PhpFilesTrait foreach ($values as $id => $value) { if ('N;' === $value) { $values[$id] = null; - } elseif (is_string($value) && isset($value[2]) && ':' === $value[1]) { + } elseif (\is_string($value) && isset($value[2]) && ':' === $value[1]) { $values[$id] = parent::unserialize($value); } } @@ -109,7 +109,7 @@ trait PhpFilesTrait */ protected function doHave($id) { - return (bool) $this->doFetch(array($id)); + return (bool) $this->doFetch([$id]); } /** @@ -118,26 +118,26 @@ trait PhpFilesTrait protected function doSave(array $values, $lifetime) { $ok = true; - $data = array($lifetime ? time() + $lifetime : PHP_INT_MAX, ''); - $allowCompile = 'cli' !== PHP_SAPI || ini_get('opcache.enable_cli'); + $data = [$lifetime ? time() + $lifetime : \PHP_INT_MAX, '']; + $allowCompile = 'cli' !== \PHP_SAPI || filter_var(ini_get('opcache.enable_cli'), \FILTER_VALIDATE_BOOLEAN); foreach ($values as $key => $value) { - if (null === $value || is_object($value)) { + if (null === $value || \is_object($value)) { $value = serialize($value); - } elseif (is_array($value)) { + } elseif (\is_array($value)) { $serialized = serialize($value); $unserialized = parent::unserialize($serialized); // Store arrays serialized if they contain any objects or references if ($unserialized !== $value || (false !== strpos($serialized, ';R:') && preg_match('/;R:[1-9]/', $serialized))) { $value = $serialized; } - } elseif (is_string($value)) { + } elseif (\is_string($value)) { // Serialize strings if they could be confused with serialized objects or arrays if ('N;' === $value || (isset($value[2]) && ':' === $value[1])) { $value = serialize($value); } } elseif (!is_scalar($value)) { - throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable %s value.', $key, gettype($value))); + throw new InvalidArgumentException(sprintf('Cache key "%s" has non-serializable "%s" value.', $key, \gettype($value))); } $data[1] = $value; @@ -150,7 +150,7 @@ trait PhpFilesTrait } if (!$ok && !is_writable($this->directory)) { - throw new CacheException(sprintf('Cache directory is not writable (%s)', $this->directory)); + throw new CacheException(sprintf('Cache directory is not writable (%s).', $this->directory)); } return $ok; diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/ProxyTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/ProxyTrait.php index 06dba7e5..d9e085b9 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/ProxyTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/ProxyTrait.php @@ -16,6 +16,8 @@ use Symfony\Component\Cache\ResettableInterface; /** * @author Nicolas Grekas + * + * @internal */ trait ProxyTrait { diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/RedisProxy.php b/advancedcontentfilter/vendor/symfony/cache/Traits/RedisProxy.php index b328f94c..98ea3aba 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/RedisProxy.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/RedisProxy.php @@ -32,7 +32,7 @@ class RedisProxy { $this->ready ?: $this->ready = $this->initializer->__invoke($this->redis); - return \call_user_func_array(array($this->redis, $method), $args); + return \call_user_func_array([$this->redis, $method], $args); } public function hscan($strKey, &$iIterator, $strPattern = null, $iCount = null) diff --git a/advancedcontentfilter/vendor/symfony/cache/Traits/RedisTrait.php b/advancedcontentfilter/vendor/symfony/cache/Traits/RedisTrait.php index ac8b5a5f..a30d6d3f 100644 --- a/advancedcontentfilter/vendor/symfony/cache/Traits/RedisTrait.php +++ b/advancedcontentfilter/vendor/symfony/cache/Traits/RedisTrait.php @@ -11,10 +11,9 @@ namespace Symfony\Component\Cache\Traits; -use Predis\Connection\Factory; use Predis\Connection\Aggregate\ClusterInterface; -use Predis\Connection\Aggregate\PredisCluster; use Predis\Connection\Aggregate\RedisCluster; +use Predis\Connection\Factory; use Predis\Response\Status; use Symfony\Component\Cache\Exception\CacheException; use Symfony\Component\Cache\Exception\InvalidArgumentException; @@ -27,7 +26,7 @@ use Symfony\Component\Cache\Exception\InvalidArgumentException; */ trait RedisTrait { - private static $defaultConnectionOptions = array( + private static $defaultConnectionOptions = [ 'class' => null, 'persistent' => 0, 'persistent_id' => null, @@ -35,23 +34,21 @@ trait RedisTrait 'read_timeout' => 0, 'retry_interval' => 0, 'lazy' => false, - ); + ]; private $redis; /** * @param \Redis|\RedisArray|\RedisCluster|\Predis\Client $redisClient */ - public function init($redisClient, $namespace = '', $defaultLifetime = 0) + private function init($redisClient, $namespace = '', $defaultLifetime = 0) { parent::__construct($namespace, $defaultLifetime); if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) { throw new InvalidArgumentException(sprintf('RedisAdapter namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0])); } - if ($redisClient instanceof \RedisCluster) { - $this->enableVersioning(); - } elseif (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy) { - throw new InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, %s given', __METHOD__, is_object($redisClient) ? get_class($redisClient) : gettype($redisClient))); + if (!$redisClient instanceof \Redis && !$redisClient instanceof \RedisArray && !$redisClient instanceof \RedisCluster && !$redisClient instanceof \Predis\Client && !$redisClient instanceof RedisProxy) { + throw new InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\Client, "%s" given.', __METHOD__, \is_object($redisClient) ? \get_class($redisClient) : \gettype($redisClient))); } $this->redis = $redisClient; } @@ -73,10 +70,10 @@ trait RedisTrait * * @return \Redis|\Predis\Client According to the "class" option */ - public static function createConnection($dsn, array $options = array()) + public static function createConnection($dsn, array $options = []) { if (0 !== strpos($dsn, 'redis://')) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s does not start with "redis://"', $dsn)); + throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s" does not start with "redis://".', $dsn)); } $params = preg_replace_callback('#^redis://(?:(?:[^:@]*+:)?([^@]*+)@)?#', function ($m) use (&$auth) { if (isset($m[1])) { @@ -86,34 +83,34 @@ trait RedisTrait return 'file://'; }, $dsn); if (false === $params = parse_url($params)) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s', $dsn)); + throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); } if (!isset($params['host']) && !isset($params['path'])) { - throw new InvalidArgumentException(sprintf('Invalid Redis DSN: %s', $dsn)); + throw new InvalidArgumentException(sprintf('Invalid Redis DSN: "%s".', $dsn)); } if (isset($params['path']) && preg_match('#/(\d+)$#', $params['path'], $m)) { $params['dbindex'] = $m[1]; - $params['path'] = substr($params['path'], 0, -strlen($m[0])); + $params['path'] = substr($params['path'], 0, -\strlen($m[0])); } if (isset($params['host'])) { $scheme = 'tcp'; } else { $scheme = 'unix'; } - $params += array( + $params += [ 'host' => isset($params['host']) ? $params['host'] : $params['path'], 'port' => isset($params['host']) ? 6379 : null, 'dbindex' => 0, - ); + ]; if (isset($params['query'])) { parse_str($params['query'], $query); $params += $query; } $params += $options + self::$defaultConnectionOptions; - if (null === $params['class'] && !extension_loaded('redis') && !class_exists(\Predis\Client::class)) { - throw new CacheException(sprintf('Cannot find the "redis" extension, and "predis/predis" is not installed: %s', $dsn)); + if (null === $params['class'] && !\extension_loaded('redis') && !class_exists(\Predis\Client::class)) { + throw new CacheException(sprintf('Cannot find the "redis" extension, and "predis/predis" is not installed: "%s".', $dsn)); } - $class = null === $params['class'] ? (extension_loaded('redis') ? \Redis::class : \Predis\Client::class) : $params['class']; + $class = null === $params['class'] ? (\extension_loaded('redis') ? \Redis::class : \Predis\Client::class) : $params['class']; if (is_a($class, \Redis::class, true)) { $connect = $params['persistent'] || $params['persistent_id'] ? 'pconnect' : 'connect'; @@ -122,21 +119,24 @@ trait RedisTrait $initializer = function ($redis) use ($connect, $params, $dsn, $auth) { try { @$redis->{$connect}($params['host'], $params['port'], $params['timeout'], $params['persistent_id'], $params['retry_interval']); + + set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; }); + $isConnected = $redis->isConnected(); + restore_error_handler(); + if (!$isConnected) { + $error = preg_match('/^Redis::p?connect\(\): (.*)/', $error, $error) ? sprintf(' (%s)', $error[1]) : ''; + throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$error.'.'); + } + + if ((null !== $auth && !$redis->auth($auth)) + || ($params['dbindex'] && !$redis->select($params['dbindex'])) + || ($params['read_timeout'] && !$redis->setOption(\Redis::OPT_READ_TIMEOUT, $params['read_timeout'])) + ) { + $e = preg_replace('/^ERR /', '', $redis->getLastError()); + throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e.'.'); + } } catch (\RedisException $e) { - throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e->getMessage(), $dsn)); - } - - if (@!$redis->isConnected()) { - $e = ($e = error_get_last()) && preg_match('/^Redis::p?connect\(\): (.*)/', $e['message'], $e) ? sprintf(' (%s)', $e[1]) : ''; - throw new InvalidArgumentException(sprintf('Redis connection failed%s: %s', $e, $dsn)); - } - - if ((null !== $auth && !$redis->auth($auth)) - || ($params['dbindex'] && !$redis->select($params['dbindex'])) - || ($params['read_timeout'] && !$redis->setOption(\Redis::OPT_READ_TIMEOUT, $params['read_timeout'])) - ) { - $e = preg_replace('/^ERR /', '', $redis->getLastError()); - throw new InvalidArgumentException(sprintf('Redis connection failed (%s): %s', $e, $dsn)); + throw new InvalidArgumentException(sprintf('Redis connection "%s" failed: ', $dsn).$e->getMessage()); } return true; @@ -153,9 +153,9 @@ trait RedisTrait $params['password'] = $auth; $redis = new $class((new Factory())->create($params)); } elseif (class_exists($class, false)) { - throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis" or "Predis\Client"', $class)); + throw new InvalidArgumentException(sprintf('"%s" is not a subclass of "Redis" or "Predis\Client".', $class)); } else { - throw new InvalidArgumentException(sprintf('Class "%s" does not exist', $class)); + throw new InvalidArgumentException(sprintf('Class "%s" does not exist.', $class)); } return $redis; @@ -166,18 +166,35 @@ trait RedisTrait */ protected function doFetch(array $ids) { - if ($ids) { + if (!$ids) { + return []; + } + + $result = []; + + if ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface) { $values = $this->pipeline(function () use ($ids) { foreach ($ids as $id) { - yield 'get' => array($id); + yield 'get' => [$id]; } }); - foreach ($values as $id => $v) { - if ($v) { - yield $id => parent::unserialize($v); - } + } else { + $values = $this->redis->mget($ids); + + if (!\is_array($values) || \count($values) !== \count($ids)) { + return []; + } + + $values = array_combine($ids, $values); + } + + foreach ($values as $id => $v) { + if ($v) { + $result[$id] = parent::unserialize($v); } } + + return $result; } /** @@ -193,32 +210,31 @@ trait RedisTrait */ protected function doClear($namespace) { - // When using a native Redis cluster, clearing the cache is done by versioning in AbstractTrait::clear(). - // This means old keys are not really removed until they expire and may need gargage collection. - $cleared = true; - $hosts = array($this->redis); - $evalArgs = array(array($namespace), 0); + $hosts = [$this->redis]; + $evalArgs = [[$namespace], 0]; if ($this->redis instanceof \Predis\Client) { - $evalArgs = array(0, $namespace); + $evalArgs = [0, $namespace]; $connection = $this->redis->getConnection(); - if ($connection instanceof PredisCluster) { - $hosts = array(); + if ($connection instanceof ClusterInterface && $connection instanceof \Traversable) { + $hosts = []; foreach ($connection as $c) { $hosts[] = new \Predis\Client($c); } - } elseif ($connection instanceof RedisCluster) { - return false; } } elseif ($this->redis instanceof \RedisArray) { - $hosts = array(); + $hosts = []; foreach ($this->redis->_hosts() as $host) { $hosts[] = $this->redis->_instance($host); } } elseif ($this->redis instanceof \RedisCluster) { - return false; + $hosts = []; + foreach ($this->redis->_masters() as $host) { + $hosts[] = $h = new \Redis(); + $h->connect($host[0], $host[1]); + } } foreach ($hosts as $host) { if (!isset($namespace[0])) { @@ -240,12 +256,12 @@ trait RedisTrait $cursor = null; do { $keys = $host instanceof \Predis\Client ? $host->scan($cursor, 'MATCH', $namespace.'*', 'COUNT', 1000) : $host->scan($cursor, $namespace.'*', 1000); - if (isset($keys[1]) && is_array($keys[1])) { + if (isset($keys[1]) && \is_array($keys[1])) { $cursor = $keys[0]; $keys = $keys[1]; } if ($keys) { - $host->del($keys); + $this->doDelete($keys); } } while ($cursor = (int) $cursor); } @@ -258,7 +274,17 @@ trait RedisTrait */ protected function doDelete(array $ids) { - if ($ids) { + if (!$ids) { + return true; + } + + if ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface) { + $this->pipeline(function () use ($ids) { + foreach ($ids as $id) { + yield 'del' => [$id]; + } + })->rewind(); + } else { $this->redis->del($ids); } @@ -270,8 +296,8 @@ trait RedisTrait */ protected function doSave(array $values, $lifetime) { - $serialized = array(); - $failed = array(); + $serialized = []; + $failed = []; foreach ($values as $id => $value) { try { @@ -288,9 +314,9 @@ trait RedisTrait $results = $this->pipeline(function () use ($serialized, $lifetime) { foreach ($serialized as $id => $value) { if (0 >= $lifetime) { - yield 'set' => array($id, $value); + yield 'set' => [$id, $value]; } else { - yield 'setEx' => array($id, $lifetime, $value); + yield 'setEx' => [$id, $lifetime, $value]; } } }); @@ -305,24 +331,33 @@ trait RedisTrait private function pipeline(\Closure $generator) { - $ids = array(); + $ids = []; - if ($this->redis instanceof \Predis\Client && !$this->redis->getConnection() instanceof ClusterInterface) { + if ($this->redis instanceof \RedisCluster || ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof RedisCluster)) { + // phpredis & predis don't support pipelining with RedisCluster + // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining + // see https://github.com/nrk/predis/issues/267#issuecomment-123781423 + $results = []; + foreach ($generator() as $command => $args) { + $results[] = \call_user_func_array([$this->redis, $command], $args); + $ids[] = $args[0]; + } + } elseif ($this->redis instanceof \Predis\Client) { $results = $this->redis->pipeline(function ($redis) use ($generator, &$ids) { foreach ($generator() as $command => $args) { - call_user_func_array(array($redis, $command), $args); + \call_user_func_array([$redis, $command], $args); $ids[] = $args[0]; } }); } elseif ($this->redis instanceof \RedisArray) { - $connections = $results = $ids = array(); + $connections = $results = $ids = []; foreach ($generator() as $command => $args) { if (!isset($connections[$h = $this->redis->_target($args[0])])) { - $connections[$h] = array($this->redis->_instance($h), -1); + $connections[$h] = [$this->redis->_instance($h), -1]; $connections[$h][0]->multi(\Redis::PIPELINE); } - call_user_func_array(array($connections[$h][0], $command), $args); - $results[] = array($h, ++$connections[$h][1]); + \call_user_func_array([$connections[$h][0], $command], $args); + $results[] = [$h, ++$connections[$h][1]]; $ids[] = $args[0]; } foreach ($connections as $h => $c) { @@ -331,19 +366,10 @@ trait RedisTrait foreach ($results as $k => list($h, $c)) { $results[$k] = $connections[$h][$c]; } - } elseif ($this->redis instanceof \RedisCluster || ($this->redis instanceof \Predis\Client && $this->redis->getConnection() instanceof ClusterInterface)) { - // phpredis & predis don't support pipelining with RedisCluster - // see https://github.com/phpredis/phpredis/blob/develop/cluster.markdown#pipelining - // see https://github.com/nrk/predis/issues/267#issuecomment-123781423 - $results = array(); - foreach ($generator() as $command => $args) { - $results[] = call_user_func_array(array($this->redis, $command), $args); - $ids[] = $args[0]; - } } else { $this->redis->multi(\Redis::PIPELINE); foreach ($generator() as $command => $args) { - call_user_func_array(array($this->redis, $command), $args); + \call_user_func_array([$this->redis, $command], $args); $ids[] = $args[0]; } $results = $this->redis->exec(); diff --git a/advancedcontentfilter/vendor/symfony/cache/composer.json b/advancedcontentfilter/vendor/symfony/cache/composer.json index e13cd967..f412e4f1 100644 --- a/advancedcontentfilter/vendor/symfony/cache/composer.json +++ b/advancedcontentfilter/vendor/symfony/cache/composer.json @@ -28,9 +28,9 @@ }, "require-dev": { "cache/integration-tests": "dev-master", - "doctrine/cache": "~1.6", - "doctrine/dbal": "~2.4", - "predis/predis": "~1.0" + "doctrine/cache": "^1.6", + "doctrine/dbal": "^2.4|^3.0", + "predis/predis": "^1.0" }, "conflict": { "symfony/var-dumper": "<3.3" @@ -41,10 +41,5 @@ "/Tests/" ] }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - } + "minimum-stability": "dev" } diff --git a/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist b/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist index 9b3c30d7..c35458ca 100644 --- a/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist +++ b/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist @@ -1,7 +1,7 @@ - Cache\IntegrationTests - Doctrine\Common\Cache - Symfony\Component\Cache - Symfony\Component\Cache\Tests\Fixtures - Symfony\Component\Cache\Traits + Cache\IntegrationTests + Doctrine\Common\Cache + Symfony\Component\Cache + Symfony\Component\Cache\Tests\Fixtures + Symfony\Component\Cache\Traits diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Compiler.php b/advancedcontentfilter/vendor/symfony/expression-language/Compiler.php index 66d10604..1ae427b9 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Compiler.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Compiler.php @@ -110,22 +110,22 @@ class Compiler */ public function repr($value) { - if (is_int($value) || is_float($value)) { - if (false !== $locale = setlocale(LC_NUMERIC, 0)) { - setlocale(LC_NUMERIC, 'C'); + if (\is_int($value) || \is_float($value)) { + if (false !== $locale = setlocale(\LC_NUMERIC, 0)) { + setlocale(\LC_NUMERIC, 'C'); } $this->raw($value); if (false !== $locale) { - setlocale(LC_NUMERIC, $locale); + setlocale(\LC_NUMERIC, $locale); } } elseif (null === $value) { $this->raw('null'); - } elseif (is_bool($value)) { + } elseif (\is_bool($value)) { $this->raw($value ? 'true' : 'false'); - } elseif (is_array($value)) { - $this->raw('array('); + } elseif (\is_array($value)) { + $this->raw('['); $first = true; foreach ($value as $key => $value) { if (!$first) { @@ -136,7 +136,7 @@ class Compiler $this->raw(' => '); $this->repr($value); } - $this->raw(')'); + $this->raw(']'); } else { $this->string($value); } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/ExpressionFunction.php b/advancedcontentfilter/vendor/symfony/expression-language/ExpressionFunction.php index ad775dbd..77c88f66 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/ExpressionFunction.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/ExpressionFunction.php @@ -76,23 +76,23 @@ class ExpressionFunction public static function fromPhp($phpFunctionName, $expressionFunctionName = null) { $phpFunctionName = ltrim($phpFunctionName, '\\'); - if (!function_exists($phpFunctionName)) { + if (!\function_exists($phpFunctionName)) { throw new \InvalidArgumentException(sprintf('PHP function "%s" does not exist.', $phpFunctionName)); } $parts = explode('\\', $phpFunctionName); - if (!$expressionFunctionName && count($parts) > 1) { + if (!$expressionFunctionName && \count($parts) > 1) { throw new \InvalidArgumentException(sprintf('An expression function name must be defined when PHP function "%s" is namespaced.', $phpFunctionName)); } $compiler = function () use ($phpFunctionName) { - return sprintf('\%s(%s)', $phpFunctionName, implode(', ', func_get_args())); + return sprintf('\%s(%s)', $phpFunctionName, implode(', ', \func_get_args())); }; $evaluator = function () use ($phpFunctionName) { - $args = func_get_args(); + $args = \func_get_args(); - return call_user_func_array($phpFunctionName, array_splice($args, 1)); + return \call_user_func_array($phpFunctionName, array_splice($args, 1)); }; return new self($expressionFunctionName ?: end($parts), $compiler, $evaluator); diff --git a/advancedcontentfilter/vendor/symfony/expression-language/ExpressionLanguage.php b/advancedcontentfilter/vendor/symfony/expression-language/ExpressionLanguage.php index a9cfc4ca..16476669 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/ExpressionLanguage.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/ExpressionLanguage.php @@ -28,20 +28,20 @@ class ExpressionLanguage private $parser; private $compiler; - protected $functions = array(); + protected $functions = []; /** * @param CacheItemPoolInterface $cache * @param ExpressionFunctionProviderInterface[] $providers */ - public function __construct($cache = null, array $providers = array()) + public function __construct($cache = null, array $providers = []) { if (null !== $cache) { if ($cache instanceof ParserCacheInterface) { - @trigger_error(sprintf('Passing an instance of %s as constructor argument for %s is deprecated as of 3.2 and will be removed in 4.0. Pass an instance of %s instead.', ParserCacheInterface::class, self::class, CacheItemPoolInterface::class), E_USER_DEPRECATED); + @trigger_error(sprintf('Passing an instance of %s as constructor argument for %s is deprecated as of 3.2 and will be removed in 4.0. Pass an instance of %s instead.', ParserCacheInterface::class, self::class, CacheItemPoolInterface::class), \E_USER_DEPRECATED); $cache = new ParserCacheAdapter($cache); } elseif (!$cache instanceof CacheItemPoolInterface) { - throw new \InvalidArgumentException(sprintf('Cache argument has to implement %s.', CacheItemPoolInterface::class)); + throw new \InvalidArgumentException(sprintf('Cache argument has to implement "%s".', CacheItemPoolInterface::class)); } } @@ -60,7 +60,7 @@ class ExpressionLanguage * * @return string The compiled PHP source code */ - public function compile($expression, $names = array()) + public function compile($expression, $names = []) { return $this->getCompiler()->compile($this->parse($expression, $names)->getNodes())->getSource(); } @@ -71,9 +71,9 @@ class ExpressionLanguage * @param Expression|string $expression The expression to compile * @param array $values An array of values * - * @return string The result of the evaluation of the expression + * @return mixed The result of the evaluation of the expression */ - public function evaluate($expression, $values = array()) + public function evaluate($expression, $values = []) { return $this->parse($expression, array_keys($values))->getNodes()->evaluate($this->functions, $values); } @@ -93,10 +93,10 @@ class ExpressionLanguage } asort($names); - $cacheKeyItems = array(); + $cacheKeyItems = []; foreach ($names as $nameKey => $name) { - $cacheKeyItems[] = is_int($nameKey) ? $name : $nameKey.':'.$name; + $cacheKeyItems[] = \is_int($nameKey) ? $name : $nameKey.':'.$name; } $cacheItem = $this->cache->getItem(rawurlencode($expression.'//'.implode('|', $cacheKeyItems))); @@ -129,7 +129,7 @@ class ExpressionLanguage throw new \LogicException('Registering functions after calling evaluate(), compile() or parse() is not supported.'); } - $this->functions[$name] = array('compiler' => $compiler, 'evaluator' => $evaluator); + $this->functions[$name] = ['compiler' => $compiler, 'evaluator' => $evaluator]; } public function addFunction(ExpressionFunction $function) diff --git a/advancedcontentfilter/vendor/symfony/expression-language/LICENSE b/advancedcontentfilter/vendor/symfony/expression-language/LICENSE index 21d7fb9e..9e936ec0 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/LICENSE +++ b/advancedcontentfilter/vendor/symfony/expression-language/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2018 Fabien Potencier +Copyright (c) 2004-2020 Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Lexer.php b/advancedcontentfilter/vendor/symfony/expression-language/Lexer.php index aeeda8a8..ace847b0 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Lexer.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Lexer.php @@ -29,11 +29,11 @@ class Lexer */ public function tokenize($expression) { - $expression = str_replace(array("\r", "\n", "\t", "\v", "\f"), ' ', $expression); + $expression = str_replace(["\r", "\n", "\t", "\v", "\f"], ' ', $expression); $cursor = 0; - $tokens = array(); - $brackets = array(); - $end = strlen($expression); + $tokens = []; + $brackets = []; + $end = \strlen($expression); while ($cursor < $end) { if (' ' == $expression[$cursor]) { @@ -45,26 +45,26 @@ class Lexer if (preg_match('/[0-9]+(?:\.[0-9]+)?/A', $expression, $match, 0, $cursor)) { // numbers $number = (float) $match[0]; // floats - if (preg_match('/^[0-9]+$/', $match[0]) && $number <= PHP_INT_MAX) { + if (preg_match('/^[0-9]+$/', $match[0]) && $number <= \PHP_INT_MAX) { $number = (int) $match[0]; // integers lower than the maximum } $tokens[] = new Token(Token::NUMBER_TYPE, $number, $cursor + 1); - $cursor += strlen($match[0]); + $cursor += \strlen($match[0]); } elseif (false !== strpos('([{', $expression[$cursor])) { // opening bracket - $brackets[] = array($expression[$cursor], $cursor); + $brackets[] = [$expression[$cursor], $cursor]; $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); ++$cursor; } elseif (false !== strpos(')]}', $expression[$cursor])) { // closing bracket if (empty($brackets)) { - throw new SyntaxError(sprintf('Unexpected "%s"', $expression[$cursor]), $cursor, $expression); + throw new SyntaxError(sprintf('Unexpected "%s".', $expression[$cursor]), $cursor, $expression); } list($expect, $cur) = array_pop($brackets); if ($expression[$cursor] != strtr($expect, '([{', ')]}')) { - throw new SyntaxError(sprintf('Unclosed "%s"', $expect), $cur, $expression); + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression); } $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); @@ -72,11 +72,11 @@ class Lexer } elseif (preg_match('/"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\'/As', $expression, $match, 0, $cursor)) { // strings $tokens[] = new Token(Token::STRING_TYPE, stripcslashes(substr($match[0], 1, -1)), $cursor + 1); - $cursor += strlen($match[0]); - } elseif (preg_match('/not in(?=[\s(])|\!\=\=|not(?=[\s(])|and(?=[\s(])|\=\=\=|\>\=|or(?=[\s(])|\<\=|\*\*|\.\.|in(?=[\s(])|&&|\|\||matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, 0, $cursor)) { + $cursor += \strlen($match[0]); + } elseif (preg_match('/(?<=^|[\s(])not in(?=[\s(])|\!\=\=|(?<=^|[\s(])not(?=[\s(])|(?<=^|[\s(])and(?=[\s(])|\=\=\=|\>\=|(?<=^|[\s(])or(?=[\s(])|\<\=|\*\*|\.\.|(?<=^|[\s(])in(?=[\s(])|&&|\|\||(?<=^|[\s(])matches|\=\=|\!\=|\*|~|%|\/|\>|\||\!|\^|&|\+|\<|\-/A', $expression, $match, 0, $cursor)) { // operators $tokens[] = new Token(Token::OPERATOR_TYPE, $match[0], $cursor + 1); - $cursor += strlen($match[0]); + $cursor += \strlen($match[0]); } elseif (false !== strpos('.,?:', $expression[$cursor])) { // punctuation $tokens[] = new Token(Token::PUNCTUATION_TYPE, $expression[$cursor], $cursor + 1); @@ -84,10 +84,10 @@ class Lexer } elseif (preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $expression, $match, 0, $cursor)) { // names $tokens[] = new Token(Token::NAME_TYPE, $match[0], $cursor + 1); - $cursor += strlen($match[0]); + $cursor += \strlen($match[0]); } else { // unlexable - throw new SyntaxError(sprintf('Unexpected character "%s"', $expression[$cursor]), $cursor, $expression); + throw new SyntaxError(sprintf('Unexpected character "%s".', $expression[$cursor]), $cursor, $expression); } } @@ -95,7 +95,7 @@ class Lexer if (!empty($brackets)) { list($expect, $cur) = array_pop($brackets); - throw new SyntaxError(sprintf('Unclosed "%s"', $expect), $cur, $expression); + throw new SyntaxError(sprintf('Unclosed "%s".', $expect), $cur, $expression); } return new TokenStream($tokens, $expression); diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/ArgumentsNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/ArgumentsNode.php index 1c78d805..e9849a44 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/ArgumentsNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/ArgumentsNode.php @@ -27,7 +27,7 @@ class ArgumentsNode extends ArrayNode public function toArray() { - $array = array(); + $array = []; foreach ($this->getKeyValuePairs() as $pair) { $array[] = $pair['value']; diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/ArrayNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/ArrayNode.php index e1a2f2e9..921319a7 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/ArrayNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/ArrayNode.php @@ -41,14 +41,14 @@ class ArrayNode extends Node */ public function compile(Compiler $compiler) { - $compiler->raw('array('); + $compiler->raw('['); $this->compileArguments($compiler); - $compiler->raw(')'); + $compiler->raw(']'); } public function evaluate($functions, $values) { - $result = array(); + $result = []; foreach ($this->getKeyValuePairs() as $pair) { $result[$pair['key']->evaluate($functions, $values)] = $pair['value']->evaluate($functions, $values); } @@ -58,12 +58,12 @@ class ArrayNode extends Node public function toArray() { - $value = array(); + $value = []; foreach ($this->getKeyValuePairs() as $pair) { $value[$pair['key']->attributes['value']] = $pair['value']; } - $array = array(); + $array = []; if ($this->isHash($value)) { foreach ($value as $k => $v) { @@ -88,9 +88,9 @@ class ArrayNode extends Node protected function getKeyValuePairs() { - $pairs = array(); + $pairs = []; foreach (array_chunk($this->nodes, 2) as $pair) { - $pairs[] = array('key' => $pair[0], 'value' => $pair[1]); + $pairs[] = ['key' => $pair[0], 'value' => $pair[1]]; } return $pairs; diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/BinaryNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/BinaryNode.php index 33b4c8f0..549161b3 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/BinaryNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/BinaryNode.php @@ -20,24 +20,24 @@ use Symfony\Component\ExpressionLanguage\Compiler; */ class BinaryNode extends Node { - private static $operators = array( + private static $operators = [ '~' => '.', 'and' => '&&', 'or' => '||', - ); + ]; - private static $functions = array( + private static $functions = [ '**' => 'pow', '..' => 'range', 'in' => 'in_array', 'not in' => '!in_array', - ); + ]; public function __construct($operator, Node $left, Node $right) { parent::__construct( - array('left' => $left, 'right' => $right), - array('operator' => $operator) + ['left' => $left, 'right' => $right], + ['operator' => $operator] ); } @@ -93,7 +93,7 @@ class BinaryNode extends Node $right = $this->nodes['right']->evaluate($functions, $values); if ('not in' === $operator) { - return !in_array($left, $right); + return !\in_array($left, $right); } $f = self::$functions[$operator]; @@ -135,9 +135,9 @@ class BinaryNode extends Node case '<=': return $left <= $right; case 'not in': - return !in_array($left, $right); + return !\in_array($left, $right); case 'in': - return in_array($left, $right); + return \in_array($left, $right); case '+': return $left + $right; case '-': @@ -147,8 +147,16 @@ class BinaryNode extends Node case '*': return $left * $right; case '/': + if (0 == $right) { + throw new \DivisionByZeroError('Division by zero.'); + } + return $left / $right; case '%': + if (0 == $right) { + throw new \DivisionByZeroError('Modulo by zero.'); + } + return $left % $right; case 'matches': return preg_match($right, $left); @@ -157,6 +165,6 @@ class BinaryNode extends Node public function toArray() { - return array('(', $this->nodes['left'], ' '.$this->attributes['operator'].' ', $this->nodes['right'], ')'); + return ['(', $this->nodes['left'], ' '.$this->attributes['operator'].' ', $this->nodes['right'], ')']; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/ConditionalNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/ConditionalNode.php index 9db0f931..ca1b484b 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/ConditionalNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/ConditionalNode.php @@ -23,7 +23,7 @@ class ConditionalNode extends Node public function __construct(Node $expr1, Node $expr2, Node $expr3) { parent::__construct( - array('expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3) + ['expr1' => $expr1, 'expr2' => $expr2, 'expr3' => $expr3] ); } @@ -51,6 +51,6 @@ class ConditionalNode extends Node public function toArray() { - return array('(', $this->nodes['expr1'], ' ? ', $this->nodes['expr2'], ' : ', $this->nodes['expr3'], ')'); + return ['(', $this->nodes['expr1'], ' ? ', $this->nodes['expr2'], ' : ', $this->nodes['expr3'], ')']; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/ConstantNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/ConstantNode.php index 733d481b..670e52ed 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/ConstantNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/ConstantNode.php @@ -26,8 +26,8 @@ class ConstantNode extends Node { $this->isIdentifier = $isIdentifier; parent::__construct( - array(), - array('value' => $value) + [], + ['value' => $value] ); } @@ -43,7 +43,7 @@ class ConstantNode extends Node public function toArray() { - $array = array(); + $array = []; $value = $this->attributes['value']; if ($this->isIdentifier) { @@ -56,7 +56,7 @@ class ConstantNode extends Node $array[] = 'null'; } elseif (is_numeric($value)) { $array[] = $value; - } elseif (!is_array($value)) { + } elseif (!\is_array($value)) { $array[] = $this->dumpString($value); } elseif ($this->isHash($value)) { foreach ($value as $k => $v) { diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/FunctionNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/FunctionNode.php index 13928c8d..90008d5d 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/FunctionNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/FunctionNode.php @@ -23,36 +23,36 @@ class FunctionNode extends Node public function __construct($name, Node $arguments) { parent::__construct( - array('arguments' => $arguments), - array('name' => $name) + ['arguments' => $arguments], + ['name' => $name] ); } public function compile(Compiler $compiler) { - $arguments = array(); + $arguments = []; foreach ($this->nodes['arguments']->nodes as $node) { $arguments[] = $compiler->subcompile($node); } $function = $compiler->getFunction($this->attributes['name']); - $compiler->raw(call_user_func_array($function['compiler'], $arguments)); + $compiler->raw(\call_user_func_array($function['compiler'], $arguments)); } public function evaluate($functions, $values) { - $arguments = array($values); + $arguments = [$values]; foreach ($this->nodes['arguments']->nodes as $node) { $arguments[] = $node->evaluate($functions, $values); } - return call_user_func_array($functions[$this->attributes['name']]['evaluator'], $arguments); + return \call_user_func_array($functions[$this->attributes['name']]['evaluator'], $arguments); } public function toArray() { - $array = array(); + $array = []; $array[] = $this->attributes['name']; foreach ($this->nodes['arguments']->nodes as $node) { diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/GetAttrNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/GetAttrNode.php index 2ecba97f..dffe0e30 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/GetAttrNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/GetAttrNode.php @@ -27,8 +27,8 @@ class GetAttrNode extends Node public function __construct(Node $node, Node $attribute, ArrayNode $arguments, $type) { parent::__construct( - array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), - array('type' => $type) + ['node' => $node, 'attribute' => $attribute, 'arguments' => $arguments], + ['type' => $type] ); } @@ -69,7 +69,7 @@ class GetAttrNode extends Node switch ($this->attributes['type']) { case self::PROPERTY_CALL: $obj = $this->nodes['node']->evaluate($functions, $values); - if (!is_object($obj)) { + if (!\is_object($obj)) { throw new \RuntimeException('Unable to get a property on a non-object.'); } @@ -79,18 +79,24 @@ class GetAttrNode extends Node case self::METHOD_CALL: $obj = $this->nodes['node']->evaluate($functions, $values); - if (!is_object($obj)) { + if (!\is_object($obj)) { throw new \RuntimeException('Unable to get a property on a non-object.'); } - if (!is_callable($toCall = array($obj, $this->nodes['attribute']->attributes['value']))) { - throw new \RuntimeException(sprintf('Unable to call method "%s" of object "%s".', $this->nodes['attribute']->attributes['value'], get_class($obj))); + if (!\is_callable($toCall = [$obj, $this->nodes['attribute']->attributes['value']])) { + throw new \RuntimeException(sprintf('Unable to call method "%s" of object "%s".', $this->nodes['attribute']->attributes['value'], \get_class($obj))); } - return call_user_func_array($toCall, $this->nodes['arguments']->evaluate($functions, $values)); + $arguments = $this->nodes['arguments']->evaluate($functions, $values); + + if (\PHP_VERSION_ID >= 80000) { + $arguments = array_values($arguments); + } + + return \call_user_func_array($toCall, $arguments); case self::ARRAY_CALL: $array = $this->nodes['node']->evaluate($functions, $values); - if (!is_array($array) && !$array instanceof \ArrayAccess) { + if (!\is_array($array) && !$array instanceof \ArrayAccess) { throw new \RuntimeException('Unable to get an item on a non-array.'); } @@ -102,13 +108,13 @@ class GetAttrNode extends Node { switch ($this->attributes['type']) { case self::PROPERTY_CALL: - return array($this->nodes['node'], '.', $this->nodes['attribute']); + return [$this->nodes['node'], '.', $this->nodes['attribute']]; case self::METHOD_CALL: - return array($this->nodes['node'], '.', $this->nodes['attribute'], '(', $this->nodes['arguments'], ')'); + return [$this->nodes['node'], '.', $this->nodes['attribute'], '(', $this->nodes['arguments'], ')']; case self::ARRAY_CALL: - return array($this->nodes['node'], '[', $this->nodes['attribute'], ']'); + return [$this->nodes['node'], '[', $this->nodes['attribute'], ']']; } } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/NameNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/NameNode.php index 9e1462f2..1c9c277b 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/NameNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/NameNode.php @@ -23,8 +23,8 @@ class NameNode extends Node public function __construct($name) { parent::__construct( - array(), - array('name' => $name) + [], + ['name' => $name] ); } @@ -40,6 +40,6 @@ class NameNode extends Node public function toArray() { - return array($this->attributes['name']); + return [$this->attributes['name']]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/Node.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/Node.php index 1db4e852..95045902 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/Node.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/Node.php @@ -20,14 +20,14 @@ use Symfony\Component\ExpressionLanguage\Compiler; */ class Node { - public $nodes = array(); - public $attributes = array(); + public $nodes = []; + public $attributes = []; /** * @param array $nodes An array of nodes * @param array $attributes An array of attributes */ - public function __construct(array $nodes = array(), array $attributes = array()) + public function __construct(array $nodes = [], array $attributes = []) { $this->nodes = $nodes; $this->attributes = $attributes; @@ -35,14 +35,14 @@ class Node public function __toString() { - $attributes = array(); + $attributes = []; foreach ($this->attributes as $name => $value) { $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true))); } - $repr = array(str_replace('Symfony\Component\ExpressionLanguage\Node\\', '', get_class($this)).'('.implode(', ', $attributes)); + $repr = [str_replace('Symfony\Component\ExpressionLanguage\Node\\', '', static::class).'('.implode(', ', $attributes)]; - if (count($this->nodes)) { + if (\count($this->nodes)) { foreach ($this->nodes as $node) { foreach (explode("\n", (string) $node) as $line) { $repr[] = ' '.$line; @@ -66,7 +66,7 @@ class Node public function evaluate($functions, $values) { - $results = array(); + $results = []; foreach ($this->nodes as $node) { $results[] = $node->evaluate($functions, $values); } @@ -76,7 +76,7 @@ class Node public function toArray() { - throw new \BadMethodCallException(sprintf('Dumping a "%s" instance is not supported yet.', get_class($this))); + throw new \BadMethodCallException(sprintf('Dumping a "%s" instance is not supported yet.', static::class)); } public function dump() diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Node/UnaryNode.php b/advancedcontentfilter/vendor/symfony/expression-language/Node/UnaryNode.php index 58310321..497b7fe5 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Node/UnaryNode.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Node/UnaryNode.php @@ -20,18 +20,18 @@ use Symfony\Component\ExpressionLanguage\Compiler; */ class UnaryNode extends Node { - private static $operators = array( + private static $operators = [ '!' => '!', 'not' => '!', '+' => '+', '-' => '-', - ); + ]; public function __construct($operator, Node $node) { parent::__construct( - array('node' => $node), - array('operator' => $operator) + ['node' => $node], + ['operator' => $operator] ); } @@ -61,6 +61,6 @@ class UnaryNode extends Node public function toArray() { - return array('(', $this->attributes['operator'].' ', $this->nodes['node'], ')'); + return ['(', $this->attributes['operator'].' ', $this->nodes['node'], ')']; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Parser.php b/advancedcontentfilter/vendor/symfony/expression-language/Parser.php index 4b1ce8e3..bfc24395 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Parser.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Parser.php @@ -36,40 +36,40 @@ class Parser { $this->functions = $functions; - $this->unaryOperators = array( - 'not' => array('precedence' => 50), - '!' => array('precedence' => 50), - '-' => array('precedence' => 500), - '+' => array('precedence' => 500), - ); - $this->binaryOperators = array( - 'or' => array('precedence' => 10, 'associativity' => self::OPERATOR_LEFT), - '||' => array('precedence' => 10, 'associativity' => self::OPERATOR_LEFT), - 'and' => array('precedence' => 15, 'associativity' => self::OPERATOR_LEFT), - '&&' => array('precedence' => 15, 'associativity' => self::OPERATOR_LEFT), - '|' => array('precedence' => 16, 'associativity' => self::OPERATOR_LEFT), - '^' => array('precedence' => 17, 'associativity' => self::OPERATOR_LEFT), - '&' => array('precedence' => 18, 'associativity' => self::OPERATOR_LEFT), - '==' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '===' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '!=' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '!==' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '<' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '>' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '>=' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '<=' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - 'not in' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - 'in' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - 'matches' => array('precedence' => 20, 'associativity' => self::OPERATOR_LEFT), - '..' => array('precedence' => 25, 'associativity' => self::OPERATOR_LEFT), - '+' => array('precedence' => 30, 'associativity' => self::OPERATOR_LEFT), - '-' => array('precedence' => 30, 'associativity' => self::OPERATOR_LEFT), - '~' => array('precedence' => 40, 'associativity' => self::OPERATOR_LEFT), - '*' => array('precedence' => 60, 'associativity' => self::OPERATOR_LEFT), - '/' => array('precedence' => 60, 'associativity' => self::OPERATOR_LEFT), - '%' => array('precedence' => 60, 'associativity' => self::OPERATOR_LEFT), - '**' => array('precedence' => 200, 'associativity' => self::OPERATOR_RIGHT), - ); + $this->unaryOperators = [ + 'not' => ['precedence' => 50], + '!' => ['precedence' => 50], + '-' => ['precedence' => 500], + '+' => ['precedence' => 500], + ]; + $this->binaryOperators = [ + 'or' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT], + '||' => ['precedence' => 10, 'associativity' => self::OPERATOR_LEFT], + 'and' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT], + '&&' => ['precedence' => 15, 'associativity' => self::OPERATOR_LEFT], + '|' => ['precedence' => 16, 'associativity' => self::OPERATOR_LEFT], + '^' => ['precedence' => 17, 'associativity' => self::OPERATOR_LEFT], + '&' => ['precedence' => 18, 'associativity' => self::OPERATOR_LEFT], + '==' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '===' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '!=' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '!==' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '<' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '>' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '>=' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '<=' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + 'not in' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + 'in' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + 'matches' => ['precedence' => 20, 'associativity' => self::OPERATOR_LEFT], + '..' => ['precedence' => 25, 'associativity' => self::OPERATOR_LEFT], + '+' => ['precedence' => 30, 'associativity' => self::OPERATOR_LEFT], + '-' => ['precedence' => 30, 'associativity' => self::OPERATOR_LEFT], + '~' => ['precedence' => 40, 'associativity' => self::OPERATOR_LEFT], + '*' => ['precedence' => 60, 'associativity' => self::OPERATOR_LEFT], + '/' => ['precedence' => 60, 'associativity' => self::OPERATOR_LEFT], + '%' => ['precedence' => 60, 'associativity' => self::OPERATOR_LEFT], + '**' => ['precedence' => 200, 'associativity' => self::OPERATOR_RIGHT], + ]; } /** @@ -92,14 +92,14 @@ class Parser * * @throws SyntaxError */ - public function parse(TokenStream $stream, $names = array()) + public function parse(TokenStream $stream, $names = []) { $this->stream = $stream; $this->names = $names; $node = $this->parseExpression(); if (!$stream->isEOF()) { - throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s"', $stream->current->type, $stream->current->value), $stream->current->cursor, $stream->getExpression()); + throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', $stream->current->type, $stream->current->value), $stream->current->cursor, $stream->getExpression()); } return $node; @@ -195,18 +195,18 @@ class Parser default: if ('(' === $this->stream->current->value) { if (false === isset($this->functions[$token->value])) { - throw new SyntaxError(sprintf('The function "%s" does not exist', $token->value), $token->cursor, $this->stream->getExpression(), $token->value, array_keys($this->functions)); + throw new SyntaxError(sprintf('The function "%s" does not exist.', $token->value), $token->cursor, $this->stream->getExpression(), $token->value, array_keys($this->functions)); } $node = new Node\FunctionNode($token->value, $this->parseArguments()); } else { - if (!in_array($token->value, $this->names, true)) { - throw new SyntaxError(sprintf('Variable "%s" is not valid', $token->value), $token->cursor, $this->stream->getExpression(), $token->value, $this->names); + if (!\in_array($token->value, $this->names, true)) { + throw new SyntaxError(sprintf('Variable "%s" is not valid.', $token->value), $token->cursor, $this->stream->getExpression(), $token->value, $this->names); } // is the name used in the compiled code different // from the name used in the expression? - if (is_int($name = array_search($token->value, $this->names))) { + if (\is_int($name = array_search($token->value, $this->names))) { $name = $token->value; } @@ -227,7 +227,7 @@ class Parser } elseif ($token->test(Token::PUNCTUATION_TYPE, '{')) { $node = $this->parseHashExpression(); } else { - throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s"', $token->type, $token->value), $token->cursor, $this->stream->getExpression()); + throw new SyntaxError(sprintf('Unexpected token "%s" of value "%s".', $token->type, $token->value), $token->cursor, $this->stream->getExpression()); } } @@ -289,7 +289,7 @@ class Parser } else { $current = $this->stream->current; - throw new SyntaxError(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', $current->type, $current->value), $current->cursor, $this->stream->getExpression()); + throw new SyntaxError(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s".', $current->type, $current->value), $current->cursor, $this->stream->getExpression()); } $this->stream->expect(Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); @@ -327,7 +327,7 @@ class Parser // As a result, if $token is NOT an operator OR $token->value is NOT a valid property or method name, an exception shall be thrown. (Token::OPERATOR_TYPE !== $token->type || !preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/A', $token->value)) ) { - throw new SyntaxError('Expected name', $token->cursor, $this->stream->getExpression()); + throw new SyntaxError('Expected name.', $token->cursor, $this->stream->getExpression()); } $arg = new Node\ConstantNode($token->value, true); @@ -364,7 +364,7 @@ class Parser */ public function parseArguments() { - $args = array(); + $args = []; $this->stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); while (!$this->stream->current->test(Token::PUNCTUATION_TYPE, ')')) { if (!empty($args)) { diff --git a/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php b/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php index 12496250..f009df73 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ArrayParserCache.php @@ -11,7 +11,7 @@ namespace Symfony\Component\ExpressionLanguage\ParserCache; -@trigger_error('The '.__NAMESPACE__.'\ArrayParserCache class is deprecated since Symfony 3.2 and will be removed in 4.0. Use the Symfony\Component\Cache\Adapter\ArrayAdapter class instead.', E_USER_DEPRECATED); +@trigger_error('The '.__NAMESPACE__.'\ArrayParserCache class is deprecated since Symfony 3.2 and will be removed in 4.0. Use the Symfony\Component\Cache\Adapter\ArrayAdapter class instead.', \E_USER_DEPRECATED); use Symfony\Component\ExpressionLanguage\ParsedExpression; @@ -22,7 +22,7 @@ use Symfony\Component\ExpressionLanguage\ParsedExpression; */ class ArrayParserCache implements ParserCacheInterface { - private $cache = array(); + private $cache = []; /** * {@inheritdoc} diff --git a/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php b/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php index a3e227d0..b9b448dd 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheAdapter.php @@ -30,7 +30,7 @@ class ParserCacheAdapter implements CacheItemPoolInterface $this->pool = $pool; $this->createCacheItem = \Closure::bind( - function ($key, $value, $isHit) { + static function ($key, $value, $isHit) { $item = new CacheItem(); $item->key = $key; $item->value = $value; @@ -65,9 +65,9 @@ class ParserCacheAdapter implements CacheItemPoolInterface /** * {@inheritdoc} */ - public function getItems(array $keys = array()) + public function getItems(array $keys = []) { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } /** @@ -75,7 +75,7 @@ class ParserCacheAdapter implements CacheItemPoolInterface */ public function hasItem($key) { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } /** @@ -83,7 +83,7 @@ class ParserCacheAdapter implements CacheItemPoolInterface */ public function clear() { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } /** @@ -91,7 +91,7 @@ class ParserCacheAdapter implements CacheItemPoolInterface */ public function deleteItem($key) { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } /** @@ -99,7 +99,7 @@ class ParserCacheAdapter implements CacheItemPoolInterface */ public function deleteItems(array $keys) { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } /** @@ -107,7 +107,7 @@ class ParserCacheAdapter implements CacheItemPoolInterface */ public function saveDeferred(CacheItemInterface $item) { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } /** @@ -115,6 +115,6 @@ class ParserCacheAdapter implements CacheItemPoolInterface */ public function commit() { - throw new \BadMethodCallException('Not implemented'); + throw new \BadMethodCallException('Not implemented.'); } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php b/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php index ed66b21b..98a80edd 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/ParserCache/ParserCacheInterface.php @@ -11,7 +11,7 @@ namespace Symfony\Component\ExpressionLanguage\ParserCache; -@trigger_error('The '.__NAMESPACE__.'\ParserCacheInterface interface is deprecated since Symfony 3.2 and will be removed in 4.0. Use Psr\Cache\CacheItemPoolInterface instead.', E_USER_DEPRECATED); +@trigger_error('The '.__NAMESPACE__.'\ParserCacheInterface interface is deprecated since Symfony 3.2 and will be removed in 4.0. Use Psr\Cache\CacheItemPoolInterface instead.', \E_USER_DEPRECATED); use Symfony\Component\ExpressionLanguage\ParsedExpression; diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php b/advancedcontentfilter/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php index 74a10089..c86e9625 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Resources/bin/generate_operator_regex.php @@ -9,15 +9,19 @@ * file that was distributed with this source code. */ -$operators = array('not', '!', 'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', 'matches', '**'); +$operators = ['not', '!', 'or', '||', '&&', 'and', '|', '^', '&', '==', '===', '!=', '!==', '<', '>', '>=', '<=', 'not in', 'in', '..', '+', '-', '~', '*', '/', '%', 'matches', '**']; $operators = array_combine($operators, array_map('strlen', $operators)); arsort($operators); -$regex = array(); +$regex = []; foreach ($operators as $operator => $length) { - // an operator that ends with a character must be followed by - // a whitespace or a parenthesis - $regex[] = preg_quote($operator, '/').(ctype_alpha($operator[$length - 1]) ? '(?=[\s(])' : ''); + // Collisions of character operators: + // - an operator that begins with a character must have a space or a parenthesis before or starting at the beginning of a string + // - an operator that ends with a character must be followed by a whitespace or a parenthesis + $regex[] = + (ctype_alpha($operator[0]) ? '(?<=^|[\s(])' : '') + .preg_quote($operator, '/') + .(ctype_alpha($operator[$length - 1]) ? '(?=[\s(])' : ''); } echo '/'.implode('|', $regex).'/A'; diff --git a/advancedcontentfilter/vendor/symfony/expression-language/SyntaxError.php b/advancedcontentfilter/vendor/symfony/expression-language/SyntaxError.php index 12348e68..a942b8cb 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/SyntaxError.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/SyntaxError.php @@ -15,14 +15,14 @@ class SyntaxError extends \LogicException { public function __construct($message, $cursor = 0, $expression = '', $subject = null, array $proposals = null) { - $message = sprintf('%s around position %d', $message, $cursor); + $message = sprintf('%s around position %d', rtrim($message, '.'), $cursor); if ($expression) { $message = sprintf('%s for expression `%s`', $message, $expression); } $message .= '.'; if (null !== $subject && null !== $proposals) { - $minScore = INF; + $minScore = \INF; foreach ($proposals as $proposal) { $distance = levenshtein($subject, $proposal); if ($distance < $minScore) { diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php index f2710fb1..d7e23cb4 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionFunctionTest.php @@ -21,21 +21,17 @@ use Symfony\Component\ExpressionLanguage\ExpressionFunction; */ class ExpressionFunctionTest extends TestCase { - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage PHP function "fn_does_not_exist" does not exist. - */ public function testFunctionDoesNotExist() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('PHP function "fn_does_not_exist" does not exist.'); ExpressionFunction::fromPhp('fn_does_not_exist'); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage An expression function name must be defined when PHP function "Symfony\Component\ExpressionLanguage\Tests\fn_namespaced" is namespaced. - */ public function testFunctionNamespaced() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('An expression function name must be defined when PHP function "Symfony\Component\ExpressionLanguage\Tests\fn_namespaced" is namespaced.'); ExpressionFunction::fromPhp('Symfony\Component\ExpressionLanguage\Tests\fn_namespaced'); } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php index 70328c8e..97e915ac 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ExpressionLanguageTest.php @@ -11,8 +11,8 @@ namespace Symfony\Component\ExpressionLanguage\Tests; -use Symfony\Component\ExpressionLanguage\ExpressionFunction; use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\ExpressionFunction; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; use Symfony\Component\ExpressionLanguage\ParsedExpression; use Symfony\Component\ExpressionLanguage\Tests\Fixtures\TestProvider; @@ -36,18 +36,18 @@ class ExpressionLanguageTest extends TestCase $cacheItemMock ->expects($this->exactly(2)) ->method('get') - ->will($this->returnCallback(function () use (&$savedParsedExpression) { + ->willReturnCallback(function () use (&$savedParsedExpression) { return $savedParsedExpression; - })) + }) ; $cacheItemMock ->expects($this->exactly(1)) ->method('set') ->with($this->isInstanceOf(ParsedExpression::class)) - ->will($this->returnCallback(function ($parsedExpression) use (&$savedParsedExpression) { + ->willReturnCallback(function ($parsedExpression) use (&$savedParsedExpression) { $savedParsedExpression = $parsedExpression; - })) + }) ; $cacheMock @@ -56,10 +56,10 @@ class ExpressionLanguageTest extends TestCase ->with($cacheItemMock) ; - $parsedExpression = $expressionLanguage->parse('1 + 1', array()); + $parsedExpression = $expressionLanguage->parse('1 + 1', []); $this->assertSame($savedParsedExpression, $parsedExpression); - $parsedExpression = $expressionLanguage->parse('1 + 1', array()); + $parsedExpression = $expressionLanguage->parse('1 + 1', []); $this->assertSame($savedParsedExpression, $parsedExpression); } @@ -70,7 +70,6 @@ class ExpressionLanguageTest extends TestCase { $cacheMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); - $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); $savedParsedExpression = null; $expressionLanguage = new ExpressionLanguage($cacheMock); @@ -85,29 +84,27 @@ class ExpressionLanguageTest extends TestCase ->expects($this->exactly(1)) ->method('save') ->with('1%20%2B%201%2F%2F', $this->isInstanceOf(ParsedExpression::class)) - ->will($this->returnCallback(function ($key, $expression) use (&$savedParsedExpression) { + ->willReturnCallback(function ($key, $expression) use (&$savedParsedExpression) { $savedParsedExpression = $expression; - })) + }) ; - $parsedExpression = $expressionLanguage->parse('1 + 1', array()); + $parsedExpression = $expressionLanguage->parse('1 + 1', []); $this->assertSame($savedParsedExpression, $parsedExpression); } - /** - * @expectedException \InvalidArgumentException - * @expectedExceptionMessage Cache argument has to implement Psr\Cache\CacheItemPoolInterface. - */ public function testWrongCacheImplementation() { + $this->expectException('InvalidArgumentException'); + $this->expectExceptionMessage('Cache argument has to implement "Psr\Cache\CacheItemPoolInterface".'); $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemSpoolInterface')->getMock(); - $expressionLanguage = new ExpressionLanguage($cacheMock); + new ExpressionLanguage($cacheMock); } public function testConstantFunction() { $expressionLanguage = new ExpressionLanguage(); - $this->assertEquals(PHP_VERSION, $expressionLanguage->evaluate('constant("PHP_VERSION")')); + $this->assertEquals(\PHP_VERSION, $expressionLanguage->evaluate('constant("PHP_VERSION")')); $expressionLanguage = new ExpressionLanguage(); $this->assertEquals('\constant("PHP_VERSION")', $expressionLanguage->compile('constant("PHP_VERSION")')); @@ -115,7 +112,7 @@ class ExpressionLanguageTest extends TestCase public function testProviders() { - $expressionLanguage = new ExpressionLanguage(null, array(new TestProvider())); + $expressionLanguage = new ExpressionLanguage(null, [new TestProvider()]); $this->assertEquals('foo', $expressionLanguage->evaluate('identity("foo")')); $this->assertEquals('"foo"', $expressionLanguage->compile('identity("foo")')); $this->assertEquals('FOO', $expressionLanguage->evaluate('strtoupper("foo")')); @@ -146,45 +143,43 @@ class ExpressionLanguageTest extends TestCase $this->assertSame($expected, $result); } - /** - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError - * @expectedExceptionMessage Unexpected end of expression around position 6 for expression `node.`. - */ public function testParseThrowsInsteadOfNotice() { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Unexpected end of expression around position 6 for expression `node.`.'); $expressionLanguage = new ExpressionLanguage(); - $expressionLanguage->parse('node.', array('node')); + $expressionLanguage->parse('node.', ['node']); } public function shortCircuitProviderEvaluate() { - $object = $this->getMockBuilder('stdClass')->setMethods(array('foo'))->getMock(); + $object = $this->getMockBuilder('stdClass')->setMethods(['foo'])->getMock(); $object->expects($this->never())->method('foo'); - return array( - array('false and object.foo()', array('object' => $object), false), - array('false && object.foo()', array('object' => $object), false), - array('true || object.foo()', array('object' => $object), true), - array('true or object.foo()', array('object' => $object), true), - ); + return [ + ['false and object.foo()', ['object' => $object], false], + ['false && object.foo()', ['object' => $object], false], + ['true || object.foo()', ['object' => $object], true], + ['true or object.foo()', ['object' => $object], true], + ]; } public function shortCircuitProviderCompile() { - return array( - array('false and foo', array('foo' => 'foo'), false), - array('false && foo', array('foo' => 'foo'), false), - array('true || foo', array('foo' => 'foo'), true), - array('true or foo', array('foo' => 'foo'), true), - ); + return [ + ['false and foo', ['foo' => 'foo'], false], + ['false && foo', ['foo' => 'foo'], false], + ['true || foo', ['foo' => 'foo'], true], + ['true or foo', ['foo' => 'foo'], true], + ]; } public function testCachingForOverriddenVariableNames() { $expressionLanguage = new ExpressionLanguage(); $expression = 'a + b'; - $expressionLanguage->evaluate($expression, array('a' => 1, 'b' => 1)); - $result = $expressionLanguage->compile($expression, array('a', 'B' => 'b')); + $expressionLanguage->evaluate($expression, ['a' => 1, 'b' => 1]); + $result = $expressionLanguage->compile($expression, ['a', 'B' => 'b']); $this->assertSame('($a + $B)', $result); } @@ -192,7 +187,7 @@ class ExpressionLanguageTest extends TestCase { $expressionLanguage = new ExpressionLanguage(); $expression = '123 === a'; - $result = $expressionLanguage->compile($expression, array('a')); + $result = $expressionLanguage->compile($expression, ['a']); $this->assertSame('(123 === $a)', $result); } @@ -201,7 +196,7 @@ class ExpressionLanguageTest extends TestCase $cacheMock = $this->getMockBuilder('Psr\Cache\CacheItemPoolInterface')->getMock(); $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); $expressionLanguage = new ExpressionLanguage($cacheMock); - $savedParsedExpressions = array(); + $savedParsedExpression = null; $cacheMock ->expects($this->exactly(2)) @@ -213,18 +208,18 @@ class ExpressionLanguageTest extends TestCase $cacheItemMock ->expects($this->exactly(2)) ->method('get') - ->will($this->returnCallback(function () use (&$savedParsedExpression) { + ->willReturnCallback(function () use (&$savedParsedExpression) { return $savedParsedExpression; - })) + }) ; $cacheItemMock ->expects($this->exactly(1)) ->method('set') ->with($this->isInstanceOf(ParsedExpression::class)) - ->will($this->returnCallback(function ($parsedExpression) use (&$savedParsedExpression) { + ->willReturnCallback(function ($parsedExpression) use (&$savedParsedExpression) { $savedParsedExpression = $parsedExpression; - })) + }) ; $cacheMock @@ -234,48 +229,57 @@ class ExpressionLanguageTest extends TestCase ; $expression = 'a + b'; - $expressionLanguage->compile($expression, array('a', 'B' => 'b')); - $expressionLanguage->compile($expression, array('B' => 'b', 'a')); + $expressionLanguage->compile($expression, ['a', 'B' => 'b']); + $expressionLanguage->compile($expression, ['B' => 'b', 'a']); + } + + public function testOperatorCollisions() + { + $expressionLanguage = new ExpressionLanguage(); + $expression = 'foo.not in [bar]'; + $compiled = $expressionLanguage->compile($expression, ['foo', 'bar']); + $this->assertSame('in_array($foo->not, [0 => $bar])', $compiled); + + $result = $expressionLanguage->evaluate($expression, ['foo' => (object) ['not' => 'test'], 'bar' => 'test']); + $this->assertTrue($result); } /** * @dataProvider getRegisterCallbacks - * @expectedException \LogicException */ public function testRegisterAfterParse($registerCallback) { + $this->expectException('LogicException'); $el = new ExpressionLanguage(); - $el->parse('1 + 1', array()); + $el->parse('1 + 1', []); $registerCallback($el); } /** * @dataProvider getRegisterCallbacks - * @expectedException \LogicException */ public function testRegisterAfterEval($registerCallback) { + $this->expectException('LogicException'); $el = new ExpressionLanguage(); $el->evaluate('1 + 1'); $registerCallback($el); } - /** - * @expectedException \RuntimeException - * @expectedExceptionMessageRegExp /Unable to call method "\w+" of object "\w+"./ - */ public function testCallBadCallable() { + $this->expectException('RuntimeException'); + $this->expectExceptionMessageMatches('/Unable to call method "\w+" of object "\w+"./'); $el = new ExpressionLanguage(); - $el->evaluate('foo.myfunction()', array('foo' => new \stdClass())); + $el->evaluate('foo.myfunction()', ['foo' => new \stdClass()]); } /** * @dataProvider getRegisterCallbacks - * @expectedException \LogicException */ public function testRegisterAfterCompile($registerCallback) { + $this->expectException('LogicException'); $el = new ExpressionLanguage(); $el->compile('1 + 1'); $registerCallback($el); @@ -283,22 +287,22 @@ class ExpressionLanguageTest extends TestCase public function getRegisterCallbacks() { - return array( - array( + return [ + [ function (ExpressionLanguage $el) { $el->register('fn', function () {}, function () {}); }, - ), - array( + ], + [ function (ExpressionLanguage $el) { $el->addFunction(new ExpressionFunction('fn', function () {}, function () {})); }, - ), - array( + ], + [ function (ExpressionLanguage $el) { $el->registerProvider(new TestProvider()); }, - ), - ); + ], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php index 20c5182b..8405d4f9 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Fixtures/TestProvider.php @@ -19,7 +19,7 @@ class TestProvider implements ExpressionFunctionProviderInterface { public function getFunctions() { - return array( + return [ new ExpressionFunction('identity', function ($input) { return $input; }, function (array $values, $input) { @@ -31,7 +31,7 @@ class TestProvider implements ExpressionFunctionProviderInterface ExpressionFunction::fromPhp('\strtolower'), ExpressionFunction::fromPhp('Symfony\Component\ExpressionLanguage\Tests\Fixtures\fn_namespaced', 'fn_namespaced'), - ); + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/LexerTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/LexerTest.php index 87c16f70..6c3d1a7d 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/LexerTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/LexerTest.php @@ -33,59 +33,55 @@ class LexerTest extends TestCase */ public function testTokenize($tokens, $expression) { - $tokens[] = new Token('end of expression', null, strlen($expression) + 1); + $tokens[] = new Token('end of expression', null, \strlen($expression) + 1); $this->assertEquals(new TokenStream($tokens, $expression), $this->lexer->tokenize($expression)); } - /** - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError - * @expectedExceptionMessage Unexpected character "'" around position 33 for expression `service(faulty.expression.example').dummyMethod()`. - */ public function testTokenizeThrowsErrorWithMessage() { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Unexpected character "\'" around position 33 for expression `service(faulty.expression.example\').dummyMethod()`.'); $expression = "service(faulty.expression.example').dummyMethod()"; $this->lexer->tokenize($expression); } - /** - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError - * @expectedExceptionMessage Unclosed "(" around position 7 for expression `service(unclosed.expression.dummyMethod()`. - */ public function testTokenizeThrowsErrorOnUnclosedBrace() { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Unclosed "(" around position 7 for expression `service(unclosed.expression.dummyMethod()`.'); $expression = 'service(unclosed.expression.dummyMethod()'; $this->lexer->tokenize($expression); } public function getTokenizeData() { - return array( - array( - array(new Token('name', 'a', 3)), + return [ + [ + [new Token('name', 'a', 3)], ' a ', - ), - array( - array(new Token('name', 'a', 1)), + ], + [ + [new Token('name', 'a', 1)], 'a', - ), - array( - array(new Token('string', 'foo', 1)), + ], + [ + [new Token('string', 'foo', 1)], '"foo"', - ), - array( - array(new Token('number', '3', 1)), + ], + [ + [new Token('number', '3', 1)], '3', - ), - array( - array(new Token('operator', '+', 1)), + ], + [ + [new Token('operator', '+', 1)], '+', - ), - array( - array(new Token('punctuation', '.', 1)), + ], + [ + [new Token('punctuation', '.', 1)], '.', - ), - array( - array( + ], + [ + [ new Token('punctuation', '(', 1), new Token('number', '3', 2), new Token('operator', '+', 4), @@ -101,21 +97,33 @@ class LexerTest extends TestCase new Token('punctuation', '[', 25), new Token('number', '4', 26), new Token('punctuation', ']', 27), - ), + ], '(3 + 5) ~ foo("bar").baz[4]', - ), - array( - array(new Token('operator', '..', 1)), + ], + [ + [new Token('operator', '..', 1)], '..', - ), - array( - array(new Token('string', '#foo', 1)), + ], + [ + [new Token('string', '#foo', 1)], "'#foo'", - ), - array( - array(new Token('string', '#foo', 1)), + ], + [ + [new Token('string', '#foo', 1)], '"#foo"', - ), - ); + ], + [ + [ + new Token('name', 'foo', 1), + new Token('punctuation', '.', 4), + new Token('name', 'not', 5), + new Token('operator', 'in', 9), + new Token('punctuation', '[', 12), + new Token('name', 'bar', 13), + new Token('punctuation', ']', 16), + ], + 'foo.not in [bar]', + ], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php index a6f80c2f..29750374 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/AbstractNodeTest.php @@ -19,7 +19,7 @@ abstract class AbstractNodeTest extends TestCase /** * @dataProvider getEvaluateData */ - public function testEvaluate($expected, $node, $variables = array(), $functions = array()) + public function testEvaluate($expected, $node, $variables = [], $functions = []) { $this->assertSame($expected, $node->evaluate($functions, $variables)); } @@ -29,7 +29,7 @@ abstract class AbstractNodeTest extends TestCase /** * @dataProvider getCompileData */ - public function testCompile($expected, $node, $functions = array()) + public function testCompile($expected, $node, $functions = []) { $compiler = new Compiler($functions); $node->compile($compiler); diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php index 60a6d1ca..9d88b4ae 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArgumentsNodeTest.php @@ -17,16 +17,16 @@ class ArgumentsNodeTest extends ArrayNodeTest { public function getCompileData() { - return array( - array('"a", "b"', $this->getArrayNode()), - ); + return [ + ['"a", "b"', $this->getArrayNode()], + ]; } public function getDumpData() { - return array( - array('"a", "b"', $this->getArrayNode()), - ); + return [ + ['"a", "b"', $this->getArrayNode()], + ]; } protected function createArrayNode() diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php index 11a35d46..3d03d837 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ArrayNodeTest.php @@ -30,31 +30,31 @@ class ArrayNodeTest extends AbstractNodeTest public function getEvaluateData() { - return array( - array(array('b' => 'a', 'b'), $this->getArrayNode()), - ); + return [ + [['b' => 'a', 'b'], $this->getArrayNode()], + ]; } public function getCompileData() { - return array( - array('array("b" => "a", 0 => "b")', $this->getArrayNode()), - ); + return [ + ['["b" => "a", 0 => "b"]', $this->getArrayNode()], + ]; } public function getDumpData() { - yield array('{"b": "a", 0: "b"}', $this->getArrayNode()); + yield ['{"b": "a", 0: "b"}', $this->getArrayNode()]; $array = $this->createArrayNode(); $array->addElement(new ConstantNode('c'), new ConstantNode('a"b')); $array->addElement(new ConstantNode('d'), new ConstantNode('a\b')); - yield array('{"a\\"b": "c", "a\\\\b": "d"}', $array); + yield ['{"a\\"b": "c", "a\\\\b": "d"}', $array]; $array = $this->createArrayNode(); $array->addElement(new ConstantNode('c')); $array->addElement(new ConstantNode('d')); - yield array('["c", "d"]', $array); + yield ['["c", "d"]', $array]; } protected function getArrayNode() diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php index 258d276b..b45a1e57 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/BinaryNodeTest.php @@ -11,8 +11,8 @@ namespace Symfony\Component\ExpressionLanguage\Tests\Node; -use Symfony\Component\ExpressionLanguage\Node\BinaryNode; use Symfony\Component\ExpressionLanguage\Node\ArrayNode; +use Symfony\Component\ExpressionLanguage\Node\BinaryNode; use Symfony\Component\ExpressionLanguage\Node\ConstantNode; class BinaryNodeTest extends AbstractNodeTest @@ -23,47 +23,47 @@ class BinaryNodeTest extends AbstractNodeTest $array->addElement(new ConstantNode('a')); $array->addElement(new ConstantNode('b')); - return array( - array(true, new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))), - array(true, new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))), - array(false, new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))), - array(false, new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))), + return [ + [true, new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))], + [true, new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))], + [false, new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))], + [false, new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))], - array(0, new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))), - array(6, new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))), - array(6, new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))), + [0, new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))], + [6, new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))], + [6, new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))], - array(true, new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))), - array(true, new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))), - array(true, new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))), + [true, new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))], + [true, new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))], + [true, new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))], - array(false, new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))), - array(false, new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))), - array(true, new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))), + [false, new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))], + [false, new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))], + [true, new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))], - array(true, new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))), - array(false, new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))), + [true, new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))], + [false, new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))], - array(false, new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))), - array(true, new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))), + [false, new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))], + [true, new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))], - array(-1, new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))), - array(3, new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))), - array(4, new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))), - array(1, new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))), - array(1, new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))), - array(25, new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))), - array('ab', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))), + [-1, new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))], + [3, new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))], + [4, new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))], + [1, new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))], + [1, new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))], + [25, new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))], + ['ab', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))], - array(true, new BinaryNode('in', new ConstantNode('a'), $array)), - array(false, new BinaryNode('in', new ConstantNode('c'), $array)), - array(true, new BinaryNode('not in', new ConstantNode('c'), $array)), - array(false, new BinaryNode('not in', new ConstantNode('a'), $array)), + [true, new BinaryNode('in', new ConstantNode('a'), $array)], + [false, new BinaryNode('in', new ConstantNode('c'), $array)], + [true, new BinaryNode('not in', new ConstantNode('c'), $array)], + [false, new BinaryNode('not in', new ConstantNode('a'), $array)], - array(array(1, 2, 3), new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))), + [[1, 2, 3], new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))], - array(1, new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))), - ); + [1, new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))], + ]; } public function getCompileData() @@ -72,47 +72,47 @@ class BinaryNodeTest extends AbstractNodeTest $array->addElement(new ConstantNode('a')); $array->addElement(new ConstantNode('b')); - return array( - array('(true || false)', new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))), - array('(true || false)', new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))), - array('(true && false)', new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))), - array('(true && false)', new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))), + return [ + ['(true || false)', new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))], + ['(true || false)', new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))], + ['(true && false)', new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))], + ['(true && false)', new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))], - array('(2 & 4)', new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))), - array('(2 | 4)', new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))), - array('(2 ^ 4)', new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))), + ['(2 & 4)', new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))], + ['(2 | 4)', new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))], + ['(2 ^ 4)', new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))], - array('(1 < 2)', new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))), - array('(1 <= 2)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))), - array('(1 <= 1)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))), + ['(1 < 2)', new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 2)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 1)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))], - array('(1 > 2)', new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))), - array('(1 >= 2)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))), - array('(1 >= 1)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))), + ['(1 > 2)', new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 2)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 1)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))], - array('(true === true)', new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))), - array('(true !== true)', new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))), + ['(true === true)', new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))], + ['(true !== true)', new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))], - array('(2 == 1)', new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))), - array('(2 != 1)', new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))), + ['(2 == 1)', new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))], + ['(2 != 1)', new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))], - array('(1 - 2)', new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))), - array('(1 + 2)', new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))), - array('(2 * 2)', new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))), - array('(2 / 2)', new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))), - array('(5 % 2)', new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))), - array('pow(5, 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))), - array('("a" . "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))), + ['(1 - 2)', new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))], + ['(1 + 2)', new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))], + ['(2 * 2)', new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))], + ['(2 / 2)', new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))], + ['(5 % 2)', new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))], + ['pow(5, 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))], + ['("a" . "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))], - array('in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('in', new ConstantNode('a'), $array)), - array('in_array("c", array(0 => "a", 1 => "b"))', new BinaryNode('in', new ConstantNode('c'), $array)), - array('!in_array("c", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('c'), $array)), - array('!in_array("a", array(0 => "a", 1 => "b"))', new BinaryNode('not in', new ConstantNode('a'), $array)), + ['in_array("a", [0 => "a", 1 => "b"])', new BinaryNode('in', new ConstantNode('a'), $array)], + ['in_array("c", [0 => "a", 1 => "b"])', new BinaryNode('in', new ConstantNode('c'), $array)], + ['!in_array("c", [0 => "a", 1 => "b"])', new BinaryNode('not in', new ConstantNode('c'), $array)], + ['!in_array("a", [0 => "a", 1 => "b"])', new BinaryNode('not in', new ConstantNode('a'), $array)], - array('range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))), + ['range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))], - array('preg_match("/^[a-z]+/i\$/", "abc")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))), - ); + ['preg_match("/^[a-z]+/i\$/", "abc")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))], + ]; } public function getDumpData() @@ -121,46 +121,46 @@ class BinaryNodeTest extends AbstractNodeTest $array->addElement(new ConstantNode('a')); $array->addElement(new ConstantNode('b')); - return array( - array('(true or false)', new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))), - array('(true || false)', new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))), - array('(true and false)', new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))), - array('(true && false)', new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))), + return [ + ['(true or false)', new BinaryNode('or', new ConstantNode(true), new ConstantNode(false))], + ['(true || false)', new BinaryNode('||', new ConstantNode(true), new ConstantNode(false))], + ['(true and false)', new BinaryNode('and', new ConstantNode(true), new ConstantNode(false))], + ['(true && false)', new BinaryNode('&&', new ConstantNode(true), new ConstantNode(false))], - array('(2 & 4)', new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))), - array('(2 | 4)', new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))), - array('(2 ^ 4)', new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))), + ['(2 & 4)', new BinaryNode('&', new ConstantNode(2), new ConstantNode(4))], + ['(2 | 4)', new BinaryNode('|', new ConstantNode(2), new ConstantNode(4))], + ['(2 ^ 4)', new BinaryNode('^', new ConstantNode(2), new ConstantNode(4))], - array('(1 < 2)', new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))), - array('(1 <= 2)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))), - array('(1 <= 1)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))), + ['(1 < 2)', new BinaryNode('<', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 2)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(2))], + ['(1 <= 1)', new BinaryNode('<=', new ConstantNode(1), new ConstantNode(1))], - array('(1 > 2)', new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))), - array('(1 >= 2)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))), - array('(1 >= 1)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))), + ['(1 > 2)', new BinaryNode('>', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 2)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(2))], + ['(1 >= 1)', new BinaryNode('>=', new ConstantNode(1), new ConstantNode(1))], - array('(true === true)', new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))), - array('(true !== true)', new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))), + ['(true === true)', new BinaryNode('===', new ConstantNode(true), new ConstantNode(true))], + ['(true !== true)', new BinaryNode('!==', new ConstantNode(true), new ConstantNode(true))], - array('(2 == 1)', new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))), - array('(2 != 1)', new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))), + ['(2 == 1)', new BinaryNode('==', new ConstantNode(2), new ConstantNode(1))], + ['(2 != 1)', new BinaryNode('!=', new ConstantNode(2), new ConstantNode(1))], - array('(1 - 2)', new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))), - array('(1 + 2)', new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))), - array('(2 * 2)', new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))), - array('(2 / 2)', new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))), - array('(5 % 2)', new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))), - array('(5 ** 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))), - array('("a" ~ "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))), + ['(1 - 2)', new BinaryNode('-', new ConstantNode(1), new ConstantNode(2))], + ['(1 + 2)', new BinaryNode('+', new ConstantNode(1), new ConstantNode(2))], + ['(2 * 2)', new BinaryNode('*', new ConstantNode(2), new ConstantNode(2))], + ['(2 / 2)', new BinaryNode('/', new ConstantNode(2), new ConstantNode(2))], + ['(5 % 2)', new BinaryNode('%', new ConstantNode(5), new ConstantNode(2))], + ['(5 ** 2)', new BinaryNode('**', new ConstantNode(5), new ConstantNode(2))], + ['("a" ~ "b")', new BinaryNode('~', new ConstantNode('a'), new ConstantNode('b'))], - array('("a" in ["a", "b"])', new BinaryNode('in', new ConstantNode('a'), $array)), - array('("c" in ["a", "b"])', new BinaryNode('in', new ConstantNode('c'), $array)), - array('("c" not in ["a", "b"])', new BinaryNode('not in', new ConstantNode('c'), $array)), - array('("a" not in ["a", "b"])', new BinaryNode('not in', new ConstantNode('a'), $array)), + ['("a" in ["a", "b"])', new BinaryNode('in', new ConstantNode('a'), $array)], + ['("c" in ["a", "b"])', new BinaryNode('in', new ConstantNode('c'), $array)], + ['("c" not in ["a", "b"])', new BinaryNode('not in', new ConstantNode('c'), $array)], + ['("a" not in ["a", "b"])', new BinaryNode('not in', new ConstantNode('a'), $array)], - array('(1 .. 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))), + ['(1 .. 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))], - array('("abc" matches "/^[a-z]+/i$/")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))), - ); + ['("abc" matches "/^[a-z]+/i$/")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php index cbf9e8d4..13b7cbde 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConditionalNodeTest.php @@ -18,25 +18,25 @@ class ConditionalNodeTest extends AbstractNodeTest { public function getEvaluateData() { - return array( - array(1, new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))), - array(2, new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))), - ); + return [ + [1, new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))], + [2, new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))], + ]; } public function getCompileData() { - return array( - array('((true) ? (1) : (2))', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))), - array('((false) ? (1) : (2))', new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))), - ); + return [ + ['((true) ? (1) : (2))', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))], + ['((false) ? (1) : (2))', new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))], + ]; } public function getDumpData() { - return array( - array('(true ? 1 : 2)', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))), - array('(false ? 1 : 2)', new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))), - ); + return [ + ['(true ? 1 : 2)', new ConditionalNode(new ConstantNode(true), new ConstantNode(1), new ConstantNode(2))], + ['(false ? 1 : 2)', new ConditionalNode(new ConstantNode(false), new ConstantNode(1), new ConstantNode(2))], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php index af79a91c..fee9f5bf 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/ConstantNodeTest.php @@ -17,44 +17,44 @@ class ConstantNodeTest extends AbstractNodeTest { public function getEvaluateData() { - return array( - array(false, new ConstantNode(false)), - array(true, new ConstantNode(true)), - array(null, new ConstantNode(null)), - array(3, new ConstantNode(3)), - array(3.3, new ConstantNode(3.3)), - array('foo', new ConstantNode('foo')), - array(array(1, 'b' => 'a'), new ConstantNode(array(1, 'b' => 'a'))), - ); + return [ + [false, new ConstantNode(false)], + [true, new ConstantNode(true)], + [null, new ConstantNode(null)], + [3, new ConstantNode(3)], + [3.3, new ConstantNode(3.3)], + ['foo', new ConstantNode('foo')], + [[1, 'b' => 'a'], new ConstantNode([1, 'b' => 'a'])], + ]; } public function getCompileData() { - return array( - array('false', new ConstantNode(false)), - array('true', new ConstantNode(true)), - array('null', new ConstantNode(null)), - array('3', new ConstantNode(3)), - array('3.3', new ConstantNode(3.3)), - array('"foo"', new ConstantNode('foo')), - array('array(0 => 1, "b" => "a")', new ConstantNode(array(1, 'b' => 'a'))), - ); + return [ + ['false', new ConstantNode(false)], + ['true', new ConstantNode(true)], + ['null', new ConstantNode(null)], + ['3', new ConstantNode(3)], + ['3.3', new ConstantNode(3.3)], + ['"foo"', new ConstantNode('foo')], + ['[0 => 1, "b" => "a"]', new ConstantNode([1, 'b' => 'a'])], + ]; } public function getDumpData() { - return array( - array('false', new ConstantNode(false)), - array('true', new ConstantNode(true)), - array('null', new ConstantNode(null)), - array('3', new ConstantNode(3)), - array('3.3', new ConstantNode(3.3)), - array('"foo"', new ConstantNode('foo')), - array('foo', new ConstantNode('foo', true)), - array('{0: 1, "b": "a", 1: true}', new ConstantNode(array(1, 'b' => 'a', true))), - array('{"a\\"b": "c", "a\\\\b": "d"}', new ConstantNode(array('a"b' => 'c', 'a\\b' => 'd'))), - array('["c", "d"]', new ConstantNode(array('c', 'd'))), - array('{"a": ["b"]}', new ConstantNode(array('a' => array('b')))), - ); + return [ + ['false', new ConstantNode(false)], + ['true', new ConstantNode(true)], + ['null', new ConstantNode(null)], + ['3', new ConstantNode(3)], + ['3.3', new ConstantNode(3.3)], + ['"foo"', new ConstantNode('foo')], + ['foo', new ConstantNode('foo', true)], + ['{0: 1, "b": "a", 1: true}', new ConstantNode([1, 'b' => 'a', true])], + ['{"a\\"b": "c", "a\\\\b": "d"}', new ConstantNode(['a"b' => 'c', 'a\\b' => 'd'])], + ['["c", "d"]', new ConstantNode(['c', 'd'])], + ['{"a": ["b"]}', new ConstantNode(['a' => ['b']])], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php index 8d6f92a9..c6cb02c1 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/FunctionNodeTest.php @@ -11,42 +11,42 @@ namespace Symfony\Component\ExpressionLanguage\Tests\Node; -use Symfony\Component\ExpressionLanguage\Node\FunctionNode; use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\FunctionNode; use Symfony\Component\ExpressionLanguage\Node\Node; class FunctionNodeTest extends AbstractNodeTest { public function getEvaluateData() { - return array( - array('bar', new FunctionNode('foo', new Node(array(new ConstantNode('bar')))), array(), array('foo' => $this->getCallables())), - ); + return [ + ['bar', new FunctionNode('foo', new Node([new ConstantNode('bar')])), [], ['foo' => $this->getCallables()]], + ]; } public function getCompileData() { - return array( - array('foo("bar")', new FunctionNode('foo', new Node(array(new ConstantNode('bar')))), array('foo' => $this->getCallables())), - ); + return [ + ['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')])), ['foo' => $this->getCallables()]], + ]; } public function getDumpData() { - return array( - array('foo("bar")', new FunctionNode('foo', new Node(array(new ConstantNode('bar')))), array('foo' => $this->getCallables())), - ); + return [ + ['foo("bar")', new FunctionNode('foo', new Node([new ConstantNode('bar')])), ['foo' => $this->getCallables()]], + ]; } protected function getCallables() { - return array( + return [ 'compiler' => function ($arg) { return sprintf('foo(%s)', $arg); }, 'evaluator' => function ($variables, $arg) { return $arg; }, - ); + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php index cf7cd7a0..c790f33a 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/GetAttrNodeTest.php @@ -12,49 +12,49 @@ namespace Symfony\Component\ExpressionLanguage\Tests\Node; use Symfony\Component\ExpressionLanguage\Node\ArrayNode; -use Symfony\Component\ExpressionLanguage\Node\NameNode; -use Symfony\Component\ExpressionLanguage\Node\GetAttrNode; use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\GetAttrNode; +use Symfony\Component\ExpressionLanguage\Node\NameNode; class GetAttrNodeTest extends AbstractNodeTest { public function getEvaluateData() { - return array( - array('b', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), array('foo' => array('b' => 'a', 'b'))), - array('a', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), array('foo' => array('b' => 'a', 'b'))), + return [ + ['b', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b']]], + ['a', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b']]], - array('bar', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), array('foo' => new Obj())), + ['bar', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]], - array('baz', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), array('foo' => new Obj())), - array('a', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), array('foo' => array('b' => 'a', 'b'), 'index' => 'b')), - ); + ['baz', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]], + ['a', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL), ['foo' => ['b' => 'a', 'b'], 'index' => 'b']], + ]; } public function getCompileData() { - return array( - array('$foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)), - array('$foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)), + return [ + ['$foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ['$foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], - array('$foo->foo', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), array('foo' => new Obj())), + ['$foo->foo', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]], - array('$foo->foo(array("b" => "a", 0 => "b"))', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), array('foo' => new Obj())), - array('$foo[$index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)), - ); + ['$foo->foo(["b" => "a", 0 => "b"])', new GetAttrNode(new NameNode('foo'), new ConstantNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]], + ['$foo[$index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ]; } public function getDumpData() { - return array( - array('foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)), - array('foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)), + return [ + ['foo[0]', new GetAttrNode(new NameNode('foo'), new ConstantNode(0), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ['foo["b"]', new GetAttrNode(new NameNode('foo'), new ConstantNode('b'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], - array('foo.foo', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), array('foo' => new Obj())), + ['foo.foo', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), $this->getArrayNode(), GetAttrNode::PROPERTY_CALL), ['foo' => new Obj()]], - array('foo.foo({"b": "a", 0: "b"})', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), array('foo' => new Obj())), - array('foo[index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)), - ); + ['foo.foo({"b": "a", 0: "b"})', new GetAttrNode(new NameNode('foo'), new NameNode('foo'), $this->getArrayNode(), GetAttrNode::METHOD_CALL), ['foo' => new Obj()]], + ['foo[index]', new GetAttrNode(new NameNode('foo'), new NameNode('index'), $this->getArrayNode(), GetAttrNode::ARRAY_CALL)], + ]; } protected function getArrayNode() diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php index 5fa2c37f..a30c27b8 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NameNodeTest.php @@ -17,22 +17,22 @@ class NameNodeTest extends AbstractNodeTest { public function getEvaluateData() { - return array( - array('bar', new NameNode('foo'), array('foo' => 'bar')), - ); + return [ + ['bar', new NameNode('foo'), ['foo' => 'bar']], + ]; } public function getCompileData() { - return array( - array('$foo', new NameNode('foo')), - ); + return [ + ['$foo', new NameNode('foo')], + ]; } public function getDumpData() { - return array( - array('foo', new NameNode('foo')), - ); + return [ + ['foo', new NameNode('foo')], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NodeTest.php index 0f35b5fe..351da051 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/NodeTest.php @@ -12,14 +12,14 @@ namespace Symfony\Component\ExpressionLanguage\Tests\Node; use PHPUnit\Framework\TestCase; -use Symfony\Component\ExpressionLanguage\Node\Node; use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\Node; class NodeTest extends TestCase { public function testToString() { - $node = new Node(array(new ConstantNode('foo'))); + $node = new Node([new ConstantNode('foo')]); $this->assertEquals(<<<'EOF' Node( @@ -31,7 +31,7 @@ EOF public function testSerialization() { - $node = new Node(array('foo' => 'bar'), array('bar' => 'foo')); + $node = new Node(['foo' => 'bar'], ['bar' => 'foo']); $serializedNode = serialize($node); $unserializedNode = unserialize($serializedNode); diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php index ae2e3eee..bac75d24 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/Node/UnaryNodeTest.php @@ -11,38 +11,38 @@ namespace Symfony\Component\ExpressionLanguage\Tests\Node; -use Symfony\Component\ExpressionLanguage\Node\UnaryNode; use Symfony\Component\ExpressionLanguage\Node\ConstantNode; +use Symfony\Component\ExpressionLanguage\Node\UnaryNode; class UnaryNodeTest extends AbstractNodeTest { public function getEvaluateData() { - return array( - array(-1, new UnaryNode('-', new ConstantNode(1))), - array(3, new UnaryNode('+', new ConstantNode(3))), - array(false, new UnaryNode('!', new ConstantNode(true))), - array(false, new UnaryNode('not', new ConstantNode(true))), - ); + return [ + [-1, new UnaryNode('-', new ConstantNode(1))], + [3, new UnaryNode('+', new ConstantNode(3))], + [false, new UnaryNode('!', new ConstantNode(true))], + [false, new UnaryNode('not', new ConstantNode(true))], + ]; } public function getCompileData() { - return array( - array('(-1)', new UnaryNode('-', new ConstantNode(1))), - array('(+3)', new UnaryNode('+', new ConstantNode(3))), - array('(!true)', new UnaryNode('!', new ConstantNode(true))), - array('(!true)', new UnaryNode('not', new ConstantNode(true))), - ); + return [ + ['(-1)', new UnaryNode('-', new ConstantNode(1))], + ['(+3)', new UnaryNode('+', new ConstantNode(3))], + ['(!true)', new UnaryNode('!', new ConstantNode(true))], + ['(!true)', new UnaryNode('not', new ConstantNode(true))], + ]; } public function getDumpData() { - return array( - array('(- 1)', new UnaryNode('-', new ConstantNode(1))), - array('(+ 3)', new UnaryNode('+', new ConstantNode(3))), - array('(! true)', new UnaryNode('!', new ConstantNode(true))), - array('(not true)', new UnaryNode('not', new ConstantNode(true))), - ); + return [ + ['(- 1)', new UnaryNode('-', new ConstantNode(1))], + ['(+ 3)', new UnaryNode('+', new ConstantNode(3))], + ['(! true)', new UnaryNode('!', new ConstantNode(true))], + ['(not true)', new UnaryNode('not', new ConstantNode(true))], + ]; } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php index 44731611..f82af92e 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserCache/ParserCacheAdapterTest.php @@ -12,9 +12,9 @@ namespace Symfony\Component\ExpressionLanguage\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Component\ExpressionLanguage\Node\Node; use Symfony\Component\ExpressionLanguage\ParsedExpression; use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheAdapter; -use Symfony\Component\ExpressionLanguage\Node\Node; /** * @group legacy @@ -38,8 +38,8 @@ class ParserCacheAdapterTest extends TestCase $cacheItem = $parserCacheAdapter->getItem($key); - $this->assertEquals($cacheItem->get(), $value); - $this->assertEquals($cacheItem->isHit(), true); + $this->assertEquals($value, $cacheItem->get()); + $this->assertTrue($cacheItem->isHit()); } public function testSave() @@ -47,7 +47,7 @@ class ParserCacheAdapterTest extends TestCase $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); $key = 'key'; - $value = new ParsedExpression('1 + 1', new Node(array(), array())); + $value = new ParsedExpression('1 + 1', new Node([], [])); $parserCacheAdapter = new ParserCacheAdapter($poolMock); $poolMock @@ -68,14 +68,14 @@ class ParserCacheAdapterTest extends TestCase ->willReturn($value) ; - $cacheItem = $parserCacheAdapter->save($cacheItemMock); + $parserCacheAdapter->save($cacheItemMock); } public function testGetItems() { $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $parserCacheAdapter = new ParserCacheAdapter($poolMock); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->getItems(); } @@ -85,7 +85,7 @@ class ParserCacheAdapterTest extends TestCase $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $key = 'key'; $parserCacheAdapter = new ParserCacheAdapter($poolMock); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->hasItem($key); } @@ -94,7 +94,7 @@ class ParserCacheAdapterTest extends TestCase { $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $parserCacheAdapter = new ParserCacheAdapter($poolMock); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->clear(); } @@ -104,7 +104,7 @@ class ParserCacheAdapterTest extends TestCase $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $key = 'key'; $parserCacheAdapter = new ParserCacheAdapter($poolMock); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->deleteItem($key); } @@ -112,9 +112,9 @@ class ParserCacheAdapterTest extends TestCase public function testDeleteItems() { $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); - $keys = array('key'); + $keys = ['key']; $parserCacheAdapter = new ParserCacheAdapter($poolMock); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->deleteItems($keys); } @@ -124,7 +124,7 @@ class ParserCacheAdapterTest extends TestCase $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $parserCacheAdapter = new ParserCacheAdapter($poolMock); $cacheItemMock = $this->getMockBuilder('Psr\Cache\CacheItemInterface')->getMock(); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->saveDeferred($cacheItemMock); } @@ -133,7 +133,7 @@ class ParserCacheAdapterTest extends TestCase { $poolMock = $this->getMockBuilder('Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface')->getMock(); $parserCacheAdapter = new ParserCacheAdapter($poolMock); - $this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}(\BadMethodCallException::class); + $this->expectException(\BadMethodCallException::class); $parserCacheAdapter->commit(); } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserTest.php b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserTest.php index 11464abd..2d5a0a6c 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserTest.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Tests/ParserTest.php @@ -12,41 +12,37 @@ namespace Symfony\Component\ExpressionLanguage\Tests; use PHPUnit\Framework\TestCase; -use Symfony\Component\ExpressionLanguage\Parser; use Symfony\Component\ExpressionLanguage\Lexer; use Symfony\Component\ExpressionLanguage\Node; +use Symfony\Component\ExpressionLanguage\Parser; class ParserTest extends TestCase { - /** - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError - * @expectedExceptionMessage Variable "foo" is not valid around position 1 for expression `foo`. - */ public function testParseWithInvalidName() { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Variable "foo" is not valid around position 1 for expression `foo`.'); $lexer = new Lexer(); - $parser = new Parser(array()); + $parser = new Parser([]); $parser->parse($lexer->tokenize('foo')); } - /** - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError - * @expectedExceptionMessage Variable "foo" is not valid around position 1 for expression `foo`. - */ public function testParseWithZeroInNames() { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Variable "foo" is not valid around position 1 for expression `foo`.'); $lexer = new Lexer(); - $parser = new Parser(array()); - $parser->parse($lexer->tokenize('foo'), array(0)); + $parser = new Parser([]); + $parser->parse($lexer->tokenize('foo'), [0]); } /** * @dataProvider getParseData */ - public function testParse($node, $expression, $names = array()) + public function testParse($node, $expression, $names = []) { $lexer = new Lexer(); - $parser = new Parser(array()); + $parser = new Parser([]); $this->assertEquals($node, $parser->parse($lexer->tokenize($expression), $names)); } @@ -57,63 +53,66 @@ class ParserTest extends TestCase $arguments->addElement(new Node\ConstantNode(2)); $arguments->addElement(new Node\ConstantNode(true)); - return array( - array( + $arrayNode = new Node\ArrayNode(); + $arrayNode->addElement(new Node\NameNode('bar')); + + return [ + [ new Node\NameNode('a'), 'a', - array('a'), - ), - array( + ['a'], + ], + [ new Node\ConstantNode('a'), '"a"', - ), - array( + ], + [ new Node\ConstantNode(3), '3', - ), - array( + ], + [ new Node\ConstantNode(false), 'false', - ), - array( + ], + [ new Node\ConstantNode(true), 'true', - ), - array( + ], + [ new Node\ConstantNode(null), 'null', - ), - array( + ], + [ new Node\UnaryNode('-', new Node\ConstantNode(3)), '-3', - ), - array( + ], + [ new Node\BinaryNode('-', new Node\ConstantNode(3), new Node\ConstantNode(3)), '3 - 3', - ), - array( + ], + [ new Node\BinaryNode('*', new Node\BinaryNode('-', new Node\ConstantNode(3), new Node\ConstantNode(3)), new Node\ConstantNode(2) ), '(3 - 3) * 2', - ), - array( + ], + [ new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode('bar', true), new Node\ArgumentsNode(), Node\GetAttrNode::PROPERTY_CALL), 'foo.bar', - array('foo'), - ), - array( + ['foo'], + ], + [ new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode('bar', true), new Node\ArgumentsNode(), Node\GetAttrNode::METHOD_CALL), 'foo.bar()', - array('foo'), - ), - array( + ['foo'], + ], + [ new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode('not', true), new Node\ArgumentsNode(), Node\GetAttrNode::METHOD_CALL), 'foo.not()', - array('foo'), - ), - array( + ['foo'], + ], + [ new Node\GetAttrNode( new Node\NameNode('foo'), new Node\ConstantNode('bar', true), @@ -121,24 +120,24 @@ class ParserTest extends TestCase Node\GetAttrNode::METHOD_CALL ), 'foo.bar("arg1", 2, true)', - array('foo'), - ), - array( + ['foo'], + ], + [ new Node\GetAttrNode(new Node\NameNode('foo'), new Node\ConstantNode(3), new Node\ArgumentsNode(), Node\GetAttrNode::ARRAY_CALL), 'foo[3]', - array('foo'), - ), - array( + ['foo'], + ], + [ new Node\ConditionalNode(new Node\ConstantNode(true), new Node\ConstantNode(true), new Node\ConstantNode(false)), 'true ? true : false', - ), - array( + ], + [ new Node\BinaryNode('matches', new Node\ConstantNode('foo'), new Node\ConstantNode('/foo/')), '"foo" matches "/foo/"', - ), + ], // chained calls - array( + [ $this->createGetAttrNode( $this->createGetAttrNode( $this->createGetAttrNode( @@ -147,15 +146,45 @@ class ParserTest extends TestCase 'baz', Node\GetAttrNode::PROPERTY_CALL), '3', Node\GetAttrNode::ARRAY_CALL), 'foo.bar().foo().baz[3]', - array('foo'), - ), + ['foo'], + ], - array( + [ new Node\NameNode('foo'), 'bar', - array('foo' => 'bar'), - ), - ); + ['foo' => 'bar'], + ], + + // Operators collisions + [ + new Node\BinaryNode( + 'in', + new Node\GetAttrNode( + new Node\NameNode('foo'), + new Node\ConstantNode('not', true), + new Node\ArgumentsNode(), + Node\GetAttrNode::PROPERTY_CALL + ), + $arrayNode + ), + 'foo.not in [bar]', + ['foo', 'bar'], + ], + [ + new Node\BinaryNode( + 'or', + new Node\UnaryNode('not', new Node\NameNode('foo')), + new Node\GetAttrNode( + new Node\NameNode('foo'), + new Node\ConstantNode('not', true), + new Node\ArgumentsNode(), + Node\GetAttrNode::PROPERTY_CALL + ) + ), + 'not foo or foo.not', + ['foo'], + ], + ]; } private function createGetAttrNode($node, $item, $type) @@ -165,46 +194,44 @@ class ParserTest extends TestCase /** * @dataProvider getInvalidPostfixData - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError */ - public function testParseWithInvalidPostfixData($expr, $names = array()) + public function testParseWithInvalidPostfixData($expr, $names = []) { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); $lexer = new Lexer(); - $parser = new Parser(array()); + $parser = new Parser([]); $parser->parse($lexer->tokenize($expr), $names); } public function getInvalidPostfixData() { - return array( - array( + return [ + [ 'foo."#"', - array('foo'), - ), - array( + ['foo'], + ], + [ 'foo."bar"', - array('foo'), - ), - array( + ['foo'], + ], + [ 'foo.**', - array('foo'), - ), - array( + ['foo'], + ], + [ 'foo.123', - array('foo'), - ), - ); + ['foo'], + ], + ]; } - /** - * @expectedException \Symfony\Component\ExpressionLanguage\SyntaxError - * @expectedExceptionMessage Did you mean "baz"? - */ public function testNameProposal() { + $this->expectException('Symfony\Component\ExpressionLanguage\SyntaxError'); + $this->expectExceptionMessage('Did you mean "baz"?'); $lexer = new Lexer(); - $parser = new Parser(array()); + $parser = new Parser([]); - $parser->parse($lexer->tokenize('foo > bar'), array('foo', 'baz')); + $parser->parse($lexer->tokenize('foo > bar'), ['foo', 'baz']); } } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/Token.php b/advancedcontentfilter/vendor/symfony/expression-language/Token.php index 4517335b..60dc32d7 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/Token.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/Token.php @@ -54,7 +54,7 @@ class Token /** * Tests the current token for a type and/or a value. * - * @param array|int $type The type to test + * @param string $type The type to test * @param string|null $value The token value * * @return bool diff --git a/advancedcontentfilter/vendor/symfony/expression-language/TokenStream.php b/advancedcontentfilter/vendor/symfony/expression-language/TokenStream.php index 9096b183..09d3854e 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/TokenStream.php +++ b/advancedcontentfilter/vendor/symfony/expression-language/TokenStream.php @@ -53,7 +53,7 @@ class TokenStream ++$this->position; if (!isset($this->tokens[$this->position])) { - throw new SyntaxError('Unexpected end of expression', $this->current->cursor, $this->expression); + throw new SyntaxError('Unexpected end of expression.', $this->current->cursor, $this->expression); } $this->current = $this->tokens[$this->position]; @@ -70,7 +70,7 @@ class TokenStream { $token = $this->current; if (!$token->test($type, $value)) { - throw new SyntaxError(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s)', $message ? $message.'. ' : '', $token->type, $token->value, $type, $value ? sprintf(' with value "%s"', $value) : ''), $token->cursor, $this->expression); + throw new SyntaxError(sprintf('%sUnexpected token "%s" of value "%s" ("%s" expected%s).', $message ? $message.'. ' : '', $token->type, $token->value, $type, $value ? sprintf(' with value "%s"', $value) : ''), $token->cursor, $this->expression); } $this->next(); } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/composer.json b/advancedcontentfilter/vendor/symfony/expression-language/composer.json index 5f662ffd..5d5825b9 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/composer.json +++ b/advancedcontentfilter/vendor/symfony/expression-language/composer.json @@ -17,7 +17,8 @@ ], "require": { "php": "^5.5.9|>=7.0.8", - "symfony/cache": "~3.1|~4.0" + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" }, "autoload": { "psr-4": { "Symfony\\Component\\ExpressionLanguage\\": "" }, @@ -25,10 +26,5 @@ "/Tests/" ] }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "3.4-dev" - } - } + "minimum-stability": "dev" } diff --git a/advancedcontentfilter/vendor/symfony/expression-language/phpunit.xml.dist b/advancedcontentfilter/vendor/symfony/expression-language/phpunit.xml.dist index 517322fb..ae84dcd9 100644 --- a/advancedcontentfilter/vendor/symfony/expression-language/phpunit.xml.dist +++ b/advancedcontentfilter/vendor/symfony/expression-language/phpunit.xml.dist @@ -1,7 +1,7 @@ $v) { if (!apc_add($k, $v, $ttl)) { $errors[$k] = -1; @@ -39,11 +39,11 @@ final class Apcu public static function apcu_store($key, $var = null, $ttl = 0) { - if (!is_array($key)) { + if (!\is_array($key)) { return apc_store($key, $var, $ttl); } - $errors = array(); + $errors = []; foreach ($key as $k => $v) { if (!apc_store($k, $v, $ttl)) { $errors[$k] = -1; @@ -55,11 +55,11 @@ final class Apcu public static function apcu_exists($keys) { - if (!is_array($keys)) { + if (!\is_array($keys)) { return apc_exists($keys); } - $existing = array(); + $existing = []; foreach ($keys as $k) { if (apc_exists($k)) { $existing[$k] = true; @@ -71,12 +71,12 @@ final class Apcu public static function apcu_fetch($key, &$success = null) { - if (!is_array($key)) { + if (!\is_array($key)) { return apc_fetch($key, $success); } $succeeded = true; - $values = array(); + $values = []; foreach ($key as $k) { $v = apc_fetch($k, $success); if ($success) { @@ -92,7 +92,7 @@ final class Apcu public static function apcu_delete($key) { - if (!is_array($key)) { + if (!\is_array($key)) { return apc_delete($key); } diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE b/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE index 24fa32c2..6e3afce6 100644 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE +++ b/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2018 Fabien Potencier +Copyright (c) 2015-present Fabien Potencier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md b/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md index e614bcab..57f4bf6b 100644 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md +++ b/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md @@ -1,10 +1,10 @@ Symfony Polyfill / APCu ======================== -This component provides `apcu_*` functions and the `APCUIterator` class to users of the legacy APC extension. +This component provides `apcu_*` functions and the `APCuIterator` class to users of the legacy APC extension. More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md). +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). License ======= diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php index 305183b6..96b2706a 100644 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php +++ b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php @@ -15,32 +15,67 @@ if (!extension_loaded('apc') && !extension_loaded('apcu')) { return; } -if (!function_exists('apcu_add')) { - if (extension_loaded('Zend Data Cache')) { - function apcu_add($key, $var = null, $ttl = 0) { return p\Apcu::apcu_add($key, $var, $ttl); } - function apcu_delete($key) { return p\Apcu::apcu_delete($key); } - function apcu_exists($keys) { return p\Apcu::apcu_exists($keys); } - function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); } - function apcu_store($key, $var = null, $ttl = 0) { return p\Apcu::apcu_store($key, $var, $ttl); } - } else { - function apcu_add($key, $var = null, $ttl = 0) { return apc_add($key, $var, $ttl); } - function apcu_delete($key) { return apc_delete($key); } - function apcu_exists($keys) { return apc_exists($keys); } - function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } - function apcu_store($key, $var = null, $ttl = 0) { return apc_store($key, $var, $ttl); } +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (extension_loaded('Zend Data Cache')) { + if (!function_exists('apcu_add')) { + function apcu_add($key, $value = null, $ttl = 0) { return p\Apcu::apcu_add($key, $value, $ttl); } } + if (!function_exists('apcu_delete')) { + function apcu_delete($key) { return p\Apcu::apcu_delete($key); } + } + if (!function_exists('apcu_exists')) { + function apcu_exists($key) { return p\Apcu::apcu_exists($key); } + } + if (!function_exists('apcu_fetch')) { + function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); } + } + if (!function_exists('apcu_store')) { + function apcu_store($key, $value = null, $ttl = 0) { return p\Apcu::apcu_store($key, $value, $ttl); } + } +} else { + if (!function_exists('apcu_add')) { + function apcu_add($key, $value = null, $ttl = 0) { return apc_add($key, $value, $ttl); } + } + if (!function_exists('apcu_delete')) { + function apcu_delete($key) { return apc_delete($key); } + } + if (!function_exists('apcu_exists')) { + function apcu_exists($key) { return apc_exists($key); } + } + if (!function_exists('apcu_fetch')) { + function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } + } + if (!function_exists('apcu_store')) { + function apcu_store($key, $value = null, $ttl = 0) { return apc_store($key, $value, $ttl); } + } +} + +if (!function_exists('apcu_cache_info')) { function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } +} +if (!function_exists('apcu_cas')) { function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } +} +if (!function_exists('apcu_clear_cache')) { function apcu_clear_cache() { return apc_clear_cache('user'); } +} +if (!function_exists('apcu_dec')) { function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } +} +if (!function_exists('apcu_inc')) { function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } +} +if (!function_exists('apcu_sma_info')) { function apcu_sma_info($limited = false) { return apc_sma_info($limited); } } -if (!class_exists('APCUIterator', false) && class_exists('APCIterator', false)) { - class APCUIterator extends APCIterator +if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { + class APCuIterator extends APCIterator { - public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) + public function __construct($search = null, $format = \APC_ITER_ALL, $chunk_size = 100, $list = \APC_LIST_ACTIVE) { parent::__construct('user', $search, $format, $chunk_size, $list); } diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php new file mode 100644 index 00000000..69e9f160 --- /dev/null +++ b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php @@ -0,0 +1,75 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Apcu as p; + +if (extension_loaded('Zend Data Cache')) { + if (!function_exists('apcu_add')) { + function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_add($key, $value, (int) $ttl); } + } + if (!function_exists('apcu_delete')) { + function apcu_delete($key): array|bool { return p\Apcu::apcu_delete($key); } + } + if (!function_exists('apcu_exists')) { + function apcu_exists($key): array|bool { return p\Apcu::apcu_exists($key); } + } + if (!function_exists('apcu_fetch')) { + function apcu_fetch($key, &$success = null): mixed { return p\Apcu::apcu_fetch($key, $success); } + } + if (!function_exists('apcu_store')) { + function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_store($key, $value, (int) $ttl); } + } +} else { + if (!function_exists('apcu_add')) { + function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return apc_add($key, $value, (int) $ttl); } + } + if (!function_exists('apcu_delete')) { + function apcu_delete($key): array|bool { return apc_delete($key); } + } + if (!function_exists('apcu_exists')) { + function apcu_exists($key): array|bool { return apc_exists($key); } + } + if (!function_exists('apcu_fetch')) { + function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } + } + if (!function_exists('apcu_store')) { + function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return apc_store($key, $value, (int) $ttl); } + } +} + +if (!function_exists('apcu_cache_info')) { + function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } +} +if (!function_exists('apcu_cas')) { + function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } +} +if (!function_exists('apcu_clear_cache')) { + function apcu_clear_cache() { return apc_clear_cache('user'); } +} +if (!function_exists('apcu_dec')) { + function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } +} +if (!function_exists('apcu_inc')) { + function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } +} +if (!function_exists('apcu_sma_info')) { + function apcu_sma_info($limited = false) { return apc_sma_info($limited); } +} + +if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { + class APCuIterator extends APCIterator + { + public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) + { + parent::__construct('user', $search, $format, $chunk_size, $list); + } + } +} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json b/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json index 54ea2b85..e92524f3 100644 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json +++ b/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "autoload": { "psr-4": { "Symfony\\Polyfill\\Apcu\\": "" }, @@ -25,7 +25,11 @@ "minimum-stability": "dev", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } } } From 8b35c9fddba1cd7695a33ce4d9aa5e2d9dd312b2 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 22 Jan 2024 18:01:51 +0000 Subject: [PATCH 008/294] Tesseract: Improved detection --- tesseract/tesseract.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php index 3c61273f..b3e1feb6 100644 --- a/tesseract/tesseract.php +++ b/tesseract/tesseract.php @@ -24,6 +24,10 @@ function tesseract_ocr_detection(&$media) { $ocr = new TesseractOCR(); try { + $languages = $ocr->availableLanguages(); + if ($languages) { + $ocr->lang(implode('+', $languages)); + } $ocr->tempDir(System::getTempPath()); $ocr->imageData($media['img_str'], strlen($media['img_str'])); $media['description'] = $ocr->run(); From c9f985d8424c3410cf85b9636ad4d3df2ea2c8a7 Mon Sep 17 00:00:00 2001 From: Hannes Heute Date: Fri, 2 Feb 2024 14:08:06 +0100 Subject: [PATCH 009/294] remove .php from openstreetmap server in config to fix created links --- openstreetmap/config/openstreetmap.config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstreetmap/config/openstreetmap.config.php b/openstreetmap/config/openstreetmap.config.php index c649da5f..d633fd26 100644 --- a/openstreetmap/config/openstreetmap.config.php +++ b/openstreetmap/config/openstreetmap.config.php @@ -10,7 +10,7 @@ return [ 'tmsserver' => 'https://www.openstreetmap.org', // nomserver (String) - 'nomserver' => 'https://nominatim.openstreetmap.org/search.php', + 'nomserver' => 'https://nominatim.openstreetmap.org/search', // zoom (Integer) // The default zoom level on the map. From 84fc5ba9220f393d75ad0cb110260e458082ae0b Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 10 Feb 2024 12:00:36 +0000 Subject: [PATCH 010/294] Markdown: Avoid problems with [*] BBCode element --- markdown/markdown.php | 1 + 1 file changed, 1 insertion(+) diff --git a/markdown/markdown.php b/markdown/markdown.php index 236fb297..6f459244 100644 --- a/markdown/markdown.php +++ b/markdown/markdown.php @@ -64,6 +64,7 @@ function markdown_post_local_start(&$request) { // (right chevrons are used for quoting in Markdown) // See https://github.com/friendica/friendica/issues/10634 $text = strtr($text, ['<' => '<']); + $text = str_replace('[*]', '[li]', $text); return Markdown::toBBCode($text); }); From f678468d429b597ce5ff42d6979fc8aa370d8fe8 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 16 Feb 2024 02:29:12 +0000 Subject: [PATCH 011/294] Bluesky/Twitter: New parameter added for rhe picture creation --- bluesky/bluesky.php | 2 +- twitter/twitter.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index a2c85ad3..fe1faab1 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -896,7 +896,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass $retrial = Worker::getRetrial(); $content = Photo::getImageForPhoto($photo); - $picture = new Image($content, $photo['type']); + $picture = new Image($content, $photo['type'], $photo['filename']); $height = $picture->getHeight(); $width = $picture->getWidth(); $size = strlen($content); diff --git a/twitter/twitter.php b/twitter/twitter.php index b01345b7..11c163ef 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -308,7 +308,7 @@ function twitter_upload_image(int $uid, array $image, int $retrial) $picturedata = Photo::getImageForPhoto($photo); - $picture = new Image($picturedata, $photo['type']); + $picture = new Image($picturedata, $photo['type'], $photo['filename']); $height = $picture->getHeight(); $width = $picture->getWidth(); $size = strlen($picturedata); From 9208fd46a4afefd9c2789bd866585e29f425705b Mon Sep 17 00:00:00 2001 From: Morgan McMillian Date: Tue, 20 Feb 2024 17:53:21 -0800 Subject: [PATCH 012/294] Pnut: add connector for pnut.io --- pnut/LICENSE | 662 +++++++ pnut/README.md | 5 + pnut/lib/LICENSE | 24 + pnut/lib/phpnut.php | 2504 +++++++++++++++++++++++++ pnut/lib/phpnutException.php | 5 + pnut/pnut.php | 293 +++ pnut/pnut.svg | 1 + pnut/templates/connector_settings.tpl | 12 + 8 files changed, 3506 insertions(+) create mode 100644 pnut/LICENSE create mode 100644 pnut/README.md create mode 100644 pnut/lib/LICENSE create mode 100644 pnut/lib/phpnut.php create mode 100644 pnut/lib/phpnutException.php create mode 100644 pnut/pnut.php create mode 100644 pnut/pnut.svg create mode 100644 pnut/templates/connector_settings.tpl diff --git a/pnut/LICENSE b/pnut/LICENSE new file mode 100644 index 00000000..fe6b9036 --- /dev/null +++ b/pnut/LICENSE @@ -0,0 +1,662 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. + diff --git a/pnut/README.md b/pnut/README.md new file mode 100644 index 00000000..d935efe7 --- /dev/null +++ b/pnut/README.md @@ -0,0 +1,5 @@ +# Pnut connector + +With this addon to friendica you can give your users the possibility to post their *public* messages to pnut.io. + +No setup is needed for the admins to make it work for their users. diff --git a/pnut/lib/LICENSE b/pnut/lib/LICENSE new file mode 100644 index 00000000..579599a8 --- /dev/null +++ b/pnut/lib/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2013, Josh Dolitsky +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Josh Dolitsky nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL TRAVIS RICHARDSON BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/pnut/lib/phpnut.php b/pnut/lib/phpnut.php new file mode 100644 index 00000000..303a860b --- /dev/null +++ b/pnut/lib/phpnut.php @@ -0,0 +1,2504 @@ +_clientId = $client_id_or_token; + $this->_clientSecret = $client_secret; + } else { + $this->_accessToken = $client_id_or_token; + } + + // if the digicert certificate exists in the same folder as this file, + // remember that fact for later + if (file_exists(__DIR__ . '/DigiCertHighAssuranceEVRootCA.pem')) { + $this->_sslCA = __DIR__ . '/DigiCertHighAssuranceEVRootCA.pem'; + } + } + + /** + * Set whether or not to strip Envelope Response (meta) information + * This option will be deprecated in the future. Is it to allow + * a stepped migration path between code expecting the old behavior + * and new behavior. When not stripped, you still can use the proper + * method to pull the meta information. Please start converting your code ASAP + */ + public function includeResponseEnvelope(): void + { + $this->_stripResponseEnvelope = false; + } + + /** + * Construct the proper Auth URL for the user to visit and either grant + * or not access to your app. Usually you would place this as a link for + * the user to client, or a redirect to send them to the auth URL. + * Also can be called after authentication for additional scopes + * @param string $callbackUri Where you want the user to be directed + * after authenticating with pnut.io. This must be one of the URIs + * allowed by your pnut.io application settings. + * @param array $scope An array of scopes (permissions) you wish to obtain + * from the user. If you don't specify anything, you'll only receive + * access to the user's basic profile (the default). + */ + public function getAuthUrl(?string $callback_uri=null, array|string|null $scope=null): string + { + if (empty($this->_clientId)) { + throw new phpnutException('You must specify your pnut client ID'); + } + + if (is_null($callback_uri)) { + if (defined('PNUT_REDIRECT_URI')) { + $callback_uri = PNUT_REDIRECT_URI; + } elseif (isset($_ENV['PNUT_REDIRECT_URI'])) { + $callback_uri = $_ENV['PNUT_REDIRECT_URI']; + } else { + throw new phpnutException('You must specify your pnut callback URI'); + } + } + + if (is_null($scope)) { + if (defined('PNUT_APP_SCOPE')) { + $scope = PNUT_APP_SCOPE; + } elseif (isset($_ENV['PNUT_APP_SCOPE'])) { + $scope = $_ENV['PNUT_APP_SCOPE']; + } else { + $scope = 'basic'; + } + } + + if (is_array($scope)) { + $scope = implode(',', $scope); + } + + // construct an authorization url based on our client id and other data + $data = [ + 'client_id'=>$this->_clientId, + 'response_type'=>'code', + 'redirect_uri'=>$callback_uri, + 'scope'=>$scope, + ]; + + $url = $this->_authUrl; + if ($this->_accessToken) { + $url .= 'authorize?'; + } else { + $url .= 'authenticate?'; + } + $url .= $this->buildQueryString($data); + + // return the constructed url + return $url; + } + + /** + * Call this after they return from the auth page, or anytime you need the + * token. For example, you could store it in a database and use + * setAccessToken() later on to return on behalf of the user. + */ + public function getAccessToken(string $callback_uri) + { + // if there's no access token set, and they're returning from + // the auth page with a code, use the code to get a token + if (!$this->_accessToken && isset($_GET['code']) && $_GET['code'] !== '') { + + if (empty($this->_clientId) || empty($this->_clientSecret)) { + throw new phpnutException('You must specify your Pnut client ID and client secret'); + } + + // construct the necessary elements to get a token + $data = [ + 'client_id'=>$this->_clientId, + 'client_secret'=>$this->_clientSecret, + 'grant_type'=>'authorization_code', + 'redirect_uri'=>$callback_uri, + 'code'=>$_GET['code'], + ]; + + // try and fetch the token with the above data + $res = $this->httpReq( + 'post', + "{$this->_baseUrl}oauth/access_token", + $data + ); + + // store it for later + $this->_accessToken = $res['access_token']; + $this->_username = $res['username']; + $this->_user_id = $res['user_id']; + } + + // return what we have (this may be a token, or it may be nothing) + return $this->_accessToken; + } + + /** + * Check the scope of current token to see if it has required scopes + * has to be done after a check + */ + public function checkScopes(array $app_scopes): int|array + { + if (count($this->_scopes) === 0) { + return -1; // _scope is empty + } + $missing = []; + foreach($app_scopes as $scope) { + if (!in_array($scope, $this->_scopes)) { + if ($scope === 'public_messages') { + // messages works for public_messages + if (in_array('messages', $this->_scopes)) { + // if we have messages in our scopes + continue; + } + } + $missing[] = $scope; + } + } + // identify the ones missing + if (count($missing) !== 0) { + // do something + return $missing; + } + return 0; // 0 missing + } + + /** + * Set the access token (eg: after retrieving it from offline storage) + * @param string $token A valid access token you're previously received + * from calling getAccessToken(). + */ + public function setAccessToken(?string $token=null): void + { + $this->_accessToken = $token; + } + + /** + * Deauthorize the current token (delete your authorization from the API) + * Generally this is useful for logging users out from a web app, so they + * don't get automatically logged back in the next time you redirect them + * to the authorization URL. + */ + public function deauthorizeToken() + { + return $this->httpReq('delete', "{$this->_baseUrl}token"); + } + + /** + * Retrieve an app access token from the app.net API. This allows you + * to access the API without going through the user access flow if you + * just want to (eg) consume global. App access tokens are required for + * some actions (like streaming global). DO NOT share the return value + * of this function with any user (or save it in a cookie, etc). This + * is considered secret info for your app only. + * @return string The app access token + */ + public function getAppAccessToken() + { + if (empty($this->_clientId) || empty($this->_clientSecret)) { + throw new phpnutException('You must specify your Pnut client ID and client secret'); + } + + // construct the necessary elements to get a token + $data = [ + 'client_id'=>$this->_clientId, + 'client_secret'=>$this->_clientSecret, + 'grant_type'=>'client_credentials', + ]; + // try and fetch the token with the above data + $res = $this->httpReq( + 'post', + "{$this->_baseUrl}oauth/access_token", + $data + ); + // store it for later + $this->_appAccessToken = $res['access_token']; + $this->_accessToken = $res['access_token']; + $this->_username = null; + $this->_user_id = null; + return $this->_accessToken; + } + + /** + * Returns the total number of requests you're allowed within the + * alloted time period. + * @see getRateLimitReset() + */ + public function getRateLimit() + { + return $this->_rateLimit; + } + + /** + * The number of requests you have remaining within the alloted time period + * @see getRateLimitReset() + */ + public function getRateLimitRemaining() + { + return $this->_rateLimitRemaining; + } + + /** + * The number of seconds remaining in the alloted time period. + * When this time is up you'll have getRateLimit() available again. + */ + public function getRateLimitReset() + { + return $this->_rateLimitReset; + } + + /** + * The scope the user has + */ + public function getScope() + { + return $this->_scope; + } + + /** + * Internal function, parses out important information pnut.io adds + * to the headers. + */ + protected function parseHeaders(string $response) + { + // take out the headers + // set internal variables + // return the body/content + $this->_rateLimit = null; + $this->_rateLimitRemaining = null; + $this->_rateLimitReset = null; + $this->_scope = null; + + $response = explode("\r\n\r\n", $response, 2); + $headers = $response[0]; + + if ($headers === 'HTTP/1.1 100 Continue') { + $response = explode("\r\n\r\n", $response[1], 2); + $headers = $response[0]; + } + + // this is not a good way to parse http headers + // it will not (for example) take into account multiline headers + // but what we're looking for is pretty basic, so we can ignore those shortcomings + $headers = explode("\r\n", $headers); + foreach ($headers as $header) { + $header = explode(': ', $header, 2); + if (count($header) < 2) { + continue; + } + list($k, $v) = $header; + switch ($k) { + case 'X-RateLimit-Remaining': + $this->_rateLimitRemaining = $v; + break; + case 'X-RateLimit-Limit': + $this->_rateLimit = $v; + break; + case 'X-RateLimit-Reset': + $this->_rateLimitReset = $v; + break; + case 'X-OAuth-Scopes': + $this->_scope = $v; + $this->_scopes = explode(',', $v); + break; + } + } + return $response[1] ?? null; + } + + /** + * Internal function. Used to turn things like TRUE into 1, and then + * calls http_build_query. + */ + protected function buildQueryString(array $array): string + { + foreach ($array as $k => &$v) { + if (is_array($v)) { + $v = implode(',', $v); + } elseif ($v === true) { + $v = '1'; + } + elseif ($v === false) { + $v = '0'; + } + unset($v); + } + return http_build_query($array); + } + + + /** + * Internal function to handle all + * HTTP requests (POST,PUT,GET,DELETE) + */ + protected function httpReq(string $act, string $req, string|array $params=[], string $contentType='application/x-www-form-urlencoded') + { + $ch = curl_init($req); + $headers = []; + if($act !== 'get') { + curl_setopt($ch, CURLOPT_POST, true); + // if they passed an array, build a list of parameters from it + if (is_array($params) && $act !== 'post-raw') { + $params = $this->buildQueryString($params); + } + curl_setopt($ch, CURLOPT_POSTFIELDS, $params); + $headers[] = "Content-Type: {$contentType}"; + } + if($act !== 'post' && $act !== 'post-raw') { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($act)); + } + if($act === 'get' && isset($params['access_token'])) { + $headers[] = "Authorization: Bearer {$params['access_token']}"; + } elseif ($this->_accessToken) { + $headers[] = "Authorization: Bearer {$this->_accessToken}"; + } + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLINFO_HEADER_OUT, true); + curl_setopt($ch, CURLOPT_HEADER, true); + if ($this->_sslCA) { + curl_setopt($ch, CURLOPT_CAINFO, $this->_sslCA); + } + $this->_last_response = curl_exec($ch); + $this->_last_request = curl_getinfo($ch, CURLINFO_HEADER_OUT); + $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + + if ($http_status === 0) { + throw new phpnutException("Unable to connect to {$req}"); + } + if ($this->_last_request === false) { + if (!curl_getinfo($ch, CURLINFO_SSL_VERIFYRESULT)) { + throw new phpnutException('SSL verification failed, connection terminated.'); + } + } + if ($this->_last_response) { + $response = $this->parseHeaders($this->_last_response); + if ($response) { + $response = json_decode($response, true); + + if (isset($response['meta'])) { + if (isset($response['meta']['max_id'])) { + $this->_maxid = $response['meta']['max_id']; + $this->_minid = $response['meta']['min_id']; + } + if (isset($response['meta']['more'])) { + $this->_more = $response['meta']['more']; + } + if (isset($response['meta']['marker'])) { + $this->_last_marker = $response['meta']['marker']; + } + } + + // look for errors + if (isset($response['error'])) { + if (is_array($response['error'])) { + throw new phpnutException( + $response['error']['message'], + $response['error']['code'] + ); + } else { + throw new phpnutException($response['error']); + } + } + + // look for response migration errors + elseif (isset($response['meta'], $response['meta']['error_message'])) { + throw new phpnutException( + $response['meta']['error_message'], + $response['meta']['code'] + ); + } + } + } + + if ($http_status < 200 || $http_status >= 300) { + throw new phpnutException("HTTP error {$http_status}"); + } + + // if we've received a migration response, handle it and return data only + elseif ($this->_stripResponseEnvelope && isset($response['meta'], $response['data'])) { + return $response['data']; + } + + // else non response migration response, just return it + elseif (isset($response)) { + return $response; + } + + else { + throw new phpnutException('No response'); + } + } + + + /** + * Get max_id from last meta response data envelope + */ + public function getResponseMaxID() + { + return $this->_maxid; + } + + /** + * Get min_id from last meta response data envelope + */ + public function getResponseMinID() + { + return $this->_minid; + } + + /** + * Get more from last meta response data envelope + */ + public function getResponseMore() + { + return $this->_more; + } + + /** + * Get marker from last meta response data envelope + */ + public function getResponseMarker() + { + return $this->_last_marker; + } + + public function getLastRequest() + { + return $this->_last_request; + } + + public function getLastResponse() + { + return $this->_last_response; + } + + /** + * Fetch API configuration object + * @return array + */ + public function getConfig() + { + return $this->httpReq('get', "{$this->_baseUrl}sys/config"); + } + + /** + * Fetch basic API statistics + * @return array + */ + public function getStats() + { + return $this->httpReq('get', "{$this->_baseUrl}sys/stats"); + } + + /** + * Process user content, message or post text. + * Mentions and hashtags will be parsed out of the + * text, as will bare URLs. To create a link in the text without using a + * bare URL, include the anchor text in the object text and include a link + * entity in the function call. + * @param string $text The text of the user/message/post + * @param array $data An associative array of optional post data. This + * will likely change as the API evolves, as of this writing allowed keys are: + * reply_to, and raw. "raw" may be a complex object represented + * by an associative array. + * @param array $params An associative array of optional data to be included + * in the URL (such as 'include_raw') + * @return array An associative array representing the post. + */ + public function processText(string $text, array $data=[], array $params=[]) + { + $data['text'] = $text; + $json = json_encode($data); + $qs = ''; + if (!empty($params)) { + $qs = '?' . $this->buildQueryString($params); + } + return $this->httpReq( + 'post', + $this->_baseUrl . 'text/process' . $qs, + $json, + 'application/json' + ); + } + + /** + * Create a new Post object. Mentions and hashtags will be parsed out of the + * post text, as will bare URLs. To create a link in a post without using a + * bare URL, include the anchor text in the post's text and include a link + * entity in the post creation call. + * @param string $text The text of the post + * @param array $data An associative array of optional post data. This + * will likely change as the API evolves, as of this writing allowed keys are: + * reply_to, is_nsfw, and raw. "raw" may be a complex object represented + * by an associative array. + * @param array $params An associative array of optional data to be included + * in the URL (such as 'include_raw') + * @return array An associative array representing the post. + */ + public function createPost(string $text, array $data=[], array $params=[]) + { + $data['text'] = $text; + $json = json_encode($data); + $qs = ''; + if (!empty($params)) { + $qs = '?' . $this->buildQueryString($params); + } + return $this->httpReq( + 'post', + $this->_baseUrl . 'posts' . $qs, + $json, + 'application/json' + ); + } + + /** + * Create a new Post object. Mentions and hashtags will be parsed out of the + * post text, as will bare URLs. To create a link in a post without using a + * bare URL, include the anchor text in the post's text and include a link + * entity in the post creation call. + * @param integer $post_id The ID of the post to revise + * @param string $text The new text of the post + * @param array $data An associative array of optional post data. This + * will likely change as the API evolves, as of this writing allowed keys are: + * is_nsfw. + * @param array $params An associative array of optional data to be included + * in the URL (such as 'include_raw') + * @return array An associative array representing the post. + */ + public function revisePost(int $post_id, string $text, array $data=[], array $params=[]) + { + $data['text'] = $text; + $json = json_encode($data); + $qs = ''; + if (!empty($params)) { + $qs = '?' . $this->buildQueryString($params); + } + return $this->httpReq( + 'put', + $this->_baseUrl . 'posts/' . urlencode($post_id) . $qs, + $json, + 'application/json' + ); + } + + /** + * Returns a specific Post. + * @param integer $post_id The ID of the post to retrieve + * @param array $params An associative array of optional general parameters. + * @return array An associative array representing the post + */ + public function getPost(int $post_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns a list of Posts. + * @param array $post_ids The list of post IDs to retrieve + * @param array $params An associative array of optional general parameters. + * @return array An array of arrays representing the posts + */ + public function getMultiplePosts(array $post_ids, array $params=[]) + { + $params['ids'] = $post_ids; + + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts?' . $this->buildQueryString($params) + ); + } + + /** + * Delete a Post. The current user must be the same user who created the Post. + * It returns the deleted Post on success. + * @param integer $post_id The ID of the post to delete + * @param array An associative array representing the post that was deleted + */ + public function deletePost(int $post_id) + { + return $this->httpReq( + 'delete', + $this->_baseUrl . 'posts/' . urlencode($post_id) + ); + } + + /** + * Retrieve the Posts that are 'in reply to' a specific Post. + * @param integer $post_id The ID of the post you want to retrieve replies for. + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getPostThread(int $post_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/thread?' + . $this->buildQueryString($params) + ); + } + + /** + * Retrieve revisions of a post. Currently only one can be created. + * @param integer $post_id The ID of the post you want to retrieve previous revisions of. + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getPostRevisions(int $post_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/revisions?' + . $this->buildQueryString($params) + ); + } + + /** + * Get the most recent Posts created by a specific User in reverse + * chronological order (most recent first). + * @param mixed $user_id Either the ID of the user you wish to retrieve posts by, + * or the string "me", which will retrieve posts for the user you're authenticated + * as. + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getUserPosts(string|int $user_id='me', array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/posts?' + . $this->buildQueryString($params) + ); + } + + /** + * Get the most recent Posts mentioning by a specific User in reverse + * chronological order (newest first). + * @param mixed $user_id Either the ID of the user who is being mentioned, or + * the string "me", which will retrieve posts for the user you're authenticated + * as. + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getUserMentions(string|int $user_id='me', array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/mentions?' + . $this->buildQueryString($params) + ); + } + + /** + * Get the currently authenticated user's recent messages + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getUserMessages(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/me/messages?' + . $this->buildQueryString($params) + ); + } + + /** + * Return the 20 most recent posts from the current User and + * the Users they follow. + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getUserStream(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/me?' + . $this->buildQueryString($params) + ); + } + + /** + * Retrieve a list of all public Posts on pnut.io, often referred to as the + * global stream. + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getPublicPosts(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/global?' + . $this->buildQueryString($params) + ); + } + + /** + * Retrieve a list of "explore" streams + * @return An array of associative arrays, each representing a single explore stream. + */ + public function getPostExploreStreams() + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/explore' + ); + } + + /** + * Retrieve a list of posts from an "explore" stream on pnut.io. + * @param string $slug [] + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single post. + */ + public function getPostExploreStream(string $slug, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/explore/' . urlencode($slug) . '?' + . $this->buildQueryString($params) + ); + } + + /** + * Bookmark a post + * @param integer $post_id The post ID to bookmark + */ + public function bookmarkPost(int $post_id) + { + return $this->httpReq( + 'put', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/bookmark' + ); + } + + /** + * Unbookmark a post + * @param integer $post_id The post ID to unbookmark + */ + public function unbookmarkPost(int $post_id) + { + return $this->httpReq( + 'delete', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/bookmark' + ); + } + + /** + * List the posts bookmarked by the current user + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: count, before_id, since_id, include_muted, include_deleted, + * and include_post_raw. + * See https://github.com/phpnut/api-spec/blob/master/resources/posts.md#general-parameters + * @return array An array of associative arrays, each representing a single + * user who has bookmarked a post + */ + public function getBookmarked(string|int $user_id='me', array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/bookmarks?' + . $this->buildQueryString($params) + ); + } + + /** + * List the interactions with a post (bookmark, repost, reply) + * @param integer $post_id the post ID to get interactions from + * @param array $params optional parameters like filters or excludes + * @return array An array of associative arrays, each representing one post interaction. + */ + public function getPostInteractions(int $post_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/interactions?' + . $this->buildQueryString($params) + ); + } + + /** + * List the bookmarks of a post + * @param integer $post_id the post ID to get stars from + * @return array An array of associative arrays, each representing one bookmark action. + */ + public function getPostBookmarks(int $post_id) + { + return $this->getPostInteractions($post_id, ['filters'=>['bookmark']]); + } + + /** + * Returns an array of User objects of users who reposted the specified post. + * @param integer $post_id the post ID to + * @return array An array of associative arrays, each representing a single + * user who reposted $post_id + */ + public function getPostReposts(int $post_id) + { + return $this->getPostInteractions($post_id, ['filters'=>['repost']]); + } + + /** + * Repost an existing Post object. + * @param integer $post_id The id of the post + * @return the reposted post + */ + public function repost(int $post_id) + { + return $this->httpReq( + 'put', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/repost' + ); + } + + /** + * Delete a post that the user has reposted. + * @param integer $post_id The id of the post + * @return the un-reposted post + */ + public function deleteRepost(int $post_id) + { + return $this->httpReq( + 'delete', + $this->_baseUrl . 'posts/' . urlencode($post_id) . '/repost' + ); + } + + /** + * Return Posts matching a specific #hashtag. + * @param string $hashtag The hashtag you're looking for. + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: count, before_id, since_id, include_muted, include_deleted, + * include_directed_posts, and include_raw. + * @return An array of associative arrays, each representing a single post. + */ + public function searchHashtags(string $hashtag, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/tags/' . urlencode($hashtag) . '?' + . $this->buildQueryString($params) + ); + } + + /** + * List the posts who match a specific search term + * @param array $params a list of filter, search query, and general Post parameters + * see: https://docs.pnut.io/resources/posts/search + * @param string $query The search query. Supports + * normal search terms. Searches post text. + * @return array An array of associative arrays, each representing one post. + * or false on error + */ + public function searchPosts(array $params=[], string $query='', string $order='default') + { + if (!is_array($params)) { + return false; + } + if (!empty($query)) { + $params['q'] = $query; + } + if ($order === 'default') { + if (!empty($query)) { + $params['order'] = 'relevance'; + } else { + $params['order'] = 'id'; + } + } + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/search?' . $this->buildQueryString($params) + ); + } + + /** + * Return the 20 most recent posts for a stream using a valid Token + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: count, before_id, since_id, include_muted, include_deleted, + * and include_post_raw. + * @return An array of associative arrays, each representing a single post. + */ + public function getUserPersonalStream(array $params=[]) + { + if ($params['access_token']) { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/me?' + . $this->buildQueryString($params), + $params + ); + } else { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/me?' + . $this->buildQueryString($params) + ); + } + } + + /** + * Return the 20 most recent Posts from the current User's personalized stream + * and mentions stream merged into one stream. + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: count, before_id, since_id, include_muted, include_deleted, + * include_directed_posts, and include_raw. + * @return An array of associative arrays, each representing a single post. + */ + public function getUserUnifiedStream(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'posts/streams/unified?' + . $this->buildQueryString($params) + ); + } + + /** + * List User interactions + */ + public function getMyActions(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/me/interactions?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns a specific user object. + * @param mixed $user_id The ID of the user you want to retrieve, or the string "@-username", or the string + * "me" to retrieve data for the users you're currently authenticated as. + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: include_raw|include_user_raw. + * @return array An associative array representing the user data. + */ + public function getUser(string|int $user_id='me', array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns multiple users request by an array of user ids + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: include_raw|include_user_raw. + * @return array An associative array representing the users data. + */ + public function getUsers(array $user_arr, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users?ids=' . implode(',', $user_arr) + . '&' . $this->buildQueryString($params) + ); + } + + /** + * Add the specified user ID to the list of users followed. + * Returns the User object of the user being followed. + * @param integer $user_id The user ID of the user to follow. + * @return array An associative array representing the user you just followed. + */ + public function followUser(string|int $user_id) + { + return $this->httpReq( + 'put', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/follow' + ); + } + + /** + * Removes the specified user ID to the list of users followed. + * Returns the User object of the user being unfollowed. + * @param integer $user_id The user ID of the user to unfollow. + * @return array An associative array representing the user you just unfollowed. + */ + public function unfollowUser(string|int $user_id) + { + return $this->httpReq( + 'delete', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/follow' + ); + } + + /** + * Returns an array of User objects the specified user is following. + * @param mixed $user_id Either the ID of the user being followed, or + * the string "me", which will retrieve posts for the user you're authenticated + * as. + * @return array An array of associative arrays, each representing a single + * user following $user_id + */ + public function getFollowing(string|int $user_id='me', array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/following?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns an array of User ids the specified user is following. + * @param mixed $user_id Either the ID of the user being followed, or + * the string "me", which will retrieve posts for the user you're authenticated + * as. + * @return array user ids the specified user is following. + */ + public function getFollowingIDs(string|int $user_id='me') + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}users/{$user_id}/following?include_user=0" + ); + } + + /** + * Returns an array of User objects for users following the specified user. + * @param mixed $user_id Either the ID of the user being followed, or + * the string "me", which will retrieve posts for the user you're authenticated + * as. + * @return array An array of associative arrays, each representing a single + * user following $user_id + */ + public function getFollowers(string|int $user_id='me', array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/followers?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns an array of User ids for users following the specified user. + * @param mixed $user_id Either the ID of the user being followed, or + * the string "me", which will retrieve posts for the user you're authenticated + * as. + * @return array user ids for users following the specified user + */ + public function getFollowersIDs(string|int $user_id='me') + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}users/{$user_id}/followers?include_user=0" + ); + } + + /** + * Retrieve a user's user ID by specifying their username. + * @param string $username The username of the user you want the ID of, without + * an @ symbol at the beginning. + * @return integer The user's user ID + */ + public function getIdByUsername(string $username) + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}users/@{$username}?include_user=0" + ); + } + + /** + * Mute a user + * @param integer $user_id The user ID to mute + */ + public function muteUser(string|int $user_id) + { + return $this->httpReq( + 'put', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/mute' + ); + } + + /** + * Unmute a user + * @param integer $user_id The user ID to unmute + */ + public function unmuteUser(string|int $user_id) + { + return $this->httpReq( + 'delete', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/mute' + ); + } + + /** + * List the users muted by the current user + * @return array An array of associative arrays, each representing one muted user. + */ + public function getMuted() + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}users/me/muted" + ); + } + + /** + * Get a user object by username + * @param string $name the @name to get + * @return array representing one user + */ + public function getUserByName(string $name) + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}users/@{$name}" + ); + } + + /** + * List the users who match a specific search term + * @param string $search The search query. Supports @username or #tag searches as + * well as normal search terms. Searches username, display name, bio information. + * Does not search posts. + * @return array An array of associative arrays, each representing one user. + */ + public function searchUsers(array $params=[], string $query='') + { + if (!is_array($params)) { + return false; + } + if ($query === '') { + return false; + } + $params['q'] = $query; + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/search?q=' . $this->buildQueryString($params) + ); + } + + /** + * Update Profile Data via JSON + * @data array containing user descriptors + */ + public function updateUserData(array $data=[], array $params=[]) + { + $json = json_encode($data); + return $this->httpReq( + 'put', + $this->_baseUrl . 'users/me?' + . $this->buildQueryString($params), + $json, + 'application/json' + ); + } + + /** + * Update a user image + * @image path reference to image + * @which avatar|cover + */ + protected function updateUserImage(string $image, string $which='avatar') + { + $test = @getimagesize($image); + if ($test && array_key_exists('mime', $test)) { + $mimeType = $test['mime']; + } + $data = [ + $which => new CurlFile($image, $mimeType) + ]; + return $this->httpReq( + 'post-raw', + "{$this->_baseUrl}users/me/{$which}", + $data, + 'multipart/form-data' + ); + } + + public function updateUserAvatar($avatar) + { + return $this->updateUserImage('avatar', $avatar); + } + + public function updateUserCover($cover) + { + return $this->updateUserImage('cover', $cover); + } + + /** + * Returns a Client object + * @param string $client_id + * @return array An array representing the client + */ + public function getClient(string $client_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'clients/' . urlencode($client_id) . '?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns a list of truncated client details made by a user + * @param string $user_id + * @return array A list of arrays representing clients + */ + public function getUserClients(string $user_id) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/' . urlencode($user_id) . '/clients' + ); + } + + /** + * update stream marker + */ + public function updateStreamMarker(array $data=[]) + { + $json = json_encode($data); + return $this->httpReq( + 'post', + "{$this->_baseUrl}markers", + $json, + 'application/json' + ); + } + + /** + * get a page of current user subscribed channels + */ + public function getMyChannelSubscriptions(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/me/channels/subscribed?' . $this->buildQueryString($params) + ); + } + + /** + * get user channels + */ + public function getMyChannels(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/me/channels?' . $this->buildQueryString($params) + ); + } + + /** + * create a channel + * note: you cannot create a channel with type=io.pnut.core.pm (see createMessage) + */ + public function createChannel(array $data=[]) + { + $json = json_encode($data); + return $this->httpReq( + 'post', + "{$this->_baseUrl}channels", + $json, + 'application/json' + ); + } + + /** + * get channelid info + */ + public function getChannel(int $channelid, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels/' . $channelid . '?' + . $this->buildQueryString($params) + ); + } + + /** + * get an existing private message channel between multiple users + * @param mixed $users Can be a comma- or space-separated string, or an array. + * Usernames with @-symbol, or user ids. + */ + public function getExistingPM(string|array $users, array $params=[]) + { + if (is_string($users)) { + $users = explode(',', str_replace(' ', ',', $users)); + } + foreach($users as $key=>$user) { + if (!is_numeric($user) && substr($user, 0, 1) !== '@') { + $users[$key] = "@{$user}"; + } + } + $params['ids'] = $users; + return $this->httpReq( + 'get', + $this->_baseUrl . 'users/me/channels/existing_pm?' + . $this->buildQueryString($params) + ); + } + + /** + * get multiple channels' info by an array of channelids + */ + public function getChannels(array $channels, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels?ids=' . implode(',', $channels) . '&' + . $this->buildQueryString($params) + ); + } + + /** + * update channelid + */ + public function updateChannel(int $channelid, array $data=[]) + { + $json = json_encode($data); + return $this->httpReq( + 'put', + "{$this->_baseUrl}channels/{$channelid}", + $json, + 'application/json' + ); + } + + /** + * subscribe from channelid + */ + public function channelSubscribe(int $channelid) + { + return $this->httpReq( + 'put', + $this->_baseUrl.'channels/'.$channelid.'/subscribe' + ); + } + + /** + * unsubscribe from channelid + */ + public function channelUnsubscribe(int $channelid) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'channels/'.$channelid.'/subscribe' + ); + } + + /** + * mute channelid + */ + public function channelMute(int $channelid) + { + return $this->httpReq( + 'put', + $this->_baseUrl.'channels/'.$channelid.'/mute' + ); + } + + /** + * unmute channelid + */ + public function channelUnmute(int $channelid) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'channels/'.$channelid.'/mute' + ); + } + + /** + * get all user objects subscribed to channelid + */ + public function getChannelSubscriptions(int $channelid, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'channels/'.$channelid.'/subscribers?' + . $this->buildQueryString($params) + ); + } + + /** + * get all user IDs subscribed to channelid + */ + public function getChannelSubscriptionsById(int $channelid) + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}channels/{$channelid}/subscribers?include_user=0" + ); + } + + /** + * Retrieve a list of "explore" streams + * @return An array of associative arrays, each representing a single explore stream. + */ + public function getChannelExploreStreams() + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels/streams/explore' + ); + } + + /** + * Retrieve a list of channels from an "explore" stream on pnut.io. + * @param string $slug [] + * @param array $params An associative array of optional general parameters. + * @return An array of associative arrays, each representing a single channel. + */ + public function getChannelExploreStream(string $slug, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels/streams/explore/' . urlencode($slug) . '?' + . $this->buildQueryString($params) + ); + } + + /** + * mark channel inactive + */ + public function deleteChannel(int $channelid) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'channels/'.$channelid + ); + } + + /** + * List the channels that match a specific search term + * @param array $params a list of filter, search query, and general Channel parameters + * see: https://docs.pnut.io/resources/channels/search + * @param string $query The search query. Supports + * normal search terms. Searches common channel raw. + * @return array An array of associative arrays, each representing one channel. + * or false on error + */ + public function searchChannels(array $params=[], string $query='', string $order='default') + { + if (!empty($query)) { + $params['q'] = $query; + } + if ($order === 'default') { + if (!empty($query)) { + $params['order'] = 'id'; + } else { + $params['order'] = 'activity'; + } + } + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels/search?' . $this->buildQueryString($params) + ); + } + + + /** + * get a page of messages in channelid + */ + public function getMessages(int $channelid, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'channels/'.$channelid.'/messages?' + . $this->buildQueryString($params) + ); + } + + /** + * get a page of messages in channelid in a thread + */ + public function getMessageThread(int $channelid, int $messageid, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'channels/'.$channelid.'/messages/'.$messageid.'/thread?' + . $this->buildQueryString($params) + ); + } + + /** + * get a page of sticky messages in channelid + */ + public function getStickyMessages(int $channelid, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'channels/'.$channelid.'/sticky_messages?' + . $this->buildQueryString($params) + ); + } + + /** + * sticky messsage + */ + public function stickyMessage(int $channelid, int $messageid) + { + return $this->httpReq( + 'put', + $this->_baseUrl.'channels/'.$channelid.'/messages/'.$messageid.'/sticky' + ); + } + + /** + * unsticky messsage + */ + public function unstickyMessage(int $channelid, int $messageid) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'channels/'.$channelid.'/messages/'.$messageid.'/sticky' + ); + } + + /** + * create message + * @param $channelid numeric or "pm" for auto-channel (type=io.pnut.core.pm) + * @param array $data array('text'=>'YOUR_MESSAGE') If a type=io.pnut.core.pm, then "destinations" key can be set to address as an array of people to send this PM too + * @param array $params query parameters + */ + public function createMessage(string|int $channelid, array $data, array $params=[]) + { + if (isset($data['destinations'])) { + if (is_string($data['destinations'])) { + $data['destinations'] = explode(',', str_replace(' ', ',', $data['destinations'])); + } + foreach($data['destinations'] as $key=>$user) { + if (!is_numeric($user) && substr($user, 0,1 ) !== '@') { + $data['destinations'][$key] = "@{$user}"; + } + } + } + $json = json_encode($data); + return $this->httpReq( + 'post', + $this->_baseUrl.'channels/'.$channelid.'/messages?' + . $this->buildQueryString($params), + $json, + 'application/json' + ); + } + + /** + * get message + */ + public function getMessage(int $channelid, int $messageid, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'channels/'.$channelid.'/messages/'.$messageid.'?' + . $this->buildQueryString($params) + ); + } + + /** + * Returns a list of Messages. + * @param array $message_ids The list of message IDs to retrieve + * @param array $params An associative array of optional general parameters. + * @return array An array of arrays representing the messages + */ + public function getMultipleMessages(array $message_ids, array $params=[]) + { + $params['ids'] = $message_ids; + + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels/messages?' . $this->buildQueryString($params) + ); + } + + /** + * delete messsage + */ + public function deleteMessage(int $channelid, int $messageid) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'channels/'.$channelid.'/messages/'.$messageid + ); + } + + /** + * List the messages that match a specific search term + * @param array $params a list of filter, search query, and general Message parameters + * see: https://docs.pnut.io/resources/messages/search + * @param string $query The search query. Supports + * normal search terms. Searches common channel raw. + * @return array An array of associative arrays, each representing one channel. + * or false on error + */ + public function searchMessages(array $params=[], string $query='', string $order='default') + { + if (!is_array($params)) { + return false; + } + if (!empty($query)) { + $params['q'] = $query; + } + if ($order === 'default') { + if (!empty($query)) { + $params['order'] = 'id'; + } else { + $params['order'] = 'relevance'; + } + } + return $this->httpReq( + 'get', + $this->_baseUrl . 'channels/messages/search?' + . $this->buildQueryString($params) + ); + } + + /** + * Upload a file to a user's file store + * @param string $file A string containing the path of the file to upload. + * @param array $data Additional data about the file you're uploading. At the + * moment accepted keys are: mime-type, kind, type, name, public and raw. + * - If you don't specify mime-type, phpnut will attempt to guess the mime type + * based on the file, however this isn't always reliable. + * - If you don't specify kind phpnut will attempt to determine if the file is + * an image or not. + * - If you don't specify name, phpnut will use the filename of the first + * parameter. + * - If you don't specify is_public, your file will be uploaded as a private file. + * - Type is REQUIRED. + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: include_raw|include_file_raw. + * @return array An associative array representing the file + */ + public function createFile($file, array $data, array $params=[]) + { + if (!$file) { + throw new PhpnutException('You must specify a path to a file'); + } + if (!file_exists($file)) { + throw new PhpnutException('File path specified does not exist'); + } + if (!is_readable($file)) { + throw new PhpnutException('File path specified is not readable'); + } + if (!array_key_exists('type', $data) || !$data['type']) { + throw new PhpnutException('Type is required when creating a file'); + } + if (!array_key_exists('name', $data)) { + $data['name'] = basename($file); + } + if (array_key_exists('mime-type', $data)) { + $mimeType = $data['mime-type']; + unset($data['mime-type']); + } else { + $mimeType = null; + } + if (!array_key_exists('kind', $data)) { + $test = @getimagesize($path); + if ($test && array_key_exists('mime', $test)) { + $data['kind'] = 'image'; + if (!$mimeType) { + $mimeType = $test['mime']; + } + } + else { + $data['kind'] = 'other'; + } + } + if (!$mimeType) { + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mimeType = finfo_file($finfo, $file); + finfo_close($finfo); + } + if (!$mimeType) { + throw new PhpnutException('Unable to determine mime type of file, try specifying it explicitly'); + } + $data['content'] = new \CurlFile($file, $mimeType); + return $this->httpReq( + 'post-raw', + "{$this->_baseUrl}files", + $data, + 'multipart/form-data' + ); + } + + public function createFilePlaceholder($file, array $params=[]) + { + $name = basename($file); + $data = [ + 'raw' => $params['raw'], + 'kind' => $params['kind'], + 'name' => $name, + 'type' => $params['metadata'] + ]; + $json = json_encode($data); + return $this->httpReq( + 'post', + $this->_baseUrl.'files', + $json, + 'application/json' + ); + } + + public function updateFileContent(int $fileid, string $file) + { + $data = file_get_contents($file); + $finfo = finfo_open(FILEINFO_MIME_TYPE); + $mime = finfo_file($finfo, $file); + finfo_close($finfo); + return $this->httpReq( + 'put', + $this->_baseUrl.'files/'.$fileid.'/content', + $data, + $mime + ); + } + + /** + * Allows for file rename and annotation changes. + * @param integer $file_id The ID of the file to update + * @param array $params An associative array of file parameters. + * @return array An associative array representing the updated file + */ + public function updateFile(int $file_id, array $params=[]) + { + $data = [ + 'raw' => $params['raw'], + 'name' => $params['name'], + ]; + $json = json_encode($data); + return $this->httpReq( + 'put', + $this->_baseUrl.'files/'.urlencode($file_id), + $json, + 'application/json' + ); + } + + /** + * Returns a specific File. + * @param integer $file_id The ID of the file to retrieve + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: include_raw|include_file_raw. + * @return array An associative array representing the file + */ + public function getFile(int $file_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'files/'.urlencode($file_id).'?' + . $this->buildQueryString($params) + ); + } + + public function getFileContent(int $file_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'files/'.urlencode($file_id).'/content?' + . $this->buildQueryString($params) + ); + } + + /** $file_key : derived_file_key */ + public function getDerivedFileContent(int $file_id, string $file_key, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'files/'.urlencode($file_id).'/content/'.urlencode($file_key).'?'.$this->buildQueryString($params) + ); + } + + /** + * Returns file objects. + * @param array $file_ids The IDs of the files to retrieve + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: include_raw|include_file_raw. + * @return array An associative array representing the file data. + */ + public function getFiles(array $file_ids, array $params=[]) + { + $ids = ''; + foreach($file_ids as $id) { + $ids .= $id . ','; + } + $params['ids'] = substr($ids, 0, -1); + return $this->httpReq( + 'get', + $this->_baseUrl.'files?'.$this->buildQueryString($params) + ); + } + + /** + * Returns a user's file objects. + * @param array $params An associative array of optional general parameters. + * This will likely change as the API evolves, as of this writing allowed keys + * are: include_raw|include_file_raw|include_user_raw. + * @return array An associative array representing the file data. + */ + public function getUserFiles(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'users/me/files?'.$this->buildQueryString($params) + ); + } + + /** + * Delete a File. The current user must be the same user who created the File. + * It returns the deleted File on success. + * @param integer $file_id The ID of the file to delete + * @return array An associative array representing the file that was deleted + */ + public function deleteFile(int $file_id) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'files/'.urlencode($file_id) + ); + } + + /** + * Create a poll + * @param array $data An associative array of the required parameters. + * @param array $params An associative array of optional general parameters. + * Allowed keys: include_raw,include_poll_raw, ... + * @return array An associative array representing the poll + */ + public function createPoll(array $data, array $params=[]) + { + $json = json_encode($data); + return $this->httpReq( + 'post', + $this->_baseUrl.'polls?'.$this->buildQueryString($params), + $json, + 'application/json' + ); + } + + /** + * Responds to a poll. + * @param integer $poll_id The ID of the poll to respond to + * @param array list of positions for the poll response + * @param array $params An associative array of optional general parameters. + */ + public function respondToPoll(int $poll_id, array $positions, array $params=[]) + { + $json = json_encode(['positions' => $positions]); + return $this->httpReq( + 'put', + $this->_baseUrl.'polls/'.urlencode($poll_id).'/response?'.$this->buildQueryString($params), + $json, + 'application/json' + ); + } + + /** + * Returns a specific Poll. + * @param integer $poll_id The ID of the poll to retrieve + * @param array $params An associative array of optional general parameters. + * @return array An associative array representing the poll + */ + public function getPoll(int $poll_id, array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'polls/'.urlencode($poll_id).'?'.$this->buildQueryString($params) + ); + } + + /** + * Returns a list of Polls. + * @param array $poll_ids The list of poll IDs to retrieve + * @param array $params An associative array of optional general parameters. + * @return array An array of arrays representing the polls + */ + public function getMultiplePolls(array $poll_ids, array $params=[]) + { + $params['ids'] = $poll_ids; + + return $this->httpReq( + 'get', + $this->_baseUrl . 'polls?' . $this->buildQueryString($params) + ); + } + + /** + * Returns a user's poll objects. + * @param array $params An associative array of optional general parameters. + * @return array An associative array representing the poll data. + */ + public function getUserPolls(array $params=[]) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'users/me/polls?'.$this->buildQueryString($params) + ); + } + + /** + * Delete a Poll. The current user must be the same user who created the Poll. + * @param integer $poll_id The ID of the poll to delete + * @param array $params An associative array of optional general parameters. + * @return array An associative array representing the poll that was deleted + */ + public function deletePoll(int $poll_id, array $params=[]) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'polls/'.urlencode($poll_id).'?'.$this->buildQueryString($params) + ); + } + + /** + * List the polls that match a specific search term + * @param array $params a list of filter, search query, and general Poll parameters + * see: https://docs.pnut.io/resources/channels/search + * @param string $query The search query. Supports + * normal search terms. + * @return array An array of associative arrays, each representing one poll. + * or false on error + */ + public function searchPolls(array $params=[], string $order='id') + { + $params['order'] = $order; + + return $this->httpReq( + 'get', + $this->_baseUrl . 'polls/search?' . $this->buildQueryString($params) + ); + } + + + /** + * Get Application Information + */ + public function getAppTokenInfo() + { + // requires appAccessToken + if (!$this->_appAccessToken) { + $this->getAppAccessToken(); + } + // ensure request is made with our appAccessToken + $params['access_token'] = $this->_appAccessToken; + return $this->httpReq( + 'get', + "{$this->_baseUrl}token", + $params + ); + } + + /** + * Get User Information + */ + public function getUserTokenInfo() + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}token" + ); + } + + /** + * Get Application Authorized User IDs + */ + public function getAppUserIDs() + { + // requires appAccessToken + if (!$this->_appAccessToken) { + $this->getAppAccessToken(); + } + // ensure request is made with our appAccessToken + $params['access_token'] = $this->_appAccessToken; + return $this->httpReq( + 'get', + "{$this->_baseUrl}apps/me/users/ids", + $params + ); + } + + /** + * Get Application Authorized User Tokens + */ + public function getAppUserTokens() + { + // requires appAccessToken + if (!$this->_appAccessToken) { + $this->getAppAccessToken(); + } + // ensure request is made with our appAccessToken + $params['access_token'] = $this->_appAccessToken; + return $this->httpReq( + 'get', + "{$this->_baseUrl}apps/me/users/tokens", + $params + ); + } + + + + /** + * Registers your function (or an array of object and method) to be called + * whenever an event is received via an open pnut.io stream. Your function + * will receive a single parameter, which is the object wrapper containing + * the meta and data. + * @param mixed A PHP callback (either a string containing the function name, + * or an array where the first element is the class/object and the second + * is the method). + */ + public function registerStreamFunction($function): void + { + $this->_streamCallback = $function; + } + + /** + * Opens a stream that's been created for this user/app and starts sending + * events/objects to your defined callback functions. You must define at + * least one callback function before opening a stream. + * @param mixed $stream Either a stream ID or the endpoint of a stream + * you've already created. This stream must exist and must be valid for + * your current access token. If you pass a stream ID, the library will + * make an API call to get the endpoint. + * + * This function will return immediately, but your callback functions + * will continue to receive events until you call closeStream() or until + * pnut.io terminates the stream from their end with an error. + * + * If you're disconnected due to a network error, the library will + * automatically attempt to reconnect you to the same stream, no action + * on your part is necessary for this. However if the pnut.io API returns + * an error, a reconnection attempt will not be made. + * + * Note there is no closeStream, because once you open a stream you + * can't stop it (unless you exit() or die() or throw an uncaught + * exception, or something else that terminates the script). + * @return boolean True + * @see createStream() + */ + public function openStream($stream): bool + { + // if there's already a stream running, don't allow another + if ($this->_currentStream) { + throw new phpnutException('There is already a stream being consumed, only one stream can be consumed per phpnutStream instance'); + } + // must register a callback (or the exercise is pointless) + if (!$this->_streamCallback) { + throw new phpnutException('You must define your callback function using registerStreamFunction() before calling openStream'); + } + // if the stream is a numeric value, get the stream info from the api + if (is_numeric($stream)) { + $stream = $this->getStream($stream); + $this->_streamUrl = $stream['endpoint']; + } + else { + $this->_streamUrl = $stream; + } + // continue doing this until we get an error back or something...? + $this->httpStream( + 'get', + $this->_streamUrl + ); + return true; + } + + /** + * Close the currently open stream. + * @return true; + */ + public function closeStream(): void + { + if (!$this->_lastStreamActivity) { + // never opened + return; + } + if (!$this->_multiStream) { + throw new phpnutException('You must open a stream before calling closeStream()'); + } + curl_close($this->_currentStream); + curl_multi_remove_handle($this->_multiStream, $this->_currentStream); + curl_multi_close($this->_multiStream); + $this->_currentStream = null; + $this->_multiStream = null; + } + + /** + * Retrieve all streams for the current access token. + * @return array An array of stream definitions. + */ + public function getAllStreams() + { + return $this->httpReq( + 'get', + "{$this->_baseUrl}streams" + ); + } + + /** + * Returns a single stream specified by a stream ID. The stream must have been + * created with the current access token. + * @return array A stream definition + */ + public function getStream(string $streamId) + { + return $this->httpReq( + 'get', + $this->_baseUrl.'streams/'.urlencode($streamId) + ); + } + + /** + * Creates a stream for the current app access token. + * + * @param array $objectTypes The objects you want to retrieve data for from the + * stream. At time of writing these can be 'post', 'bookmark', 'user_follow', 'mute', 'block', 'stream_marker', 'message', 'channel', 'channel_subscription', 'token', and/or 'user'. + * If you don't specify, a few standard events will be retrieved. + */ + public function createStream(?array $objectTypes=null) + { + // default object types to everything + if (is_null($objectTypes)) { + $objectTypes = [ + 'post', + 'bookmark', + 'user_follow', + ]; + } + $data = [ + 'object_types'=>$objectTypes, + 'type'=>'long_poll', + ]; + $data = json_encode($data); + $response = $this->httpReq( + 'post', + "{$this->_baseUrl}streams", + $data, + 'application/json' + ); + return $response; + } + + /** + * Update stream for the current app access token + * + * @param string $streamId The stream ID to update. This stream must have been + * created by the current access token. + * @param array $data allows object_types, type, filter_id and key to be updated. filter_id/key can be omitted + */ + public function updateStream(string $streamId, array $data) + { + // objectTypes is likely required + if (is_null($data['object_types'])) { + $data['object_types'] = [ + 'post', + 'bookmark', + 'user_follow', + ]; + } + // type can still only be long_poll + if (is_null($data['type'])) { + $data['type'] = 'long_poll'; + } + $data = json_encode($data); + $response = $this->httpReq( + 'put', + $this->_baseUrl.'streams/'.urlencode($streamId), + $data, + 'application/json' + ); + return $response; + } + + /** + * Deletes a stream if you no longer need it. + * + * @param string $streamId The stream ID to delete. This stream must have been + * created by the current access token. + */ + public function deleteStream(string $streamId) + { + return $this->httpReq( + 'delete', + $this->_baseUrl.'streams/'.urlencode($streamId) + ); + } + + /** + * Deletes all streams created by the current access token. + */ + public function deleteAllStreams() + { + return $this->httpReq( + 'delete', + "{$this->_baseUrl}streams" + ); + } + + /** + * Internal function used to process incoming chunks from the stream. This is only + * public because it needs to be accessed by CURL. Do not call or use this function + * in your own code. + * @ignore + */ + public function httpStreamReceive($ch, $data) + { + $this->_lastStreamActivity = time(); + $this->_streamBuffer .= $data; + if (!$this->_streamHeaders) { + $pos = strpos($this->_streamBuffer, "\r\n\r\n"); + if ($pos !== false) { + $this->_streamHeaders = substr($this->_streamBuffer, 0, $pos); + $this->_streamBuffer = substr($this->_streamBuffer, $pos+4); + } + } else { + $pos = strpos($this->_streamBuffer, "\r\n"); + while ($pos !== false) { + $command = substr($this->_streamBuffer, 0, $pos); + $this->_streamBuffer = substr($this->_streamBuffer, $pos+2); + $command = json_decode($command, true); + if ($command) { + call_user_func($this->_streamCallback, $command); + } + $pos = strpos($this->_streamBuffer, "\r\n"); + } + } + return strlen($data); + } + + /** + * Opens a long lived HTTP connection to the pnut.io servers, and sends data + * received to the httpStreamReceive function. As a general rule you should not + * directly call this method, it's used by openStream(). + */ + protected function httpStream(string $act, $req, array $params=[], string $contentType='application/x-www-form-urlencoded'): void + { + if ($this->_currentStream) { + throw new phpnutException('There is already an open stream, you must close the existing one before opening a new one'); + } + $headers = []; + $this->_streamBuffer = ''; + if ($this->_accessToken) { + $headers[] = "Authorization: Bearer {$this->_accessToken}"; + } + $this->_currentStream = curl_init($req); + curl_setopt($this->_currentStream, CURLOPT_HTTPHEADER, $headers); + curl_setopt($this->_currentStream, CURLOPT_RETURNTRANSFER, true); + curl_setopt($this->_currentStream, CURLINFO_HEADER_OUT, true); + curl_setopt($this->_currentStream, CURLOPT_HEADER, true); + if ($this->_sslCA) { + curl_setopt($this->_currentStream, CURLOPT_CAINFO, $this->_sslCA); + } + // every time we receive a chunk of data, forward it to httpStreamReceive + curl_setopt($this->_currentStream, CURLOPT_WRITEFUNCTION, array($this, 'httpStreamReceive')); + // curl_exec($ch); + // return; + $this->_multiStream = curl_multi_init(); + $this->_lastStreamActivity = time(); + curl_multi_add_handle($this->_multiStream, $this->_currentStream); + } + + public function reconnectStream(): void + { + $this->closeStream(); + $this->_connectFailCounter++; + // if we've failed a few times, back off + if ($this->_connectFailCounter > 1) { + $sleepTime = pow(2, $this->_connectFailCounter); + // don't sleep more than 60 seconds + if ($sleepTime > 60) { + $sleepTime = 60; + } + sleep($sleepTime); + } + $this->httpStream('get', $this->_streamUrl); + } + + /** + * Process an open stream for x microseconds, then return. This is useful if you want + * to be doing other things while processing the stream. If you just want to + * consume the stream without other actions, you can call processForever() instead. + * @param float @microseconds The number of microseconds to process for before + * returning. There are 1,000,000 microseconds in a second. + * + * @return void + */ + public function processStream($microseconds=null): void + { + if (!$this->_multiStream) { + throw new phpnutException('You must open a stream before calling processStream()'); + } + $start = microtime(true); + $active = null; + $inQueue = null; + $sleepFor = 0; + do { + // if we haven't received anything within 5.5 minutes, reconnect + // keepalives are sent every 5 minutes (measured on 2013-3-12 by @ryantharp) + if (time()-$this->_lastStreamActivity >= 330) { + $this->reconnectStream(); + } + curl_multi_exec($this->_multiStream, $active); + if (!$active) { + $httpCode = curl_getinfo($this->_currentStream, CURLINFO_HTTP_CODE); + // don't reconnect on 400 errors + if ($httpCode >= 400 && $httpCode <= 499) { + throw new phpnutException("Received HTTP error {$httpCode} check your URL and credentials before reconnecting"); + } + $this->reconnectStream(); + } + // sleep for a max of 2/10 of a second + $timeSoFar = (microtime(true)-$start)*1000000; + $sleepFor = $this->streamingSleepFor; + if ($timeSoFar+$sleepFor > $microseconds) { + $sleepFor = $microseconds - $timeSoFar; + } + if ($sleepFor > 0) { + usleep($sleepFor); + } + } while ($timeSoFar+$sleepFor < $microseconds); + } + + /** + * Process an open stream forever. This function will never return, if you + * want to perform other actions while consuming the stream, you should use + * processFor() instead. + * @return void This function will never return + * @see processFor(); + */ + public function processStreamForever(): void + { + while (true) { + $this->processStream(600); + } + } +} diff --git a/pnut/lib/phpnutException.php b/pnut/lib/phpnutException.php new file mode 100644 index 00000000..77e768fe --- /dev/null +++ b/pnut/lib/phpnutException.php @@ -0,0 +1,5 @@ + + * Status: In Development + */ + +require_once 'addon/pnut/lib/phpnut.php'; +require_once 'addon/pnut/lib/phpnutException.php'; + +use Friendica\Content\Text\BBCode; +use Friendica\Content\Text\Plaintext; +use Friendica\Core\Config\Util\ConfigFileManager; +use Friendica\Core\Hook; +use Friendica\Core\Logger; +use Friendica\Core\Renderer; +use Friendica\Core\System; +use Friendica\DI; +use Friendica\Model\Item; +use Friendica\Model\Photo; +use Friendica\Object\Image; +use Friendica\Network\HTTPClient\Client\HttpClientAccept; +use Friendica\Network\HTTPClient\Client\HttpClientOptions; +use Friendica\Util\DateTimeFormat; + +function pnut_install() +{ + Hook::register('load_config', __FILE__, 'pnut_load_config'); + Hook::register('hook_fork', __FILE__, 'pnut_hook_fork'); + Hook::register('post_local', __FILE__, 'pnut_post_local'); + Hook::register('notifier_normal', __FILE__, 'pnut_post_hook'); + Hook::register('jot_networks', __FILE__, 'pnut_jot_nets'); + Hook::register('connector_settings', __FILE__, 'pnut_settings'); + Hook::register('connector_settings_post', __FILE__, 'pnut_settings_post'); +} + +function pnut_module() {} + +function pnut_content() +{ + if (!DI::userSession()->getLocalUserId()) { + DI::sysmsg()->addNotice(DI::l10n()->t('Permission denied.')); + return ''; + } + + if (isset(DI::args()->getArgv()[1])) { + switch (DI::args()->getArgv()[1]) { + case 'connect': + $o = pnut_connect(); + break; + + default: + $o = print_r(DI::args()->getArgv(), true); + break; + } + } else { + $o = pnut_connect(); + } + return $o; +} + +function pnut_connect() +{ + $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); + $client_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + $callback_url = DI::baseUrl() . '/pnut/connect'; + + $nut = new phpnut\phpnut($client_id, $client_secret); + + try { + $token = $nut->getAccessToken($callback_url); + Logger::debug('TOKEN', [$token]); + $o = DI::l10n()->t('You are now authenticated with pnut.io.'); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'access_token', $token); + } catch (phpnutException $e) { + $o = DI::l10n()->t('Error fetching token. Please try again.'); + } + + $o .= '
' . DI::l10n()->t("return to the connector page").''; + + return $o; +} + +function pnut_load_config(ConfigFileManager $loader) +{ + DI::app()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); +} + +function pnut_settings(array &$data) +{ + if (!DI::userSession()->getLocalUserId()) { + return; + } + + $redirectUri = DI::baseUrl() . '/pnut/connect'; + $scope = ['write_post','files']; + + $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post') ?? false; + $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default') ?? false; + $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); + $client_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'access_token'); + + Logger::debug('CLIENT_ID', [$client_id]); + Logger::debug('CLIENT_SECRET', [$client_secret]); + + if (!empty($client_id) && !empty($client_secret) && empty($token)) { + $nut = new phpnut\phpnut($client_id, $client_secret); + $authorize_url = $nut->getAuthUrl($redirectUri, $scope); + $authorize_text = DI::l10n()->t('Authenticate with pnut.io'); + } + + if (!empty($token)) { + $disconn_btn = DI::l10n()->t('Disconnect'); + } + + $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/pnut/'); + $html = Renderer::replaceMacros($t, [ + '$enable' => ['pnut', DI::l10n()->t('Enable Pnut Post Addon'), $enabled], + '$bydefault' => ['pnut_bydefault', DI::l10n()->t('Post to Pnut by default'), $def_enabled], + '$client_id' => ['pnut_client_id', DI::l10n()->t('Client ID'), $client_id], + '$client_secret' => ['pnut_client_secret', DI::l10n()->t('Client Secret'), $client_secret], + '$access_token' => ['pnut_access_token', DI::l10n()->t('Access Token'), $token, '', '', 'readonly'], + '$authorize_url' => $authorize_url ?? '', + '$authorize_text' => $authorize_text ?? '', + '$disconn_btn' => $disconn_btn ?? '', + ]); + + $data = [ + 'connector' => 'pnut', + 'title' => DI::l10n()->t('Pnut Import/Export'), + 'image' => 'addon/pnut/pnut.svg', + 'enabled' => $enabled, + 'html' => $html, + ]; +} + +function pnut_settings_post(array &$b) +{ + if (empty($_POST['pnut-submit']) && empty($_POST['pnut-disconnect'])) { + return; + } + + if (!empty($_POST['pnut-disconnect'])) { + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'pnut', 'post'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'pnut', 'access_token'); + } else { + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'post', intval($_POST['pnut'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default', intval($_POST['pnut_bydefault'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'client_id', $_POST['pnut_client_id']); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret', $_POST['pnut_client_secret']); + } +} + +function pnut_jot_nets(array &$jotnets_fields) +{ + if (!DI::userSession()->getLocalUserId()) { + return; + } + + if (DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post')) { + $jotnets_fields[] = [ + 'type' => 'checkbox', + 'field' => [ + 'pnut_enable', + DI::l10n()->t('Post to Pnut'), + DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default') + ] + ]; + } +} + +function pnut_hook_fork(array &$b) +{ + if ($b['name'] != 'notifier_normal') { + return; + } + + $post = $b['data']; + + if (($post['created'] !== $post['edited']) && !$post['deleted']) { + DI::logger()->info('Editing is not supported by the addon'); + $b['execute'] = false; + return; + } + + if (!strstr($post['postopts'] ?? '', 'pnut') || ($post['parent'] != $post['id']) || $post['private']) { + $b['execute'] = false; + return; + } +} + +function pnut_post_local(array &$b) +{ + if ($b['edit']) { + return; + } + + if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { + return; + } + + if ($b['private'] || $b['parent']) { + return; + } + + $pnut_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post')); + $pnut_enable = (($pnut_post && !empty($_REQUEST['pnut_enable'])) ? intval($_REQUEST['pnut_enable']) : 0); + + // if API is used, default to the chosen settings + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default'))) { + $pnut_enable = 1; + } + + if (!$pnut_enable) { + return; + } + + if (strlen($b['postopts'])) { + $b['postopts'] .= ','; + } + + $b['postopts'] .= 'pnut'; +} + +function pnut_post_hook(array &$b) +{ + /** + * Post to pnut.io + */ + if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + return; + } + + Logger::notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); + Logger::debug('PNUT array', $b); + + $token = DI::pConfig()->get($b['uid'], 'pnut', 'access_token'); + $nut = new phpnut\phpnut($token); + + $msgarr = Plaintext::getPost($b, 256, true, BBCode::EXTERNAL); + $text = $msgarr['text']; + $raw = []; + + Logger::debug('PNUT msgarr', $msgarr); + + if (count($msgarr['parts']) > 1) { + $tstamp = time(); + $raw['nl.chimpnut.blog.post'][] = ['body' => $b['body'], 'tstamp' => $tstamp]; + $text = Plaintext::shorten($text, 252 - strlen($b['plink']), $b['uid']); + $text .= "\n" . $b['plink']; + } + + if ($msgarr['type'] == 'link') { + $text .= "\n[" . $msgarr['title'] . "](" . $msgarr['url'] . ")"; + } + + if ($msgarr['type'] == 'photo') { + $fileraw = ['type' => 'dev.mcmillian.friendica.image', 'kind' => 'image', 'is_public' => true]; + foreach ($msgarr['images'] as $image) { + Logger::debug('PNUT image', $image); + + if (!empty($image['id'])) { + $photo = Photo::selectFirst([], ['id' => $image['id']]); + Logger::debug('PNUT selectFirst'); + } else { + $photo = Photo::createPhotoForExternalResource($image['url']); + Logger::debug('PNUT createPhotoForExternalResource'); + } + $picturedata = Photo::getImageForPhoto($photo); + + Logger::debug('PNUT photo', $photo); + $picurefile = System::getTempPath() . DIRECTORY_SEPARATOR . $photo['filename']; + file_put_contents($picurefile, $picturedata); + Logger::debug('PNUT got file?', ['filename' => $picurefile]); + $imagefile = $nut->createFile($picurefile, $fileraw); + Logger::debug('PNUT file', ['pnutimagefile' => $imagefile]); + unlink($picurefile); + + $raw['io.pnut.core.oembed'][] = ['+io.pnut.core.file' => ['file_id' => $imagefile['id'], 'file_token' => $imagefile['file_token'], 'format' => 'oembed']]; + } + } + + $raw['io.pnut.core.crosspost'][] = ['canonical_url' => $b['plink']]; + $nut->createPost($text, ['raw' => $raw]); + + Logger::debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); +} diff --git a/pnut/pnut.svg b/pnut/pnut.svg new file mode 100644 index 00000000..6cc64b01 --- /dev/null +++ b/pnut/pnut.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pnut/templates/connector_settings.tpl b/pnut/templates/connector_settings.tpl new file mode 100644 index 00000000..7d1ad3f2 --- /dev/null +++ b/pnut/templates/connector_settings.tpl @@ -0,0 +1,12 @@ +

{{$status}}

+{{include file="field_checkbox.tpl" field=$enable}} +{{include file="field_checkbox.tpl" field=$bydefault}} +{{include file="field_input.tpl" field=$client_id}} +{{include file="field_input.tpl" field=$client_secret}} +{{include file="field_input.tpl" field=$access_token}} +{{if $authorize_url}} + {{$authorize_text}} +{{/if}} +{{if $disconn_btn}} +
+{{/if}} From e4bb463b5b36b90018672b8c8fc9c23192ddde4c Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Feb 2024 13:32:24 +0000 Subject: [PATCH 013/294] Bluesky: Several improvements and fixes --- bluesky/bluesky.php | 171 ++++++++++++++++++++------------------------ 1 file changed, 79 insertions(+), 92 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index fe1faab1..b651238b 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -141,7 +141,7 @@ function bluesky_probe_detect(array &$hookData) return; } - $hookData['result'] = bluesky_get_contact_fields($data, 0, false); + $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], false); $hookData['result']['baseurl'] = bluesky_get_pds($did); @@ -942,7 +942,7 @@ function bluesky_fetch_timeline(int $uid, int $last_poll) } foreach (array_reverse($data->feed) as $entry) { - bluesky_process_post($entry->post, $uid, Item::PR_NONE, 0, $last_poll); + bluesky_process_post($entry->post, $uid, $uid, Item::PR_NONE, 0, 0, $last_poll); if (!empty($entry->reason)) { bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); } @@ -1041,18 +1041,21 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) break; case 'mention': - $data = bluesky_process_post($notification, $uid, Item::PR_PUSHED, 0, $last_poll); - Logger::debug('Got mention', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + $contact = bluesky_get_contact($notification->author, 0, $uid); + $result = bluesky_fetch_missing_post($uri, $uid, $uid, $contact['id'], 0, $last_poll); + Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': - $data = bluesky_process_post($notification, $uid, Item::PR_PUSHED, 0, $last_poll); - Logger::debug('Got reply', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + $contact = bluesky_get_contact($notification->author, 0, $uid); + $result = bluesky_fetch_missing_post($uri, $uid, $uid, $contact['id'], 0, $last_poll); + Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': - $data = bluesky_process_post($notification, $uid, Item::PR_PUSHED, 0, $last_poll); - Logger::debug('Got quote', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + $contact = bluesky_get_contact($notification->author, 0, $uid); + $result = bluesky_fetch_missing_post($uri, $uid, $uid, $contact['id'], 0, $last_poll); + Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; default: @@ -1090,15 +1093,12 @@ function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) Logger::debug('Unwanted language detected', ['text' => $entry->post->record->text]); continue; } - $id = bluesky_process_post($entry->post, $uid, Item::PR_TAG, 0, $last_poll); - if (!empty($id)) { - $post = Post::selectFirst(['uri-id'], ['id' => $id]); - if (!empty($post['uri-id'])) { - $stored = Post\Category::storeFileByURIId($post['uri-id'], $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); - Logger::debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); - } else { - Logger::notice('Post not found', ['id' => $id, 'entry' => $entry]); - } + $uri_id = bluesky_process_post($entry->post, $uid, $uid, Item::PR_TAG, 0, 0, $last_poll); + if (!empty($uri_id)) { + $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); + Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); + } else { + Logger::notice('Post not found', ['entry' => $entry]); } if (!empty($entry->reason)) { bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); @@ -1106,22 +1106,23 @@ function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) } } -function bluesky_process_post(stdClass $post, int $uid, int $post_reason, int $level, int $last_poll): int +function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll): int { $uri = bluesky_get_uri($post); - if ($id = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $uid])) { - return $id['id']; + if ($uri_id = bluesky_fetch_uri_id($uri, $uid)) { + return $uri_id; } - if ($id = Post::selectFirst(['id'], ['extid' => $uri, 'uid' => $uid])) { - return $id['id']; + if (empty($post->record)) { + Logger::debug('Invalid post', ['uri' => $uri]); + return 0; } Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); - $item = bluesky_get_header($post, $uri, $uid, $uid); - $item = bluesky_get_content($item, $post->record, $uri, $uid, $uid, $level, $last_poll); + $item = bluesky_get_header($post, $uri, $uid, $fetch_uid); + $item = bluesky_get_content($item, $post->record, $uri, $uid, $fetch_uid, $level, $last_poll); if (empty($item)) { return 0; } @@ -1134,13 +1135,18 @@ function bluesky_process_post(stdClass $post, int $uid, int $post_reason, int $l $item['post-reason'] = $post_reason; } - return Item::insert($item); + if ($causer != 0) { + $item['causer-id'] = $causer; + } + + Item::insert($item); + return bluesky_fetch_uri_id($uri, $uid); } function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid): array { $parts = bluesky_get_uri_parts($uri); - if (empty($post->author)) { + if (empty($post->author) || empty($post->cid) || empty($parts->rkey)) { return []; } $contact = bluesky_get_contact($post->author, $uid, $fetch_uid); @@ -1293,55 +1299,35 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le break; case 'app.bsky.embed.record#view': - $uri = bluesky_get_uri($embed->record); - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => $item['uid']]); - if (empty($shared)) { - if (empty($embed->record->value)) { - Logger::info('Record has got no value', ['record' => $embed->record]); - break; - } - $shared = bluesky_get_header($embed->record, $uri, 0, $fetch_uid); - $shared = bluesky_get_content($shared, $embed->record->value, $uri, $item['uid'], $fetch_uid, $level, $last_poll); - if (!empty($shared)) { - if (!empty($embed->record->embeds)) { - foreach ($embed->record->embeds as $single) { - $shared = bluesky_add_media($single, $shared, $fetch_uid, $level, $last_poll); - } - } - Item::insert($shared); - } + $original_uri = $uri = bluesky_get_uri($embed->record); + $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, $item['contact-id'], $level, $last_poll); + if ($uri) { + $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); + $uri_id = $shared['uri-id'] ?? 0; } - if (!empty($shared['uri-id'])) { - $item['quote-uri-id'] = $shared['uri-id']; + if (!empty($uri_id)) { + $item['quote-uri-id'] = $uri_id; + } else { + Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); } break; case 'app.bsky.embed.recordWithMedia#view': - $uri = bluesky_get_uri($embed->record->record); - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => $item['uid']]); - if (empty($shared)) { - $shared = bluesky_get_header($embed->record->record, $uri, 0, $fetch_uid); - $shared = bluesky_get_content($shared, $embed->record->record->value, $uri, $item['uid'], $fetch_uid, $level, $last_poll); - if (!empty($shared)) { - if (!empty($embed->record->record->embeds)) { - foreach ($embed->record->record->embeds as $single) { - $shared = bluesky_add_media($single, $shared, $fetch_uid, $level, $last_poll); - } - } - Item::insert($shared); - } + $original_uri = $uri = bluesky_get_uri($embed->record->record); + $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, $item['contact-id'], $level, $last_poll); + if ($uri) { + $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); + $uri_id = $shared['uri-id'] ?? 0; } - if (!empty($shared['uri-id'])) { - $item['quote-uri-id'] = $shared['uri-id']; - } - - if (!empty($embed->media)) { - $item = bluesky_add_media($embed->media, $item, $fetch_uid, $level, $last_poll); + if (!empty($uri_id)) { + $item['quote-uri-id'] = $uri_id; + } else { + Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); } break; default: - Logger::notice('Unhandled embed type', ['type' => $embed->$type, 'embed' => $embed]); + Logger::notice('Unhandled embed type', ['uri-id' => $item['uri-id'], 'type' => $embed->$type, 'embed' => $embed]); break; } return $item; @@ -1449,6 +1435,21 @@ function bluesky_fetch_post(string $uri, int $uid): string return ''; } +function bluesky_fetch_uri_id(string $uri, int $uid): string +{ + $reply = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$uid, 0]]); + if (!empty($reply['uri-id'])) { + Logger::debug('Post with extid exists', ['uri' => $uri]); + return $reply['uri-id']; + } + $reply = Post::selectFirst(['uri-id'], ['extid' => $uri, 'uid' => [$uid, 0]]); + if (!empty($reply['uri-id'])) { + Logger::debug('Post with extid exists', ['uri' => $uri]); + return $reply['uri-id']; + } + return 0; +} + function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, array $cdata, int $level, int $last_poll): string { if (empty($thread->post)) { @@ -1459,27 +1460,12 @@ function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, arra $fetched_uri = bluesky_fetch_post($uri, $uid); if (empty($fetched_uri)) { - Logger::debug('Process missing post', ['uri' => $uri]); - $item = bluesky_get_header($thread->post, $uri, $uid, $uid); - $item = bluesky_get_content($item, $thread->post->record, $uri, $uid, $fetch_uid, $level, $last_poll); - if (!empty($item)) { - $item['post-reason'] = Item::PR_FETCHED; - - if (!empty($cdata['public'])) { - $item['causer-id'] = $cdata['public']; - } - - if (!empty($thread->post->embed)) { - $item = bluesky_add_media($thread->post->embed, $item, $uid, $level, $last_poll); - } - $id = Item::insert($item); - if (!$id) { - Logger::info('Item has not not been stored', ['uri' => $uri]); - return ''; - } - Logger::debug('Stored item', ['id' => $id, 'uri' => $uri]); + $uri_id = bluesky_process_post($thread->post, $uid, $fetch_uid, Item::PR_FETCHED, $cdata['public'], $level, $last_poll); + if ($uri_id) { + Logger::debug('Post has been processed and stored', ['uri-id' => $uri_id, 'uri' => $uri]); + return $uri; } else { - Logger::info('Post has not not been fetched', ['uri' => $uri]); + Logger::info('Post has not not been stored', ['uri' => $uri]); return ''; } } else { @@ -1502,7 +1488,7 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array $update = empty($contact) || $contact['updated'] < DateTimeFormat::utc('now -24 hours'); - $public_fields = $fields = bluesky_get_contact_fields($author, $fetch_uid, $update); + $public_fields = $fields = bluesky_get_contact_fields($author, $uid, $fetch_uid, $update); $public_fields['uid'] = 0; $public_fields['rel'] = Contact::NOTHING; @@ -1543,8 +1529,9 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array return Contact::getById($cid); } -function bluesky_get_contact_fields(stdClass $author, int $uid, bool $update): array +function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array { + $nick = $author->handle ?? $author->did; $fields = [ 'uid' => $uid, 'network' => Protocol::BLUESKY, @@ -1555,10 +1542,10 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, bool $update): a 'pending' => false, 'url' => $author->did, 'nurl' => $author->did, - 'alias' => BLUESKY_WEB . '/profile/' . $author->handle, - 'name' => $author->displayName ?? $author->handle, - 'nick' => $author->handle, - 'addr' => $author->handle, + 'alias' => BLUESKY_WEB . '/profile/' . $nick, + 'name' => $author->displayName ?? $nick, + 'nick' => $nick, + 'addr' => $nick, ]; if (!$update) { @@ -1572,7 +1559,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, bool $update): a $fields['gsid'] = GServer::getID($fields['baseurl'], true); } - $data = bluesky_xrpc_get($uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); + $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); if (empty($data)) { Logger::debug('Error fetching contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; From 2b5f8e9c82c2bae768b5b38a18a4587ce34020e8 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 23 Feb 2024 14:04:06 +0000 Subject: [PATCH 014/294] Fix coding standards --- bluesky/bluesky.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index b651238b..5fa2f32f 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1019,7 +1019,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) } else { Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } - break; + break; case 'repost': $item = bluesky_get_header($notification, $uri, $uid, $uid); @@ -1033,7 +1033,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) } else { Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } - break; + break; case 'follow': $contact = bluesky_get_contact($notification->author, $uid, $uid); @@ -1531,7 +1531,7 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array { - $nick = $author->handle ?? $author->did; + $nick = $author->handle ?: $author->did; $fields = [ 'uid' => $uid, 'network' => Protocol::BLUESKY, @@ -1543,7 +1543,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, 'url' => $author->did, 'nurl' => $author->did, 'alias' => BLUESKY_WEB . '/profile/' . $nick, - 'name' => $author->displayName ?? $nick, + 'name' => $author->displayName ?: $nick, 'nick' => $nick, 'addr' => $nick, ]; @@ -1741,7 +1741,6 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl $data = bluesky_get(bluesky_get_user_pds($uid) . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]]); DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); return $data; - } function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass From bcef83e14852d4bcab31fcc533a05ec96ebfcfb8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Feb 2024 06:48:19 +0000 Subject: [PATCH 015/294] Set post reasons --- bluesky/bluesky.php | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 5fa2f32f..7da7d6b5 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -183,7 +183,7 @@ function bluesky_item_by_link(array &$hookData) $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; - $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], 0, 0); + $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); Logger::debug('Got post', ['profile' => $matches[1], 'cid' => $matches[2], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); @@ -1012,7 +1012,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::LIKE; $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); if (!empty($item['thr-parent'])) { $data = Item::insert($item); Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); @@ -1026,7 +1026,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::ANNOUNCE; $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); if (!empty($item['thr-parent'])) { $data = Item::insert($item); Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); @@ -1042,19 +1042,19 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) case 'mention': $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, $contact['id'], 0, $last_poll); + $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_TO, $contact['id'], 0, $last_poll); Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, $contact['id'], 0, $last_poll); + $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_COMMENT, $contact['id'], 0, $last_poll); Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, $contact['id'], 0, $last_poll); + $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_PUSHED, $contact['id'], 0, $last_poll); Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; @@ -1187,7 +1187,7 @@ function bluesky_get_content(array $item, stdClass $record, string $uri, int $ui if (!empty($record->reply)) { $item['parent-uri'] = bluesky_get_uri($record->reply->root); if ($item['parent-uri'] != $uri) { - $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, $item['contact-id'], $level, $last_poll); + $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, Item::PR_COMPLETION, $item['contact-id'], $level, $last_poll); if (empty($item['parent-uri'])) { return []; } @@ -1195,7 +1195,7 @@ function bluesky_get_content(array $item, stdClass $record, string $uri, int $ui $item['thr-parent'] = bluesky_get_uri($record->reply->parent); if (!in_array($item['thr-parent'], [$uri, $item['parent-uri']])) { - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, $item['contact-id'], $level, $last_poll, $item['parent-uri']); + $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, Item::PR_COMPLETION, $item['contact-id'], $level, $last_poll, $item['parent-uri']); if (empty($item['thr-parent'])) { return []; } @@ -1300,7 +1300,7 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le case 'app.bsky.embed.record#view': $original_uri = $uri = bluesky_get_uri($embed->record); - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, $item['contact-id'], $level, $last_poll); + $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); if ($uri) { $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); $uri_id = $shared['uri-id'] ?? 0; @@ -1314,7 +1314,7 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le case 'app.bsky.embed.recordWithMedia#view': $original_uri = $uri = bluesky_get_uri($embed->record->record); - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, $item['contact-id'], $level, $last_poll); + $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); if ($uri) { $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); $uri_id = $shared['uri-id'] ?? 0; @@ -1385,7 +1385,7 @@ function bluesky_get_uri_parts(string $uri): ?stdClass return $class; } -function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $causer, int $level, int $last_poll = 0, string $fallback = ''): string +function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = ''): string { $fetched_uri = bluesky_fetch_post($uri, $uid); if (!empty($fetched_uri)) { @@ -1413,11 +1413,10 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ if ($causer != 0) { $cdata = Contact::getPublicAndUserContactID($causer, $uid); - } else { - $cdata = []; + $causer = $cdata['public'] ?? 0; } - return bluesky_process_thread($data->thread, $uid, $fetch_uid, $cdata, $level, $last_poll); + return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); } function bluesky_fetch_post(string $uri, int $uid): string @@ -1450,7 +1449,7 @@ function bluesky_fetch_uri_id(string $uri, int $uid): string return 0; } -function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, array $cdata, int $level, int $last_poll): string +function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll): string { if (empty($thread->post)) { Logger::info('Invalid post', ['post' => $thread]); @@ -1460,7 +1459,7 @@ function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, arra $fetched_uri = bluesky_fetch_post($uri, $uid); if (empty($fetched_uri)) { - $uri_id = bluesky_process_post($thread->post, $uid, $fetch_uid, Item::PR_FETCHED, $cdata['public'], $level, $last_poll); + $uri_id = bluesky_process_post($thread->post, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); if ($uri_id) { Logger::debug('Post has been processed and stored', ['uri-id' => $uri_id, 'uri' => $uri]); return $uri; @@ -1474,7 +1473,7 @@ function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, arra } foreach ($thread->replies ?? [] as $reply) { - $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, $cdata, $level, $last_poll); + $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, Item::PR_COMPLETION, $causer, $level, $last_poll); Logger::debug('Reply has been processed', ['uri' => $uri, 'reply' => $reply_uri]); } @@ -1531,7 +1530,7 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array { - $nick = $author->handle ?: $author->did; + $nick = $author->handle ?? $author->did; $fields = [ 'uid' => $uid, 'network' => Protocol::BLUESKY, @@ -1543,7 +1542,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, 'url' => $author->did, 'nurl' => $author->did, 'alias' => BLUESKY_WEB . '/profile/' . $nick, - 'name' => $author->displayName ?: $nick, + 'name' => $author->displayName ?? $nick, 'nick' => $nick, 'addr' => $nick, ]; From 6d578d14952251e4826103d8ab035c8dbd9dee69 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Feb 2024 08:26:06 +0000 Subject: [PATCH 016/294] Changed post reason --- bluesky/bluesky.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 7da7d6b5..5e3de1a0 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1187,7 +1187,7 @@ function bluesky_get_content(array $item, stdClass $record, string $uri, int $ui if (!empty($record->reply)) { $item['parent-uri'] = bluesky_get_uri($record->reply->root); if ($item['parent-uri'] != $uri) { - $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, Item::PR_COMPLETION, $item['contact-id'], $level, $last_poll); + $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); if (empty($item['parent-uri'])) { return []; } @@ -1195,7 +1195,7 @@ function bluesky_get_content(array $item, stdClass $record, string $uri, int $ui $item['thr-parent'] = bluesky_get_uri($record->reply->parent); if (!in_array($item['thr-parent'], [$uri, $item['parent-uri']])) { - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, Item::PR_COMPLETION, $item['contact-id'], $level, $last_poll, $item['parent-uri']); + $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll, $item['parent-uri']); if (empty($item['thr-parent'])) { return []; } @@ -1473,7 +1473,7 @@ function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, int } foreach ($thread->replies ?? [] as $reply) { - $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, Item::PR_COMPLETION, $causer, $level, $last_poll); + $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll); Logger::debug('Reply has been processed', ['uri' => $uri, 'reply' => $reply_uri]); } From 346e22c5f5ec44716c28f8447ba9844a1b375f14 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 24 Feb 2024 08:28:34 +0000 Subject: [PATCH 017/294] Tumblr: Fixed token exchange --- tumblr/tumblr.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index d6508ff8..12e9e5e0 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -1479,7 +1479,7 @@ function tumblr_exchange_token(int $uid): stdClass ]); $response = $client->post('oauth2/exchange', ['auth' => 'oauth']); - return json_decode($response->getBodyString()->getContents()); + return json_decode($response->getBody()->getContents()); } catch (RequestException $exception) { Logger::notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); return new stdClass; From 7580054394a069a754c8e64acff1b036caba3950 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 1 Mar 2024 05:53:42 +0000 Subject: [PATCH 018/294] Bluesky: fix problems with links and hashtags --- bluesky/bluesky.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 5e3de1a0..db60d1a4 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -764,7 +764,7 @@ function bluesky_get_urls(string $body): array if (preg_match_all("/#\[url\=(https?:.*?)\](.*?)\[\/url\]/ism", $body, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { $text = '#' . $match[2]; - $urls[] = ['tag' => $match[2], 'text' => $text, 'hash' => $text]; + $urls[strpos($body, $match[0])] = ['tag' => $match[2], 'text' => $text, 'hash' => $text]; $body = str_replace($match[0], $text, $body); } } @@ -774,7 +774,7 @@ function bluesky_get_urls(string $body): array foreach ($matches as $match) { $text = Strings::getStyledURL($match[1]); $hash = bluesky_get_hash_for_url($match[0], mb_strlen($text)); - $urls[] = ['url' => $match[1], 'text' => $text, 'hash' => $hash]; + $urls[strpos($body, $match[0])] = ['url' => $match[1], 'text' => $text, 'hash' => $hash]; $body = str_replace($match[0], $hash, $body); } } @@ -789,17 +789,19 @@ function bluesky_get_urls(string $body): array } if (mb_strlen($text) < 100) { $hash = bluesky_get_hash_for_url($match[0], mb_strlen($text)); - $urls[] = ['url' => $match[1], 'text' => $text, 'hash' => $hash]; + $urls[strpos($body, $match[0])] = ['url' => $match[1], 'text' => $text, 'hash' => $hash]; $body = str_replace($match[0], $hash, $body); } else { $text = Strings::getStyledURL($match[1]); $hash = bluesky_get_hash_for_url($match[0], mb_strlen($text)); - $urls[] = ['url' => $match[1], 'text' => $text, 'hash' => $hash]; + $urls[strpos($body, $match[0])] = ['url' => $match[1], 'text' => $text, 'hash' => $hash]; $body = str_replace($match[0], $text . ' ' . $hash, $body); } } } + asort($urls); + return ['body' => $body, 'urls' => $urls]; } From 5f7233fd20b85560ce903f7f26df405daf0414e2 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 28 Feb 2024 03:05:57 +0000 Subject: [PATCH 019/294] Bluesky: Enabled support for Friendica handles --- bluesky/bluesky.php | 56 +++++++++++++----- bluesky/lang/C/messages.po | 73 +++++++++++++++++------- bluesky/templates/admin.tpl | 2 + bluesky/templates/connector_settings.tpl | 1 + 4 files changed, 96 insertions(+), 36 deletions(-) create mode 100644 bluesky/templates/admin.tpl diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index db60d1a4..5fc0a4f0 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -42,6 +42,7 @@ use Friendica\Model\ItemURI; use Friendica\Model\Photo; use Friendica\Model\Post; use Friendica\Model\Tag; +use Friendica\Model\User; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Object\Image; @@ -316,20 +317,44 @@ function bluesky_unblock(array &$hook_data) $hook_data['result'] = true; } +function bluesky_addon_admin(string &$o) +{ + $t = Renderer::getMarkupTemplate('admin.tpl', 'addon/bluesky/'); + + $o = Renderer::replaceMacros($t, [ + '$submit' => DI::l10n()->t('Save Settings'), + '$friendica_handles' => ['friendica_handles', DI::l10n()->t('Allow your users to use your hostname for their Bluesky handles'), DI::config()->get('bluesky', 'friendica_handles'), DI::l10n()->t('Before enabling this option, you have to download and configure the bluesky-handles repository on your system. See https://git.friendi.ca/heluecht/bluesky-handles')], + ]); +} + +function bluesky_addon_admin_post() +{ + DI::config()->set('bluesky', 'friendica_handles', (bool)$_POST['friendica_handles']); +} + function bluesky_settings(array &$data) { if (!DI::userSession()->getLocalUserId()) { return; } - $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false; - $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; - $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); - $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); - $did = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'did'); - $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); - $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; - $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; + $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false; + $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; + $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); + $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); + $did = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'did'); + $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); + $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; + $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; + $custom_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle') ?? false; + + if (DI::config()->get('bluesky', 'friendica_handles')) { + $self = User::getById(DI::userSession()->getLocalUserId(), ['nickname']); + $handle = $self['nickname'] . '.' . DI::baseUrl()->getHost(); + $friendica_handle = ['bluesky_friendica_handle', DI::l10n()->t('Allow to use %s as your Bluesky handle.', $handle), $custom_handle, DI::l10n()->t('When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select "No DNS Panel". Then select "Verify Text File".', $handle, $handle)]; + } else { + $friendica_handle = []; + } $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/bluesky/'); $html = Renderer::replaceMacros($t, [ @@ -337,6 +362,7 @@ function bluesky_settings(array &$data) '$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled], '$import' => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import], '$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')], + '$custom_handle' => $friendica_handle, '$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'], '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle], '$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'], @@ -404,11 +430,12 @@ function bluesky_settings_post(array &$b) $handle = trim($_POST['bluesky_handle'], ' @'); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post', intval($_POST['bluesky'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post', intval($_POST['bluesky'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'])); if (!empty($handle)) { if (empty($old_did) || $old_handle != $handle) { @@ -1533,6 +1560,7 @@ function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array { $nick = $author->handle ?? $author->did; + $name = $author->displayName ?? $nick; $fields = [ 'uid' => $uid, 'network' => Protocol::BLUESKY, @@ -1544,7 +1572,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, 'url' => $author->did, 'nurl' => $author->did, 'alias' => BLUESKY_WEB . '/profile/' . $nick, - 'name' => $author->displayName ?? $nick, + 'name' => $name ?: $nick, 'nick' => $nick, 'addr' => $nick, ]; diff --git a/bluesky/lang/C/messages.po b/bluesky/lang/C/messages.po index 132e608a..0d69cc10 100644 --- a/bluesky/lang/C/messages.po +++ b/bluesky/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-06 06:30+0000\n" +"POT-Creation-Date: 2024-02-28 03:05+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,100 +17,129 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: bluesky.php:336 +#: bluesky.php:325 +msgid "Save Settings" +msgstr "" + +#: bluesky.php:326 +msgid "Allow your users to use your hostname for their Bluesky handles" +msgstr "" + +#: bluesky.php:326 +msgid "" +"Before enabling this option, you have to download and configure the bluesky-" +"handles repository on your system. See https://git.friendi.ca/heluecht/" +"bluesky-handles" +msgstr "" + +#: bluesky.php:354 +#, php-format +msgid "Allow to use %s as your Bluesky handle." +msgstr "" + +#: bluesky.php:354 +#, php-format +msgid "" +"When enabled, you can use %s as your Bluesky handle. After you enabled this " +"option, please go to https://bsky.app/settings and select to change your " +"handle. Select that you have got your own domain. Then enter %s and select " +"\"No DNS Panel\". Then select \"Verify Text File\"." +msgstr "" + +#: bluesky.php:361 msgid "Enable Bluesky Post Addon" msgstr "" -#: bluesky.php:337 +#: bluesky.php:362 msgid "Post to Bluesky by default" msgstr "" -#: bluesky.php:338 +#: bluesky.php:363 msgid "Import the remote timeline" msgstr "" -#: bluesky.php:339 +#: bluesky.php:364 msgid "Import the pinned feeds" msgstr "" -#: bluesky.php:339 +#: bluesky.php:364 msgid "" "When activated, Posts will be imported from all the feeds that you pinned in " "Bluesky." msgstr "" -#: bluesky.php:340 +#: bluesky.php:366 msgid "Personal Data Server" msgstr "" -#: bluesky.php:340 +#: bluesky.php:366 msgid "The personal data server (PDS) is the system that hosts your profile." msgstr "" -#: bluesky.php:341 +#: bluesky.php:367 msgid "Bluesky handle" msgstr "" -#: bluesky.php:342 +#: bluesky.php:368 msgid "Bluesky DID" msgstr "" -#: bluesky.php:342 +#: bluesky.php:368 msgid "" "This is the unique identifier. It will be fetched automatically, when the " "handle is entered." msgstr "" -#: bluesky.php:343 +#: bluesky.php:369 msgid "Bluesky app password" msgstr "" -#: bluesky.php:343 +#: bluesky.php:369 msgid "" "Please don't add your real password here, but instead create a specific app " "password in the Bluesky settings." msgstr "" -#: bluesky.php:349 +#: bluesky.php:375 msgid "Bluesky Import/Export" msgstr "" -#: bluesky.php:359 +#: bluesky.php:385 msgid "" "You are not authenticated. Please enter your handle and the app password." msgstr "" -#: bluesky.php:379 +#: bluesky.php:405 msgid "" "You are authenticated to Bluesky. For security reasons the password isn't " "stored." msgstr "" -#: bluesky.php:381 +#: bluesky.php:407 msgid "" "The communication with the personal data server service (PDS) is established." msgstr "" -#: bluesky.php:383 +#: bluesky.php:409 msgid "Communication issues with the personal data server service (PDS)." msgstr "" -#: bluesky.php:385 +#: bluesky.php:411 msgid "" "The DID for the provided handle could not be detected. Please check if you " "entered the correct handle." msgstr "" -#: bluesky.php:387 +#: bluesky.php:413 msgid "The personal data server service (PDS) could not be detected." msgstr "" -#: bluesky.php:389 +#: bluesky.php:415 msgid "" "The authentication with the provided handle and password failed. Please " "check if you entered the correct password." msgstr "" -#: bluesky.php:457 +#: bluesky.php:484 msgid "Post to Bluesky" msgstr "" diff --git a/bluesky/templates/admin.tpl b/bluesky/templates/admin.tpl new file mode 100644 index 00000000..7b752a88 --- /dev/null +++ b/bluesky/templates/admin.tpl @@ -0,0 +1,2 @@ +{{include file="field_checkbox.tpl" field=$friendica_handles}} +
diff --git a/bluesky/templates/connector_settings.tpl b/bluesky/templates/connector_settings.tpl index db5ac5d5..f50e9cc6 100644 --- a/bluesky/templates/connector_settings.tpl +++ b/bluesky/templates/connector_settings.tpl @@ -3,6 +3,7 @@ {{include file="field_checkbox.tpl" field=$bydefault}} {{include file="field_checkbox.tpl" field=$import}} {{include file="field_checkbox.tpl" field=$import_feeds}} +{{include file="field_checkbox.tpl" field=$custom_handle}} {{include file="field_input.tpl" field=$pds}} {{include file="field_input.tpl" field=$handle}} {{include file="field_input.tpl" field=$did}} From 2ee78d2f0b771871817440e22abf96de4bc45561 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 2 Mar 2024 13:32:11 +0000 Subject: [PATCH 020/294] Bluesky: Handle media links and shared posts --- bluesky/bluesky.php | 86 ++++++++++++++++++++++-- bluesky/templates/connector_settings.tpl | 4 +- 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 5fc0a4f0..cdedb07a 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -717,8 +717,24 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $language = ''; } - $did = DI::pConfig()->get($uid, 'bluesky', 'did'); - $urls = bluesky_get_urls(Post\Media::removeFromBody($item['body'])); + $item['body'] = Post\Media::removeFromBody($item['body']); + + foreach (Post\Media::getByURIId($item['uri-id'], [Post\Media::AUDIO, Post\Media::VIDEO, Post\Media::ACTIVITY]) as $media) { + if (strpos($item['body'], $media['url']) === false) { + $item['body'] .= "\n[url]" . $media['url'] . "[/url]\n"; + } + } + + if (!empty($item['quote-uri-id'])) { + $quote = Post::selectFirstPost(['uri', 'plink'], ['uri-id' => $item['quote-uri-id']]); + if (!empty($quote)) { + if ((strpos($item['body'], $quote['plink'] ?: $quote['uri']) === false) && (strpos($item['body'], $quote['uri']) === false)) { + $item['body'] .= "\n[url]" . ($quote['plink'] ?: $quote['uri']) . "[/url]\n"; + } + } + } + + $urls = bluesky_get_urls($item['body']); $item['body'] = $urls['body']; $msg = Plaintext::getPost($item, 300, false, BBCode::BLUESKY); @@ -756,7 +772,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $post = [ 'collection' => 'app.bsky.feed.post', - 'repo' => $did, + 'repo' => DI::pConfig()->get($uid, 'bluesky', 'did'), 'record' => $record ]; @@ -1646,13 +1662,59 @@ function bluesky_get_preferences(int $uid): stdClass return $data; } -function bluesky_get_did(string $handle): string +function bluesky_get_did_by_wellknown(string $handle): string { - $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (empty($data)) { + $curlResult = DI::httpClient()->get('http://' . $handle . '/.well-known/atproto-did'); + if ($curlResult->isSuccess() && substr($curlResult->getBodyString(), 0, 4) == 'did:') { + $did = $curlResult->getBodyString(); + if (!bluesky_valid_did($did, $handle)) { + Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); + return ''; + } + Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); + return $did; + } + return ''; +} + +function bluesky_get_did_by_dns(string $handle): string +{ + $records = @dns_get_record('_atproto.' . $handle . '.', DNS_TXT); + if (empty($records)) { return ''; } - Logger::debug('Got DID', ['return' => $data]); + foreach ($records as $record) { + if (!empty($record['txt']) && substr($record['txt'], 0, 4) == 'did=') { + $did = substr($record['txt'], 4); + if (!bluesky_valid_did($did, $handle)) { + Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); + return ''; + } + Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); + return $did; + } + } + return ''; +} + +function bluesky_get_did(string $handle): string +{ + // Deactivated at the moment, since it isn't reliable by now + //$did = bluesky_get_did_by_dns($handle); + //if ($did != '') { + // return $did; + //} + + //$did = bluesky_get_did_by_wellknown($handle); + //if ($did != '') { + // return $did; + //} + + $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); + if (empty($data) || empty($data->did)) { + return ''; + } + Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); return $data->did; } @@ -1688,6 +1750,16 @@ function bluesky_get_pds(string $did): ?string return null; } +function bluesky_valid_did(string $did, string $handle): bool +{ + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + if (empty($data) || empty($data->alsoKnownAs)) { + return false; + } + + return in_array('at://' . $handle, $data->alsoKnownAs); +} + function bluesky_get_token(int $uid): string { $token = DI::pConfig()->get($uid, 'bluesky', 'access_token'); diff --git a/bluesky/templates/connector_settings.tpl b/bluesky/templates/connector_settings.tpl index f50e9cc6..3ebea827 100644 --- a/bluesky/templates/connector_settings.tpl +++ b/bluesky/templates/connector_settings.tpl @@ -3,7 +3,9 @@ {{include file="field_checkbox.tpl" field=$bydefault}} {{include file="field_checkbox.tpl" field=$import}} {{include file="field_checkbox.tpl" field=$import_feeds}} -{{include file="field_checkbox.tpl" field=$custom_handle}} +{{if $custom_handle}} + {{include file="field_checkbox.tpl" field=$custom_handle}} +{{/if}} {{include file="field_input.tpl" field=$pds}} {{include file="field_input.tpl" field=$handle}} {{include file="field_input.tpl" field=$did}} From 58cb9337790883569cdee8c788e415e923dbf2d4 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 3 Mar 2024 17:47:42 +0800 Subject: [PATCH 021/294] do not mail dislike messages --- mailstream/mailstream.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index 968ee4c0..b513cf36 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -169,6 +169,10 @@ function mailstream_post_hook(array &$item) Logger::debug('mailstream: like item ' . $item['id']); return; } + if ($item['verb'] == Activity::DISLIKE) { + Logger::debug('mailstream: dislike item ' . $item['id']); + return; + } } $message_id = mailstream_generate_id($item['uri']); From dcafad573ea4320262e90e6107cbbd36faada2e0 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 3 Mar 2024 12:02:53 +0000 Subject: [PATCH 022/294] Pnut: Client Id/Secret can be set by admins --- pnut/README.md | 5 +- pnut/lang/C/messages.po | 74 +++++++++++++++++++++++ pnut/pnut.php | 86 ++++++++++++++++++--------- pnut/templates/admin.tpl | 3 + pnut/templates/connector_settings.tpl | 8 ++- 5 files changed, 145 insertions(+), 31 deletions(-) create mode 100644 pnut/lang/C/messages.po create mode 100644 pnut/templates/admin.tpl diff --git a/pnut/README.md b/pnut/README.md index d935efe7..6f6a9224 100644 --- a/pnut/README.md +++ b/pnut/README.md @@ -2,4 +2,7 @@ With this addon to friendica you can give your users the possibility to post their *public* messages to pnut.io. -No setup is needed for the admins to make it work for their users. +No setup is needed for the admins to make it work for their users, however it is possible for the admin to create a client, so that the users don't have to. + +To do so, go to https://pnut.io/dev and scroll down to "Create New Client". Enter a name of your choice and enter your Friendica host name as the website. Use https://(yourhost.name)/pnut/connect as a redirect url, replace "(yourhost.name)" with the host name of your system. +Limit the scope to "basic,files,follow,polls,presence,stream,update_profile,write_post" \ No newline at end of file diff --git a/pnut/lang/C/messages.po b/pnut/lang/C/messages.po new file mode 100644 index 00000000..89b065fd --- /dev/null +++ b/pnut/lang/C/messages.po @@ -0,0 +1,74 @@ +# ADDON pnut +# Copyright (C) +# This file is distributed under the same license as the Friendica pnut addon package. +# +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-03-03 11:53+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: pnut.php:42 +msgid "Permission denied." +msgstr "" + +#: pnut.php:79 +msgid "You are now authenticated with pnut.io." +msgstr "" + +#: pnut.php:82 +msgid "Error fetching token. Please try again." +msgstr "" + +#: pnut.php:85 +msgid "return to the connector page" +msgstr "" + +#: pnut.php:103 +msgid "Save Settings" +msgstr "" + +#: pnut.php:104 pnut.php:150 +msgid "Client ID" +msgstr "" + +#: pnut.php:105 pnut.php:151 +msgid "Client Secret" +msgstr "" + +#: pnut.php:139 +msgid "Authenticate with pnut.io" +msgstr "" + +#: pnut.php:143 +msgid "Disconnect" +msgstr "" + +#: pnut.php:148 +msgid "Enable Pnut Post Addon" +msgstr "" + +#: pnut.php:149 +msgid "Post to Pnut by default" +msgstr "" + +#: pnut.php:152 +msgid "Access Token" +msgstr "" + +#: pnut.php:161 +msgid "Pnut Export" +msgstr "" + +#: pnut.php:203 +msgid "Post to Pnut" +msgstr "" diff --git a/pnut/pnut.php b/pnut/pnut.php index f278fb55..e84f208b 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -2,7 +2,7 @@ /** * Name: Pnut Connector * Description: Post to pnut.io - * Version: 0.1.1 + * Version: 0.1.2 * Author: Morgan McMillian * Status: In Development */ @@ -18,12 +18,10 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; -use Friendica\Model\Item; use Friendica\Model\Photo; -use Friendica\Object\Image; -use Friendica\Network\HTTPClient\Client\HttpClientAccept; -use Friendica\Network\HTTPClient\Client\HttpClientOptions; -use Friendica\Util\DateTimeFormat; +use phpnut\phpnutException; + +const PNUT_LIMIT = 256; function pnut_install() { @@ -63,19 +61,25 @@ function pnut_content() function pnut_connect() { - $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); - $client_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + $client_id = DI::config()->get('pnut', 'client_id'); + $client_secret = DI::config()->get('pnut', 'client_secret'); + + if (empty($client_id) || empty($client_secret)) { + $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); + $client_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + } + $callback_url = DI::baseUrl() . '/pnut/connect'; $nut = new phpnut\phpnut($client_id, $client_secret); try { $token = $nut->getAccessToken($callback_url); - Logger::debug('TOKEN', [$token]); + Logger::debug('Got Token', [$token]); $o = DI::l10n()->t('You are now authenticated with pnut.io.'); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'access_token', $token); } catch (phpnutException $e) { - $o = DI::l10n()->t('Error fetching token. Please try again.'); + $o = DI::l10n()->t('Error fetching token. Please try again.', ['code' => $e->getCode(), 'message' => $e->getMessage()]); } $o .= '
' . DI::l10n()->t("return to the connector page").''; @@ -88,6 +92,26 @@ function pnut_load_config(ConfigFileManager $loader) DI::app()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } +function pnut_addon_admin(string &$o) +{ + $client_id = DI::config()->get('pnut', 'client_id'); + $client_secret = DI::config()->get('pnut', 'client_secret'); + + $t = Renderer::getMarkupTemplate('admin.tpl', 'addon/pnut/'); + + $o = Renderer::replaceMacros($t, [ + '$submit' => DI::l10n()->t('Save Settings'), + '$client_id' => ['pnut_client_id', DI::l10n()->t('Client ID'), $client_id], + '$client_secret' => ['pnut_client_secret', DI::l10n()->t('Client Secret'), $client_secret], + ]); +} + +function pnut_addon_admin_post() +{ + DI::config()->set('pnut', 'client_id', $_POST['pnut_client_id']); + DI::config()->set('pnut', 'client_secret', $_POST['pnut_client_secret']); +} + function pnut_settings(array &$data) { if (!DI::userSession()->getLocalUserId()) { @@ -99,12 +123,15 @@ function pnut_settings(array &$data) $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post') ?? false; $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default') ?? false; - $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); - $client_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + $client_id = DI::config()->get('pnut', 'client_id'); + $client_secret = DI::config()->get('pnut', 'client_secret'); $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'access_token'); - - Logger::debug('CLIENT_ID', [$client_id]); - Logger::debug('CLIENT_SECRET', [$client_secret]); + + $user_client = empty($client_id) || empty($client_secret); + if ($user_client) { + $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); + $client_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret'); + } if (!empty($client_id) && !empty($client_secret) && empty($token)) { $nut = new phpnut\phpnut($client_id, $client_secret); @@ -118,19 +145,20 @@ function pnut_settings(array &$data) $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/pnut/'); $html = Renderer::replaceMacros($t, [ - '$enable' => ['pnut', DI::l10n()->t('Enable Pnut Post Addon'), $enabled], - '$bydefault' => ['pnut_bydefault', DI::l10n()->t('Post to Pnut by default'), $def_enabled], - '$client_id' => ['pnut_client_id', DI::l10n()->t('Client ID'), $client_id], - '$client_secret' => ['pnut_client_secret', DI::l10n()->t('Client Secret'), $client_secret], - '$access_token' => ['pnut_access_token', DI::l10n()->t('Access Token'), $token, '', '', 'readonly'], - '$authorize_url' => $authorize_url ?? '', + '$enable' => ['pnut', DI::l10n()->t('Enable Pnut Post Addon'), $enabled], + '$bydefault' => ['pnut_bydefault', DI::l10n()->t('Post to Pnut by default'), $def_enabled], + '$client_id' => ['pnut_client_id', DI::l10n()->t('Client ID'), $client_id], + '$client_secret' => ['pnut_client_secret', DI::l10n()->t('Client Secret'), $client_secret], + '$access_token' => ['pnut_access_token', DI::l10n()->t('Access Token'), $token, '', '', 'readonly'], + '$authorize_url' => $authorize_url ?? '', '$authorize_text' => $authorize_text ?? '', - '$disconn_btn' => $disconn_btn ?? '', + '$disconn_btn' => $disconn_btn ?? '', + 'user_client' => $user_client, ]); $data = [ 'connector' => 'pnut', - 'title' => DI::l10n()->t('Pnut Import/Export'), + 'title' => DI::l10n()->t('Pnut Export'), 'image' => 'addon/pnut/pnut.svg', 'enabled' => $enabled, 'html' => $html, @@ -152,8 +180,12 @@ function pnut_settings_post(array &$b) } else { DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'post', intval($_POST['pnut'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default', intval($_POST['pnut_bydefault'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'client_id', $_POST['pnut_client_id']); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret', $_POST['pnut_client_secret']); + if (!empty($_POST['pnut_client_id'])) { + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'client_id', $_POST['pnut_client_id']); + } + if (!empty($_POST['pnut_client_secret'])) { + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'client_secret', $_POST['pnut_client_secret']); + } } } @@ -243,7 +275,7 @@ function pnut_post_hook(array &$b) $token = DI::pConfig()->get($b['uid'], 'pnut', 'access_token'); $nut = new phpnut\phpnut($token); - $msgarr = Plaintext::getPost($b, 256, true, BBCode::EXTERNAL); + $msgarr = Plaintext::getPost($b, PNUT_LIMIT, true, BBCode::EXTERNAL); $text = $msgarr['text']; $raw = []; @@ -275,7 +307,7 @@ function pnut_post_hook(array &$b) $picturedata = Photo::getImageForPhoto($photo); Logger::debug('PNUT photo', $photo); - $picurefile = System::getTempPath() . DIRECTORY_SEPARATOR . $photo['filename']; + $picurefile = tempnam(System::getTempPath(), 'pnut'); file_put_contents($picurefile, $picturedata); Logger::debug('PNUT got file?', ['filename' => $picurefile]); $imagefile = $nut->createFile($picurefile, $fileraw); diff --git a/pnut/templates/admin.tpl b/pnut/templates/admin.tpl new file mode 100644 index 00000000..b4cc3651 --- /dev/null +++ b/pnut/templates/admin.tpl @@ -0,0 +1,3 @@ +{{include file="field_input.tpl" field=$client_id}} +{{include file="field_input.tpl" field=$client_secret}} +
diff --git a/pnut/templates/connector_settings.tpl b/pnut/templates/connector_settings.tpl index 7d1ad3f2..6662a5ae 100644 --- a/pnut/templates/connector_settings.tpl +++ b/pnut/templates/connector_settings.tpl @@ -1,9 +1,11 @@

{{$status}}

{{include file="field_checkbox.tpl" field=$enable}} {{include file="field_checkbox.tpl" field=$bydefault}} -{{include file="field_input.tpl" field=$client_id}} -{{include file="field_input.tpl" field=$client_secret}} -{{include file="field_input.tpl" field=$access_token}} +{{if $user_client}} + {{include file="field_input.tpl" field=$client_id}} + {{include file="field_input.tpl" field=$client_secret}} + {{include file="field_input.tpl" field=$access_token}} +{{/if}} {{if $authorize_url}} {{$authorize_text}} {{/if}} From 90ec1bc83816518dca292db06abe6440d4425195 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 3 Mar 2024 17:10:09 +0000 Subject: [PATCH 023/294] Newlines added --- pnut/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pnut/README.md b/pnut/README.md index 6f6a9224..798174b8 100644 --- a/pnut/README.md +++ b/pnut/README.md @@ -4,5 +4,7 @@ With this addon to friendica you can give your users the possibility to post the No setup is needed for the admins to make it work for their users, however it is possible for the admin to create a client, so that the users don't have to. -To do so, go to https://pnut.io/dev and scroll down to "Create New Client". Enter a name of your choice and enter your Friendica host name as the website. Use https://(yourhost.name)/pnut/connect as a redirect url, replace "(yourhost.name)" with the host name of your system. +To do so, go to https://pnut.io/dev and scroll down to "Create New Client". +Enter a name of your choice and enter your Friendica host name as the website. +Use https://(yourhost.name)/pnut/connect as a redirect url, replace "(yourhost.name)" with the host name of your system. Limit the scope to "basic,files,follow,polls,presence,stream,update_profile,write_post" \ No newline at end of file From b6d706822a2c3e484d5901880492268409a4972e Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 4 Mar 2024 05:37:04 +0000 Subject: [PATCH 024/294] Blockbot: You can now allow social media agents --- blockbot/blockbot.php | 51 +++++++++++++++++++++++++----------- blockbot/lang/C/messages.po | 18 ++++++++++--- blockbot/templates/admin.tpl | 1 + 3 files changed, 50 insertions(+), 20 deletions(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index 10327edf..62a7f566 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -27,16 +27,18 @@ function blockbot_addon_admin(string &$o) $t = Renderer::getMarkupTemplate('admin.tpl', 'addon/blockbot/'); $o = Renderer::replaceMacros($t, [ - '$submit' => DI::l10n()->t('Save Settings'), - '$good_crawlers' => ['good_crawlers', DI::l10n()->t('Allow "good" crawlers'), DI::config()->get('blockbot', 'good_crawlers'), DI::l10n()->t("Don't block fediverse crawlers, relay servers and other bots with good purposes.")], - '$block_gab' => ['block_gab', DI::l10n()->t('Block GabSocial'), DI::config()->get('blockbot', 'block_gab'), DI::l10n()->t('Block the software GabSocial. This will block every access for that software. You can block dedicated gab instances in the blocklist settings in the admin section.')], - '$training' => ['training', DI::l10n()->t('Training mode'), DI::config()->get('blockbot', 'training'), DI::l10n()->t("Activates the training mode. This is only meant for developing purposes. Don't activate this on a production machine. This can cut communication with some systems.")], + '$submit' => DI::l10n()->t('Save Settings'), + '$good_crawlers' => ['good_crawlers', DI::l10n()->t('Allow "good" crawlers'), DI::config()->get('blockbot', 'good_crawlers'), DI::l10n()->t("Don't block fediverse crawlers, relay servers and other bots with good purposes.")], + '$socialmedia_agents' => ['socialmedia_agents', DI::l10n()->t('Allow preview agents'), DI::config()->get('blockbot', 'socialmedia_agents'), DI::l10n()->t("Don't block agents from social media systems that want to generate preview data for links that had been set by their users.")], + '$block_gab' => ['block_gab', DI::l10n()->t('Block GabSocial'), DI::config()->get('blockbot', 'block_gab'), DI::l10n()->t('Block the software GabSocial. This will block every access for that software. You can block dedicated gab instances in the blocklist settings in the admin section.')], + '$training' => ['training', DI::l10n()->t('Training mode'), DI::config()->get('blockbot', 'training'), DI::l10n()->t("Activates the training mode. This is only meant for developing purposes. Don't activate this on a production machine. This can cut communication with some systems.")], ]); } function blockbot_addon_admin_post() { DI::config()->set('blockbot', 'good_crawlers', $_POST['good_crawlers'] ?? false); + DI::config()->set('blockbot', 'socialmedia_agents', $_POST['socialmedia_agents'] ?? false); DI::config()->set('blockbot', 'block_gab', $_POST['block_gab'] ?? false); DI::config()->set('blockbot', 'training', $_POST['training'] ?? false); } @@ -53,34 +55,41 @@ function blockbot_init_1() $good_agents = [ 'fediverse.space crawler', 'fediverse.network crawler', 'Active_Pods_CheckBot_3.0', 'Social-Relay/', 'Test Certificate Info', 'Uptimebot/', 'GNUSocialBot', 'UptimeRobot/', - 'PTST/', 'Zabbix', 'Poduptime/' + 'PTST/', 'Zabbix', 'Poduptime/', 'FediFetcher', 'lemmy-stats-crawler', + 'FedditLemmyverseCrawler/', 'kbinBot/', 'lemmy-explorer-crawler/', ]; - // List of known crawlers. + // List of agents from social media systems that fetch preview data via opem graph or twitter cards + $socialmedia_agents = ['Twitterbot/', 'facebookexternalhit/', 'SkypeUriPreview Preview/', + 'TelegramBot', 'WhatsApp/', 'github-camo', 'Bluesky Cardyb/', 'XING-contenttabreceiver/', + 'LinkedInBot/', 'Instagram ', 'Synapse (bot; ', 'Discordbot/']; + + // List of known unwanted crawlers. $agents = [ 'SemrushBot', 's~feedly-nikon3', 'Qwantify/Bleriot/', 'ltx71', 'Sogou web spider/', - 'Diffbot/', 'Twitterbot/', 'YisouSpider', 'evc-batch/', 'LivelapBot/', 'TrendsmapResolver/', + 'Diffbot/', 'YisouSpider', 'evc-batch/', 'LivelapBot/', 'TrendsmapResolver/', 'PaperLiBot/', 'Nuzzel', 'um-LN/', 'Google Favicon', 'Datanyze', 'BLEXBot/', '360Spider', 'adscanner/', 'HeadlessChrome', 'wpif', 'startmebot/', 'Googlebot/', 'Applebot/', - 'facebookexternalhit/', 'GoogleImageProxy', 'bingbot/', 'heritrix/', 'ldspider', + 'GoogleImageProxy', 'bingbot/', 'heritrix/', 'ldspider', 'AwarioRssBot/', 'TweetmemeBot/', 'dcrawl/', 'PhantomJS/', 'Googlebot-Image/', 'CrowdTanglebot/', 'Mediapartners-Google', 'Baiduspider/', 'datagnionbot', 'MegaIndex.ru/', 'SMUrlExpander', 'Hatena-Favicon/', 'Wappalyzer', 'FlipboardProxy/', 'NetcraftSurveyAgent/', 'Dataprovider.com', 'SMTBot/', 'Nimbostratus-Bot/', 'DuckDuckGo-Favicons-Bot/', 'IndieWebCards/', 'proximic', 'netEstate NE Crawler', - 'AhrefsBot/', 'YandexBot/', 'Exabot/', 'Mediumbot-MetaTagFetcher/', 'WhatsApp/', - 'TelegramBot', 'SurdotlyBot/', 'BingPreview/', 'SabsimBot/', 'CCBot/', 'WbSrch/', + 'AhrefsBot/', 'YandexBot/', 'Exabot/', 'Mediumbot-MetaTagFetcher/', + 'SurdotlyBot/', 'BingPreview/', 'SabsimBot/', 'CCBot/', 'WbSrch/', 'DuckDuckBot-Https/', 'HTTP Banner Detection', 'YandexImages/', 'archive.org_bot', 'ArchiveTeam ArchiveBot/', 'yacybot', 'https://developers.google.com/+/web/snippet/', - 'Scrapy/', 'github-camo', 'MJ12bot/', 'DotBot/', 'Pinterestbot/', 'Jooblebot/', + 'Scrapy/', 'MJ12bot/', 'DotBot/', 'Pinterestbot/', 'Jooblebot/', 'Cliqzbot/', 'YaK/', 'Mediatoolkitbot', 'Snacktory', 'FunWebProducts', 'oBot/', '7Siters/', 'KOCMOHABT', 'Google-SearchByImage', 'FemtosearchBot/', 'HubSpot Crawler', 'DomainStatsBot/', 'Re-re Studio', 'AwarioSmartBot/', 'SummalyBot/', 'DNSResearchBot/', 'PetalBot;', 'Nmap Scripting Engine;', 'Google-Apps-Script; beanserver;', 'woorankreview/', 'Seekport Crawler;', 'AHC/', - 'SkypeUriPreview Preview/', 'Semanticbot/', 'Embed PHP library', 'XoviOnpageCrawler;', + 'Semanticbot/', 'Embed PHP library', 'XoviOnpageCrawler;', 'Pinterest/', 'GetHPinfo.com-Bot/', 'BoardReader Favicon Fetcher', 'Google-Adwords-Instant', 'newspaper/', - 'YurichevBot/', 'Crawling at Home Project', 'InfoTigerBot/' + 'YurichevBot/', 'Crawling at Home Project', 'InfoTigerBot/', + 'AdIdxBot/', 'MicrosoftPreview/', 'masscan/' ]; if (!DI::config()->get('blockbot', 'good_crawlers')) { @@ -93,13 +102,23 @@ function blockbot_init_1() } } + if (!DI::config()->get('blockbot', 'socialmedia_agents')) { + $agents = array_merge($agents, $socialmedia_agents); + } else { + foreach ($socialmedia_agents as $socialmedia_agent) { + if (stristr($_SERVER['HTTP_USER_AGENT'], $socialmedia_agent)) { + return; + } + } + } + if (DI::config()->get('blockbot', 'block_gab')) { $agents[] = 'GabSocial/'; } foreach ($agents as $agent) { if (stristr($_SERVER['HTTP_USER_AGENT'], $agent)) { - throw new ForbiddenException('Bots are not allowed'); + throw new ForbiddenException('Bots are not allowed. If you consider this a mistake, create an issue at https://github.com/friendica/friendica'); } } @@ -125,7 +144,7 @@ function blockbot_init_1() 'lua-resty-http/', 'Tiny Tiny RSS/', 'Wget/', 'PostmanRuntime/', 'W3C_Validator/', 'NetNewsWire', 'FeedValidator/', 'theoldreader.com', 'axios/', 'Paw/', 'PeerTube/', 'fedi.inex.dev', 'FediDB/', 'index.community crawler', - 'Slackbot-LinkExpanding' + 'Slackbot-LinkExpanding', 'Firefish/', 'Takahe/', 'Akkoma ', 'Misskey/' ]; if (DI::config()->get('blockbot', 'good_crawlers')) { @@ -140,5 +159,5 @@ function blockbot_init_1() } logger::notice('Blocked bot', $logdata); - throw new ForbiddenException('Bots are not allowed'); + throw new ForbiddenException('Bots are not allowed. If you consider this a mistake, create an issue at https://github.com/friendica/friendica'); } diff --git a/blockbot/lang/C/messages.po b/blockbot/lang/C/messages.po index 6f30e845..49371908 100644 --- a/blockbot/lang/C/messages.po +++ b/blockbot/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-13 06:17+0000\n" +"POT-Creation-Date: 2024-03-04 05:35+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -32,21 +32,31 @@ msgid "" msgstr "" #: blockbot.php:32 -msgid "Block GabSocial" +msgid "Allow preview agents" msgstr "" #: blockbot.php:32 msgid "" +"Don't block agents from social media systems that want to generate preview " +"data for links that had been set by their users." +msgstr "" + +#: blockbot.php:33 +msgid "Block GabSocial" +msgstr "" + +#: blockbot.php:33 +msgid "" "Block the software GabSocial. This will block every access for that " "software. You can block dedicated gab instances in the blocklist settings in " "the admin section." msgstr "" -#: blockbot.php:33 +#: blockbot.php:34 msgid "Training mode" msgstr "" -#: blockbot.php:33 +#: blockbot.php:34 msgid "" "Activates the training mode. This is only meant for developing purposes. " "Don't activate this on a production machine. This can cut communication with " diff --git a/blockbot/templates/admin.tpl b/blockbot/templates/admin.tpl index a6de1bd3..9f728d42 100644 --- a/blockbot/templates/admin.tpl +++ b/blockbot/templates/admin.tpl @@ -1,4 +1,5 @@ {{include file="field_checkbox.tpl" field=$good_crawlers}} +{{include file="field_checkbox.tpl" field=$socialmedia_agents}} {{include file="field_checkbox.tpl" field=$block_gab}} {{include file="field_checkbox.tpl" field=$training}}
From 3c0f4e3926768131ac4c093dc9ab1444cee3cca8 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Mon, 4 Mar 2024 01:16:49 -0500 Subject: [PATCH 025/294] [advancedcontentfilter] Stop using advancedcontentfilter_get_rules() outside of router context - This used to work with Slim v2, but the new requirements for module functions broke it --- advancedcontentfilter/advancedcontentfilter.php | 4 ++-- advancedcontentfilter/templates/settings.tpl | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index 55bc5005..418b253e 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -253,7 +253,7 @@ function advancedcontentfilter_content() 'cancel' => DI::l10n()->t('Cancel'), ], '$current_theme' => DI::app()->getCurrentTheme(), - '$rules' => advancedcontentfilter_get_rules(), + '$rules' => DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])), '$form_security_token' => BaseModule::getFormSecurityToken() ]); } @@ -305,7 +305,7 @@ function advancedcontentfilter_build_fields($data) * API */ -function advancedcontentfilter_get_rules(ServerRequestInterface $request, ResponseInterface $response) +function advancedcontentfilter_get_rules(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface { if (!DI::userSession()->getLocalUserId()) { throw new HTTPException\UnauthorizedException(DI::l10n()->t('You must be logged in to use this method')); diff --git a/advancedcontentfilter/templates/settings.tpl b/advancedcontentfilter/templates/settings.tpl index c9dfbe3a..8b82e595 100644 --- a/advancedcontentfilter/templates/settings.tpl +++ b/advancedcontentfilter/templates/settings.tpl @@ -3,7 +3,7 @@
+ + +
+

{{$title}} - {{$page}} ({{$count}})

+

+ {{$h_newuser}} +

+
+ + + + + + + {{foreach $th_users as $k=>$th}} + {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + + {{/if}} + {{/foreach}} + + + + + {{foreach $users as $u}} + + + + + + {{if $order_users == $th_users.2.1}} + + {{/if}} + + {{if $order_users == $th_users.3.1}} + + {{/if}} + + {{if $order_users == $th_users.4.1}} + + {{/if}} + + {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + + {{/if}} + + + + + + + + + {{/foreach}} + +
+
+ + +
+
+ + {{if $order_users == $th.1}} + {{if $order_direction_users == "+"}} + ↓ + {{else}} + ↑ + {{/if}} + {{else}} + ↕ + {{/if}} + {{$th.0}} + +
+ {{if $u.is_deletable}} +
+ + +
+ {{else}} +   + {{/if}} +
{{$u.name}}{{$u.email}}{{$u.register_date}}{{$u.login_date}}{{$u.lastitem_date}} + + + {{if $u.page_flags_raw==0 && $u.account_type_raw > 0}} + + {{/if}} + {{if $u.is_admin}}{{/if}} + {{if $u.account_expired}}{{/if}} + + +
+ + {{$pager nofilter}} +
+
From 7d5446a778419d67ec4df778c836b59083d5f163 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 23 Jun 2024 15:15:06 +0200 Subject: [PATCH 096/294] Ratioed: remove unnecessary uninstall function --- ratioed/ratioed.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 3c88705c..d8da9ac1 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -25,15 +25,6 @@ function ratioed_install() Logger::info("ratioed: installed"); } -/** - * @brief Uninstallation hook for ratioed plugin - */ -function ratioed_uninstall() { - Hook::unregister('moderation_users_tabs', 'addon/ratioed/ratioed.php', 'ratioed_users_tabs'); - - Logger::info("ratioed: uninstalled"); -} - /** * This is a statement rather than an actual function definition. The simple * existence of this method is checked to figure out if the addon offers a From 18e512cc8b0bd79a6be164e7fc06ec4a41f56dcd Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 23 Jun 2024 15:24:43 +0200 Subject: [PATCH 097/294] Ratioed: move panel class into separate file --- ratioed/RatioedPanel.php | 206 +++++++++++++++++++++++++++++++++++++++ ratioed/ratioed.php | 201 +------------------------------------- 2 files changed, 208 insertions(+), 199 deletions(-) create mode 100644 ratioed/RatioedPanel.php diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php new file mode 100644 index 00000000..16f9df6f --- /dev/null +++ b/ratioed/RatioedPanel.php @@ -0,0 +1,206 @@ +parameters['action'] ?? ''; + $uid = $this->parameters['uid'] ?? 0; + + if ($uid) { + $user = User::getById($uid, ['username', 'blocked']); + if (!$user) { + $this->systemMessages->addNotice($this->t('User not found')); + $this->baseUrl->redirect('moderation/users'); + } + } + + switch ($action) { + case 'delete': + if ($this->session->getLocalUserId() != $uid) { + self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); + // delete user + User::remove($uid); + + $this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username'])); + } else { + $this->systemMessages->addNotice($this->t('You can\'t remove yourself')); + } + + $this->baseUrl->redirect('moderation/users/active'); + break; + case 'block': + self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); + User::block($uid); + $this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username'])); + $this->baseUrl->redirect('moderation/users/active'); + break; + } + $pager = new Pager($this->l10n, $this->args->getQueryString(), 100); + + $valid_orders = [ + 'name', + 'email', + 'register_date', + 'last-activity', + 'last-item', + 'page-flags', + ]; + + $order = 'last-item'; + $order_direction = '-'; + if (!empty($request['o'])) { + $new_order = $request['o']; + if ($new_order[0] === '-') { + $order_direction = '-'; + $new_order = substr($new_order, 1); + } + + if (in_array($new_order, $valid_orders)) { + $order = $new_order; + } + } + + $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'active', $order, ($order_direction == '-')); + + $users = array_map($this->setupUserCallback(), $users); + + $header_titles = [ + $this->t('Name'), + $this->t('Email'), + $this->t('Register date'), + $this->t('Last login'), + $this->t('Last public item'), + $this->t('Type'), + $this->t('Blocked by'), + $this->t('Comments last 24h'), + $this->t('Reactions last 24h'), + $this->t('Ratio last 24h'), + ]; + $field_names = [ + 'name', + 'email', + 'register_date', + 'login_date', + 'lastitem_date', + 'page_flags', + 'blocked_by', + 'comments', + 'reactions', + 'ratio', + ]; + $th_users = array_map(null, $header_titles, $valid_orders, $field_names); + + $count = $this->database->count('user', ["`verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired` AND `uid` != ?", 0]); + + $t = Renderer::getMarkupTemplate('ratioed.tpl', 'addon/ratioed'); + return self::getTabsHTML('ratioed') . Renderer::replaceMacros($t, [ + // strings // + '$title' => $this->t('Moderation'), + '$page' => $this->t('Behaviour'), + '$select_all' => $this->t('select all'), + '$delete' => $this->t('Delete'), + '$block' => $this->t('Block'), + '$blocked' => $this->t('User blocked'), + '$siteadmin' => $this->t('Site admin'), + '$accountexpired' => $this->t('Account expired'), + '$h_newuser' => $this->t('Create a new user'), + + '$th_users' => $th_users, + '$order_users' => $order, + '$order_direction_users' => $order_direction, + + '$confirm_delete_multi' => $this->t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'), + '$confirm_delete' => $this->t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'), + + '$form_security_token' => self::getFormSecurityToken('moderation_users_active'), + + // values // + '$baseurl' => $this->baseUrl, + '$query_string' => $this->args->getQueryString(), + + '$users' => $users, + '$count' => $count, + '$pager' => $pager->renderFull($count), + ]); + } + + protected function setupUserCallback(): \Closure + { + Logger::debug("ratioed: setupUserCallback"); + $parentCallback = parent::setupUserCallback(); + return function ($user) use ($parentCallback) { + $blocked_count = DBA::count('user-contact', ['uid' => $user['uid'], 'is-blocked' => 1]); + $user['blocked_by'] = $blocked_count; + + $self_contact_result = DBA::p('SELECT admin_contact.id AS user_contact_uid FROM contact AS admin_contact JOIN contact AS user_contact ON admin_contact.`uri-id` = user_contact.`uri-id` AND admin_contact.self = 0 AND user_contact.self = 1 WHERE user_contact.uid = ?', $user['uid']); + if (DBA::isResult($self_contact_result)) { + $self_contact_result_row = DBA::fetch($self_contact_result); + $user['user_contact_uid'] = $self_contact_result_row['user_contact_uid']; + } + else { + $user['user_contact_uid'] = NULL; + } + + if ($user['user_contact_uid']) { + $post_engagement_result = DBA::p('SELECT SUM(`comments`) AS `comment_count`, SUM(`activities`) AS `activities_count` FROM `post-engagement` WHERE `post-engagement`.created > DATE_SUB(now(), INTERVAL 1 DAY) AND `post-engagement`.`owner-id` = ?', $user['user_contact_uid']); + if (DBA::isResult($post_engagement_result)) { + $post_engagement_result_row = DBA::fetch($post_engagement_result); + $user['comments'] = $post_engagement_result_row['comment_count']; + $user['reactions'] = $post_engagement_result_row['activities_count']; + if ($user['reactions'] > 0) { + $user['ratio'] = number_format($user['comments'] / $user['reactions'], 1, '.', ''); + $user['ratioed'] = (float)($user['ratio']) >= 2.0; + } + else { + if ($user['comments'] == 0) { + $user['ratio'] = '0'; + $user['ratioed'] = false; + } + else { + $user['ratio'] = '∞'; + $user['ratioed'] = false; + } + } + } + else { + $user['comments'] = 'error'; + $user['reactions'] = 'error'; + $user['ratio'] = 'error'; + $user['ratioed'] = false; + } + } + else { + $user['comments'] = 'error'; + $user['reactions'] = 'error'; + $user['ratio'] = 'error'; + $user['ratioed'] = false; + } + + $user = $parentCallback($user); + Logger::debug("ratioed: setupUserCallback", [ + 'uid' => $user['uid'], + 'blocked_by' => $user['blocked_by'], + 'comments' => $user['comments'], + 'reactions' => $user['reactions'], + 'ratio' => $user['ratio'], + 'ratioed' => $user['ratioed'], + ]); + return $user; + }; + } +} diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index d8da9ac1..8ae0d48c 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -6,14 +6,10 @@ * Author: Matthew Exon */ -use Friendica\Content\Pager; +use Friendica\Addon\ratioed\RatioedPanel; use Friendica\Core\Hook; use Friendica\Core\Logger; -use Friendica\Core\Renderer; -use Friendica\Database\DBA; use Friendica\DI; -use Friendica\Model\User; -use Friendica\Module\Moderation\Users\Active; /** * Sets up the addon hooks and updates data in the database if needed @@ -50,206 +46,13 @@ function ratioed_users_tabs(array &$arr) { ]); } -class Ratioed extends Friendica\Module\Moderation\Users\Active -{ - protected function content(array $request = []): string - { - Friendica\Module\Moderation\Users\Active::content(); - - $action = $this->parameters['action'] ?? ''; - $uid = $this->parameters['uid'] ?? 0; - - if ($uid) { - $user = User::getById($uid, ['username', 'blocked']); - if (!$user) { - $this->systemMessages->addNotice($this->t('User not found')); - $this->baseUrl->redirect('moderation/users'); - } - } - - switch ($action) { - case 'delete': - if ($this->session->getLocalUserId() != $uid) { - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - // delete user - User::remove($uid); - - $this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username'])); - } else { - $this->systemMessages->addNotice($this->t('You can\'t remove yourself')); - } - - $this->baseUrl->redirect('moderation/users/active'); - break; - case 'block': - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - User::block($uid); - $this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username'])); - $this->baseUrl->redirect('moderation/users/active'); - break; - } - $pager = new Pager($this->l10n, $this->args->getQueryString(), 100); - - $valid_orders = [ - 'name', - 'email', - 'register_date', - 'last-activity', - 'last-item', - 'page-flags', - ]; - - $order = 'last-item'; - $order_direction = '-'; - if (!empty($request['o'])) { - $new_order = $request['o']; - if ($new_order[0] === '-') { - $order_direction = '-'; - $new_order = substr($new_order, 1); - } - - if (in_array($new_order, $valid_orders)) { - $order = $new_order; - } - } - - $users = User::getList($pager->getStart(), $pager->getItemsPerPage(), 'active', $order, ($order_direction == '-')); - - $users = array_map($this->setupUserCallback(), $users); - - $header_titles = [ - $this->t('Name'), - $this->t('Email'), - $this->t('Register date'), - $this->t('Last login'), - $this->t('Last public item'), - $this->t('Type'), - $this->t('Blocked by'), - $this->t('Comments last 24h'), - $this->t('Reactions last 24h'), - $this->t('Ratio last 24h'), - ]; - $field_names = [ - 'name', - 'email', - 'register_date', - 'login_date', - 'lastitem_date', - 'page_flags', - 'blocked_by', - 'comments', - 'reactions', - 'ratio', - ]; - $th_users = array_map(null, $header_titles, $valid_orders, $field_names); - - $count = $this->database->count('user', ["`verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired` AND `uid` != ?", 0]); - - $t = Renderer::getMarkupTemplate('ratioed.tpl', 'addon/ratioed'); - return self::getTabsHTML('ratioed') . Renderer::replaceMacros($t, [ - // strings // - '$title' => $this->t('Moderation'), - '$page' => $this->t('Behaviour'), - '$select_all' => $this->t('select all'), - '$delete' => $this->t('Delete'), - '$block' => $this->t('Block'), - '$blocked' => $this->t('User blocked'), - '$siteadmin' => $this->t('Site admin'), - '$accountexpired' => $this->t('Account expired'), - '$h_newuser' => $this->t('Create a new user'), - - '$th_users' => $th_users, - '$order_users' => $order, - '$order_direction_users' => $order_direction, - - '$confirm_delete_multi' => $this->t('Selected users will be deleted!\n\nEverything these users had posted on this site will be permanently deleted!\n\nAre you sure?'), - '$confirm_delete' => $this->t('The user {0} will be deleted!\n\nEverything this user has posted on this site will be permanently deleted!\n\nAre you sure?'), - - '$form_security_token' => self::getFormSecurityToken('moderation_users_active'), - - // values // - '$baseurl' => $this->baseUrl, - '$query_string' => $this->args->getQueryString(), - - '$users' => $users, - '$count' => $count, - '$pager' => $pager->renderFull($count), - ]); - } - - protected function setupUserCallback(): \Closure - { - Logger::debug("ratioed: setupUserCallback"); - $parentCallback = parent::setupUserCallback(); - return function ($user) use ($parentCallback) { - $blocked_count = DBA::count('user-contact', ['uid' => $user['uid'], 'is-blocked' => 1]); - $user['blocked_by'] = $blocked_count; - - $self_contact_result = DBA::p('SELECT admin_contact.id AS user_contact_uid FROM contact AS admin_contact JOIN contact AS user_contact ON admin_contact.`uri-id` = user_contact.`uri-id` AND admin_contact.self = 0 AND user_contact.self = 1 WHERE user_contact.uid = ?', $user['uid']); - if (DBA::isResult($self_contact_result)) { - $self_contact_result_row = DBA::fetch($self_contact_result); - $user['user_contact_uid'] = $self_contact_result_row['user_contact_uid']; - } - else { - $user['user_contact_uid'] = NULL; - } - - if ($user['user_contact_uid']) { - $post_engagement_result = DBA::p('SELECT SUM(`comments`) AS `comment_count`, SUM(`activities`) AS `activities_count` FROM `post-engagement` WHERE `post-engagement`.created > DATE_SUB(now(), INTERVAL 1 DAY) AND `post-engagement`.`owner-id` = ?', $user['user_contact_uid']); - if (DBA::isResult($post_engagement_result)) { - $post_engagement_result_row = DBA::fetch($post_engagement_result); - $user['comments'] = $post_engagement_result_row['comment_count']; - $user['reactions'] = $post_engagement_result_row['activities_count']; - if ($user['reactions'] > 0) { - $user['ratio'] = number_format($user['comments'] / $user['reactions'], 1, '.', ''); - $user['ratioed'] = (float)($user['ratio']) >= 2.0; - } - else { - if ($user['comments'] == 0) { - $user['ratio'] = '0'; - $user['ratioed'] = false; - } - else { - $user['ratio'] = '∞'; - $user['ratioed'] = false; - } - } - } - else { - $user['comments'] = 'error'; - $user['reactions'] = 'error'; - $user['ratio'] = 'error'; - $user['ratioed'] = false; - } - } - else { - $user['comments'] = 'error'; - $user['reactions'] = 'error'; - $user['ratio'] = 'error'; - $user['ratioed'] = false; - } - - $user = $parentCallback($user); - Logger::debug("ratioed: setupUserCallback", [ - 'uid' => $user['uid'], - 'blocked_by' => $user['blocked_by'], - 'comments' => $user['comments'], - 'reactions' => $user['reactions'], - 'ratio' => $user['ratio'], - 'ratioed' => $user['ratioed'], - ]); - return $user; - }; - } -} - /** * @brief Displays the ratioed tab in the moderation panel */ function ratioed_content() { Logger::debug("ratioed: content"); - $ratioed = DI::getDice()->create(Ratioed::class, [$_SERVER]); + $ratioed = DI::getDice()->create(RatioedPanel::class, [$_SERVER]); $httpException = DI::getDice()->create(Friendica\Module\Special\HTTPException::class); $ratioed->run($httpException); } From 14e7413eb2f89effd151b4460c0a56cdb560c681 Mon Sep 17 00:00:00 2001 From: hankg Date: Mon, 24 Jun 2024 22:20:35 +0200 Subject: [PATCH 098/294] Add Relatica to blockbot fediverse client list --- blockbot/blockbot.php | 1 + 1 file changed, 1 insertion(+) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index eb634b1f..adf0a7c2 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -499,6 +499,7 @@ function blockbot_is_fediverse_client(array $parts): bool 'megalodonandroid', 'fedilab', 'mastodonapp', 'toot!', 'intravnews', 'pixeldroid', 'greatnews', 'protopage', 'newsfox', 'vienna', 'wp-urldetails', 'husky', 'activitypub-go-http-client', 'mobilesafari', 'mastodon-ios', 'mastodonpy', 'techniverse', + 'relatica', ]; foreach ($parts as $part) { From b2108c7a4c7efe5c79f8c5e762e3cae207d9e0d2 Mon Sep 17 00:00:00 2001 From: Hannes Heute Date: Thu, 27 Jun 2024 11:44:15 +0200 Subject: [PATCH 099/294] fix for curweather --- curweather/curweather.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curweather/curweather.php b/curweather/curweather.php index 5a14a9cf..9aa8584a 100644 --- a/curweather/curweather.php +++ b/curweather/curweather.php @@ -152,7 +152,7 @@ function curweather_network_mod_init(string &$body) function curweather_addon_settings_post($post) { - if (!DI::userSession()->getLocalUserId() || empty($_POST['curweather-settings-submit'])) { + if (!DI::userSession()->getLocalUserId() || empty($_POST['curweather-submit'])) { return; } From 5f27f72b0d18bbf3226f4850cb4aa6f2c36482fe Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 29 Jun 2024 15:23:24 +0200 Subject: [PATCH 100/294] Streamline log lines --- mailstream/mailstream.php | 70 +++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index b513cf36..c5cf8f3f 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -34,7 +34,7 @@ function mailstream_install() Hook::register('post_remote_end', 'addon/mailstream/mailstream.php', 'mailstream_post_hook'); Hook::register('mailstream_send_hook', 'addon/mailstream/mailstream.php', 'mailstream_send_hook'); - Logger::info("mailstream: installed"); + Logger::info("installed mailstream"); } /** @@ -44,7 +44,7 @@ function mailstream_check_version() { if (!is_null(DI::config()->get('mailstream', 'dbversion'))) { DI::config()->delete('mailstream', 'dbversion'); - Logger::info("mailstream_check_version: old version detected, reinstalling"); + Logger::info("old version detected, reinstalling"); mailstream_install(); Hook::loadHooks(); Hook::add( @@ -105,7 +105,7 @@ function mailstream_generate_id(string $uri): string $host = DI::baseUrl()->getHost(); $resource = hash('md5', $uri); $message_id = "<" . $resource . "@" . $host . ">"; - Logger::debug('mailstream: Generated message ID ' . $message_id . ' for URI ' . $uri); + Logger::debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); return $message_id; } @@ -114,20 +114,20 @@ function mailstream_send_hook(array $data) $criteria = array('uid' => $data['uid'], 'contact-id' => $data['contact-id'], 'uri' => $data['uri']); $item = Post::selectFirst([], $criteria); if (empty($item)) { - Logger::error('mailstream_send_hook could not find item'); + Logger::error('could not find item'); return; } $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('mailstream_send_hook could not fund user', ['uid' => $item['uid']]); + Logger::error('could not find user', ['uid' => $item['uid']]); return; } if (!mailstream_send($data['message_id'], $item, $user)) { - Logger::debug('mailstream_send_hook send failed, will retry', $data); + Logger::debug('send failed, will retry', $data); if (!Worker::defer()) { - Logger::error('mailstream_send_hook failed and could not defer', $data); + Logger::error('failed and could not defer', $data); } } } @@ -145,32 +145,32 @@ function mailstream_post_hook(array &$item) mailstream_check_version(); if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); + Logger::debug('mailstream not enabled.', ['item' => $item['id'], 'uid' => $item['uid']]); return; } if (!$item['uid']) { - Logger::debug('mailstream: no uid for item ' . $item['id']); + Logger::debug('no uid', ['item' => $item['id']]); return; } if (!$item['contact-id']) { - Logger::debug('mailstream: no contact-id for item ' . $item['id']); + Logger::debug('no contact-id', ['item' => $item['id']]); return; } if (!$item['uri']) { - Logger::debug('mailstream: no uri for item ' . $item['id']); + Logger::debug('no uri', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::ANNOUNCE) { - Logger::debug('mailstream: announce item ', ['item' => $item['id']]); + Logger::debug('ignoring announce', ['item' => $item['id']]); return; } if (DI::pConfig()->get($item['uid'], 'mailstream', 'nolikes')) { if ($item['verb'] == Activity::LIKE) { - Logger::debug('mailstream: like item ' . $item['id']); + Logger::debug('ignoring like', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::DISLIKE) { - Logger::debug('mailstream: dislike item ' . $item['id']); + Logger::debug('ignoring dislike', ['item' => $item['id']]); return; } } @@ -221,7 +221,7 @@ function mailstream_do_images(array &$item, array &$attachments) try { $curlResult = DI::httpClient()->fetchFull($url, HttpClientAccept::DEFAULT, 0, $cookiejar); } catch (InvalidArgumentException $e) { - Logger::error('mailstream_do_images exception fetching url', ['url' => $url, 'item_id' => $item['id']]); + Logger::error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); continue; } $attachments[$url] = [ @@ -322,13 +322,12 @@ function mailstream_subject(array $item): string } $contact = Contact::selectFirst([], ['id' => $item['contact-id'], 'uid' => $item['uid']]); if (!DBA::isResult($contact)) { - Logger::error( - 'mailstream_subject no contact for item', - ['id' => $item['id'], - 'plink' => $item['plink'], - 'contact id' => $item['contact-id'], - 'uid' => $item['uid']] - ); + Logger::error('no contact', [ + 'item' => $item['id'], + 'plink' => $item['plink'], + 'contact id' => $item['contact-id'], + 'uid' => $item['uid'] + ]); return DI::l10n()->t("Friendica post"); } if ($contact['network'] === 'dfrn') { @@ -365,17 +364,16 @@ function mailstream_subject(array $item): string function mailstream_send(string $message_id, array $item, array $user): bool { if (!is_array($item)) { - Logger::error('mailstream_send item is empty', ['message_id' => $message_id]); + Logger::error('item is empty', ['message_id' => $message_id]); return false; } if (!$item['visible']) { - Logger::debug('mailstream_send item not yet visible', ['item uri' => $item['uri']]); + Logger::debug('item not yet visible', ['item uri' => $item['uri']]); return false; } if (!$message_id) { - Logger::error('mailstream_send no message ID supplied', ['item uri' => $item['uri'], - 'user email' => $user['email']]); + Logger::error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); return true; } @@ -432,13 +430,15 @@ function mailstream_send(string $message_id, array $item, array $user): bool if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); } - Logger::debug('mailstream_send sent message', ['message ID' => $mail->MessageID, - 'subject' => $mail->Subject, - 'address' => $address]); + Logger::debug('sent message', [ + 'message ID' => $mail->MessageID, + 'subject' => $mail->Subject, + 'address' => $address + ]); } catch (phpmailerException $e) { - Logger::debug('mailstream_send PHPMailer exception sending message ' . $message_id . ': ' . $e->errorMessage()); + Logger::debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); } catch (Exception $e) { - Logger::debug('mailstream_send exception sending message ' . $message_id . ': ' . $e->getMessage()); + Logger::debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); } return true; @@ -468,7 +468,7 @@ function mailstream_html_wrap(string &$text) function mailstream_convert_table_entries() { $ms_item_ids = DBA::selectToArray('mailstream_item', [], ['message-id', 'uri', 'uid', 'contact-id'], ["`mailstream_item`.`completed` IS NULL"]); - Logger::debug('mailstream_convert_table_entries processing ' . count($ms_item_ids) . ' items'); + Logger::debug('processing items', ['count' => count($ms_item_ids)]); foreach ($ms_item_ids as $ms_item_id) { $send_hook_data = array('uid' => $ms_item_id['uid'], 'contact-id' => $ms_item_id['contact-id'], @@ -476,10 +476,10 @@ function mailstream_convert_table_entries() 'message_id' => $ms_item_id['message-id'], 'tries' => 0); if (!$ms_item_id['message-id'] || !strlen($ms_item_id['message-id'])) { - Logger::info('mailstream_convert_table_entries: item has no message-id.', ['item' => $ms_item_id['id'], 'uri' => $ms_item_id['uri']]); - continue; + Logger::info('item has no message-id', ['item' => $ms_item_id['id'], 'uri' => $ms_item_id['uri']]); + continue; } - Logger::info('mailstream_convert_table_entries: convert item to workerqueue', $send_hook_data); + Logger::info('convert item to workerqueue', $send_hook_data); Hook::fork(Worker::PRIORITY_LOW, 'mailstream_send_hook', $send_hook_data); } DBA::e('DROP TABLE `mailstream_item`'); From f3db763c599cfeb830fdf95a8de5738c183be30b Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Tue, 9 Jul 2024 20:13:00 +0100 Subject: [PATCH 101/294] More comprehensible check for root user contact --- mailstream/mailstream.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index c5cf8f3f..b86c4e2a 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -144,12 +144,12 @@ function mailstream_post_hook(array &$item) { mailstream_check_version(); - if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream not enabled.', ['item' => $item['id'], 'uid' => $item['uid']]); + if ($item['uid'] === 0) { + Logger::debug('mailstream: root user, skipping item ' . $item['id']); return; } - if (!$item['uid']) { - Logger::debug('no uid', ['item' => $item['id']]); + if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { + Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); return; } if (!$item['contact-id']) { From 589cf712cc92911d5288b1dfff06bd8c9d4cfb78 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 14 Jul 2024 18:56:22 +0200 Subject: [PATCH 102/294] Remove old version conversion code --- mailstream/mailstream.php | 44 --------------------------------------- 1 file changed, 44 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index b86c4e2a..8bce2529 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -37,25 +37,6 @@ function mailstream_install() Logger::info("installed mailstream"); } -/** - * Enforces that mailstream_install has set up the current version - */ -function mailstream_check_version() -{ - if (!is_null(DI::config()->get('mailstream', 'dbversion'))) { - DI::config()->delete('mailstream', 'dbversion'); - Logger::info("old version detected, reinstalling"); - mailstream_install(); - Hook::loadHooks(); - Hook::add( - 'mailstream_convert_table_entries', - 'addon/mailstream/mailstream.php', - 'mailstream_convert_table_entries' - ); - Hook::fork(Worker::PRIORITY_LOW, 'mailstream_convert_table_entries'); - } -} - /** * This is a statement rather than an actual function definition. The simple * existence of this method is checked to figure out if the addon offers a @@ -142,8 +123,6 @@ function mailstream_send_hook(array $data) */ function mailstream_post_hook(array &$item) { - mailstream_check_version(); - if ($item['uid'] === 0) { Logger::debug('mailstream: root user, skipping item ' . $item['id']); return; @@ -462,29 +441,6 @@ function mailstream_html_wrap(string &$text) return $text; } -/** - * Convert v1 mailstream table entries to v2 workerqueue items - */ -function mailstream_convert_table_entries() -{ - $ms_item_ids = DBA::selectToArray('mailstream_item', [], ['message-id', 'uri', 'uid', 'contact-id'], ["`mailstream_item`.`completed` IS NULL"]); - Logger::debug('processing items', ['count' => count($ms_item_ids)]); - foreach ($ms_item_ids as $ms_item_id) { - $send_hook_data = array('uid' => $ms_item_id['uid'], - 'contact-id' => $ms_item_id['contact-id'], - 'uri' => $ms_item_id['uri'], - 'message_id' => $ms_item_id['message-id'], - 'tries' => 0); - if (!$ms_item_id['message-id'] || !strlen($ms_item_id['message-id'])) { - Logger::info('item has no message-id', ['item' => $ms_item_id['id'], 'uri' => $ms_item_id['uri']]); - continue; - } - Logger::info('convert item to workerqueue', $send_hook_data); - Hook::fork(Worker::PRIORITY_LOW, 'mailstream_send_hook', $send_hook_data); - } - DBA::e('DROP TABLE `mailstream_item`'); -} - /** * Form for configuring mailstream features for a user * From c0535db74214eb0983c7bd145702d9600fc169f2 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 5 Aug 2024 20:37:58 +0000 Subject: [PATCH 103/294] Statistics: inbound / outbound for Tumblr and Bluesky --- bluesky/bluesky.php | 2 ++ tumblr/tumblr.php | 2 ++ 2 files changed, 4 insertions(+) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 6994b3e3..9f21674f 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1946,6 +1946,7 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s return null; } + Item::incrementOutbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); } catch (\Exception $e) { @@ -1982,6 +1983,7 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass { + Item::incrementInbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->get($url, $accept_content, $opts); } catch (\Exception $e) { diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index f0c68f33..945f8f35 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -1326,6 +1326,7 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array */ function tumblr_get(int $uid, string $url, array $parameters = []): stdClass { + Item::incrementInbound(Protocol::TUMBLR); $url = 'https://api.tumblr.com/v2/' . $url; if ($uid == 0) { @@ -1355,6 +1356,7 @@ function tumblr_get(int $uid, string $url, array $parameters = []): stdClass */ function tumblr_post(int $uid, string $url, array $parameters): stdClass { + Item::incrementOutbound(Protocol::TUMBLR); $url = 'https://api.tumblr.com/v2/' . $url; $curlResult = DI::httpClient()->post($url, $parameters, ['Authorization' => ['Bearer ' . tumblr_get_token($uid)]]); From 46a55f13f7bd2566e0ede5bdb5df6d78c42fdab4 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Mon, 22 Jul 2024 18:23:23 +0200 Subject: [PATCH 104/294] Ratioed: add help text --- ratioed/RatioedPanel.php | 7 +++ ratioed/templates/help.tpl | 92 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 ratioed/templates/help.tpl diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 16f9df6f..e25c7f34 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -6,6 +6,7 @@ use Friendica\Content\Pager; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; +use Friendica\DI; use Friendica\Model\User; use Friendica\Module\Moderation\Users\Active; @@ -18,6 +19,11 @@ class RatioedPanel extends Active { Active::content(); + if (isset(DI::args()->getArgv()[1]) and DI::args()->getArgv()[1] === 'help') { + $template = Renderer::getMarkupTemplate('/help.tpl', 'addon/ratioed/'); + return Renderer::replaceMacros($template, array('$config' => DI::baseUrl() . '/settings/addon')); + } + $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; @@ -111,6 +117,7 @@ class RatioedPanel extends Active return self::getTabsHTML('ratioed') . Renderer::replaceMacros($t, [ // strings // '$title' => $this->t('Moderation'), + '$help_url' => $this->baseUrl . '/ratioed/help', '$page' => $this->t('Behaviour'), '$select_all' => $this->t('select all'), '$delete' => $this->t('Delete'), diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl new file mode 100644 index 00000000..fee47e34 --- /dev/null +++ b/ratioed/templates/help.tpl @@ -0,0 +1,92 @@ +
+
+

Ratioed Plugin Help

+

+ This plugin provides administrators with additional statistics about + the behaviour of users. These may be useful as early warning signs + that warrant more carefully watching the behaviour of a user. They + are not suitable as a trigger for instantly blocking, + muting, or reporting a user, since they lack context. +

+

+ The name of the plugin comes + from "The + Ratio", a well-known quick rule of thumb: +

+
+ If the Replies:RT ratio is greater than 2:1, you done messed up. +
+

+ To "get ratioed" is to receive a large number of comments in a short + space of time, with relatively few likes or boosts. If commenters + were enthusiastic about the posts, they would also have liked or + boosted them. Receiving many comments without such likes or boosts + indicates the comments were probably angry. This anger may or may + not be justified, but either way this is probably something + moderators should be aware of. +

+

+ This plugin allows viewing of an actual ratio, calculated over the + last 24 hours. This is a useful timeframe for sudden dogpiling + events that administrators might not otherwise notice. The plugin + also calculates other statistics. +

+

Explanation of Statistics

+

Blocked by

+

+ This summarises the number of users on remote servers that have + blocked this user. +

+

+ Note that the ActivityPub spec expressly says that + implementations "SHOULD NOT" forward such block messages to + remote servers. Nevertheless some implementations do this + anyway, notably Mastodon. This statistic can only count block + messages from servers that do this, as well as blocks from local + users. As such, it is usually an undercount. +

+

+ The reason the spec recommends against forwarding these messages + is that they can lead to retaliation. For this reason, this + plugin deliberately does not provide any way to investigate + exactly who blocked the user. +

+

Comments last 24h

+

+ This gives the number of comments made on the top-level posts that + this user made within the last 24 hours. +

+

Reactions last 24h

+

+ This collects the number of likes, boosts, or other "one-click" + interactions made on the user's top-level posts within the last 24 + hours. +

+

Ratio last 24h

+

+ This is the ratio between "Comments last 24h" and "Reactions last + 24h". It is intended to approximate the traditional ratio as + understood on Twitter. +

+

Performance

+

+ The statistics are computed from scratch each time the page loads. + It's possible that this might put a heavy load on the database. and + the page may take a long time to load. +

+

Extending

+

+ Suggestions for additional statistics are welcome, especially from + moderators. This plugin should be considered a sandbox for + experimentation, so it is not necessary to prove that any statistic + is correlated with unwanted behaviour. +

+

+ However, this plugin does deal with potentially sensitive + information. Even if moderators do in principle have access to all + information, it should not necessarily be highlighted. Statistics + should be kept anonymous and neutral. Also, they should be + presented only to moderators, not to the users themselves. +

+
+
From 4bfdb45e81c8550ab89381670c068455d780bcf5 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 12 Aug 2024 20:20:32 +0000 Subject: [PATCH 105/294] Bluesky/Tumblr: Improved statistics --- bluesky/bluesky.php | 23 +++++++++++++---------- tumblr/tumblr.php | 22 +++++++++++++--------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 9f21674f..19466a42 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -294,9 +294,9 @@ function bluesky_block(array &$hook_data) $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { - $cdata = Contact::getPublicAndUserContactID($hook_data['contact']['id'], $hook_data['uid']); - if (!empty($cdata['user'])) { - Contact::remove($cdata['user']); + $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); + if ($ucid) { + Contact::remove($ucid); } Logger::debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); } @@ -975,6 +975,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass return null; } + Item::incrementOutbound(Protocol::BLUESKY); Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return $data->blob; } @@ -1048,8 +1049,8 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) $item['owner-link'] = $item['author-link']; $item['owner-avatar'] = $item['author-avatar']; if (Item::insert($item)) { - $cdata = Contact::getPublicAndUserContactID($contact['id'], $uid); - Item::update(['post-reason' => Item::PR_ANNOUNCEMENT, 'causer-id' => $cdata['public']], ['uri' => $uri, 'uid' => $uid]); + $pcid = Contact::getPublicContactId($contact['id'], $uid); + Item::update(['post-reason' => Item::PR_ANNOUNCEMENT, 'causer-id' => $pcid], ['uri' => $uri, 'uid' => $uid]); } } @@ -1537,8 +1538,7 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ Logger::debug('Reply count', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); if ($causer != 0) { - $cdata = Contact::getPublicAndUserContactID($causer, $uid); - $causer = $cdata['public'] ?? 0; + $causer = Contact::getPublicContactId($causer, $uid); } return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); @@ -1936,7 +1936,11 @@ function bluesky_create_token(int $uid, string $password): string function bluesky_xrpc_post(int $uid, string $url, $parameters): ?stdClass { - return bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + $data = bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + if (!empty($data)) { + Item::incrementOutbound(Protocol::BLUESKY); + } + return $data; } function bluesky_post(int $uid, string $url, string $params, array $headers): ?stdClass @@ -1946,7 +1950,6 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s return null; } - Item::incrementOutbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); } catch (\Exception $e) { @@ -1983,7 +1986,6 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass { - Item::incrementInbound(Protocol::BLUESKY); try { $curlResult = DI::httpClient()->get($url, $accept_content, $opts); } catch (\Exception $e) { @@ -1996,5 +1998,6 @@ function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEF return null; } + Item::incrementInbound(Protocol::BLUESKY); return json_decode($curlResult->getBodyString()); } diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 945f8f35..dd34bd41 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -133,6 +133,7 @@ function tumblr_item_by_link(array &$hookData) Logger::debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); if (!empty($result->response->posts)) { $hookData['item_id'] = tumblr_process_post($result->response->posts[0], $hookData['uid'], Item::PR_FETCHED); + Item::incrementInbound(Protocol::TUMBLR); } } @@ -203,9 +204,9 @@ function tumblr_block(array &$hook_data) $hook_data['result'] = ($result->meta->status <= 399); if ($hook_data['result']) { - $cdata = Contact::getPublicAndUserContactID($hook_data['contact']['id'], $hook_data['uid']); - if (!empty($cdata['user'])) { - Contact::remove($cdata['user']); + $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); + if ($ucid) { + Contact::remove($ucid); } } } @@ -238,9 +239,7 @@ function tumblr_get_contact_uuid(array $contact): string * existence of this method is checked to figure out if the addon offers a * module. */ -function tumblr_module() -{ -} +function tumblr_module() {} function tumblr_content() { @@ -756,6 +755,7 @@ function tumblr_fetch_tags(int $uid, int $last_poll) $post = Post::selectFirst(['uri-id'], ['id' => $id]); $stored = Post\Category::storeFileByURIId($post['uri-id'], $uid, Post\Category::SUBCRIPTION, $tag); Logger::debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); + Item::incrementInbound(Protocol::TUMBLR); } } } @@ -795,6 +795,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) Logger::debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); tumblr_process_post($post, $uid, Item::PR_NONE, $last_poll); + Item::incrementInbound(Protocol::TUMBLR); DI::pConfig()->set($uid, 'tumblr', 'last_id', $last); } @@ -1167,6 +1168,7 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); return $fields; } + Item::incrementInbound(Protocol::TUMBLR); $avatar = $info->response->blog->avatar; if (!empty($avatar)) { @@ -1231,6 +1233,8 @@ function tumblr_get_blogs(int $uid): array return []; } + Item::incrementInbound(Protocol::TUMBLR); + $blogs = []; foreach ($userinfo->response->user->blogs as $blog) { $blogs[$blog->uuid] = $blog->name; @@ -1287,10 +1291,11 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array if ($info->meta->status > 399) { Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); return null; - } else { - Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); } + Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); + Item::incrementInbound(Protocol::TUMBLR); + $baseurl = 'https://tumblr.com'; $url = $baseurl . '/' . $info->response->blog->name; @@ -1326,7 +1331,6 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array */ function tumblr_get(int $uid, string $url, array $parameters = []): stdClass { - Item::incrementInbound(Protocol::TUMBLR); $url = 'https://api.tumblr.com/v2/' . $url; if ($uid == 0) { From a55f80cb39ea8737a56e265cb9edda6739cc2755 Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Thu, 15 Aug 2024 06:44:57 +0200 Subject: [PATCH 106/294] updated translations --- curweather/lang/fr/messages.po | 7 ++++--- curweather/lang/fr/strings.php | 2 +- geonames/lang/fr/messages.po | 7 ++++--- geonames/lang/fr/strings.php | 2 +- gnot/lang/fr/messages.po | 7 ++++--- gnot/lang/fr/strings.php | 2 +- gravatar/lang/fr/messages.po | 7 ++++--- gravatar/lang/fr/strings.php | 2 +- ijpost/lang/fr/messages.po | 7 ++++--- ijpost/lang/fr/strings.php | 2 +- krynn/lang/fr/messages.po | 7 ++++--- krynn/lang/fr/strings.php | 2 +- 12 files changed, 30 insertions(+), 24 deletions(-) diff --git a/curweather/lang/fr/messages.po b/curweather/lang/fr/messages.po index 57ed6b8b..21e60c54 100644 --- a/curweather/lang/fr/messages.po +++ b/curweather/lang/fr/messages.po @@ -5,6 +5,7 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 # Hypolite Petovan , 2022 # Hypolite Petovan , 2016 # ea1cd8241cb389ffb6f92bc6891eff5d_dc12308 <70dced5587d47e18d88f9298024d96f8_93383>, 2015 @@ -15,8 +16,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2014-06-22 11:34+0000\n" -"Last-Translator: Hypolite Petovan , 2022\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -45,7 +46,7 @@ msgstr "Vent" #: curweather.php:140 msgid "Last Updated" -msgstr "Dernière mise-à-jour" +msgstr "Dernière mise à jour" #: curweather.php:141 msgid "Data by" diff --git a/curweather/lang/fr/strings.php b/curweather/lang/fr/strings.php index be5c1ba5..268b3a42 100644 --- a/curweather/lang/fr/strings.php +++ b/curweather/lang/fr/strings.php @@ -10,7 +10,7 @@ $a->strings['Current Weather'] = 'Météo actuelle'; $a->strings['Relative Humidity'] = 'Humidité relative'; $a->strings['Pressure'] = 'Pression'; $a->strings['Wind'] = 'Vent'; -$a->strings['Last Updated'] = 'Dernière mise-à-jour'; +$a->strings['Last Updated'] = 'Dernière mise à jour'; $a->strings['Data by'] = 'Données de'; $a->strings['Show on map'] = 'Montrer sur la carte'; $a->strings['There was a problem accessing the weather data. But have a look'] = 'Une erreur est survenue lors de l\'accès aux données météo. Vous pouvez quand même jeter un oeil'; diff --git a/geonames/lang/fr/messages.po b/geonames/lang/fr/messages.po index b1cd8ce1..9fe03bdb 100644 --- a/geonames/lang/fr/messages.po +++ b/geonames/lang/fr/messages.po @@ -6,6 +6,7 @@ # Translators: # bob lebonche , 2021 # ButterflyOfFire, 2020 +# cracrayol, 2024 # Hypolite Petovan , 2016 msgid "" msgstr "" @@ -13,8 +14,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2014-06-23 08:27+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -29,7 +30,7 @@ msgstr "Remplacer les coordonnées par le nom de la localité la plus proche dan #: geonames.php:136 msgid "Enable Geonames Addon" -msgstr "Activer l'application complémentaire Geonames" +msgstr "Activer l'extension Geonames" #: geonames.php:141 msgid "Geonames Settings" diff --git a/geonames/lang/fr/strings.php b/geonames/lang/fr/strings.php index 297e3b73..802dd118 100644 --- a/geonames/lang/fr/strings.php +++ b/geonames/lang/fr/strings.php @@ -6,5 +6,5 @@ function string_plural_select_fr($n){ if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Replace numerical coordinates by the nearest populated location name in your posts.'] = 'Remplacer les coordonnées par le nom de la localité la plus proche dans votre publication.'; -$a->strings['Enable Geonames Addon'] = 'Activer l\'application complémentaire Geonames'; +$a->strings['Enable Geonames Addon'] = 'Activer l\'extension Geonames'; $a->strings['Geonames Settings'] = 'Paramètres Geonames'; diff --git a/gnot/lang/fr/messages.po b/gnot/lang/fr/messages.po index 3ce82e7f..8a928544 100644 --- a/gnot/lang/fr/messages.po +++ b/gnot/lang/fr/messages.po @@ -6,6 +6,7 @@ # Translators: # bob lebonche , 2021 # ButterflyOfFire, 2020 +# cracrayol, 2024 # Hypolite Petovan , 2016 msgid "" msgstr "" @@ -13,8 +14,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2014-06-23 08:30+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -29,7 +30,7 @@ msgstr "Permettre le filtrage des notifications de commentaires par courriel sur #: gnot.php:64 msgid "Enable this addon?" -msgstr "Activer cette application complémentaire ?" +msgstr "Activer cette extension ?" #: gnot.php:69 msgid "Gnot Settings" diff --git a/gnot/lang/fr/strings.php b/gnot/lang/fr/strings.php index c498f7e8..53104349 100644 --- a/gnot/lang/fr/strings.php +++ b/gnot/lang/fr/strings.php @@ -6,6 +6,6 @@ function string_plural_select_fr($n){ if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Allows threading of email comment notifications on Gmail and anonymising the subject line.'] = 'Permettre le filtrage des notifications de commentaires par courriel sur Gmail et l\'anonymisation de l\'objet.'; -$a->strings['Enable this addon?'] = 'Activer cette application complémentaire ?'; +$a->strings['Enable this addon?'] = 'Activer cette extension ?'; $a->strings['Gnot Settings'] = 'Paramètres Gnot'; $a->strings['[Friendica:Notify] Comment to conversation #%d'] = '[Friendica:Notify] Commentaire vers conversation #%d'; diff --git a/gravatar/lang/fr/messages.po b/gravatar/lang/fr/messages.po index f8a64a1b..6ffa6214 100644 --- a/gravatar/lang/fr/messages.po +++ b/gravatar/lang/fr/messages.po @@ -5,6 +5,7 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 # Marie Olive , 2018 # ea1cd8241cb389ffb6f92bc6891eff5d_dc12308 <70dced5587d47e18d88f9298024d96f8_93383>, 2015 msgid "" @@ -13,8 +14,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-02-01 18:15+0100\n" "PO-Revision-Date: 2014-06-23 08:33+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -50,7 +51,7 @@ msgid "" "Libravatar addon is installed, too. Please disable Libravatar addon or this " "Gravatar addon.
The Libravatar addon will fall back to Gravatar if " "nothing was found at Libravatar." -msgstr "L'application complémentaire Libravatar est aussi installée. Merci de désactiver l'application complémentaire Libravatar ou cette application complémentaire Gravatar. L'application complémentaire se repliera sur Gravatar si rien n'est trouvé dans Libravatar." +msgstr "L'extension Libravatar est aussi installée. Merci de désactiver l'extension Libravatar ou cette extension Gravatar. L'extension se repliera sur Gravatar si rien n'est trouvé dans Libravatar." #: gravatar.php:102 msgid "Save Settings" diff --git a/gravatar/lang/fr/strings.php b/gravatar/lang/fr/strings.php index b826ab65..930d7169 100644 --- a/gravatar/lang/fr/strings.php +++ b/gravatar/lang/fr/strings.php @@ -11,7 +11,7 @@ $a->strings['monster face'] = 'Face de monstre'; $a->strings['computer generated face'] = 'visage généré par ordinateur'; $a->strings['retro arcade style face'] = 'Face style retro arcade'; $a->strings['Information'] = 'Information'; -$a->strings['Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.
The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar.'] = 'L\'application complémentaire Libravatar est aussi installée. Merci de désactiver l\'application complémentaire Libravatar ou cette application complémentaire Gravatar. L\'application complémentaire se repliera sur Gravatar si rien n\'est trouvé dans Libravatar.'; +$a->strings['Libravatar addon is installed, too. Please disable Libravatar addon or this Gravatar addon.
The Libravatar addon will fall back to Gravatar if nothing was found at Libravatar.'] = 'L\'extension Libravatar est aussi installée. Merci de désactiver l\'extension Libravatar ou cette extension Gravatar. L\'extension se repliera sur Gravatar si rien n\'est trouvé dans Libravatar.'; $a->strings['Save Settings'] = 'Sauvegarder les paramètres.'; $a->strings['Default avatar image'] = 'Image par défaut d\'avatar'; $a->strings['Select default avatar image if none was found at Gravatar. See README'] = 'Sélectionner l\'avatar par défaut, si aucun n\'est trouvé sur Gravatar. Voir Lisezmoi.'; diff --git a/ijpost/lang/fr/messages.po b/ijpost/lang/fr/messages.po index bc322337..6f29cad7 100644 --- a/ijpost/lang/fr/messages.po +++ b/ijpost/lang/fr/messages.po @@ -5,6 +5,7 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 # Hypolite Petovan , 2016 msgid "" msgstr "" @@ -12,8 +13,8 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:17-0500\n" "PO-Revision-Date: 2014-06-23 08:37+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -26,7 +27,7 @@ msgstr "Publier sur Insanejournal" #: ijpost.php:61 msgid "Enable InsaneJournal Post Addon" -msgstr "Activer l'application complémentaire InsaneJournalPost" +msgstr "Activer l'extension InsaneJournal" #: ijpost.php:62 msgid "InsaneJournal username" diff --git a/ijpost/lang/fr/strings.php b/ijpost/lang/fr/strings.php index d8e3e95d..d2fafc92 100644 --- a/ijpost/lang/fr/strings.php +++ b/ijpost/lang/fr/strings.php @@ -6,7 +6,7 @@ function string_plural_select_fr($n){ if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} $a->strings['Post to Insanejournal'] = 'Publier sur Insanejournal'; -$a->strings['Enable InsaneJournal Post Addon'] = 'Activer l\'application complémentaire InsaneJournalPost'; +$a->strings['Enable InsaneJournal Post Addon'] = 'Activer l\'extension InsaneJournal'; $a->strings['InsaneJournal username'] = 'Identifiant du InsaneJournal'; $a->strings['InsaneJournal password'] = 'Mot de passe du InsaneJournal'; $a->strings['Post to InsaneJournal by default'] = 'Publier sur le InsaneJournal par défaut'; diff --git a/krynn/lang/fr/messages.po b/krynn/lang/fr/messages.po index a96af8de..8a306eb1 100644 --- a/krynn/lang/fr/messages.po +++ b/krynn/lang/fr/messages.po @@ -5,14 +5,15 @@ # # Translators: # bob lebonche , 2021 +# cracrayol, 2024 msgid "" msgstr "" "Project-Id-Version: friendica\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-21 19:14-0500\n" "PO-Revision-Date: 2015-07-07 15:14+0000\n" -"Last-Translator: bob lebonche , 2021\n" -"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n" +"Last-Translator: cracrayol, 2024\n" +"Language-Team: French (http://app.transifex.com/Friendica/friendica/language/fr/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -21,7 +22,7 @@ msgstr "" #: krynn.php:127 msgid "Enable Krynn Addon" -msgstr "Activer l'application complémentaire Krynn" +msgstr "Activer l'extension Krynn" #: krynn.php:132 msgid "Krynn Settings" diff --git a/krynn/lang/fr/strings.php b/krynn/lang/fr/strings.php index 3c3574d0..84293f79 100644 --- a/krynn/lang/fr/strings.php +++ b/krynn/lang/fr/strings.php @@ -5,5 +5,5 @@ function string_plural_select_fr($n){ $n = intval($n); if (($n == 0 || $n == 1)) { return 0; } else if ($n != 0 && $n % 1000000 == 0) { return 1; } else { return 2; } }} -$a->strings['Enable Krynn Addon'] = 'Activer l\'application complémentaire Krynn'; +$a->strings['Enable Krynn Addon'] = 'Activer l\'extension Krynn'; $a->strings['Krynn Settings'] = 'Paramètres de Krynn'; From 276c27678feb7f2660efb7b199c40346abdb5bb3 Mon Sep 17 00:00:00 2001 From: Philipp Date: Tue, 20 Aug 2024 18:07:51 +0200 Subject: [PATCH 107/294] [CI] Add safe.directory config --- .woodpecker/.code_standards_check.yml | 3 +++ .woodpecker/.continuous-deployment.yml | 3 +++ .woodpecker/.messages.po_check.yml | 3 +++ .woodpecker/.phpunit.yml | 3 +++ .woodpecker/.releaser.yml | 3 +++ 5 files changed, 15 insertions(+) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index 8e0f7dc7..fb5be33c 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -4,6 +4,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index d1202978..4d3bc5b7 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -9,6 +9,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index ea9fa4d5..aa40ab4e 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -4,6 +4,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 0c25a2bd..887e897e 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -21,6 +21,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH clone_friendica_addon: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index 68bdfb21..f12697b9 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -9,6 +9,9 @@ pipeline: clone_friendica_base: image: alpine/git commands: + - git config --global user.email "no-reply@friendi.ca" + - git config --global user.name "Friendica" + - git config --global --add safe.directory $CI_WORKSPACE - git clone https://github.com/friendica/friendica.git . - git checkout $CI_COMMIT_BRANCH when: From 50930c301d3d736fb204a69d1cafd778af819ca8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 1 Sep 2024 11:39:59 +0000 Subject: [PATCH 108/294] Bluesky: Improve DID detection for custom PDS --- bluesky/bluesky.php | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 19466a42..101568c7 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1793,23 +1793,19 @@ function bluesky_get_did(string $handle): string $handle .= '.' . BLUESKY_HOSTNAME; } - // Deactivated at the moment, since it isn't reliable by now - //$did = bluesky_get_did_by_dns($handle); - //if ($did != '') { - // return $did; - //} - - //$did = bluesky_get_did_by_wellknown($handle); - //if ($did != '') { - // return $did; - //} - $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (empty($data) || empty($data->did)) { - return ''; + if (!empty($data) && !empty($data->did)) { + Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); + return $data->did; } - Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; + + // Possibly a custom PDS. + $did = bluesky_get_did_by_dns($handle); + if ($did != '') { + return $did; + } + + return bluesky_get_did_by_wellknown($handle); } function bluesky_get_user_did(int $uid, bool $refresh = false): ?string From 2f9076bffdede3add6feeae7e66e4ca095105a2c Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 3 Sep 2024 11:28:49 +0000 Subject: [PATCH 109/294] Bluesky: probing for bluesky handles --- bluesky/bluesky.php | 146 +++++++++++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 34 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 101568c7..9145fc32 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -45,10 +45,12 @@ use Friendica\Model\Tag; use Friendica\Model\User; use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; +use Friendica\Network\HTTPClient\Client\HttpClientRequest; use Friendica\Object\Image; use Friendica\Protocol\Activity; use Friendica\Protocol\Relay; use Friendica\Util\DateTimeFormat; +use Friendica\Util\Network; use Friendica\Util\Strings; const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes @@ -129,8 +131,13 @@ function bluesky_probe_detect(array &$hookData) if (parse_url($hookData['uri'], PHP_URL_SCHEME) == 'did') { $did = $hookData['uri']; - } elseif (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $hookData['uri'], $matches)) { - $did = bluesky_get_did($matches[1]); + } elseif (parse_url($hookData['uri'], PHP_URL_PATH) == $hookData['uri'] && strpos($hookData['uri'], '@') === false) { + $did = bluesky_get_did($hookData['uri'], $pconfig['uid']); + if (empty($did)) { + return; + } + } elseif (Network::isValidHttpUrl($hookData['uri'])) { + $did = bluesky_get_did_by_profile($hookData['uri']); if (empty($did)) { return; } @@ -148,19 +155,14 @@ function bluesky_probe_detect(array &$hookData) return; } - $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], false); - - $hookData['result']['baseurl'] = bluesky_get_pds($did); + $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], true); // Preparing probe data. This differs slightly from the contact array - $hookData['result']['about'] = HTML::toBBCode($data->description ?? ''); $hookData['result']['photo'] = $data->avatar ?? ''; - $hookData['result']['header'] = $data->banner ?? ''; $hookData['result']['batch'] = ''; $hookData['result']['notify'] = ''; $hookData['result']['poll'] = ''; $hookData['result']['poco'] = ''; - $hookData['result']['pubkey'] = ''; $hookData['result']['priority'] = 0; $hookData['result']['guid'] = ''; } @@ -177,21 +179,21 @@ function bluesky_item_by_link(array &$hookData) return; } - if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { - return; - } - - $did = bluesky_get_did($matches[1]); + $did = bluesky_get_did_by_profile($hookData['uri']); if (empty($did)) { return; } - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'handle' => $matches[1], 'did' => $did, 'cid' => $matches[2]]); + if (!preg_match('#/profile/.+/post/(.+)#', $hookData['uri'], $matches)) { + return; + } - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; + Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[1]]); + + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[1]; $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); - Logger::debug('Got post', ['profile' => $matches[1], 'cid' => $matches[2], 'result' => $uri]); + Logger::debug('Got post', ['did' => $did, 'cid' => $matches[1], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -1678,10 +1680,14 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, return $fields; } - $fields['baseurl'] = bluesky_get_pds($author->did); - if (!empty($fields['baseurl'])) { - GServer::check($fields['baseurl'], Protocol::BLUESKY); - $fields['gsid'] = GServer::getID($fields['baseurl'], true); + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); + if (!empty($data)) { + $fields['baseurl'] = bluesky_get_pds('', $data); + if (!empty($fields['baseurl'])) { + GServer::check($fields['baseurl'], Protocol::BLUESKY); + $fields['gsid'] = GServer::getID($fields['baseurl'], true); + } + $fields['pubkey'] = bluesky_get_public_key('', $data); } $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); @@ -1748,6 +1754,42 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } +function bluesky_get_did_by_profile(string $url): string +{ + try { + $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); + } catch (\Throwable $th) { + return ''; + } + if (!$curlResult->isSuccess()) { + return ''; + } + $profile = $curlResult->getBodyString(); + + $doc = new DOMDocument(); + @$doc->loadHTML($profile); + $xpath = new DOMXPath($doc); + $list = $xpath->query('//p[@id]'); + foreach ($list as $node) { + foreach ($node->attributes as $attribute) { + if ($attribute->name == 'id') { + $ids[$attribute->value] = $node->textContent; + } + } + } + + if (empty($ids['bsky_handle']) || empty($ids['bsky_did'])) { + return ''; + } + + if (!bluesky_valid_did($ids['bsky_did'], $ids['bsky_handle'])) { + Logger::notice('Invalid DID', ['handle' => $ids['bsky_handle'], 'did' => $ids['bsky_did']]); + return ''; + } + + return $ids['bsky_did']; +} + function bluesky_get_did_by_wellknown(string $handle): string { $curlResult = DI::httpClient()->get('http://' . $handle . '/.well-known/atproto-did'); @@ -1757,7 +1799,6 @@ function bluesky_get_did_by_wellknown(string $handle): string Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); return ''; } - Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); return $did; } return ''; @@ -1776,14 +1817,13 @@ function bluesky_get_did_by_dns(string $handle): string Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); return ''; } - Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); return $did; } } return ''; } -function bluesky_get_did(string $handle): string +function bluesky_get_did(string $handle, int $uid): string { if ($handle == '') { return ''; @@ -1793,19 +1833,39 @@ function bluesky_get_did(string $handle): string $handle .= '.' . BLUESKY_HOSTNAME; } + // At first we use the user PDS. That should cover most cases. + $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); + if (!empty($pds)) { + $data = bluesky_get($pds . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); + if (!empty($data) && !empty($data->did)) { + Logger::debug('Got DID by user PDS call', ['handle' => $handle, 'did' => $data->did]); + return $data->did; + } + } + + // Then we query the DNS, which is used for third party handles (DNS should be faster than wellknown) + $did = bluesky_get_did_by_dns($handle); + if ($did != '') { + Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); + return $did; + } + + // Then we query wellknown, which should mostly cover the rest. + $did = bluesky_get_did_by_wellknown($handle); + if ($did != '') { + Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); + return $did; + } + + // And finally we use the default PDS from Bluesky. $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by PDS call', ['handle' => $handle, 'did' => $data->did]); + Logger::debug('Got DID by system PDS call', ['handle' => $handle, 'did' => $data->did]); return $data->did; } - // Possibly a custom PDS. - $did = bluesky_get_did_by_dns($handle); - if ($did != '') { - return $did; - } - - return bluesky_get_did_by_wellknown($handle); + Logger::notice('No DID detected', ['handle' => $handle]); + return ''; } function bluesky_get_user_did(int $uid, bool $refresh = false): ?string @@ -1822,7 +1882,7 @@ function bluesky_get_user_did(int $uid, bool $refresh = false): ?string return null; } - $did = bluesky_get_did($handle); + $did = bluesky_get_did($handle, $uid); if (empty($did)) { return null; } @@ -1853,9 +1913,11 @@ function bluesky_get_user_pds(int $uid): ?string return $pds; } -function bluesky_get_pds(string $did): ?string +function bluesky_get_pds(string $did, stdClass $data = null): ?string { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + if (empty($data)) { + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + } if (empty($data) || empty($data->service)) { return null; } @@ -1869,6 +1931,22 @@ function bluesky_get_pds(string $did): ?string return null; } +function bluesky_get_public_key(string $did, stdClass $data = null): ?string +{ + if (empty($data)) { + $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); + } + if (empty($data) || empty($data->verificationMethod)) { + return null; + } + foreach ($data->verificationMethod as $method) { + if (!empty($method->publicKeyMultibase)) { + return $method->publicKeyMultibase; + } + } + return null; +} + function bluesky_valid_did(string $did, string $handle): bool { $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); From 0dfb345f85d0b8016fd6b0c25be48e26a49e94fd Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 4 Sep 2024 11:46:33 +0000 Subject: [PATCH 110/294] "fetchFull" is replaced by "get" --- mailstream/mailstream.php | 30 +++++++++++-------- mastodoncustomemojis/mastodoncustomemojis.php | 4 +-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index cc283789..ae57c4dd 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -6,7 +6,6 @@ * Author: Matthew Exon */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; @@ -16,12 +15,11 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; -use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\User; use Friendica\Network\HTTPClient\Client\HttpClientAccept; +use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Protocol\Activity; -use Friendica\Util\DateTimeFormat; /** * Sets up the addon hooks and the database table @@ -53,10 +51,12 @@ function mailstream_addon_admin(string &$o) { $frommail = DI::config()->get('mailstream', 'frommail'); $template = Renderer::getMarkupTemplate('admin.tpl', 'addon/mailstream/'); - $config = ['frommail', + $config = [ + 'frommail', DI::l10n()->t('From Address'), $frommail, - DI::l10n()->t('Email address that stream items will appear to be from.')]; + DI::l10n()->t('Email address that stream items will appear to be from.') + ]; $o .= Renderer::replaceMacros($template, [ '$frommail' => $config, '$submit' => DI::l10n()->t('Save Settings') @@ -101,7 +101,7 @@ function mailstream_send_hook(array $data) $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('could not find user', ['uid' => $item['uid']]); + Logger::error('could not find user', ['uid' => $item['uid']]); return; } @@ -198,10 +198,13 @@ function mailstream_do_images(array &$item, array &$attachments) $cookiejar = tempnam(System::getTempPath(), 'cookiejar-mailstream-'); try { - $curlResult = DI::httpClient()->fetchFull($url, HttpClientAccept::DEFAULT, 0, $cookiejar); + $curlResult = DI::httpClient()->get($url, HttpClientAccept::DEFAULT, [HttpClientOptions::COOKIEJAR => $cookiejar]); if (!$curlResult->isSuccess()) { Logger::debug('mailstream: fetch image url failed', [ - 'url' => $url, 'item_id' => $item['id'], 'return_code' => $curlResult->getReturnCode()]); + 'url' => $url, + 'item_id' => $item['id'], + 'return_code' => $curlResult->getReturnCode() + ]); continue; } } catch (InvalidArgumentException $e) { @@ -361,7 +364,7 @@ function mailstream_send(string $message_id, array $item, array $user): bool return true; } - require_once (dirname(__file__) . '/phpmailer/class.phpmailer.php'); + require_once(dirname(__file__) . '/phpmailer/class.phpmailer.php'); $item['body'] = Post\Media::addAttachmentsToBody($item['uri-id'], $item['body']); @@ -406,10 +409,11 @@ function mailstream_send(string $message_id, array $item, array $user): bool $item['body'] = BBCode::convertForUriId($item['uri-id'], $item['body'], BBCode::CONNECTORS); $item['url'] = DI::baseUrl() . '/display/' . $item['guid']; $mail->Body = Renderer::replaceMacros($template, [ - '$upstream' => DI::l10n()->t('Upstream'), - '$uri' => DI::l10n()->t('URI'), - '$local' => DI::l10n()->t('Local'), - '$item' => $item]); + '$upstream' => DI::l10n()->t('Upstream'), + '$uri' => DI::l10n()->t('URI'), + '$local' => DI::l10n()->t('Local'), + '$item' => $item + ]); $mail->Body = mailstream_html_wrap($mail->Body); if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); diff --git a/mastodoncustomemojis/mastodoncustomemojis.php b/mastodoncustomemojis/mastodoncustomemojis.php index 561262f1..fcb8feea 100644 --- a/mastodoncustomemojis/mastodoncustomemojis.php +++ b/mastodoncustomemojis/mastodoncustomemojis.php @@ -1,5 +1,4 @@ fetchFull($api_url); + $fetchResult = DI::httpClient()->get($api_url); if ($fetchResult->isSuccess()) { $emojis_array = json_decode($fetchResult->getBodyString(), true); From 3dc77b21023c1258d2a7a23033f6ff6d0300b215 Mon Sep 17 00:00:00 2001 From: loma-one Date: Sat, 7 Sep 2024 21:04:43 +0200 Subject: [PATCH 111/294] unicode_smilies/unicode_smilies.php aktualisiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addition of the unicode character ‘asterism’ & ‘outlines white star’ --- unicode_smilies/unicode_smilies.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 3bd30644..22ee3439 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -1293,6 +1293,8 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':microscope:', '🔬'); Smilies::add($b, ':telescope:', '🔭'); Smilies::add($b, ':satellite antenna:', '📡'); + Smilies::add($b, ':asterism:', '⁂'); + Smilies::add($b, ':outlines white star:', '⚝'); // medical Smilies::add($b, ':syringe:', '💉'); From 712edf42366d0ad118116be0f23cc20ea2b6bbdd Mon Sep 17 00:00:00 2001 From: loma-one Date: Sat, 7 Sep 2024 21:10:02 +0200 Subject: [PATCH 112/294] invidious/invidious.php aktualisiert Further addresses have been added, which are now redirected. --- invidious/invidious.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/invidious/invidious.php b/invidious/invidious.php index 7153aab9..033ecce5 100644 --- a/invidious/invidious.php +++ b/invidious/invidious.php @@ -96,6 +96,8 @@ function invidious_render(array &$b) $b['html'] = preg_replace("~https?://(?:www\.)?youtube\.com/watch\?v=(.*?)~ism", $server . '/watch?v=$1', $b['html']); $b['html'] = preg_replace("~https?://(?:www\.)?youtube\.com/embed/(.*?)~ism", $server . '/embed/$1', $b['html']); $b['html'] = preg_replace("~https?://(?:www\.)?youtube\.com/shorts/(.*?)~ism", $server . '/shorts/$1', $b['html']); + $b['html'] = preg_replace ("/https?:\/\/music.youtube.com\/(.*?)/ism", $server . '/watch?v=$1', $b['html']); + $b['html'] = preg_replace ("/https?:\/\/m.youtube.com\/(.*?)/ism", $server . '/watch?v=$1', $b['html']); $b['html'] = preg_replace("/https?:\/\/youtu.be\/(.*?)/ism", $server . '/watch?v=$1', $b['html']); if ($original != $b['html']) { From 14e1c9677527118c73e999a221c006dd698a2b79 Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 10 Sep 2024 10:26:05 +0000 Subject: [PATCH 113/294] Bluesky: Fix for the handling of invalid profiles --- bluesky/bluesky.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 9145fc32..181e8d2d 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1765,9 +1765,16 @@ function bluesky_get_did_by_profile(string $url): string return ''; } $profile = $curlResult->getBodyString(); + if (empty($profile)) { + return ''; + } $doc = new DOMDocument(); - @$doc->loadHTML($profile); + try { + @$doc->loadHTML($profile); + } catch (\Throwable $th) { + return ''; + } $xpath = new DOMXPath($doc); $list = $xpath->query('//p[@id]'); foreach ($list as $node) { From 10521115c4f51b4e773e94f3a8149711c125701e Mon Sep 17 00:00:00 2001 From: loma-one Date: Sun, 8 Sep 2024 18:12:13 +0200 Subject: [PATCH 114/294] More and updated icons for the smiley pack --- smiley_pack/icons/commercial/facebook.gif | Bin 0 -> 269 bytes smiley_pack/icons/commercial/github.png | Bin 0 -> 4720 bytes smiley_pack/icons/commercial/google.gif | Bin 0 -> 270 bytes smiley_pack/icons/commercial/instagram.gif | Bin 0 -> 1302 bytes smiley_pack/icons/commercial/signal.gif | Bin 0 -> 339 bytes smiley_pack/icons/commercial/telegram.gif | Bin 0 -> 627 bytes smiley_pack/icons/commercial/threads.png | Bin 0 -> 1025 bytes smiley_pack/icons/commercial/threema.png | Bin 0 -> 4777 bytes smiley_pack/icons/commercial/tiktok.gif | Bin 0 -> 257 bytes smiley_pack/icons/commercial/whatsapp.gif | Bin 0 -> 1353 bytes smiley_pack/icons/commercial/windows.png | Bin 0 -> 3584 bytes smiley_pack/icons/fediverse/diaspora.gif | Bin 79 -> 1147 bytes smiley_pack/icons/fediverse/diaspora.png | Bin 0 -> 4656 bytes smiley_pack/icons/fediverse/fediverse.gif | Bin 0 -> 444 bytes smiley_pack/icons/fediverse/friendica.png | Bin 0 -> 4719 bytes smiley_pack/icons/fediverse/funkwhale.gif | Bin 0 -> 471 bytes smiley_pack/icons/fediverse/gnusocial.gif | Bin 0 -> 135 bytes smiley_pack/icons/fediverse/hubzilla.png | Bin 0 -> 4563 bytes smiley_pack/icons/fediverse/lemmy.gif | Bin 0 -> 418 bytes smiley_pack/icons/fediverse/misskey.gif | Bin 405 -> 1177 bytes smiley_pack/icons/fediverse/peertube.gif | Bin 0 -> 137 bytes smiley_pack/icons/fediverse/pixelfed.gif | Bin 1064 -> 1262 bytes smiley_pack/icons/fediverse/pleroma.gif | Bin 100 -> 180 bytes smiley_pack/icons/fediverse/plume.gif | Bin 0 -> 410 bytes smiley_pack/icons/fediverse/writefreely.gif | Bin 0 -> 112 bytes smiley_pack/icons/noncommercial/bluesky.png | Bin 0 -> 4766 bytes smiley_pack/icons/noncommercial/invidious.gif | Bin 0 -> 908 bytes smiley_pack/icons/noncommercial/vivaldi.png | Bin 0 -> 4945 bytes smiley_pack/icons/opensource/archlinux.png | Bin 0 -> 4598 bytes smiley_pack/icons/opensource/debian.png | Bin 0 -> 5357 bytes smiley_pack/icons/opensource/fdroid.png | Bin 0 -> 7919 bytes smiley_pack/icons/opensource/fedora.png | Bin 0 -> 1408 bytes smiley_pack/icons/opensource/firefox.png | Bin 0 -> 12229 bytes .../icons/opensource/firefoxnightly.png | Bin 0 -> 4987 bytes smiley_pack/icons/opensource/foss.png | Bin 0 -> 4981 bytes smiley_pack/icons/opensource/jabber.png | Bin 0 -> 4301 bytes smiley_pack/icons/opensource/kde.png | Bin 0 -> 4678 bytes smiley_pack/icons/opensource/linux.png | Bin 0 -> 5149 bytes smiley_pack/icons/opensource/matrix.png | Bin 0 -> 4347 bytes smiley_pack/icons/opensource/mint.png | Bin 0 -> 8663 bytes smiley_pack/icons/opensource/opensuse.png | Bin 0 -> 12271 bytes smiley_pack/icons/opensource/raspi.png | Bin 0 -> 4534 bytes smiley_pack/icons/opensource/thunderbird.png | Bin 0 -> 4661 bytes smiley_pack/icons/opensource/tutanota.png | Bin 0 -> 5011 bytes smiley_pack/icons/opensource/ubuntu.png | Bin 0 -> 5067 bytes smiley_pack/icons/opensource/xmpp.png | Bin 0 -> 4985 bytes smiley_pack/icons/respect/cc.png | Bin 0 -> 4461 bytes smiley_pack/icons/respect/cc0.png | Bin 0 -> 4669 bytes smiley_pack/icons/respect/ccby.png | Bin 0 -> 4407 bytes smiley_pack/icons/respect/ccsa.png | Bin 0 -> 4848 bytes smiley_pack/smiley_pack.php | 242 +++++++++++++----- 51 files changed, 175 insertions(+), 67 deletions(-) create mode 100644 smiley_pack/icons/commercial/facebook.gif create mode 100644 smiley_pack/icons/commercial/github.png create mode 100644 smiley_pack/icons/commercial/google.gif create mode 100644 smiley_pack/icons/commercial/instagram.gif create mode 100644 smiley_pack/icons/commercial/signal.gif create mode 100644 smiley_pack/icons/commercial/telegram.gif create mode 100644 smiley_pack/icons/commercial/threads.png create mode 100644 smiley_pack/icons/commercial/threema.png create mode 100644 smiley_pack/icons/commercial/tiktok.gif create mode 100644 smiley_pack/icons/commercial/whatsapp.gif create mode 100644 smiley_pack/icons/commercial/windows.png create mode 100644 smiley_pack/icons/fediverse/diaspora.png create mode 100644 smiley_pack/icons/fediverse/fediverse.gif create mode 100644 smiley_pack/icons/fediverse/friendica.png create mode 100644 smiley_pack/icons/fediverse/funkwhale.gif create mode 100644 smiley_pack/icons/fediverse/gnusocial.gif create mode 100644 smiley_pack/icons/fediverse/hubzilla.png create mode 100644 smiley_pack/icons/fediverse/lemmy.gif create mode 100644 smiley_pack/icons/fediverse/peertube.gif create mode 100644 smiley_pack/icons/fediverse/plume.gif create mode 100644 smiley_pack/icons/fediverse/writefreely.gif create mode 100644 smiley_pack/icons/noncommercial/bluesky.png create mode 100644 smiley_pack/icons/noncommercial/invidious.gif create mode 100644 smiley_pack/icons/noncommercial/vivaldi.png create mode 100644 smiley_pack/icons/opensource/archlinux.png create mode 100644 smiley_pack/icons/opensource/debian.png create mode 100644 smiley_pack/icons/opensource/fdroid.png create mode 100644 smiley_pack/icons/opensource/fedora.png create mode 100644 smiley_pack/icons/opensource/firefox.png create mode 100644 smiley_pack/icons/opensource/firefoxnightly.png create mode 100644 smiley_pack/icons/opensource/foss.png create mode 100644 smiley_pack/icons/opensource/jabber.png create mode 100644 smiley_pack/icons/opensource/kde.png create mode 100644 smiley_pack/icons/opensource/linux.png create mode 100644 smiley_pack/icons/opensource/matrix.png create mode 100644 smiley_pack/icons/opensource/mint.png create mode 100644 smiley_pack/icons/opensource/opensuse.png create mode 100644 smiley_pack/icons/opensource/raspi.png create mode 100644 smiley_pack/icons/opensource/thunderbird.png create mode 100644 smiley_pack/icons/opensource/tutanota.png create mode 100644 smiley_pack/icons/opensource/ubuntu.png create mode 100644 smiley_pack/icons/opensource/xmpp.png create mode 100644 smiley_pack/icons/respect/cc.png create mode 100644 smiley_pack/icons/respect/cc0.png create mode 100644 smiley_pack/icons/respect/ccby.png create mode 100644 smiley_pack/icons/respect/ccsa.png diff --git a/smiley_pack/icons/commercial/facebook.gif b/smiley_pack/icons/commercial/facebook.gif new file mode 100644 index 0000000000000000000000000000000000000000..45488a5b5147f33b9237402acee364ec90062e08 GIT binary patch literal 269 zcmZ?wbhEHblwgoxXc1?yikx8`Iit2~L+gai^Oqmou>H)I-52&8ymau`^>Y{RK6>){ z@zdAOUc7tp^8Jff?_Yw@hj$;oeEa_E$IstCfBpIM=kNdj|0SiBa3RHig3d*$i6yBi z3gww484B*6z5xu1KUo;L7~~mr7=Qre5C+!L2kLz(ne$Q?tb4I@UxD@^lkRIQ$&nXc zUuwC#PEh$OQ}6G{@6j#vIbr5d>brml}1xFoc_Dev7nyK2dYUe*vl|J70-tWEld+&Rd zFNHDD;V#bZ&JYB-$RlL2;6B3gb+iXpV+_9@+-fqFGpSfK9X1&C1euJ(RE7bEaWhFk zkokr-<}26Ju;Yh^BPZwC_uVsYi{lZI~87Ce!H|^iCGyd7% zzYIK<=IJ;|v8=@O?-C9DtGe`(i#8!Ig~olCa~{3rt#1reGQ&EToieg0mz?+Pr3E$K zD%&Kt4rKV|e40I$J+VRe>|H)SCH@37?ELD>YxXl`522QDxxLLm z&4fEkvU2ARYhG_V=uEbfeLZdj?Fjkyv3m5Vl>Ko&!TB*0k33E=wvOhJ5wUYSz9HzTci zH7n-K5dU(v;_2a&-0cK&@>JURFX|TTf6d;v-o2fdGN*w$Kl-J|bdf&g>U@{0$GvmV z-MfF7WGW#Blao|V!(~2+TbH^gdnGo=%UACFu(lxQr;aK2W6#CejjOeJdl23=0TH&Wx?|FoxV1#M?0L3_ok zsguy#j-8;xq*_9s;io_ph7dfFjL0!J2sM*w9JFLaLE>myRu-GDzh=p)i91a6$FiaUb3NSh7(!7`%;7MqE%v|3hg3lkNZ20*$4`a=to66{h|EN;@L z8ZkUH4cAfQdPAtO9(zNoG1;1q8e`$fxE83IfLC@Om*H|nOpk?y0u8A(SgioreKaYO z_(WEp*eom7bb1E@%zJSAXn)MzstmLg3b9O&rCP$1%OrG*f3aGRk!rE^5kUwwiU@HA zn^374JWPl&gj@lKArkOKLbaOUarwMnP;#A#LUkB!fdb%665#MuC@x^51cOfy0tQcj zh!`S1!DSF^p@3lX*|>_!=>;*>NP@0JlY2*Hfl>n~g6l`{__%H(PEw0%aF#)*u`XB$7YD`2C3FrG`6P)+MkxXqNa#_d zF4g>LK}l-yX%uQA2AZI?;m3Mwr|#LM&wwgJb})sHIN< zfYk!zA`UU)D5WXBJTW2^v;CADwwNOnb2$?c zju`2suUC^q#{bf`Y#!LZtK<=+3HZ;jin?~xG(4s2t?Mn{M|Zn^l#_qZ3K(0Ba@c%6Lyd7U22aG}F+?0Ln}G{NTt1&8SG_}cO$_mq*fcOU#T`04~& zaH#)cOkbahWV#(PHRQw(YzrA1utH`bC0^R_}s5jpQSd^Ekn$k9ptOw zjFe`lg3~tiss&yd{+6f|_`@~|IIsmj-vBo&9v#<0}Rv%agnoS5Gy zO{{;GcJpn^^NUsbYVq{T$Y8hSVYAVr2X9tr(i^Kzm{{82D@OCH2?fdY+){d|VLr-V6BIO*Hf~jPna856w#CPnyZU?=Y1;g-eBKXO*_D)& zhc_&9*{k$@rHPMR_n^A*m8t&WtLT~hB3kXXQlF_=rnr}?@^dZ)r=R;qHFi8VR@7_P fcCP;IdePZ{i!aO>NYRW;;1`mIM#~NcC*=JX_GaJF literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/google.gif b/smiley_pack/icons/commercial/google.gif new file mode 100644 index 0000000000000000000000000000000000000000..5855c74d745237a6fa3c8d17f4c630c9350b38d8 GIT binary patch literal 270 zcmZ?wbhEHblwgoxXc1$0?IkyGmz$Ie&weYb6<9k5t1*ye-JXvMldYAp1Ex)gjyuV%J=T^RtyTpI*VU?6t!h;n52|5?0CYGe8D3oWG zWGJ|M`UWs4{$yd~VvuLhVE_V)!r)_wNk} zM+F(!5~q5(I9PK{7H<1IbIk#^8*9X(edD%2SXau*SHA!0o8?}WKK2hvT`xK8*}jO& yrSXOTN2S`PGRMNk<~l77c9y8FjtRBgtPutiCvvheJ5HbIH@7KYd7gnHgEas)?q!Yu literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/instagram.gif b/smiley_pack/icons/commercial/instagram.gif new file mode 100644 index 0000000000000000000000000000000000000000..f15e6ee8a2df5f527707ba988a3026bd3087283b GIT binary patch literal 1302 zcmdVZ|1;Zn0LSsq`y(NIlqBc~vxL}u7oCOp5|J+=p}s`#w(DWsO1tC6b#|szO^7eU zG-!Hmxcas+#gJL++Y&=WJEj|*J8nf?u^-y#%;%k*)#A_C>mK*~4_;zPY#1lY8F5B- ze?lOE013n+OZy{B@{yJOkrmm9y=lbUU)s7GZQT!S-Cx+fwMX{dKjrr)*=LvH|AI{4 zqxkJp{BR1`aC+}0g#jtZGY2-L0Gx{8RPfv}V9P0V`&8KW*)Zq`Hk~=^G~qf;v_TVY z&_wI5q77H!ihIfm-AuMhPg$kQp3r404B10w`ih5a)gyJ0nX$yoSoAXcaLFs<8mI3% zr~f)ph^GYLzAQO~Eepebf zR2n%v=l_W|ut*zNERWJCqBQ!zTy0RXHt3ozs94U`D7YgEu0|VNTpm4I&NKUAETm#A zq;f2zYCNQ}BIZFw%-92V#b{{N7`svv)-c4mJtJYf{ALuM5XZl zP`G*|yrEh+{)K3=Ml@9;`mvAOb&uPAkK57DZ6Arc)6eawi`DfH=@brrE9k73%-oX9bczO5(m9n>-(YUMnZ6-@ zu1zx0m|$p?PPR&?niA%l5)4fV3wO@X-%gx|5(G*BlmeIrOlIi-<^xl{xkOk1Oat@~6yr5Ta5X!tF#8g{=;OjGbg|@oGQuzsfDLkj_#@_>9t9!2Moz4c zd!8qH#J2^CWV1bqEv&S5|NY>COw~IXYdbN@g5SDh6?>5z)Cy~RH;bY*vdrsDYYppU z>M=EYL84$@{Fz17^zi)R3XjW|vxGK^)N|XMHHiaL_2~|2wu~uOT6z$k7=ypYTA~s{ zqy80KUX1=qYQy~8n6Ip*@f%Ce`0d}l8;*{pS+jWURjnbVnJXV%rtp(aY>8Cw9E^yd zE{@qLo;lwrlZb=X7RoZ7gsse6!B(sf}`nr1n+_`>{f!V%CPn zZ#|CC?5cQ)>WdxJIPWPQ<{&TNUq#giYF=C3w$u+*$l|E3B&D1nnlmOjq?Sxu=C>JM z)$qFH9tJYwFr=L9Y+bk wCC~D7lf{qx2ZtITsyuTFE}?dEd6{jnsS~Tc(RohlEx%H{gSuUCBqI_30Z9t(Y5)KL literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/signal.gif b/smiley_pack/icons/commercial/signal.gif new file mode 100644 index 0000000000000000000000000000000000000000..db5aea12ec33b315e405aa7871c8403e2dc420b3 GIT binary patch literal 339 zcmZ?wbhEHblwgoxSZcxm1k&M$tja!EmVE${#@TQ5vR}cumZcwbvL9HLf}~9I-u*iFh(swWhSOHKk2)zgDGAVj# zSpsCdHwPK`-U4JeNTZ~*5<#T+Ptdt2HL)Z$MWH;iBtya7(>H)Y@h1x-7lS>64#;~T zk20`DADCa@AtJ$gWXY%U5VPqQl!a!^@mhavsc5yR-`torm!+RooquX1JlCv#X0D;N zp4p+7vDW+g?mTa=D{CmP&dzSEO=&4iZ*PsN=q>J!ZEK$15;8L=A%8}we}E%{H2|4w Bj4}WK literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/telegram.gif b/smiley_pack/icons/commercial/telegram.gif new file mode 100644 index 0000000000000000000000000000000000000000..6ab4851ad4169b691ed355562ba2172e84516493 GIT binary patch literal 627 zcmZ?wbhEHblwgoxIOf2>JnISbtf$PgpD@n`lFwLxO8P~jL-1D9Z zEqpGr=(*UU=Tb|a%Po5$zwCw5@)yc0UZ}2kp|R?v)~c7r>t30ze`UVmmBZ%Oj$2;4 zZF>{F?_J#fcgY9eXB>W?b>u_YiH}X^K25y*Wy;krb8dW{d*kc8n_m~){JQ+kw{4HU z?|l4Y*OMQ6p8PoQ?8ng;KaaimdHm(i6EA;WefRtN``=H${(1iG?~8AL-~IUe<@dku zfByac`~UC1|Ns7jfTXn2kVcCC1f7dg6H8K46v{J8G8EiBeFGR2f3h%gF*q>jFaQB4 zq8QkBH#jskH#4&`w=uVL_b_$zPhe*0>7F>Pe@fHz*=E ze8$(UIVUon?dO$K;u12wZf`X0#WW7H5B4h4CeP-xx3XJTy5R~}P^*lj#T^Z|MuiE! x{5lFv9}cnYWn|#$w0dwLW<}5hjm9HWI8z#Yn)TdHbrel(Ok-6`EX>4Tx04R}tkv&MmKpe$iQ^g{cqIOVm$WWc^q9Ts93Pq?8YK2xEOfLO`CJjl7 zi=*ILaPVWX>fqw6tAnc`2!4P#J2)x2NQwVT3N2ziIPS;0dyl(!fKV?p&FYE)nr@q^ zL|n{dSH+%J1Q5ai`Y|js%b1g-Bsz|-d-(Wz7v))<&;2?2)SSftpGX{IhG`RT5YKGd z2Iqa^Fe}O`@j3B?Nf#u3C`-Nm{=^dvC_t@XllgM#1U1~DPPEV zta9Gstd*;*c~AbrU`}6I<~q$$B(R7jND!f*iW17O5v5fp#X^eq;~o4Xu3sXTLaq`R zITlcX2HEw4|H1EWt^CxamlTWx-7k*wF$VPP0*#vEd>=bb;{@U#SDLpQP7X zTI2`_Z37qAElt@2E_Z;TCqp)6SMt*o@_FF>jJ_!g4Bi60YhG{7eVjf3Y3eF@0~{Oz z;|0oI@9^$GdvE`qY4-O6Z8mbG3y)5n00006VoOIv02lyr0HVfz8O8tr010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=m-xI5hy1flq>)M0scuuK~y-)t&}lqB2f^>=PKbi z?gOMrlRi~o7sMi;KuEDjDtlYI1PftBQl?53@KW3@+~JZ!k-(OLEDPDnMjJ)8G00oV z5_V&L*TlV(i)+F;@Zilb{N6C{KO-XYSwy~x2>*G0h{#vj5^Q;XeR{pTX}MfZYPFi| z?d^$(NDu_#IF7X2ZOO7XU$bqSD2f1hd3oXa`5A!4V!{3WJ({MitMcEV>$=2oOt06Y zR4S!$P19(#S}3JZN^y92xEXkHaRGp7nrnM?e0+>j3g7oP1A`#I^E^ZZUDt6OhcFCD zl7zuvK)GB-L@-SgAobq_9vvO6RCj)UP8`Q{yIm~HA_xMe(`lOD?RKeDD(ivGW)ol~ zVcC4cFesHu05lqnEb07lEX!H}YMO@UdBkzd-`4N<(RKafK*w>2qKK=jD^5;MsMqVM zbd*x$^Z9Jx+1c3&a6BI4x^C)Mt5pC_PfwZ8=Qxg&4P5qU`6<`e*XgI&wvAGX;c$qE zaCdjdWHNc5Y;JFFQ~&1XhKGj-!Z5`5eF}vFB7*PxDLfN+d3m`}*yVDWBuTJs`(vYL z+cw2wF^%u<@28_T8jUzOICvj$DcYx}CjcHFADPW&scc-=UAr7I*O#vAVi<<(?Cgk$ v$ZR%~PN%bReSP2Jg8eBX^5yli4cP8)Z#s&ArhdKc00000NkvXXu0mjfzromS literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/threema.png b/smiley_pack/icons/commercial/threema.png new file mode 100644 index 0000000000000000000000000000000000000000..897230aa06fedcc0189c81925c89430f8ff703f9 GIT binary patch literal 4777 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 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/whatsapp.gif b/smiley_pack/icons/commercial/whatsapp.gif new file mode 100644 index 0000000000000000000000000000000000000000..59898b09bffb5b83fd36b4a9bc1753bf93f725c8 GIT binary patch literal 1353 zcmWlYX;70_6o%sxYY{C8E~vD!s2~OjvY3Pb+4qfXBqW4<9|>EkLxt*8>Qqt00*cnL zP^PvPYpuYv2B%c{Q&C)o!P-t~OIt(;kU&CKl8}}39<{^^U>7)ri$y?ChngXk2CAUo#7SK4 zJPQozSWY=~m@tXMnYjlIB!*MQbjp$^@tAoI6a!7FO_F6~uw3#;Btmx-L${C`+f~9_ zQgW9RN9Ng(g3wczV`B2%r6qnXBulkR4jbuE7SSq%{1kaqd1fBXE`>Z~&e23(wJKPZ zW+3KU_)t+rpkn`20mD(8F-tu(OTjE~IIa@OG9XOJfu5s@y@1%OF7}nMJ;sndi4ivTmvM$b|4W?t%aVd87t-ql(R)C^f2s)pFrp_RB8`81dXcCLxF=QUR5D+j_grGZMiL&|i@u?yU?U{%6v9NQ)5tagT#ZDatU8me8I zV`6calzg|c$WunPi4=Y<(JB&o%l1tb~S6 zW0sOWLrIw`z*~7Kkg>@;xlbeTsDSY53!-PKfk@C3@d|yaJrmfK$cn;WQM?Q~R-ESW z;#}A?8Jd0^croZ78V~*Vd+^V4|FMzaE7fw%SDri9+&7w+uH6pw=^Up{J6r1Qja`B6 z9&i7>;6RnX?!IsE&ve8P98&@PbrL6!YzxvdUw=aQU4 zsjX6O)@j_eIcBEVug*6K`6e*OLeDT!Dl;)CFES$((ppq>TyiL(&`y$OqXS%A;|4`%sO-Vp2 z3xEP2DDgH3eU*tT2=Z|)P_NY_oUE>|N}w~j0$8Gd{hBCP1crh^WA&rJHm<-TZ--7M z!J|@9C*p~Ql-QU|eE&pIcI{LWayKs?*I5fZX-3#X*sLprvvG0MPNK7IT;DM=Kxt%r z|10Bc(cT-wUOpFPkngM`|B-%`K+3<66)Y zj_Iu(Y2Zg`an+jZO&wZ2_@Nf5f7z)Ypt(us$c(1OqrYHUb1d+f!PtM%SHA1nzFB?0 z-VcAj<>?M>a?8%`S~W+?lz>2c5S#WxNLWHf4b$WY~cKFD#UXbwe4hY{4FB9GrdlN%*WqsMd4(w;q?vi zw?_E!pIxD+_ukW<+ZGe(?$~lzIer0M5!P(lHQv{~NlldLY47|ze0=i^osw03xCEAPCp6*VwQYQyN6)$OPr2Z;b1 zJeqJ8sSJD@mHtED@zz5>O(9#wLrTQcuGDbsTVFnK_j8ed$N$lVx<6)MBjU~vJ^LEI zaqRg`<%TtMWEi+}?u-p^Y}n1)Tz?lC{{k_b8WT7&d?$9@h($ literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/commercial/windows.png b/smiley_pack/icons/commercial/windows.png new file mode 100644 index 0000000000000000000000000000000000000000..33109cfa72a07cb5637e72dbe3e3b26ba976d7ed GIT binary patch literal 3584 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 literal 79 zcmZ?wbhEHb6krfwXkcUj0!e8l#h)yUTnvm1Iv_qshJi_~hrjal#0!tQb5DI;5SaJu eeyx&uUxa7tw3JPYR;TvtS<4Zgtr^O|U=0A+vKN~G diff --git a/smiley_pack/icons/fediverse/diaspora.png b/smiley_pack/icons/fediverse/diaspora.png new file mode 100644 index 0000000000000000000000000000000000000000..06c32f6bfa29412330007d7c1f429f18816cbe37 GIT binary patch literal 4656 zcmeHLdsGuw8Xwv!h@w~!A7yn;q!z>^lVL)bG2s~=aSet?QK=OslL<`CYm)&IJYq$u z0xhnJZAGbXd8jC$i1gU7RO5LlER5i;~8Is~h;bI}HcF`VWV*;L?;CKaY(iGhl;JuVyqf z%vuaIOq&@s1evdD71vxE5vSi$@(PkC*E|Y{UN`H;mbUSZp6|!-9uJ$+G3vxG&$3#C z!QSxUPnexv%Q5B$?)P^(W>Ra5pPyXQxO=qs8hBkqjQc0KPs`fKmU>-G;KX|~-#st9 z)ar0~V~qIJ_Ni6LF55jKW`FbbU(%=euHW?^@yV*4zCVl^)mpcB%Cw#%@z-t^$yM9F z(8^C=Xm$Blz+2b33hItBCpD?v^IOkz9*+-{jCk_)-G9%An;p3h5ah6e2@6xm!opr9 z1k%{FWQ`=MG1#*y>7%CUxzJ32V;zu@~ESoNr-c1l;Lr1Pf3i-?>u^;}Pd@O;z&8Sj;Kr|!Yy_u98LW_>f!AH8R3MJg2!k`FJRe@>BGk~=l8Jmz@N{i>6e z{OZKA%6~|H9T{fP(i`q$k!wzIzJxTd)?u)&Fs0qd-?=7CwW6%Dcy2Bxx=I5Bh%tV58JvO&MM}Xz1Py> zI)NYiOWm0x%ZraaU%czetue!bjkl-#dcg%Wo|yp+HcvjAp!8ZEsnRQHo>^-Eod-eU zAhUs_7SSxMq*EB3gwu7To&z%~31_ZQj>rvRbSe{-X{6&aqvNT}MHH^$1O+;a%>*FO z(kuy^wHlp?FiSXgUIN_P%zO@Php>wzoOyBu9HuwYFvi1p2shl!q@$cbXIN}hsfk!= zL>~osl5kR4)9mfWI*>v|_4^yrj2e47DvD2QXf1%6z^sBnQ%1_|yO5lfyRLB4-na;$LI*PVY0dgJ#co2~Yr~Gk> z>nFm6T+Cmo2mI*ui6Y6?WCAIKfW{ZJeeV!bijy%T7o33Q^3Q-JXNFuS|0ECfgf z2us@f6cE_$AQvLcNRzDI7_ZlBBpe$BZ1e0NmV@P_B3V*OvNRw?P>etV2!VgRKtKq= zjh`=q6376&Ud5;_{|jwfJg~U8AV z(`l7GPQcYWM5U6t6dLRveeL?n&ip|u2n4taQ3_GeLp09CC>-Mkpr9X6l}aGOMQRkI zsln_fy_(G+jdVx~&=F__+S9HT>}@ZU&tP;$Ds8I*5R8iiaDOitzb|3FZO?d>v6%lm zO~iJF7%YorvK02!fer?V!W29^XXTjE<~K9`4xT*! zOHEx~CZf1@LB;ckyQ^w1S*_NI)z;4wc86D6kH)x;UYXmZtX;sne6PFn=E8c*q4ob9 z2_0R?Uq7p9RCGz)3fI!|yo&o1K3mp!8)>s@zFfGkr{|`sa^|j!?G#a5q(5?_pu8L^ zEw2mPai3Tg+;Xe<$UoW#B9M}m@$EvY{^q1rL& zWkl)O{JTGUCnWBvnTLgE>X!WG1=sYv%=@Y8^uEnO$7fAm-R@osEfjC5>^iYBC^dXb U{*8DK3n)7z3y+pogeGVI7lk^>ga7~l literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/fediverse.gif b/smiley_pack/icons/fediverse/fediverse.gif new file mode 100644 index 0000000000000000000000000000000000000000..498b57426b264f7d09e8e72465e00b2148ef9a3d GIT binary patch literal 444 zcmZ?wbhEHblwgoxSZc~JmEr#qwzvNo82&Rbc8UMGAkiOf_Hwzwj=kE;cj>R%YC3DX z>9ljUQWwG{r$(Rt706Ind2@EfB!iaH*sel~~e#zNuh{UQ_himcx$ba0zc`w8LOn*{Ff$ZF?z#n>=Ht%j`K^^PP&EMD>@IS=<{Cs}z>Cn*os+4JXa zmtG@v%>6|2T2YbJM|~MN1-BpBTy)-t;jzGxO$9O+JRUQ!u(7%D2?~-D_Tbl`3it_JYO-VF*cjXd>kW*CPNQHp zOHaX+nbts%`MOs1+0a_p@pZeKY-zCA>~ndS=ww(yqT?vn8|7`BeHGjTCljNONgeHW z@~>y7*1_|!!A{=~sJ{?Lwns|*i|^|>NwmsUy^4qK@jd4*GkZBBS;r}Qdx^N2Wo`1b7v_0`jL@pB#K zhB?26(lhlj?7E?EH@VF_W7hvtV0!*{(<5j}#ktsuWOtSS`LjC;pMp`xr-$AhX4_3>5lKdV;k{%Xg{(wV11+Yi-bt*V$;R`E>s zyHl;5mMXe0ZdhBx-3U+4$;ZZ*)J)Ewv)awo^Lljli--|bk^G{BVTfVkHv3_PZ4Phq zZr$8cr}#z5@yl)TxY0G-VQJ;0z4(n=4M%QbHnxq`8=9UpZ>j#t@80S)?lN2Zqq(c@ zuNm{mW>Zl0*{}JYg}!zvFIR=%ev^M{+>k-HY~Q5nn1_ptL!kJM@ryt4@v(IseQv>X zv#F%==#s|oU%j$&!Iht~lj%j9|2UoMhA#->lVxwu7MHP_rHm^?Gh&JCR6K>3J3s}=N(FtXv9fTSm(KaDWPf<-Ebp^Qw1 zfuO=ODIM$Emx3gE>yoVwi{Mz8DoVx`@{#uzRT|D}K!A)poz`WT z-#cPyEj5e9Eo!2HLXiYPr6Lp+1xf=%??H1YgAsJ1g%d^iBC*wDnHCHb1BAsbeF_My zc2El@H&8gs7-AVFO~$pP1Y06|-Ab^WNSwtLI7M+gPu-7cv~?-Luys*jIMH2#5znMZYo36s z+eM_{x?~FM9zE^)&QAYHE2slCh$K)$@d5}5$`d1~kS9^25*~@8LXA)=6;Wijti9|; zM#GwL0~MAGbOc&~_OxmRkF`$JxDRtNrBIex0D|!l3Ga`B33>_^SoVx}6$cCcph>V5 z&}WkYaosksd4au9(7PG-Xa@5AD?dGR@mCH3!~KJNl)n9P^~?293Val}zq|V7`X~iH z3f$ja|2Mff?~hZI4!i}Kz+owO_%Q=GXxXc$MJS-*kOA6W|Al8gung2k#v38X3H%x0 zP4#2d-N> zMLA$JIz{D0;M)T-y$JPg_h(HZ-mdq`nwQV<8i%;EoE1a%A?a-s?AJP9qrN=p^t`3W zIPuvEZ}BK`*N;CI{oYtC5PeNR^$iV-2Fr7pKO$Rk#yws|Er-d*g74O^mfe)J zr?<3izm)L9f^6`T-+ASZ;kdWotD1|y=H^tJRSqW>Ur?S|6sq_1Tj_CH8Z8Z#cRqZ> ztDLjB($ulYFRYVsmNan&{x+W~9($oVM-~xZwDpJ7ymQT6$UR-aOr|{V$bWWRU4MM~ zGLO0y;?6@iOxMc!)8$u&jMf%>+Koi@Pg!|X*Z4GxRn=*20{)QKR3UqVMuJzMQ zSkd**Pt@%>w`^lt^to?`&Q5D9dC3cZh$%83bAx79^B2y=Gb?LqCxnZGF5him;5|lE z8qT;hU5s5xhkNww(?R5uX(0(?H*a|3Sw7;y;ZZYw&fl;)E~_g*ez0|R2QmzyI$WtV&ho*xI>j_UQ!YotQnMB+Sw}K7}GfE>Ex%$hs$kdyTos8 gJiouLq52xLcS6CCT$hWwc6x=<10~i#4vM_Qn z*fZ#Wya)0q1Ka%r^9w9^B>Imm`E(*jYw}r*Pd_I|F`s|@^igM(-ki*jD`xuGi9ddt z{LbL`@t&Q!GyToZWfePboUK_=877u0ER-2k6(*jR7~an)EHS}dQISzmlTlk!UQ|sPD_RMTZt)tRkfV4$&3N0m`mEl^WKQD5(nqL$WlRXu%0 zjahD8dl}U7G8zLe85kqoiVRU6=Aa`kWXdp*PO;7+K`2+z9 z0096j000007yuXm00K#jfvKD34516Lw!`Sso8Rmqm~u?O_;r)nNh_L?=+mmT42BVW pjx25y(SSE0$n|pVR!fVsr+W&A(&_8!!D?q)?WLQvg2$@@06T;qHFf|1 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/hubzilla.png b/smiley_pack/icons/fediverse/hubzilla.png new file mode 100644 index 0000000000000000000000000000000000000000..c5fc6278e937629bba214062056c09fe2a4c6d7c GIT binary patch literal 4563 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 M=~O8@`> literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/misskey.gif b/smiley_pack/icons/fediverse/misskey.gif index 84982750c6ffcc159c88b23e461aee4596f8f555..a4d6bb340edc3d19574a397ed51940eeffb6824e 100644 GIT binary patch delta 979 zcmXxiZA=?=90%~b_GquAv`BHQ(DATgDU3}9LlDSHXMi>_5tt@(0mIP55R+|jD1|c0 zRvua&T6*_C1_ig4r!K^8Y#<8Q_BuscdiOu-T-=N@GZSY_Os2*JLeg1Y_{%5Xd|!ND z{wV&K$W*PbDtYa!0#P7Oy~sruYM4X}lW6M{^6@nC$u!a$%b6I|FoU%3L5(wrVK#(mr0oXM9y7-`ekSOMxh3elozOX-V7eo0y_?;&AiumIzp^ATf01Hd zmYJ6mJHO2DT+TOjugH2gh@s>HG?>|M#|`%2R1m07*G)hq7z;{85+z$dW! z`GY>p>W{a0vj_bGv#-$XJ8q#9EWYd^8tbQ%Y&6#GFS64-dw@3_;0*+hTD~r|uk&r+ zD(yj@J%|mh9Ul(K93lDeM*K(!9b7*#Xj<2dY@j0>{Gnh4!JxLFmS8X3X&BQObQWJk!(C*UL@HBl9iIIjAUOR*(8#c zlWg)R%X4hRmitCojAZwdtb$}yNH&#Z^2Q)WhD}-kl>i=~SQUV2fXxLk9l#6#GXXp_ z#>D}c1>nnoJ?7*v096E237{Il8~}4krV7A30FMB86u?5jY5*)I*=hhw04xQ2rJUkk zp}1odS1=xlqqst6L^K`|P+Sqky-IP#6j!37xKfHMqqx}g1jT76u7cvU6sL23C#N|5 z#C^fYrvB3h!fOvi&hN9X{~&Tb6uTaYuRlt3{}?~{lVs}Wq^T|G^p@1&D0jGy{7>Lu zQ%%p2JS28|zlGpY9NpCNoshDg`^j$C`A* zFD~I3Ix|yQr&y$oGW?lcklJ!1psBqO=#k^v#)Eu*LsuY9`uXoq2J(H1M5OFLs?xj$ delta 331 zcmbQqIhDEI-P6s&GEss-f?=sP14G9uhRziXohuo-fM^v%*J`G&mCRi$7`j(7bgyFQ zUd_wlM9*bC-X8( z*V{AbFaQC_VGL|@56my{(2?ptv83o^j+7)9D_dqqSsN$o!{eQ9%x*2=3xB%q5jY+3 zQPJw!@^~|;oohr@A3oOmRk=s4tXxyEoU7JJ%c-fYtwTXv#J;CDyH+_)Wy;jJ+GK&* zbK32bOBYRB61QwB>x!jQqLb|flIN|O!ldUUoommsb!EvE2DjosjkHz5aooIa%*pJN a<0Oj$g*+m8MV$i${O&(^_~@Y{gEau$?t9<> diff --git a/smiley_pack/icons/fediverse/peertube.gif b/smiley_pack/icons/fediverse/peertube.gif new file mode 100644 index 0000000000000000000000000000000000000000..0cfeee9c3e965236fad3af30caf570285a0f4de8 GIT binary patch literal 137 zcmZ?wbhEHblwgoxSjfzvD6ddlT>LSES5jI@@t>e`QEFmIYKlU6W=V#EyQgmegW^vX zMlJ?s1|0?<0BK@ia-Gw^^7PpUix>mUyxty)RPL)3w%|~Twx9U{bJMM1Hy;T)w oSsXWY|EM#bm;AzbkI9LYbC-O&W|=W>%2G{YzqR&zGy{V*0P)i<(EtDd literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/pixelfed.gif b/smiley_pack/icons/fediverse/pixelfed.gif index da5c1e97bed58f41233e32428537f70cd9c1b665..b42d26b5ce5d3e5fcf32a8e476c6cc98cba7fd3b 100644 GIT binary patch delta 1241 zcmV;~1Sb2a2<{1gM@dFFIbj$87y#$~07r04i+p|ZRxQ|N7XO45|AiF)h7&P%n3-+Bt6wT zGfucU3g=W0-AVO{4&M?=?h#P$6i@IMP30$1?Fv%v4pH$NO!6U0@g7U_BuLaOIuO}K z>;_cyC`S-~+eQ)BL-j31)-*Tk8(r-ZPxdoH?GI4@YYr39Jn>^&} zb$k5u?f?J(_}s=A$vGI!H}!M~+$mkqCuY1RgsvxlnW8AFnj)v6CAE$amAP=em?*!V zD7~2~!;&h>voX2CF{;Efvdb~7%P*wFEStS9q0BS0&@!*pFsrs4kI{Cy2;o%5HMz+& zw!}8P3ENS@H@*kcP`^0Ar{}&1$V7JCo4Gm1yg9@?%XbXcM&$VL2);fG%TTsD$}7uc zvpday!S3P%k@~Pa&>F;60F(Y7&L|JTd;*jGtv%BRy`lh;`2dvusy@~T$%Fuq{s6Al zs6N>b#$W)e`~ax@SjgEo%*s5xU<9r+0ITf)kNu`U+XBJ80L#lB$;1Go{Q#x>0Mpd~ zyXFAd-Uskr7|<;Ntl|LP=K#(34%0&bp#1=U*7g9~^#GFo4b?XQo$!v+-vFJv0OIce z;PU{|_W+&!)Ox}Lr_KPG{Q$`L0G0j#!}tKb`2e^20JHl5uKTV!#yEr00FnQ$Jjq&K z&UaSCzdFLIL9qah|F=5Eusq1KJI#$sy%u)q0Eqtpkn`RyqyU8V0Cf7%GOp?>o6Rx} zu^evVdQQaRES~iyl9LAmD1R6L7ytkW{s8|895}E60t5*ZEFj3Rp#%vLAUrULK!L@E z4JQZ?AYuRn2nQG(RJa18z#>(MXeq)(K*R?j4;C1K@yL-ONRm8}!i2^{i6IlLXu{CQ zO(IH`NU_po%7hFMfo^D$V&D-YLXa+bV#Ugr8#F?MfEwX}1*!wF5`W3LGtHd0Z`rsR z`+!1|7Fh(|WGkgh965jk$C*231r)shgbYEN1W%$ofg{VAGseOQC@8XsS*!$4pFo86 zNEUpCLk-Me#H`H&S`s5fqXEb1@!~X!)JWb0+Egi0KG?BKQK}6kN@^vEPKmlSX;Gor zpGL7@aoV`8C52j%;(s(r(sRJ2O1ELs1Ok!|>OYLT`bQ`hDc+I3=Q?(5RWlbST(F3d zew9E&wJ3KtMnoeA-}XD3U`LgcMUYpVABmSvNQw6D!^pJ z%0RWa$D1U|JOd3j%ya`zIO5zwj5FN8!cZ&%MuN^a9)2_9I6}7!lZ`j#U}Pb8fAk_F zjpN{gBP{Hg^v`>hNRkdN;Sfp8k>*rs6O84v(F DFu+Gr literal 1064 zcmZ?wbhEHb6krfwc)pflfkx9i(SVs+lirK^zZdiWAnvzHv+k{=&j(4r4^qAhb!UB) z_Wda1^Ip#9BM`}Zzfy9)sha#r!TXbf&nHE%XR09&)T1tGXYSUU_gTgBv#RGC4cE_V z9=G+a@95iXHr{YXckUNW_b*!RpS4|gnC;zTw&%3*#+wF9uNkhqY_#Tr@%jruH71+S znruF4y6u4Zfn#Pn&zo#GX143F`QCk&hhO7VvkE*~nS zMYo4DZ1^Rz)AK{6G{eSU^QR~Na z`SU#r;CmdPa3^)urdWo%4;k)!;dvI!^E`y%-WQ%1p~BB%xn4zby@_IY`nl`qvCrE| zCfr#4Xy5g_hpxWZfAjH?+gt7&J%07pzQ>R5etG)$*SCLv|NQ^^_y7O@lF~{e6Dj@^ zbS_FwEJ;mKD9CR@Sj140SG`Dg@NM(!+%bZ6VH4ljpKLl#Qf0b zo~TjyY>TGxGOok*(tIWj4;FIDT4bKmNHj5UU}O`q=y{=V?A&qHW;US+1;^$N8LJsD z4koLgoa_9bO{HRjqRWiXH4#gHO*!ta?DSv2VnqT&!-^%Ip_wxuaRe%`39=+G2y$g# z@|-3oDP-c<*eRm!Hq&+K%S(%0YIJG}7BaDFhAsDMoV4X-kcw-b-js%mO0AmyQ~rJV za9C4V#U%RQ#2F8hSOtvc8hkZWV(FT!%^ZIqA<)@(scXZlIWL`_o^X(wQ}{t+i#wl$ gPEc3Ol!K4hCYi>qv5_n)OyH5Wu474*5MZzd0RKgqy#N3J diff --git a/smiley_pack/icons/fediverse/pleroma.gif b/smiley_pack/icons/fediverse/pleroma.gif index 7be5eca482992d966a37bd6cc8f7662fdcb48547..88b362395249c8b9aa41da0089e69a8ced223aeb 100644 GIT binary patch literal 180 zcmZ?wbhEHblwgoxc+AbfAfPNHrLr>5enYY2;Rg3}?VgXP1U#7<@O44x&&6TCmxN17 zDc5k^=nu8oXg+l)NhJq8DB}0h@IOn#C8d>sNbx5NBNqcZgAM}_fYdTD zYgTCK+}4`+Ol`_E+uoP!CQWagsL^&ka+&z4#8~e2@BiG)TY679=hU8HCI)K&0KXPh_z{vYttjwr$=r` zkKC9ZxhW%Rb4JwG%&2Xd(c814cVH)Y@h1x-7lS>6 z4g(N?Jj%ef=)n8}4;?8+kHwQDI!ZirP86Nw*qL@iI3bFqB<042R%@56Ll3Vt{0Vm8 zGcYkb9JfJE=I0v`1^EzTW$hvjw&-96wJKvnc_#K0=_+kG4iQz(7#_na6{T?D7zUN@ zM2Qr^r4h>)sV>!Dn8LSIlRL*=vC2@kHit#ONNL-4d$B})1>Pf04C;n*LfNOCM2v(k ZyRc}B-f)p!bJw0#y#3+RhxU#P)&Ml;m(&0N literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/fediverse/writefreely.gif b/smiley_pack/icons/fediverse/writefreely.gif new file mode 100644 index 0000000000000000000000000000000000000000..baeb03b0ff7dc3b862c1d0492f49552a1ab2d3ba GIT binary patch literal 112 zcmZ?wbhEHblwgoxXkcWxcI}#^w36aKLFb~>#FEq$h4Rdj31pDc`A42%pq z3_t)<&cI~U)4%fcTmHp!w%j`1U}yb>tzzND*2SMIPjJrDoV`*-re4s<1XYv?#f-bCMl2!Fzk=-UY6Y6 zUiLQ0B|s4@Euey^u@%z}C>BPY&~!qPajZ!Z6seWzh|yNSA{A`4NNpem2K(K;BqXCV zPG;&~&CTtP@B6;@dGCF`@B8Myw=G&(G0mE9MG$0KC>W@M&m4GVXHA6nyRO7vgpb~~ zniYB#*McTBRg&WX)mxJQ1!-AAko2FGXkGTi?_}M)mgk*7tSZ^@Y2vZ7dtM{%{rL;Z z{Kh#w5BWW355|sovYri|>F$502VKQZ%e8K5q&9bSSi)Tw?wnJLF6lZmXYX&<`##Tl zFgLrppWnCh-uL?!{p{a;MB(-aUoPxhm)}qG+b8_0cWc+4rZb&|?_Zpho4=pg)~S5) z>Qjn(@apv3f`_Ia|HF)Fzn)uE5E2_t%O@`{&ADl5Y))3`yJlQoV#WFOpQYzsd^z>v<<Cir?&muWGYzNNhQ1RUXWK3npIo`$yFG7a*Q6;}-rGMY{kH48{`Y+=UO%b_RfOJNL%Qy^G@A3&&(D4=WM6eGJm|*^CKMBZ!P+`WarEA4y6{-KDX^B;9L?%qG$|3q8+?=0Ebo36|N2XEZG@9i^(H=gUhac$z%DcT0Fh`j=fE-l02 zS`i7ef~wd!QRRUxtt4U9AxMcYo#ccDprbs9$q6rZ`K4DdR2IG1a%Y5$B+Ed(9Bk7- zbz5bP(AFS$M9jC)T9RfVfC6+5O)K$4icNbl6PJbWhM2%mQ$=s^Vk;t1v`p0iO511~ ziI=D4W(r$qMN2eMVygm+2O;3di`DCTk|l_imKIx!!=`F6!tU{S2$CWw3Wpkasx_f= zX*`iCG$1k<0gw_jIjPHP0yQu>UTxC77zXFjq4<^|0Ckp1{4Ih$q+|y zIRw&0x^bt&?Z9c^;c*Y+rf|_EcwC}~k!Z?20%EBq!>Z)sBcn2)Lt->KqM0}bHX5;Esch}7-h=@Zc3tY zPM4s87YoaYru1#q8d(9=I%lwHcT)~GO*0fpQ63kSab#LA16m4JqJe2AZ4TNrH$Hu{gO+5LJSeB2|5j6!*-_P?F*C{xPW;UH&5+xZ4RgKO~(dVtX5PR7LVI9=m(jfsIVDUVmzI9+36U`)#6 z)%8E4%X<4b1rqRAPzyXP?RAvyg=gYh(Qr+9JGrbP87^9Vb^QB($iVS6?>-8T+!np6 zvKsM!^e+5s2eI%=DgwyXI|_nuFeMqRO(DpgxyEHdc6ZE%!pV9lQa<@o*7O-jUfqF{ zFF_F#3Y6Al^(i~+tO%KP^!xwZc**|Rp-SJYlOA8-|KY6JKgpwix`(;rIZN@0|2RLq i{>B&IYWQU^?$docXIk+7{;I_g0|}K^209n5+5BJDr0P5X literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/noncommercial/invidious.gif b/smiley_pack/icons/noncommercial/invidious.gif new file mode 100644 index 0000000000000000000000000000000000000000..deb471fe9c741ce4e47fd93f20fa8aa4fb4dc9cb GIT binary patch literal 908 zcmdUu*-z2|9Ke5OhpUIuTIsZ-?u2<2Y8DI zc!45FJ3^ zqeDVMqNAgelaq6Eb4yE0Yierh>+74Fn_F61T3cHi8yjnDYbz@&i;9XeGcywt6NyA( zKtO*`s{QdnWCnpsOMR0KN^z`)n z{Jcmcij9rsa=9BD8xn~mK0cn!W|x8F;o*si2^x(?rBW*@DspmihK7bVH#fJp zw+jmkDHKXsSs9&9UszbEuCCVW^=9VJ{}-+P7~2!EXcE@nG6qk=Svoj5|3Iv+ZW`Q0 z^oT8T&A(9)qhE-jk%i+x6F1%H;cL%%f?_KBfw^6V<0YDxXR3cAs(FtVe6}zqTHp!R v!ZfSzCe~&q?ZTqBKQXpf#8=LgNB1{GHbj-6`pNIxN*e}!rPaak2J-1IzTnMy literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/noncommercial/vivaldi.png b/smiley_pack/icons/noncommercial/vivaldi.png new file mode 100644 index 0000000000000000000000000000000000000000..17d09db33a04906c325e1c0c92390d3421698a81 GIT binary patch literal 4945 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 Js$$dT{t8o%qb&dc literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/debian.png b/smiley_pack/icons/opensource/debian.png new file mode 100644 index 0000000000000000000000000000000000000000..b9b8a16b300e65fea37a1e065c2a1f2278083a4d GIT binary patch literal 5357 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 O0000X1^@s6D=Y3@001ZCdQ@0+Qek%> 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 -%Km!a0WU8%-`a^r~M{&vog?*f!4afNi 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 MXRc$<;-ZKC1S>)FzW@LL literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/kde.png b/smiley_pack/icons/opensource/kde.png new file mode 100644 index 0000000000000000000000000000000000000000..6a6ff9ac7a5460d0ca7a7a791cc556e7ded3f434 GIT binary patch literal 4678 zcmeHKc~BEs8gEe%L1#f3Wfe6B1x1o{Cm~7q5R{uB!7OAH@uJh+freZr4MbTGqpYK_ z&N#3GQeNXRqJqO}%^)5th~PDfQ!?CXGtGgGx?)y{vU(#QLb-}}Db z``%am)~aG6Mmmpkh9GF9A~G}a>nLW-w@A+8 z9h~#IXaQ;5bXexI2U#m|Yx?l(zw3-eHQ7J+~US|Vx*p#(F9$Bk$ z&z-a2t1w^Zbl0V)Rhut|g?XmFzfLu|(YYKeKKl4iCE_X5`Ri?|H8or7_O8l1xc|NV zHcr>z*1Ih`Z*r$L6}cyz>}q)!cp>wKsW~g>_(2_t_`{b>_%3r(~Q~9574FG zY;#;YsfvH(d3{w|#nzjsmjDB1&_lc@+J;ib)~v4 zEu!FQ&bbMRZHl51XEr#fUuxW}Gj|xz4z8`7^{V89$|q>dq#VEVzFC7kJsn0*J-hg+ zHKR1s@T!S!=oprrX5J^#mM#WWXQe@P#VeyR!l>utq)|iht$GtEI|vGxX*Jav$Eb2x7C(3ulpCbd{>Xm~FK7|FTG z3}eCsf{cs|euju|G$#oV6h#HFP#_fYfCbO8%)sDQp26b9LiAvSQWnBYn;6TIuyg>@8_@51Skz#X3SudX zG0jX+Vd<2C@#+sj5`F%rG_%g04oL_o9i<1R7BDOF)|3$nrK-<^r67sco9teI?6)i# zTKk5qw_;;8_H_CO0^Iv>-?Dz4yWJRADV12Lkw|01Q-sR7?EDyMBxn+|zltSNRE8pA z9)Z9To>+nqJX|9a^H35DxR!x=4bkaMGHLz?xC zLQU(bI0k3gM5IEIREEM*R4NkrBj_8Wxs=%gDv`xRV7^Ff*Racifn)%&I9sOxz%B>5 zU?FA-XN+dG(WsMi*^oG_XP;ULwiAgncqq?2RO? zUG~4M+0DZV=vnee+5+ZZW*7DBs5okA&!}gpqwQOX!?AA)3@3V0u;A$wX^#_N^{9ws z+>k_p?$KMWujTablme+i5D_XB@<zx>QC*y(Y8ldZ)7x3~jH^{&PK$3^zs2w?L4~X!aTem2C0= z!eNX;88+;uldGfK2Nj(gi@<66fg&_WEjzcXK%VR#>xZ|FXs`RJu_i1JS3R|!5a)Rwa-YQMwv>U*)sv%qlzZlZ(7 zApXNw{?6`Eb#0?^@~esS_gCH%UfnHq!Xz&0Z;CZe-0&Q~>iUxhJ`oO`_t1MyMwDdN zklHNovFqz>-3QhMl}d|N`APY88(-dq=cnJg`L|HirI`||sX{NW^Y zq4Va|aY99x92t7Km{H0F=}_rAj=717(KT(>oO zA-Ypvh<~nVTK!0lU0ai2?J8?pSl#72{>am)|I8^V+&v+I`SDoDsm^V&X^~Th+|z&h zymQGuoqNitj-heIKXHSP{IX>Iql4{nhlt!uvPzExG{M)qJ1uP*l$oPzymO{<jE) literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/linux.png b/smiley_pack/icons/opensource/linux.png new file mode 100644 index 0000000000000000000000000000000000000000..0340301df931cfba0f78c5c8119d0dfe051a7e79 GIT binary patch literal 5149 zcmeHLc~Dd57QZaA3AiDmMGV0Ok*ox=NB|*`r33>+#iEs)o11VU8%cl&1p%QJ!BPsi zP$(FeiUrhK*|Z`msHh+pyr&iN)^ zGPyy%7G_J#006M?_hW^i_XX(J+QbOGVvE1niQXhnj8W~7!x&hN z2mwIdA>npfTqc@47w!2t!Y<|sEhsObyY#^#{mT1QtNy%b%Yb^-%w=-rT(fImMM=(D z@1h{>xVHI^S3$XX4=$DcxYf9P^(O`ASHI)hPy1z*^wDixIDUP?2Jo|tl|P@{zTPS| z3EMhCi9)Ve=^tB{BP-}oeUl8XZ8qO)5TtqfgXhSds%pYB%LPlt(PZI1o0M@Ac{OWq z?w76~cO6t8xa&PJfB-!Y-M1`WnpXB10O+M7K0aK3AD@@Gpcxb;BMx869=vYCIwl2 z_hjq#ktf6B_?9#0hsJA-^3$#ZC0<1lb>KYN+*a{>jJ~A%CTrd`8>YwHEH%npR*OIP zys7r#sS?rpY_afjnzwU)UDzOhlN;|oa{ss{Du1Z8wp`wGzkE}FdH1TFU`=U-v$8nK ze6=&*6l-|x_~A4s=PStfex%$(Pmk>0**={0@YCxX^&GD1M{(`x$xl2-nc-(>u0OBL z$nzS?lI+YjXxLVI=hVOu)F~|nQboN1{iD&Gh-Z1fulLQe)7#Z~u`$*+ZzSc$(ujxt z`^~TC>hmV}^VFV)Wz7bctG!+nuC0DX4_cPue9I}xz}8lO!HVYhN7V7h6QwVDkk%pN zF5m$kC<)0C!Kd9E74_6^0Ls5GfNobgmwY zK?F?fW>*f8Blm$L5x)cl9GVcsgA$@4x&Z6xVdk!8pa2qB1!B|^u~f-WGqE~c2KuZO z6R;Sai7J|j4dZYzJ~9Q2q2MWaB95&_;>cJJGmN`JAY_EF)=xp8Z%k~YN+o9y2=Vdp z_;?q*Od%qW=yW=PNG6cUIMf2C+#ywgYMfN*poN&kV8KdAfyh;eOp4KBf_z!5iiyRd zdd$oCBytXC8eXcLVgcoYpa$gx5}rtqNC-1Mlqz-{3NjVYKYA#6=!gYnCcR_=>F8 zV$*7L>C6lSb)Uw4&H82TI%Cv|!(p&wP^>mQe-;y~U7sP4L5P4c`RGEX3MoVw2fEQg z9EA)*I6ldZj&mbY1+Fe`FvXPy&VcflDpjBqg0)a6I37W9K$r@G5Cr2$APL4%V7eO) z6i|dXDxV?{!XSw#aC4afu|a{LT?vY3Mx})kpimG+Ky?++VVn@Ay5cA_AqfY`;fCjnp1v)4J#8@v=NIRYKH(i48=g zvFcX}9wLE5RiKtl5|!*irO`=5qAStGg-&^8vYBALP<(ikK+p7u&(kcn%E zWCn4Dy-a`zcl!DADzI=tPqf6$-~pzD>T05#1DLbR0+*qOCx6)z*$C1mVeU znnqX3gsON@0k0FGJfd8o?WyAmHGB zZ;KKDW}|-v%wC`e6c*W_LSvObhi&}WWUkSCE28O$1ppW{`?J>ZXg3P-w+DuAw7pv2 z*P{$~9CtZ4TW-8*A(DaHgprb~uA-nn)y#X)X+yLYk~# zO_O=HiPS+@lTo_#2UT=H$Jw*hx4%_%cJ?H;4mV^6&RW^`$6sqpo+sB2jo8l1p@oKq zDndi^G>&_4Hs*u2o7UK_Y`J;UysmrjmYnv%8e2aItRU~WKSLP7%mWJSf|9NW;1cZM%q@L=zQ z=XzsqkSQDkdqbsC`4J1dswk+>7r@&Ujt&pU?1+qXT$I&V1KMh5Eg@y?i4G19pV!qfxB>Pi`mEseZmIE6tBQ(>#{&aw{Qk>> zgM(L%FCF{hi-q4&2u^$SgP$iBXOjTH-Y`GJ=0iPpaPQMUKM6RRfBN+4r+-~i)OO8c z2YZ?5_1P9F56sEPCw&-FX4pcXpJ`ZCRfX~Y_Fxj&ZBh7vc*KLZF{83SBD>+Ma%N;1 z&-)P9%cErXjYnzU_h&fndFMq;=$s38S@D(IZeNNYp6D~Q+-=}dBAauppFuuozU13_ z4g8mJd1a-hZN-mA#=0|&&H3Fnac6!j**@QQf&xZch8Rg(XV-k)mebZ2OrcVJK3#5Q zHj9Ow_ceU-QvZa}=AB&`orZN?RXm1$bvHj#y1+e*TME6L32^qJR>{PWdRs zQSW52P%WCEcFAeI!|Ku#PW$%llTYCEU0N^xW_^XcyNo1$)O>UBXns`L*PClLxBRgD zTDiV_UT;w8vzm-U9b#b=*l@VNj<;=F#kuamM`MM>XSyDyGz15QH{MJ--(Mdx3WOQ& zICXxlY;I%l-cXGN!EB?ASEkjFWRC&!-V)F82PNm)PX$E=`!`+xDJ~%4=YuEPI}?q5 z9XV22RK{ou`xfg zeCA%Tvx}{>H9c|h{k;vQU1Zz4UNhX4q}W>Aq&aK9DrM`^wY# zIk(Op522)`=Gcs0QzrfB6<2ysVPm>#N35}9+U54v&OH1Gre*2|s z>%yHC4$dRIQc-vMmE%`Zealy8HFg~R>Avl{r33YYuXR7zJM*)oHL0P6b1p$p%x2MK zvRO=~k%B-OEj2G1^G-aO5-u+aFaB}v(ngA_c>V8hBHNCra^FpQ_PN!mtJHTJ9#6D1 zZEd^yl;!NxzccJX*}Mz&WxvN&+OR#RvNwS;KtjxL-TsqyngXqwRpfVu-P&%t@irS$UyRqhBL9}XYKs5Cv!t%*%R*{{`gdT#j_{7PckLl z>E(Y6w0l2|wEuR0d$8c%@%8!TYd)vX5ow1SAInR6V^7oUu0s#KU9vEo({$@v>R{V} za^%&V1GDEF9=6pdT>5s?{g3+HzZ>j%>(#l*5H&iX92rgEKh zuBK%fB=#*1#-*ghUYpjnuK%l>Pi~a%w~Dv^85cb4-P`#x)ddlmti~a5Zy+k|5zsii<}WD)md??$HZ5Nc_A-f6v{7VLzS$7 zL$a2sG6OUqaPcw&2V73Kj}91-C@&4}6*GpwQHWe=M9Qo-*d%#*m{gN$9L)`g)f!}( z3eNO$0$pfcK1>0gj7WtnduR;v`~7OaRxNoQ7-29NFkFLaG$=rzzMxxX0;t=!K%p4o zF!MgvD|%#6a>EKIW0$IABZ2@wJd&TwW3`UbyM4nd06nk(-3=b~N5o<#k5O;aH4!@-6`NfmMkKORlh3ZKDy2 z1P;;ViADjjCm>}}7!zwkZi**b&iF(?_$coL^hoVdFhE(Yv{_=Sl=LiSBciNNa}q0Z zbo5rBhz!QS5vWe5*Q2DJ_Wp$&8!j6)Hfk76Fe=M;YvT zA_E0j9ZDJm14@w`jtW{qL$Cx#aRfV#qQEPHu4J6!vr?!yg$k!gEyoC`U8mttQqO8p zN-GE`WgzurhM?840u`m=SbDkSbunN&MHl1XF^}63btr<<**1$2(Wvn;i_OW%0thf7 zt3-EIV9Zf0y7(fQQPd>#8ZCtrxGqDh*AP1G7-%)`^?^=QI0;;>C8Hi?TWC-W5SCH; z6c9x1pcdNX7E6-Th$tz+O5~{93XT)U$c&khc|eM5NE)YTBBPifXsw>sW-P%q zG(HY5aiS3XUufm_P|yrJRDzGG=DBE| zfNRLbRxoY{52nX(yN=k!?`Z`)C$JnP=ushq;ZagUk|?FaNt7q-6vG&JyFmUIyH65i zKjY=I9Y9B*6==_>R`8ePo+^dY~YAdr9-B$DckFGCwZa zXSe;r{F^V}>_`Ec=qh@nr1q2k&+l~@Zv533cd}LWa`%GdeU`t?yU1ydl=Lj3lGksU z6DngG)pvHVn@tz~5NRo2zv-FCI~4Ns!4DRd$2a{sC)u&~LbkTPKWmz`uy$)z*ZG%z zuiaC6qN8{4?X%x>K6A9QuAwKqC!z{x{Tn$_AKB-+_|%2eMGq3YpKpCH4x|fNa`Vjx Ia@IHe2RrI31ONa4 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/mint.png b/smiley_pack/icons/opensource/mint.png new file mode 100644 index 0000000000000000000000000000000000000000..83617fcd313b54a3ec540664f04895ea11de933b GIT binary patch literal 8663 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 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/opensuse.png b/smiley_pack/icons/opensource/opensuse.png new file mode 100644 index 0000000000000000000000000000000000000000..0be8f1bdb9160105fc71eb47dd09c21ee9308251 GIT binary patch literal 12271 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 JPDHLkV1hSIF`57X literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/raspi.png b/smiley_pack/icons/opensource/raspi.png new file mode 100644 index 0000000000000000000000000000000000000000..c07eff2e7caed932cf7c078e395f8a204d07ef08 GIT binary patch literal 4534 zcmeHKYfuzd7H)iip!mQL5D|KZ7?jx4^XPFNGQc>)W5Ce~paGRYPd|p%c{$U-fF>x4 zfz>F+Yz1AdauZp6fUB;QSwSO$NYRYUzAM5QE-~~aDw>D0b2<{WPYm7Vi5B~854sNINl2h13JO{Sftu$kz zU^drA!IYDsA;{Tg)?f9m6O8FL{&CaEv*Ux#Fo}DovfXp%?fbk_8!`UidH*Zv7d*Zl zG0$u9>-#Ggv6;;c*9vb$MV9I(oFBD7c=<+i23j0DW$)#h{I5MjL+>8==jq1#ttoe6 znjarULxNO>Pn(tmRAD|r-tlWAP83$P+Mk~~c5B>JkAjxlhw>ktK6=zQKejaI4=UrN zX(QtTM|beQ+P1qsdh<1TSoGrU&*t`Yc8scVyD~l1Z*g9`6@uK>GHSJ6t5)}C19I5$ z-WFwCT~y%d^rW)ruxV|o-RkvsNk88e6$@v~E!4kt^uC_qgyg-zZnDI-c-gR+l4x6JC`mIvMH{np$_TNLpl^UFm-3y_+-k zH-Q@eRKVah0Qb58>=hq z?KdkfZ?9Onpy!nS?ex^!igW&#QtEx)DAG4+d?hJyP5ZVQcnLqxobY1Ltxp=uO7?rj zY#QD27gcum_526bOa6{YI^HZyJb8VCIe(+unzUWbhdaB7tM_+6J;v+tUC-{BGoEaH zylBCOV7D9Q>o<>;&s=%(`|*NDEhXNqTe`8rL{DerXVx%i%aV-DbDfpdo0~o0*fh$r zdaXL6W?t*Ppsw*xo<8Z?X33ANd0?;4{_)KZK+`!H&|E3Hc?!a6=HsN*K=GYs8|XR+ z3XgQ!aAG;d!UoF7Sd_f3>MwXOLn?XiNOS_7O-*Goad~zsDQ|u2w417Dt~7Ko8W3+fX52fSS$dP!9(ioefC(0{T@C zM>1HWXd>mXX4wfUI-9bvAwwxhV!+>)WjDFfAqkW+QDy*jfLVnvO&P1z=?6SG35<-{ z=JEn!zl3BNdQhyFV&g_!=?o17xDW8YgznGX1qLXcPNA_9SzLHpjgrUBuOO`iLn>U4 zG785jjKUDHK_oyhg2WKHL4qTsftJZ=Aw}b}@gY=Ni-W~21jSJSay|oiWJ0-NHX)*r z*)ow7!6;ge7~~iY80AvRAQt0NOg@BSft>+eiJOK-#Zi%fijoQ?Qn7$W3}P9DU=lHn z;4-NU!Q>K5h6`jOOoF+nNJ0@~wVQEJPR5KIDb!{$x&}DG6)L?}$rJGfgBHCBXKCP| z7xI92E3bmcWS*tzSYBec&Tu3nIIWVjP%ZbEUT!XU|AQgx(g+QhdN|HrFg-E85 z$lnr(6oMgmE6LEgzlG)&4;mJ$rR7KH*QdQ))V z*%axD6L9qo5t+EfNP*p>uU-4?%&)WpArT8fL*WQ5C&dURl;Mb+qA>&))1(-qMS|J# z-mC`L9afsn!R?gF2y_Hmf%bH11O+Mv~_l4WNLKROgYQZ;e?7w2|*dLCug zt#%u$4b84?*p)WUFnz{P6C(=BCfo=~8C5aM5T9E8aaf11rXa(oM7+J~O7%HQP5qjg z*>q3qvpd0Si0bmJ&J$e+@(ihgFk4$S+4J4KZeMRI`*7W9XwSVP+Vk|Nnuu}5VbTBX zbo+i;@uSxp_D=_oZw7uqA_0h#S?O&2faU<5RcPszw&oM~}!pi@k7lpo6nH%R6k@XFq6XnnTMGCei zxEGf{a?g8s;`aU8PcAfW%ZeK7_XGcOT3gNY5&Jfl*1Zs=`G5jI+UWV319LM9{s)I9 BizNU6 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/thunderbird.png b/smiley_pack/icons/opensource/thunderbird.png new file mode 100644 index 0000000000000000000000000000000000000000..2d849e5d30e1f1440869d78dfdbb18a521059ce1 GIT binary patch literal 4661 zcmeHKeNYo;8c&EK=1@`L@B`a5R<9tNY`!E}38Dl6B^V(pSkP>CH*qD&#$m8-Q=t1VFUP)7x+p5h^T?*>GicIL*J>wjcszn=Gb ze(&%3Jd+P|JXcf1bBRvsY_(yu?)y&r;U`E zgqYPf5+a?Hk;8FbvuG_N&q7{3je+SyhU!8;NU>B*yw`O$M`M}WdV|~6$?fS@w#dDw z@IDn(wFO+Mw4ZaSbCPC?J;T2Bc)T?Eq0LX5Q1Wr`_Ioc(Vaq()c2+QBw;lIC_J#H| zw?5+h#BU3|3hoJYDVzSucYI|`-I)BzPfM<5CTi~0WaCXGg=^}PA7!q&9F}`EFkbtP zVPbY2UhGo)P9b{~Ps3eR`G&kB z2S*;vfx39D_gYGB3#K;h@LgKl)$(iDr8T!~&1L3CYh%~O`F{5xdHItEojt-!M^1J0RC#XCxxm>IzFU6+8%_H(nwO%t*0y?0pU>}9 zuDV$4x%urX;mK!pRW}dsG0oj#Hh!#_6TJOIV!L7S3|%YLTDouL_KwD?1Gc8t1B>q- z`1vncSY`3&!H%Mp-hsh};esLOOZVpl1=mtPM2olXeOU6htSg;)H@96_#GUfB$4c#F z<+=y6x>WBSQONI1+n68Tk!Q);!mCLs{{Ha&4*a^ch_l|*GVg9zsz(1f|Iys2ytlX; zu2-K+i^_kJ-7raiGiHbPg{>aC=Z4YFS^MdF-r3{fFLus6{#Y6Jc6RVLL2G#d0Ul$g z)-QYF%qU%BebGcUb_`pWX8%lTEL{e=&PjppO4P)nIBgMP1Z^ONPKyn+9fuP-%W1># zRFZ)Vq=~Ys1RW>O2q21336{t;h{hH{uArhb?PNk`oDR=S#g&9$Rv16ji2?u%$zYJv zVzxR^r%K?)MZr6376~A?3zMo6BxthM&tlVP`r)mPJ{5o-A}3}OiG_&BVi66Da4?bS0Hlx5??yOuV3CUA zNe7)~$H~Za(#lL32tnZe@wPO(*_{r7i%2tR0j>@(tN67kqhd7L{s>kA6J@cvqk!12 zc`}sol~}KFV@KTS3?u@=`*C0Mewn-58F*RtJMwagv1s;6e)E$Rrp+7^N7DOT=yn^8>13Pgvcw4){HSm5TFvoQr0x* zs{tKlArlykRZ|=yk%lOgVu>7)i)A4*UO6o$?GDh1ET$L{N_#1=WkEqQKv<0JQvl$O z0J)$Mb`oP~yN;&KDgjFgVk7&9HDEar7=x)Xh6JF9M1~>?R6Ik+-W8}!J{^&u$N+zu zpp2{kmp8k3pwQluM^g?k|7y3XcSR+Tt9rkBKh2bTDM65XQJ@&!n}P#NCkZ!CfYm#M zufVJ(66_v*?fTMA{Z1<=rMM(Sstkc;I6=ZPg+dA|jTiyTafQq%F~|*aq*tVVbO&u@ zGB7(i+XQq3T7mX-YX!aQE>z&_TryUWY!!fDFrt8eE10M+VG+A$yv#UM^czh=-3|jb z84%ZN1DhAv3q}2#VV`Dz?;rW=tHmEV1q2OF@<#d&$~7q08!7Nc&V$`GDAyY)@J7yq z-SvNyi~s64MOwkXpbT(WD)!gk1_v!q!~7^UXB@}Q*;lu2d>yb1w?!v8!0GG<_TtWY zcb5|whcPjl$YHm=d_2d%w0G7}aGGw3QP0*X8cuINovK^tb1sVx@$#G<-~;DoFCC)Z z;M_1SGO_jA@bsLGP}d??ez$+@)SQ%~M~_A0zWc6L7SFt18697m3k?|}TKIr>qy5^& z`iD;|cKK%h(pmV+r7EeZ&HGv7SVOs{PF7J+Xy#n?wvFg&ds1GF>Z^B`U8MO)?NMIk z&}429ZyUw+kNwyE_p>Lv#4Uk`v-158auZw?UHNvj!C4Of7ab}iYUdv3Yy~0`N5!G|X8gyt*YO#8u|^;p_OpyAzO|HTzxjp6sEYF3)H!9kZ7o RR|U$?iHVF;ADpAl`7c%W%y|F+ literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/tutanota.png b/smiley_pack/icons/opensource/tutanota.png new file mode 100644 index 0000000000000000000000000000000000000000..9008c6845c386fdb021f665f7a73cdd1bb24964e GIT binary patch literal 5011 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 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/opensource/ubuntu.png b/smiley_pack/icons/opensource/ubuntu.png new file mode 100644 index 0000000000000000000000000000000000000000..1e68494c797857105972c72386c36f02d60b5d8a GIT binary patch literal 5067 zcmZu#by$<{_a5CPrHIlSNF$QcBgQrwK@bE)8tGO_kdPLnC8Q+-zokyRK)?-gBOF?sK2}JntV{gqDUX1t}9L2n3>lsX=vs@0-{UF&?l_6%Y1< zK$Kd(dWP;g=3cDMu1;3A4$oQLeVm`OKKHh@0)f0|%2I7zZ&xLRTrJbNg>+Lg6WMn* zwJ`^@-V=pIFgVKfsIkR6dW?yVG4WvySX4 zvag22dc00B9!G!MUHXnThkI&v52CjYJd`L;k1sD8`<6cx&e2Y)a)*^xQJtj7s=M-8lJx_mbd_!Z#w=^o`YW{V z(P+=p9qSJTn6|)SFQ=2HyV6I3ZW$4Gd(@pg8!Kl2c+SfuyP!NR=iQ#4dZ^0IPAx2K z*PZhDRk$@WB(y#GB|E;%eI65Z$IZ8e{~-PBZS(NC@fp8C6QOB3b8Y&kqa35Kt~v_O z8LK*zbE$2!w{85%J{~V5DyAZb%Nv6h`PbH`UL;3X_@4(G5Pmp%;yK)6Xj0ej%lF98 z$4Eu$yX7Mp%<5G0(?3%vC)yo;^O&ITV~@7K!(LWV9Ax~prlYLFe6iKT7`d62pR%}= z_Po{}d?I1ibe@{4iizZ}@INsSC8wC`V@zL{!2w(B^jekn;2C_Dow2OgW~K?cLw0Gq zJ$Htdx?4F46`#&0TYzNfW|R)fOm7-8&Nq-Zqr*37ZFQZsIv%ri#`V@I5_pZU$3v}%?-HR3}wa?V)!EqmcKl^rXFbUlJTeD)#3(pE=@HBL=roqUws%KP{ zH~(pEdjnpxy8*Ag$!tw32aapi^0%k+`I@pKZ3Bl!cE%0IKaAFTKS~d8H(5l{1Xp}7 zcwsQp);XuR&~Yqt)*(V^TsqIuyL;o0sl`I{*DBQ~BFA&EN3AL;JbU%wlmk|zZ_7rf zPM%p5OdN%qdG11!s9rl3PFn~{78((!X%S|)B&}FCNOY2xiL3tT7Ezk+oV19rOz!O8 zZJjX9r5NodG}@AGzY?!l)5P=lM{fInZ(T>&8+~!KM5Stl@wuaxjiLrF4nOtiESIdD zF{C@s`<2EQ_C$6qwwrKTxO9{k#FxMwv=TaIe7SR3ZZ8LAN(S8MiIr5*v`_Mx5E00& z8&^1_+40m@oI&uWm35D+*yk9$lz=CgJh2R}pj7sV(zmb67cf}imOUXkh?9tD;-}?e zdrX8;n(G^~@am++503VG@OQfosU7p)da5^=SVHi7*oI0}&hsVC&9zW71C%k}I-+?|PkmJg33aflOX9H}dxutTE2 zU4I_%Z2IYdU{4d+G2#JfPLvnO&+dmj&(<20%rcB_IXw>4iFPQjRBU)?!6+DG$aKPi zA5OksJD3(8-P=z?7YTZD`xoU|(k7*5Q_9!RoE4fx+uy9*yss{gp!hG3I#*}VQOpIN z)Gsycb@$l^n;ARY5?q1|z>)+BixUnnbKb0T;uzX7ITDA7x|WpXR59&6^x@!WZ!({i*LvoOO z{2nK>8&M8PFKf>IM3XEp)MmifQ~`M}!Zy z`o190b%znLX32WV4CwIF&}y!N2211590q;z64(CPB^*s6sTB-MN|Dp#40^k}1GmPu zRxTL(zidfPjBM!`^=}Z`I zPQ`(G3-QSbJBJM*DIAsf+ZYpj^@D67Q9H9tSBO7;QI?P9lZ8>eUf9q=#bSTJmB3n#Q;~agG%39a7Lw_cz)nJXJWV-o`EZ*y0^nki@P$mP-rKwn&PY=_}2TY zc7n-vf;I5#a8DU(;l7)k(n*2)e5y4iE8l3}-xz(yXv|`*!v^O>R7?mJkL2fXR%R-; z>L}eU4cLd*-~FrjtwX@%XTDpbhOVw$5k*Y;)<_hI$VzER&3iWB6z>T<4%(vK#Czh_0r00s6~ZtP70I_gO%DcncoI zR;J-Z(hgtN6@2%5bq7NlCNrU}L&vE-1Potu!-B&s14)kR;wET(<=@kehT~Eb5llpx z&g()&jKYM3+D+aPbH!`fK*Pa0lTbyzpRB%gGBVw=4-uQ$6ahRz1G5B0D^X8DkjT@E zH_Ag&L!x=bc~u%Y>=jm~+HMGgbC+IwC}T+Teja-6gG8nF^F^@?JIc2toIxd@?lOGD zUGzSU)8u$ahYXdmdoS7Mu$SMeEkI)E@VD3!+J`D+j5Dcg7|6086tp5s89c{(oU!+5 zae%R!`QuBG8BAS|*;I$++MpGLW}G#F*e=2A-GxMZ^Yk_gaGCY0%3^DWm8ni>q=lqdH*9cn7T+{8xY)y9G*vLAdYXnXSaeil#If3aM zS5CYf-Q5=7ky4E?i-?|8<}CCVIE4IMtDmLKdhw|C!~{egXPj=WZ5#9&;nN>4o;#$C zVBHk!C1h3g6BQJ`Bdu1FRyX>{dwUJC396qxDAg2VF)4wIv%DhNBGtP z!mWXqPh5<@p(d}zzKUlTpz@33@GdHyg=j#XJG=4`lwz-T=EG==r$J1$`qp3FMb(xV zF)miN_KZ&GYYS2)1j)tC4E2E0>}LO>MPuu4FP$hdNcT^r^6cktn<|Es)PaSJ)x(j* zFvyDbX)a3fEWgy_xVq&2y{$`D3^><_ESUWZcBC27|%dx^)1ajklKN;dts*{No(E#Y|D-5%(Uc`no7 zagk3a^!Ty7p5k1K0VVWXJiN|ui7W|Tza&D{uYIRr=shHUaXOw?BPP|N#ChUGs7=pt+` z8&Yj+lWk8QW+L3`M3N}W8cm6XdD*~Ro$eop>m;+dn#67h3(%U+xVnCa-T#;|*SPsj zT)Zbc!YQWM%)v07eaf7&(#l>MnZ|cHDL>1R6@X4fB?YrX_x1(@p7LHkxtGRb*G&=_ zvQbc-wXqXsaAYuebFu3w`jTu$`ZFrRDifn$9KysB8u`%B*qQUOp_fDZblB{&E%6Xh z-Be0+4ZgCC+?L#c{^i`p*N)X92noYc6ho5c4-PuKo!`Wfw$B2TLuJF*{HU}_`9gFE z_({~*RJrJ`HfVIj*2Icn!Y`Sf(1M!z9s8W$ zjlGLvp9V0~Ld8-Ys_tQ(AYWu6EhN z&XNn+W7o=cnnb1q;jg{FCuz{{<D~A#kbeX*J<{SC_MiQ-RC~pX!X|Pz^ywZJOt+t4qJ}Sb6goD;l)WKi`py}sYi5h z(nT`ahvO76^Pxf()1hB|y=^WpikCe;@O_9e5;>(U7}J%eO3~0no^L8(Hkn$285APq z(YUJiW0t&n#9`_8lml?tYquz$oq0%E{~(UpsmO0S%gFP1>nW#y3~xmZGmwaiw~cA< zs@>;WF?{>pxlHD+t^TXLi5e-6yU-7e`Gzi0iNaAM&VDkcqQm4IBM=;?ORABPMpaY7 zvV9N;C)8F+NeiZ=#HyvEsRBbN1HULUUd79(b;vV!J=M);rzheKmw*;6nJMUXYJbuS zAk%hVD*{TVuPNIc%zG$@VV8k>V(9Qy+4hrffZiDA65f)hez|* z_z3Z#OSi02#15nm#tR&s7a%c}xurLL)fLhdWvQC8M#Y~8eK5{; zo7gI=iX9_jMVfFq1-@1?tCyd)m)+a7+1WwekG}K=Ih(l_>}t0qfwA{;W0WM9^2 z#-;!sI2Z*a!XX3q@Bh?*EFvI)XG29`4ao%f|CIxr6Z*W12+r$ZY}T>{2fzn_1ro7N zfB=wqjRu&@2*A$`m~$j63vwy+4`U}3Kp z0>H%T0GKEk=XH-j?tiEMhJsB2l)(xMET9&4|A+7|5nzi=2inIfiJjwhv)Hf&4K}O^ zARxhO*8-x{uloW@TuX!{d_6}%Mj&z?$`0(n0xB*6;$xxyyBL60*EGOrKz}TM2wIhA zQ=bm>HqbM_562jfYYUGO3Uipb1EDt>{zik@H!D&8Y>hW zg1vP>*7dyt_62pG>rSy@*W>$7z3b6{(J(BrB{&bz`}IV?(qgL|z&n8BuA`v~l3)7? z{Lux%v4E>WLE!{<)BuCTS?#eK2qXYR32@+e=gWBlP9k?0QkiIt2$!B)!cRw-3~(91 zpbC22!$}Ekq##yeC7I@{t2NeprO10!@y3*e%FRUdl!Un~+%Zd?FQd4d5)zX-hnT%S zH%pk;IF;>oA~$FBPZs-!&D+v)`7GPLakGug24DKWp`jq;!Hq_5T^Rr+Krm$uXt|(ROkN|^@3l$L% z23J7Af{ciQ%V-ruYh@_{YKvHxp^n=WIz?Kst`zzupyFxInd3Rr|I9fr@4fro`}^+w z-R0!V=Fnh&OX4gd1VNUf0O2xlCxOd~Fd2MXL~Tq2x0ZBCgl-w4C#y9onLG(6>(bOX z88^sf5M;Qi2=$(NflN5_GRMQ)j8rBq#;QDf2OEfOb9XCSNYiB-Huk@~aUqdhXx6qo zaN)d(-&F3;_o~R}My~X+kJLC`oZ*<6ft;REeCnJ> z?vTIx{3V1HoYl&vHsbxsJ$p%kUFn%$9&2{H8f@2;l3q6da_SBhit9wHbWtHH(f$26=3;qCwDvjdEY#P?4|itB61xrJ03- zfD2ys&2cN6ok`|y+1X~*!Kq7aTBEWk62b|envdr1T;pBz>D=b#rD`ho+0lp;b@H|D z^UJNxJiSW)QfeDh*)%dQYdY*;|MXr@V{4Dw7jbk}_m9~V4$5X$3!}fn!n10_&A#5M z%teK0mB%MJB13*%#h7Wu76@)v10A)TdDWV2=0@@quS%DCmk=V{5C4;KB4#4 zWLoXY;xkjCA3_^K>al=)+w#84->-YhdQr8Ap|*H@=yapY)8rRWWp&McOSPJiJHsiX z=U&hGC*KVVx_%s(Qedq)<`&i~0+nZwg9?if2l1sU1r5PeC{8md)S&br$lcSRMx=?j zj*Q~*a;1PW&~T1ImSX}+xQmz}R{P=!@_=*=9+n;~k)|g~c^JjhgXnJH0{{iCL&ye2 zl2Xez2q-38K6o~Y=@ha_MVBa`M2JJlzA6n)X4BX-2G!3XPi0a(h-7ySCgU#?E*^sb zZvsk!PN(M6>3Y4Mrf1Pqns_?Q0&f~rz<0tyAJlVAC#P>aQ{;g#Ak762b~1EQwGGzMLvppUoE>ikjx$e2TaXrYyW zMx`&qwW<`26!%NTl{&}q5Sa9}y*fpcWC{n9((xo*0aUeMSNN?h{YB!?*A_+!;^hjp z$qJDDmZnZFdqdV+z8P0c;f!|#n7_t-OZ!#qCS{-{7W0KFX^PQ3kx)P}?$5_mQaQ#q zJ#slx1_NWusBDzUqOx5$D3!}YI8-L;%EftHgeS$(aZnh!Bk&R3(x$-YX*%2A~ieXQ3`E8Pyf# zVN^DkiBJ&)0m!f`2SqV9j}5z+pfD+au}Y&rKsx0LBp#=$mGPzpBjJ4SP?3Pbq%qz| zLX!}k3>XL~L2_k^;mv|XuE4`|h>=a0!(?$83?2-_92VPUob?J^qXm^{#Dp0%7TaWQ zObZ_b1BgY8bqWAXau5sOSA!!ul}4gcB?%}-m&iuT*UMtiP8gy?goq9YpbRFP&*1W5 zR|yRBSuT7SUdUkb8RPU-m|T|jzqF0bLv|lcd4OCC_D?g3Mms7DPab_6eNB>^T8T_H zH3c7$j)tH`QgO`WC%_tAk|rR^cpOZRv2uMSm;XU2uwW?{W8w@@O$f*zlY>!F9CM{| z*ceYHgE2OSB5$K>RWh9((cs?kfJeX;C{GhtWG7Ri7QC&kPr!{?0EAH)TiWOYMSOFd!j<4xkRBYCtd^$i0SB$gXrR9kvV%0xXDw@H zwgAZo>VQZs_!nTB@tOb?m)Zg06rD)yH>H^f5D!20If`~~ESP_7ZZX!O_)iB<`y|$5o0m`3-8HfQ{hV|AW?;ul&lsP+ zr^1Y~!*1#Os?QdzeK0KDF_I>0NJK9bDMJSis;KikyzkzN0Pm;0(-5oH%C!;in4kU*?8>X!A(vg4j(ocs0UJOZFA+vbzEq zY7=%lpUaChD<_n)ovW^h)q7H3jU3zTTWlF-r?HD_L=o1q`XYxi|$p!D}McC zC*{<1@0rg1`vYulu48^2b?oHc;T%iiUl0F${e$|btI(;3Ezq63nI(1(gR_qm-IytX z$!_VF27(uvYgPDEvRi1-E=z9Q@y?HS-6s{$G8FUy$6KD`D`*AiTr|vwLYuX{|28EVWt28 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/respect/cc.png b/smiley_pack/icons/respect/cc.png new file mode 100644 index 0000000000000000000000000000000000000000..b28ef687f359018c136149b631ae3f0bfb38bbc4 GIT binary patch literal 4461 zcmeHKdr(tn7QYA6`?@m09F_a-+_i4>CnK>{g63ftW-H@P=(A+IJEl2~5_ z1uHv?U~NUwirUW5W$3t5w^r(-i`KR{t5mVpy35l6YAvtUx{JmAZa^N>&UBdB{zqn# zd%yGeedqkn`Of5fRhyO+=pX41K~SJNS(yQzA?(-B2mId38A}3>k2dSFnGC|ovDvLg z+C*^}w~gXZF4_n|uG?nq3&G7Czel~H@{)PaEW3>Nr&_Od|90M|7vEmjJ)E7V${qdi zPlIT#vE%a-4}QO|WSw*A!DRcN4?DUJpFMhQ_)dA|v*w&-r*53y{@n=OLF8xg5{Cnb znqB|wMB)?sUNLc7zCgbwlzkh5N;}(APHk-3Mtu2sz>s%h?8vS6&-6dId2C>DSK^sK ziu=IplOXRvjZ&I+c->~(h;IH=PXG9j?v8sm&rX)J-)i*CTJr@}vYT9-% zwRw5E<4~KVNh03b7Q|a!+eHZUpY7barxDNW4KJ71Z%nu#Us;Dgon?KyW>3^}YgfOa zXnpp?S9p)P&3z;zarnR|Ezx(XKD*vSjQ#NP{qBZ;zbEQ-Yki6e6WSsxJAeGm&9ZCm zvi@~F^-|690ogW zV`!^|!(tM8YY`*oa)F-nBtElEqnU)aI3`#Cd>}5uhG0AtF`JR;9u7uT3_vCV`dJT$ z4xAt)gK}7l>;_6zOj(!}(;-O1q`$4mZt|o<8W74vnSrST?266UGD)q`PI|Bu!;+zmQ)JDEjn#P4nH~smpTwPE{UmpfF|g8TWJ;@{hz(DzlylkrWu(MK`Cc*T2Y8sT<;$R4ifnuQmIFAN6QlXF(>kT4U zgb@HoK;W=csMo`Uh&1wzD8(;@5iW#rQlf|T z7$$*5e2UUbq#}VpD)vB;23exjZYDrEX)}>WAvQ~%N5K*+u><-Y0EGCBX1h_}TmPH1V0mKq) zp8^1n9ONQX*eQas+I3c|NzP?M;;^2RY7IC}B*73$f}sE?%Ex7>M1~1)9PeIhuPV*t^t4njg9F3* z^sS*j7TC;t1?kX+pJ7VFpQ;<1pQ7y0rio5Vv(JyD4&5DG>HEdrr=&gKI?uOX?u={v z+i2|7!7Z*1_qjzn_0V4eH$+Fb;PnOfZc}GJ3h*A>aXET-PG{7GxaQhTcf-(2u<(MUnh zk%&s&ze3y#+cV3)P9ONsjcuck?!G2jvn^}IK#MH&<4u~c?tP&0c62>2?5%&NJNRbn zUMP20Ii8U&b{}2RcOqhk&mZ1B9_}@`n;L#Cd!^S>@A6t`v0_0(&p|T>bI> z2}wa|OM$79eEcQT>^Rla7?G}%ht`w@9jiO&yuP5S2@*U!S@xZZtgEJXEN@H=_+zNF z%eeB<3qBA3u{;dff9z0D#W%Lm%F5_ZUrxEzcOc}PXl*c-R2}o)zEwwegl2aKn%i#9 Yzjdr?x2;a80o8%jsx)QehTM|>0f6af00000 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/respect/cc0.png b/smiley_pack/icons/respect/cc0.png new file mode 100644 index 0000000000000000000000000000000000000000..51ebdf1fc1be3a5bb42c11051c89467254762aeb GIT binary patch literal 4669 zcmeHLdsGuw8jlKwMPaod#rj|x)S{ToOfuv#B_K_ZM2tp67gnuKG7}id%VaP?SA0+v zbp>&?Dxy^spFm}OQN#yEM2jm?#I@41QmW$C7JLgw)V&Fac-nJ%JZJkKIVYLi?|$F! ze&6r=-FtGgNI*(CYT+gDs8|r6z{C+Y$ZRp`Xgvin zX=Vzd?6i)>vfnhQXMEs*yxN=mrOU!G`_S6mf|F6%v;EhvQf-+xD?t}M=XLq)2lt{v zptLJ-vC4qBf;d6`#a%w%~d^m6QIJ07>cZ06}h&9v{+KEvcqC8jn_ef>XAI^>_$3;S=WWH+RH zln$OEi!B_;{*brgRK%0z?e(<-A9yzOPYm!c`0H>MtJfE_Or}=KWN(TACFCv2kt!VH zhE~p=QOOzP`KkZB3+h=%e8)5<98`bdy>ohUUB&IIaPrl4yGzC1#h&cQfP=og%Vl_} z_p%0d=HZNg9W)etA} zOyH;yx}U81o0m1UmaWYG+J4NYudhb zLnB**+MBPBov12P?(}fJ)YJzBkE`K13+tafFENNFFF7MH7aVWb*jl8PBSZ2$VD=xBB=8KK>b{dE)K{XNAnhZRGG-)WF-Czc)W3j>`?Pfxo zLNSnrN}`QYPRohY9Ec{RoWF#r5S3X*CDV!p7HaB(N%7hRDOw51iHz_Lx8nf7KrsYl zH|UL4+%Dy~adGh7WrjJB+l5JyauQT(NM^E75XQrJ2sheJ&*yU@yrFOlsl(&s<2xb1 zNXkiO7&8vTHk*xS6YxxyBp8)QBrw8<`Ft+$;9Ap+3}NRQt-&sc4h%VE)mmsXLz|3{ z3zN{8QW+_S1LmPO`5DYARTsR`+Q|ao1GW=p808_b!2oxUurkr}0Z3;;zZqeT2YVEb zqpYS>iPZ^ou?hvH5E8d)H(YwnbwJ@cp48YY2Rz=@gGDfLVcSX1;NTLm9cN8G| z9Z!bVy(R0N+*~v6a=Ir1!n<(a@qSag+ZlMNRJh!vO?9QGluJ3T^>NaqrAgfVmC}Ww zA_Aqjq>ezj7=j{PjYuTo3i)9oR3t=%8cfm+N@=t*gi%Ympa3|J1~?j&)DS42;tDXK zmWv5=1eXwCe6EH>5Q$DB<|8QC4Pvr|2C5|V-LrB*kpK$SP+C-r3Atj4M8L)P5)qdW z^T80&kP;z+h_sZ*4Ml44@g|Fb0PUm=L=pv?jY;ka7vXr6S}Eo5dB|IfT2C-K5Fq7D zq>ZWew-fQSfttz?E;dmS9|L4aL|ArJWOu{EY+qnpVintgWrUNPvQe3`()Byk}5i$4Igu$H!!>%*qO~v8xuQ&;J zJ9Il_KwO6n9A4logu4#IPR>9Ef8?vP7k}gu5Y)5Cd-2;tR}Wq9#lU+x_o%CfuJ>Z# zy_|d0^?#$w`|Wj#GJ;=0HgH+m_jTiSaM9|kiH(u70$CPT{`vI5=Yi!=HA(WcDFga8z%^W+7n=V; zaOREVaTOuP1h3IW>zAmo5RW0AMMYx^^>VYr)8C_CKhKXL;j!X+WNWT7>+|o=dFYU=`#HyBOkWbpYV&}-B?0im-n$Z(PSQJ& z%ZrMAs2cT|!Idl&7m!%kJ+TiAQU;O!1|ZX;{Yp@aEY zAiL_&;Gna&st?~kGHkKaXVb$y>+ALeMoiWoYxv~V_)|OMT8@`~9;>TC5<`yM9eVc9 zdHrW@m!B$gZabI4)Hzp_NFF>FMc-O|qF3>^f*(R}rnDu_{w9yNec_ns;XFt%?TX2v z@X2;AEvUScd^wA3V}+LR9+@`g8nS|NeQ~z5@*a7j7 zP_uAt&IIS(hR0KfC7H!jUaTqEPryd9ck!q-7Ri$;&d8nTAGE98b8<#W)Zcicb{)T(x#HS}${XA8wN(`( hn)jxpd^Gq~A2PwVG$Qu(3ZMg)GJ2A{__I07{s-^H&x!y5 literal 0 HcmV?d00001 diff --git a/smiley_pack/icons/respect/ccby.png b/smiley_pack/icons/respect/ccby.png new file mode 100644 index 0000000000000000000000000000000000000000..69d237d25027f8c992fc2a30025b1358667814c5 GIT binary patch literal 4407 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 G^M3&g)*ssd literal 0 HcmV?d00001 diff --git a/smiley_pack/smiley_pack.php b/smiley_pack/smiley_pack.php index 4361b2f5..343ea262 100644 --- a/smiley_pack/smiley_pack.php +++ b/smiley_pack/smiley_pack.php @@ -2,30 +2,28 @@ /* * Name: Smiley Pack * Description: Pack of smileys that make master too AOLish. - * Version: 1.05 + * Version: 1.06 * Author: Thomas Willingham (based on Mike Macgirvin's Adult Smile template) * Author: Matthias Ebers * All smileys from sites offering them as Public Domain */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; -function smiley_pack_install() { +function smiley_pack_install() +{ Hook::register('smilie', 'addon/smiley_pack/smiley_pack.php', 'smiley_pack_smilies'); } function smiley_pack_smilies(array &$b) { -#Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. + #Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. -#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : -#when all else fails. + #Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : + #when all else fails. - - -#Animal smileys. + #Animal smileys. $b['texts'][] = ':bunnyflowers:'; $b['icons'][] = '' . ':bunnyflowers:' . ''; @@ -50,7 +48,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':cow:'; $b['icons'][] = '' . ':cow:' . ''; - + $b['texts'][] = ':crab:'; $b['icons'][] = '' . ':crab:' . ''; @@ -71,7 +69,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':horse:'; $b['icons'][] = '' . ':horse:' . ''; - + $b['texts'][] = ':parrot:'; $b['icons'][] = '' . ':parrot:' . ''; @@ -99,16 +97,13 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':pig:'; $b['icons'][] = '' . ':pig:' . ''; - - -#Baby Smileys + #Baby Smileys $b['texts'][] = ':baby:'; $b['icons'][] = '' . ':baby:' . ''; $b['texts'][] = ':babycot:'; $b['icons'][] = '' . ':babycot:' . ''; - $b['texts'][] = ':pregnant:'; $b['icons'][] = '' . ':pregnant:' . ''; @@ -116,11 +111,10 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':stork:'; $b['icons'][] = '' . ':stork:' . ''; - -#Confused Smileys + #Confused Smileys $b['texts'][] = ':confused:'; $b['icons'][] = '' . ':confused:' . ''; - + $b['texts'][] = ':shrug:'; $b['icons'][] = '' . ':shrug:' . ''; @@ -130,13 +124,12 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':dazed:'; $b['icons'][] = '' . ':dazed:' . ''; - -#Cool Smileys + #Cool Smileys $b['texts'][] = ':affro:'; $b['icons'][] = '' . ':affro:' . ''; -#Devil/Angel Smileys + #Devil/Angel Smileys $b['texts'][] = ':angel:'; $b['icons'][] = '' . ':angel:' . ''; @@ -152,20 +145,20 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':devillish:'; $b['icons'][] = '' . ':devillish:' . ''; - + $b['texts'][] = ':daseesaw:'; $b['icons'][] = '' . ':daseesaw:' . ''; $b['texts'][] = ':turnevil:'; $b['icons'][] = '' . ':turnevil:' . ''; - + $b['texts'][] = ':saint:'; $b['icons'][] = '' . ':saint:' . ''; $b['texts'][] = ':graveside:'; $b['icons'][] = '' . ':graveside:' . ''; -#Unpleasent smileys. + #Unpleasent smileys. $b['texts'][] = ':toilet:'; $b['icons'][] = '' . ':toilet:' . ''; @@ -176,7 +169,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':fartblush:'; $b['icons'][] = '' . ':fartblush:' . ''; -#Drinks + #Drinks $b['texts'][] = ':tea:'; $b['icons'][] = '' . ':tea:' . ''; @@ -184,7 +177,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':drool:'; $b['icons'][] = '' . ':drool:' . ''; -#Sad smileys + #Sad smileys $b['texts'][] = ':crying:'; $b['icons'][] = '' . ':crying:' . ''; @@ -195,12 +188,12 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':sigh:'; $b['icons'][] = '' . ':sigh:' . ''; -#Smoking - only one smiley in here, maybe it needs moving elsewhere? + #Smoking - only one smiley in here, maybe it needs moving elsewhere? $b['texts'][] = ':smoking:'; $b['icons'][] = '' . ':smoking:' . ''; -#Sport smileys + #Sport smileys $b['texts'][] = ':basketball:'; $b['icons'][] = '' . ':basketball:' . ''; @@ -231,11 +224,11 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':snooker:'; $b['icons'][] = '' . ':snooker:' . ''; - + $b['texts'][] = ':horseriding:'; $b['icons'][] = '' . ':horseriding:' . ''; -#Love smileys + #Love smileys $b['texts'][] = ':iloveyou:'; $b['icons'][] = '' . ':iloveyou:' . ''; @@ -255,7 +248,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':loveheart:'; $b['icons'][] = '' . ':loveheart:' . ''; -#Tired/Sleep smileys + #Tired/Sleep smileys $b['texts'][] = ':countsheep'; $b['icons'][] = '' . ':countsheep:' . ''; @@ -269,7 +262,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':yawn:'; $b['icons'][] = '' . ':yawn:' . ''; -#Fight/Flame/Violent smileys + #Fight/Flame/Violent smileys $b['texts'][] = ':2guns:'; $b['icons'][] = '' . ':2guns:' . ''; @@ -313,7 +306,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':acid:'; $b['icons'][] = '' . ':acid:' . ''; -#Fantasy smileys - monsters and dragons fantasy. The other type of fantasy belongs in adult smileys + #Fantasy smileys - monsters and dragons fantasy. The other type of fantasy belongs in adult smileys $b['texts'][] = ':alienmonster:'; $b['icons'][] = '' . ':alienmonster:' . ''; @@ -336,7 +329,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':mummy:'; $b['icons'][] = '' . ':mummy:' . ''; -#Food smileys + #Food smileys $b['texts'][] = ':apple:'; $b['icons'][] = '' . ':apple:' . ''; @@ -368,7 +361,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':birthdaycake:'; $b['icons'][] = '' . ':birthdaycake:' . ''; -#Happy smileys + #Happy smileys $b['texts'][] = ':cloud9:'; $b['icons'][] = '' . ':cloud9:' . ''; @@ -376,7 +369,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':tearsofjoy:'; $b['icons'][] = '' . ':tearsofjoy:' . ''; -#Repsect smileys + #Repsect smileys $b['texts'][] = ':bow:'; $b['icons'][] = '' . ':bow:' . ''; @@ -390,7 +383,19 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':number1:'; $b['icons'][] = '' . ':number1:' . ''; -#Laugh smileys + $b['texts'][] = ':cc_cc:'; + $b['icons'][] = '' . ':cc_cc:' . ''; + + $b['texts'][] = ':cc_by:'; + $b['icons'][] = '' . ':cc_by:' . ''; + + $b['texts'][] = ':cc_sa:'; + $b['icons'][] = '' . ':cc_sa:' . ''; + + $b['texts'][] = ':cc_0:'; + $b['icons'][] = '' . ':cc_0:' . ''; + + #Laugh smileys $b['texts'][] = ':hahaha:'; $b['icons'][] = '' . ':hahaha:' . ''; @@ -401,24 +406,23 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':rofl:'; $b['icons'][] = '' . ':rofl:' . ''; -#Music smileys + #Music smileys $b['texts'][] = ':drums:'; $b['icons'][] = '' . ':drums:' . ''; - $b['texts'][] = ':guitar:'; $b['icons'][] = '' . ':guitar:' . ''; $b['texts'][] = ':trumpet:'; $b['icons'][] = '' . ':trumpet:' . ''; -#Smileys that used to be in core + #Smileys that used to be in core $b['texts'][] = ':headbang:'; $b['icons'][] = '' . ':headbang:' . ''; - $b['texts'][] = ':beard:'; + $b['texts'][] = ':beard:'; $b['icons'][] = '' . ':beard:' . ''; $b['texts'][] = ':whitebeard:'; @@ -436,7 +440,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':headdesk:'; $b['icons'][] = '' . ':headdesk:' . ''; -#These two are still in core, so oldcore isn't strictly right, but we don't want too many directories + #These two are still in core, so oldcore isn't strictly right, but we don't want too many directories $b['texts'][] = ':-d'; $b['icons'][] = '' . ':-d' . ''; @@ -444,8 +448,8 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':-o'; $b['icons'][] = '' . ':-o' . ''; -# Regex killers - stick these at the bottom so they appear at the end of the English and -# at the start of $OtherLanguage. + # Regex killers - stick these at the bottom so they appear at the end of the English and + # at the start of $OtherLanguage. $b['texts'][] = ':cool:'; $b['icons'][] = '' . ':cool:' . ''; @@ -455,7 +459,7 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':golf:'; $b['icons'][] = '' . ':golf:' . ''; - + $b['texts'][] = ':football:'; $b['icons'][] = '' . ':football:' . ''; @@ -480,63 +484,167 @@ function smiley_pack_smilies(array &$b) $b['texts'][] = ':gangs:'; $b['icons'][] = '' . ':gangs:' . ''; - $b['texts'][] = ':dj:'; $b['icons'][] = '' . ':dj:' . ''; - $b['texts'][] = ':elvis:'; $b['icons'][] = '' . ':elivs:' . ''; $b['texts'][] = ':violin:'; $b['icons'][] = '' . ':violin:' . ''; -# New Gif Emoji (@one@loma.ml) -# Fediverse + # New Gif Emoji (@one@loma.ml) + # Fediverse $b['texts'][] = ':friendica:'; - $b['icons'][] = '' . ':friendica:' . ''; - + $b['icons'][] = '' . ':friendica:' . ''; + + $b['texts'][] = ':fediverse:'; + $b['icons'][] = '' . ':fediverse:' . ''; + $b['texts'][] = ':mastodon:'; $b['icons'][] = '' . ':mastodon:' . ''; - + $b['texts'][] = ':pleroma:'; $b['icons'][] = '' . ':pleroma:' . ''; - + $b['texts'][] = ':misskey:'; $b['icons'][] = '' . ':misskey:' . ''; - + $b['texts'][] = ':diaspora:'; - $b['icons'][] = '' . ':diaspora:' . ''; - + $b['icons'][] = '' . ':diaspora:' . ''; + $b['texts'][] = ':hubzilla:'; - $b['icons'][] = '' . ':hubzilla:' . ''; - + $b['icons'][] = '' . ':hubzilla:' . ''; + $b['texts'][] = ':pixelfed:'; $b['icons'][] = '' . ':pixelfeed:' . ''; - + $b['texts'][] = ':nextcloud:'; $b['icons'][] = '' . ':nextcloud:' . ''; - + $b['texts'][] = ':activitypub:'; $b['icons'][] = '' . ':activitypub:' . ''; - -# ccc + + # ccc $b['texts'][] = ':ccc event:'; $b['icons'][] = '' . ':ccc event:' . ''; - -# Commercial + + # Commercial $b['texts'][] = ':youtube:'; $b['icons'][] = '' . ':youtube:' . ''; - + $b['texts'][] = ':spotify:'; $b['icons'][] = '' . ':spotify:' . ''; - + $b['texts'][] = ':twitter:'; $b['icons'][] = '' . ':twitter:' . ''; - + $b['texts'][] = ':twitch:'; $b['icons'][] = '' . ':twitch:' . ''; + + $b['texts'][] = ':facebook:'; + $b['icons'][] = '' . ':facebook:' . ''; + + $b['texts'][] = ':threads:'; + $b['icons'][] = '' . ':threads:' . ''; + + $b['texts'][] = ':google:'; + $b['icons'][] = '' . ':google:' . ''; + + $b['texts'][] = ':signal:'; + $b['icons'][] = '' . ':signal:' . ''; + + $b['texts'][] = ':tiktok:'; + $b['icons'][] = '' . ':tiktok:' . ''; + + $b['texts'][] = ':whatsapp:'; + $b['icons'][] = '' . ':whatsapp:' . ''; + + $b['texts'][] = ':instagram:'; + $b['icons'][] = '' . ':instagram:' . ''; + + $b['texts'][] = ':telegram:'; + $b['icons'][] = '' . ':telegram:' . ''; + + $b['texts'][] = ':windows:'; + $b['icons'][] = '' . ':windows:' . ''; + + $b['texts'][] = ':github:'; + $b['icons'][] = '' . ':github:' . ''; + + $b['texts'][] = ':threema:'; + $b['icons'][] = '' . ':threema:' . ''; + + # nonCommercial + + $b['texts'][] = ':invidious:'; + $b['icons'][] = '' . ':invidious:' . ''; + + $b['texts'][] = ':bluesky:'; + $b['icons'][] = '' . ':bluesky:' . ''; + + $b['texts'][] = ':vivaldi:'; + $b['icons'][] = '' . ':vivaldi:' . ''; + + # opensource + + $b['texts'][] = ':firefox:'; + $b['icons'][] = '' . ':firefox:' . ''; + + $b['texts'][] = ':linuxopensuse:'; + $b['icons'][] = '' . ':linuxopensuse:' . ''; + + $b['texts'][] = ':linuxdebian:'; + $b['icons'][] = '' . ':linuxdebian:' . ''; + + $b['texts'][] = ':linuxfedora:'; + $b['icons'][] = '' . ':linuxfedora:' . ''; + + $b['texts'][] = ':linuxubuntu:'; + $b['icons'][] = '' . ':linuxubuntu:' . ''; + + $b['texts'][] = ':linuxmint:'; + $b['icons'][] = '' . ':linuxmint:' . ''; + + $b['texts'][] = ':fdroid:'; + $b['icons'][] = '' . ':fdroid:' . ''; + + $b['texts'][] = ':tutanota:'; + $b['icons'][] = '' . ':tutanota:' . ''; + + $b['texts'][] = ':raspi:'; + $b['icons'][] = '' . ':raspi:' . ''; + + $b['texts'][] = ':linux:'; + $b['icons'][] = '' . ':linux:' . ''; + + $b['texts'][] = ':kde:'; + $b['icons'][] = '' . ':kde:' . ''; + + $b['texts'][] = ':firefoxnightly:'; + $b['icons'][] = '' . ':firefoxnightly:' . ''; + + $b['texts'][] = ':archlinux:'; + $b['icons'][] = '' . ':archlinux:' . ''; + + $b['texts'][] = ':thunderbird:'; + $b['icons'][] = '' . ':thunderbird:' . ''; + + $b['texts'][] = ':vivaldi:'; + $b['icons'][] = '' . ':vivaldi:' . ''; + + $b['texts'][] = ':jabber:'; + $b['icons'][] = '' . ':jabber:' . ''; + + $b['texts'][] = ':matrix:'; + $b['icons'][] = '' . ':matrix:' . ''; + + $b['texts'][] = ':xmpp:'; + $b['icons'][] = '' . ':xmpp:' . ''; + + $b['texts'][] = ':foss:'; + $b['icons'][] = '' . ':foss:' . ''; } From 6f3ba10466a78d174d17594b8e2f0fe3a1ceb967 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 14 Sep 2024 14:40:48 +0000 Subject: [PATCH 115/294] Bluesky: Preparation for video posts --- bluesky/bluesky.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 181e8d2d..f4e2f456 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1410,6 +1410,19 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le } break; + case 'app.bsky.embed.video#view': + $media = [ + 'uri-id' => $item['uri-id'], + 'type' => Post\Media::HLS, + 'url' => $embed->playlist, + 'preview' => $embed->thumbnail, + 'description' => $embed->alt ?? '', + 'height' => $embed->aspectRatio->height, + 'width' => $embed->aspectRatio->width, + ]; + Post\Media::insert($media); + break; + case 'app.bsky.embed.external#view': $media = [ 'uri-id' => $item['uri-id'], From f8f63532f4297db73f6cfc578ef4a5e8959db61c Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 29 Sep 2024 18:19:38 +0000 Subject: [PATCH 116/294] Bluesky: New option to complete threads --- bluesky/bluesky.php | 203 ++++++++++++++++------- bluesky/bluesky_feed.php | 8 +- bluesky/bluesky_notifications.php | 8 +- bluesky/bluesky_timeline.php | 8 +- bluesky/lang/C/messages.po | 168 +++++++++---------- bluesky/templates/connector_settings.tpl | 1 + 6 files changed, 235 insertions(+), 161 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index f4e2f456..73b19612 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1,7 +1,7 @@ * @@ -10,6 +10,8 @@ * - Outgoing mentions * * At some point in time: + * - post videos + * - direct messages * - Sending Quote shares https://atproto.com/lexicons/app-bsky-embed#appbskyembedrecord and https://atproto.com/lexicons/app-bsky-embed#appbskyembedrecordwithmedia * * Possibly not possible: @@ -151,7 +153,7 @@ function bluesky_probe_detect(array &$hookData) } $data = bluesky_xrpc_get($pconfig['uid'], 'app.bsky.actor.getProfile', ['actor' => $did]); - if (empty($data)) { + if (empty($data) || empty($data->did)) { return; } @@ -346,15 +348,16 @@ function bluesky_settings(array &$data) return; } - $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false; - $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; - $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); - $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); - $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); - $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; - $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; - $custom_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle') ?? false; + $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post') ?? false; + $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; + $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); + $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); + $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); + $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); + $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; + $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; + $complete_threads = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads') ?? false; + $custom_handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle') ?? false; if (DI::config()->get('bluesky', 'friendica_handles')) { $self = User::getById(DI::userSession()->getLocalUserId(), ['nickname']); @@ -369,16 +372,17 @@ function bluesky_settings(array &$data) $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/bluesky/'); $html = Renderer::replaceMacros($t, [ - '$enable' => ['bluesky', DI::l10n()->t('Enable Bluesky Post Addon'), $enabled], - '$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled], - '$import' => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import], - '$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')], - '$custom_handle' => $friendica_handle, - '$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'], - '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle, '', '', $custom_handle ? 'readonly' : ''], - '$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'], - '$password' => ['bluesky_password', DI::l10n()->t('Bluesky app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the Bluesky settings.")], - '$status' => bluesky_get_status($handle, $did, $pds, $token), + '$enable' => ['bluesky', DI::l10n()->t('Enable Bluesky Post Addon'), $enabled], + '$bydefault' => ['bluesky_bydefault', DI::l10n()->t('Post to Bluesky by default'), $def_enabled], + '$import' => ['bluesky_import', DI::l10n()->t('Import the remote timeline'), $import], + '$import_feeds' => ['bluesky_import_feeds', DI::l10n()->t('Import the pinned feeds'), $import_feeds, DI::l10n()->t('When activated, Posts will be imported from all the feeds that you pinned in Bluesky.')], + '$complete_threads' => ['bluesky_complete_threads', DI::l10n()->t('Complete the threads'), $complete_threads, DI::l10n()->t('When activated, the system fetches additional replies for the posts in the timeline. This leads to more complete threads.')], + '$custom_handle' => $friendica_handle, + '$pds' => ['bluesky_pds', DI::l10n()->t('Personal Data Server'), $pds, DI::l10n()->t('The personal data server (PDS) is the system that hosts your profile.'), '', 'readonly'], + '$handle' => ['bluesky_handle', DI::l10n()->t('Bluesky handle'), $handle, '', '', $custom_handle ? 'readonly' : ''], + '$did' => ['bluesky_did', DI::l10n()->t('Bluesky DID'), $did, DI::l10n()->t('This is the unique identifier. It will be fetched automatically, when the handle is entered.'), '', 'readonly'], + '$password' => ['bluesky_password', DI::l10n()->t('Bluesky app password'), '', DI::l10n()->t("Please don't add your real password here, but instead create a specific app password in the Bluesky settings.")], + '$status' => bluesky_get_status($handle, $did, $pds, $token), ]); $data = [ @@ -446,6 +450,7 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false)); if (!empty($handle)) { @@ -534,15 +539,15 @@ function bluesky_cron() Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); bluesky_get_token($pconfig['uid']); - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid'], $last); + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid']); if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import')) { - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid'], $last); + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid']); } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { - Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed, $last); + Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed); } } Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]); @@ -710,7 +715,7 @@ function bluesky_create_activity(array $item, stdClass $parent = null) } $activity = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); - if (empty($activity)) { + if (empty($activity->uri)) { return; } Logger::debug('Activity done', ['return' => $activity]); @@ -794,7 +799,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren ]; $parent = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); - if (empty($parent)) { + if (empty($parent->uri)) { if ($part == 0) { Worker::defer(); } @@ -972,7 +977,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); $data = bluesky_post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); - if (empty($data)) { + if (empty($data) || empty($data->blob)) { Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; } @@ -993,7 +998,7 @@ function bluesky_delete_post(string $uri, int $uid) Logger::debug('Deleted', ['parts' => $parts]); } -function bluesky_fetch_timeline(int $uid, int $last_poll) +function bluesky_fetch_timeline(int $uid) { $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getTimeline'); if (empty($data)) { @@ -1004,15 +1009,44 @@ function bluesky_fetch_timeline(int $uid, int $last_poll) return; } + $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); + $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; + foreach (array_reverse($data->feed) as $entry) { + $causer = bluesky_get_contact($entry->post->author, 0, $uid); + if (!empty($entry->reply)) { + if (!empty($entry->reply->root)) { + bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], $last_poll); + } + if (!empty($entry->reply->parent)) { + bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], $last_poll); + } + } bluesky_process_post($entry->post, $uid, $uid, Item::PR_NONE, 0, 0, $last_poll); if (!empty($entry->reason)) { bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); } } +} - // @todo Support paging - // [cursor] => 1684670516000::bafyreidq3ilwslmlx72jf5vrk367xcc63s6lrhzlyup2bi3zwcvso6w2vi +function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $last_poll): int +{ + $complete = DI::pConfig()->get($uid, 'bluesky', 'complete_threads'); + $existing_uri = bluesky_fetch_post(bluesky_get_uri($post), $uid); + if (!empty($existing_uri)) { + $comments = Post::countPosts(['thr-parent' => $existing_uri, 'gravity' => Item::GRAVITY_COMMENT]); + if (($post->replyCount <= $comments) || !$complete) { + return bluesky_fetch_uri_id($existing_uri, $uid); + } + } + + if ($complete) { + $uri = bluesky_fetch_missing_post($post->uri, $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); + $uri_id = bluesky_fetch_uri_id($uri, $uid); + } else { + $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll); + } + return $uri_id; } function bluesky_process_reason(stdClass $reason, string $uri, int $uid) @@ -1056,12 +1090,16 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) } } -function bluesky_fetch_notifications(int $uid, int $last_poll) +function bluesky_fetch_notifications(int $uid) { $data = bluesky_xrpc_get($uid, 'app.bsky.notification.listNotifications'); if (empty($data->notifications)) { return; } + + $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); + $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; + foreach ($data->notifications as $notification) { $uri = bluesky_get_uri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { @@ -1071,7 +1109,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': - $item = bluesky_get_header($notification, $uri, $uid, $uid); + $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::LIKE; $item['thr-parent'] = bluesky_get_uri($notification->record->subject); @@ -1085,7 +1123,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) break; case 'repost': - $item = bluesky_get_header($notification, $uri, $uid, $uid); + $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::ANNOUNCE; $item['thr-parent'] = bluesky_get_uri($notification->record->subject); @@ -1128,7 +1166,7 @@ function bluesky_fetch_notifications(int $uid, int $last_poll) } } -function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) +function bluesky_fetch_feed(int $uid, string $feed) { $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeed', ['feed' => $feed]); if (empty($data)) { @@ -1139,8 +1177,11 @@ function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) return; } + $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); + $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; + $feeddata = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeedGenerator', ['feed' => $feed]); - if (!empty($feeddata)) { + if (!empty($feeddata) && !empty($feeddata->view)) { $feedurl = $feeddata->view->uri; $feedname = $feeddata->view->displayName; } else { @@ -1153,10 +1194,11 @@ function bluesky_fetch_feed(int $uid, string $feed, int $last_poll) $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { - Logger::debug('Unwanted language detected', ['text' => $entry->post->record->text]); + Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } - $uri_id = bluesky_process_post($entry->post, $uid, $uid, Item::PR_TAG, 0, 0, $last_poll); + $causer = bluesky_get_contact($entry->post->author, 0, $uid); + $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], $last_poll); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); @@ -1184,7 +1226,7 @@ function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $pos Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); - $item = bluesky_get_header($post, $uri, $uid, $fetch_uid); + $item = bluesky_get_header($post, $uri, $uid, $fetch_uid, $last_poll); $item = bluesky_get_content($item, $post->record, $uri, $uid, $fetch_uid, $level, $last_poll); if (empty($item)) { return 0; @@ -1208,7 +1250,7 @@ function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $pos return bluesky_fetch_uri_id($uri, $uid); } -function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid): array +function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid, int $last_poll = 0): array { $parts = bluesky_get_uri_parts($uri); if (empty($post->author) || empty($post->cid) || empty($parts->rkey)) { @@ -1221,6 +1263,7 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui 'wall' => false, 'uri' => $uri, 'guid' => $post->cid, + 'received' => DateTimeFormat::utc($post->indexedAt, DateTimeFormat::MYSQL), 'private' => Item::UNLISTED, 'verb' => Activity::POST, 'contact-id' => $contact['id'], @@ -1231,6 +1274,10 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui 'source' => json_encode($post), ]; + if (($last_poll != 0) && strtotime($item['received']) < $last_poll) { + unset($item['received']); + } + $account = Contact::selectFirstAccountUser(['pid'], ['id' => $contact['id']]); $item['author-id'] = $account['pid']; @@ -1329,10 +1376,6 @@ function bluesky_get_content(array $item, stdClass $record, string $uri, int $ui $item['created'] = DateTimeFormat::utc($record->createdAt, DateTimeFormat::MYSQL); $item['transmitted-languages'] = $record->langs ?? []; - if (($last_poll != 0) && strtotime($item['created']) > $last_poll) { - $item['received'] = $item['created']; - } - return $item; } @@ -1422,7 +1465,7 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le ]; Post\Media::insert($media); break; - + case 'app.bsky.embed.external#view': $media = [ 'uri-id' => $item['uri-id'], @@ -1522,10 +1565,10 @@ function bluesky_get_uri_parts(string $uri): ?stdClass return $class; } -function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = ''): string +function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = '', bool $always_fetch = false): string { $fetched_uri = bluesky_fetch_post($uri, $uid); - if (!empty($fetched_uri)) { + if (!$always_fetch && !empty($fetched_uri)) { return $fetched_uri; } @@ -1545,7 +1588,7 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ Logger::debug('Fetch missing post', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.feed.getPostThread', ['uri' => $fetch_uri]); - if (empty($data)) { + if (empty($data) || empty($data->thread)) { Logger::info('Thread was not fetched', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); return $fallback; } @@ -1556,9 +1599,31 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ $causer = Contact::getPublicContactId($causer, $uid); } + if (!empty($data->thread->parent)) { + $parents = bluesky_fetch_parents($data->thread->parent, $uid); + + foreach ($parents as $parent) { + $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll); + Logger::debug('Parent created', ['uri-id' => $uri_id]); + } + } + return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); } +function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): array +{ + if (!empty($parent->parent)) { + $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); + } + + if (empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { + $parents[] = $parent->post; + } + + return $parents; +} + function bluesky_fetch_post(string $uri, int $uid): string { if (Post::exists(['uri' => $uri, 'uid' => [$uid, 0]])) { @@ -1694,7 +1759,7 @@ function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, } $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); - if (!empty($data)) { + if (!empty($data)) { $fields['baseurl'] = bluesky_get_pds('', $data); if (!empty($fields['baseurl'])) { GServer::check($fields['baseurl'], Protocol::BLUESKY); @@ -1877,6 +1942,13 @@ function bluesky_get_did(string $handle, int $uid): string return $did; } + // The profile page can contain hints to the DID as well + $did = bluesky_get_did_by_profile('https://' . $handle); + if ($did != '') { + Logger::debug('Got DID by profile page', ['handle' => $handle, 'did' => $did]); + return $did; + } + // And finally we use the default PDS from Bluesky. $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); if (!empty($data) && !empty($data->did)) { @@ -1996,7 +2068,7 @@ function bluesky_refresh_token(int $uid): string $token = DI::pConfig()->get($uid, 'bluesky', 'refresh_token'); $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); - if (empty($data)) { + if (empty($data) || empty($data->accessJwt)) { return ''; } @@ -2015,7 +2087,7 @@ function bluesky_create_token(int $uid, string $password): string } $data = bluesky_post($uid, '/xrpc/com.atproto.server.createSession', json_encode(['identifier' => $did, 'password' => $password]), ['Content-type' => 'application/json']); - if (empty($data)) { + if (empty($data) || empty($data->accessJwt)) { DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); return ''; } @@ -2052,14 +2124,18 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s return null; } + $data = json_decode($curlResult->getBodyString()); if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; + Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); + if (!$data) { + DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); + return null; + } + $data->code = $curlResult->getReturnCode(); } DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); - return json_decode($curlResult->getBodyString()); + return $data; } function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass @@ -2073,7 +2149,14 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl return null; } - $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]]); + $headers = ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]; + + $languages = User::getWantedLanguages($uid); + if (!empty($languages)) { + $headers['Accept-Language'] = implode(',', $languages); + } + + $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); return $data; } @@ -2087,11 +2170,15 @@ function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEF return null; } + $data = json_decode($curlResult->getBodyString()); if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'error' => json_decode($curlResult->getBodyString()) ?: $curlResult->getBodyString()]); - return null; + Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); + if (!$data) { + return null; + } + $data->code = $curlResult->getReturnCode(); } Item::incrementInbound(Protocol::BLUESKY); - return json_decode($curlResult->getBodyString()); + return $data; } diff --git a/bluesky/bluesky_feed.php b/bluesky/bluesky_feed.php index c9a54223..a20ef1b9 100644 --- a/bluesky/bluesky_feed.php +++ b/bluesky/bluesky_feed.php @@ -6,11 +6,11 @@ function bluesky_feed_run($argv, $argc) { require_once 'addon/bluesky/bluesky.php'; - if ($argc != 4) { + if ($argc < 3) { return; } - Logger::debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2], 'last_poll' => $argv[3]]); - bluesky_fetch_feed($argv[1], $argv[2], $argv[3]); - Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2], 'last_poll' => $argv[3]]); + Logger::debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]); + bluesky_fetch_feed($argv[1], $argv[2]); + Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); } diff --git a/bluesky/bluesky_notifications.php b/bluesky/bluesky_notifications.php index ad35dfe0..1fbc8f67 100644 --- a/bluesky/bluesky_notifications.php +++ b/bluesky/bluesky_notifications.php @@ -6,11 +6,11 @@ function bluesky_notifications_run($argv, $argc) { require_once 'addon/bluesky/bluesky.php'; - if ($argc != 3) { + if ($argc < 2) { return; } - Logger::notice('importing notifications - start', ['user' => $argv[1], 'last_poll' => $argv[2]]); - bluesky_fetch_notifications($argv[1], $argv[2]); - Logger::notice('importing notifications - done', ['user' => $argv[1], 'last_poll' => $argv[2]]); + Logger::notice('importing notifications - start', ['user' => $argv[1]]); + bluesky_fetch_notifications($argv[1]); + Logger::notice('importing notifications - done', ['user' => $argv[1]]); } diff --git a/bluesky/bluesky_timeline.php b/bluesky/bluesky_timeline.php index 22ef2224..fda846ba 100644 --- a/bluesky/bluesky_timeline.php +++ b/bluesky/bluesky_timeline.php @@ -6,11 +6,11 @@ function bluesky_timeline_run($argv, $argc) { require_once 'addon/bluesky/bluesky.php'; - if ($argc != 3) { + if ($argc < 2) { return; } - Logger::notice('importing timeline - start', ['user' => $argv[1], 'last_poll' => $argv[2]]); - bluesky_fetch_timeline($argv[1], $argv[2]); - Logger::notice('importing timeline - done', ['user' => $argv[1], 'last_poll' => $argv[2]]); + Logger::notice('importing timeline - start', ['user' => $argv[1]]); + bluesky_fetch_timeline($argv[1]); + Logger::notice('importing timeline - done', ['user' => $argv[1]]); } diff --git a/bluesky/lang/C/messages.po b/bluesky/lang/C/messages.po index 9521ab89..d573972c 100644 --- a/bluesky/lang/C/messages.po +++ b/bluesky/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-22 05:31+0000\n" +"POT-Creation-Date: 2024-09-29 18:16+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,131 +17,117 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: bluesky.php:325 +#: bluesky.php:335 msgid "Save Settings" msgstr "" -#: bluesky.php:326 +#: bluesky.php:336 msgid "Allow your users to use your hostname for their Bluesky handles" msgstr "" -#: bluesky.php:326 +#: bluesky.php:336 #, php-format -msgid "" -"Before enabling this option, you have to setup a wildcard domain " -"configuration and you have to enable wildcard requests in your webserver " -"configuration. On Apache this is done by adding \"ServerAlias *.%s\" to your " -"HTTP configuration. You don't need to change the HTTPS configuration." +msgid "Before enabling this option, you have to setup a wildcard domain configuration and you have to enable wildcard requests in your webserver configuration. On Apache this is done by adding \"ServerAlias *.%s\" to your HTTP configuration. You don't need to change the HTTPS configuration." msgstr "" -#: bluesky.php:354 +#: bluesky.php:365 #, php-format msgid "Allow to use %s as your Bluesky handle." msgstr "" -#: bluesky.php:354 +#: bluesky.php:365 #, php-format -msgid "" -"When enabled, you can use %s as your Bluesky handle. After you enabled this " -"option, please go to https://bsky.app/settings and select to change your " -"handle. Select that you have got your own domain. Then enter %s and select " -"\"No DNS Panel\". Then select \"Verify Text File\"." -msgstr "" - -#: bluesky.php:361 -msgid "Enable Bluesky Post Addon" -msgstr "" - -#: bluesky.php:362 -msgid "Post to Bluesky by default" -msgstr "" - -#: bluesky.php:363 -msgid "Import the remote timeline" -msgstr "" - -#: bluesky.php:364 -msgid "Import the pinned feeds" -msgstr "" - -#: bluesky.php:364 -msgid "" -"When activated, Posts will be imported from all the feeds that you pinned in " -"Bluesky." -msgstr "" - -#: bluesky.php:366 -msgid "Personal Data Server" -msgstr "" - -#: bluesky.php:366 -msgid "The personal data server (PDS) is the system that hosts your profile." -msgstr "" - -#: bluesky.php:367 -msgid "Bluesky handle" -msgstr "" - -#: bluesky.php:368 -msgid "Bluesky DID" -msgstr "" - -#: bluesky.php:368 -msgid "" -"This is the unique identifier. It will be fetched automatically, when the " -"handle is entered." -msgstr "" - -#: bluesky.php:369 -msgid "Bluesky app password" -msgstr "" - -#: bluesky.php:369 -msgid "" -"Please don't add your real password here, but instead create a specific app " -"password in the Bluesky settings." +msgid "When enabled, you can use %s as your Bluesky handle. After you enabled this option, please go to https://bsky.app/settings and select to change your handle. Select that you have got your own domain. Then enter %s and select \"No DNS Panel\". Then select \"Verify Text File\"." msgstr "" #: bluesky.php:375 +msgid "Enable Bluesky Post Addon" +msgstr "" + +#: bluesky.php:376 +msgid "Post to Bluesky by default" +msgstr "" + +#: bluesky.php:377 +msgid "Import the remote timeline" +msgstr "" + +#: bluesky.php:378 +msgid "Import the pinned feeds" +msgstr "" + +#: bluesky.php:378 +msgid "When activated, Posts will be imported from all the feeds that you pinned in Bluesky." +msgstr "" + +#: bluesky.php:379 +msgid "Complete the threads" +msgstr "" + +#: bluesky.php:379 +msgid "When activated, the system fetches additional replies for the posts in the timeline. This leads to more complete threads." +msgstr "" + +#: bluesky.php:381 +msgid "Personal Data Server" +msgstr "" + +#: bluesky.php:381 +msgid "The personal data server (PDS) is the system that hosts your profile." +msgstr "" + +#: bluesky.php:382 +msgid "Bluesky handle" +msgstr "" + +#: bluesky.php:383 +msgid "Bluesky DID" +msgstr "" + +#: bluesky.php:383 +msgid "This is the unique identifier. It will be fetched automatically, when the handle is entered." +msgstr "" + +#: bluesky.php:384 +msgid "Bluesky app password" +msgstr "" + +#: bluesky.php:384 +msgid "Please don't add your real password here, but instead create a specific app password in the Bluesky settings." +msgstr "" + +#: bluesky.php:390 msgid "Bluesky Import/Export" msgstr "" -#: bluesky.php:385 -msgid "" -"You are not authenticated. Please enter your handle and the app password." +#: bluesky.php:400 +msgid "You are not authenticated. Please enter your handle and the app password." msgstr "" -#: bluesky.php:405 -msgid "" -"You are authenticated to Bluesky. For security reasons the password isn't " -"stored." +#: bluesky.php:420 +msgid "You are authenticated to Bluesky. For security reasons the password isn't stored." msgstr "" -#: bluesky.php:407 -msgid "" -"The communication with the personal data server service (PDS) is established." +#: bluesky.php:422 +msgid "The communication with the personal data server service (PDS) is established." msgstr "" -#: bluesky.php:409 +#: bluesky.php:424 msgid "Communication issues with the personal data server service (PDS)." msgstr "" -#: bluesky.php:411 -msgid "" -"The DID for the provided handle could not be detected. Please check if you " -"entered the correct handle." +#: bluesky.php:426 +msgid "The DID for the provided handle could not be detected. Please check if you entered the correct handle." msgstr "" -#: bluesky.php:413 +#: bluesky.php:428 msgid "The personal data server service (PDS) could not be detected." msgstr "" -#: bluesky.php:415 -msgid "" -"The authentication with the provided handle and password failed. Please " -"check if you entered the correct password." +#: bluesky.php:430 +msgid "The authentication with the provided handle and password failed. Please check if you entered the correct password." msgstr "" -#: bluesky.php:484 +#: bluesky.php:492 msgid "Post to Bluesky" msgstr "" diff --git a/bluesky/templates/connector_settings.tpl b/bluesky/templates/connector_settings.tpl index 3ebea827..a85bcd89 100644 --- a/bluesky/templates/connector_settings.tpl +++ b/bluesky/templates/connector_settings.tpl @@ -3,6 +3,7 @@ {{include file="field_checkbox.tpl" field=$bydefault}} {{include file="field_checkbox.tpl" field=$import}} {{include file="field_checkbox.tpl" field=$import_feeds}} +{{include file="field_checkbox.tpl" field=$complete_threads}} {{if $custom_handle}} {{include file="field_checkbox.tpl" field=$custom_handle}} {{/if}} From 08c17c9dd47388da281875c2def8d07d4a0085d6 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 19 Oct 2024 07:41:24 +0000 Subject: [PATCH 117/294] Bluesky: Fixes "E_WARNING: Undefined property: stdClass::$post" --- bluesky/bluesky.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 73b19612..95857b01 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1617,7 +1617,7 @@ function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); } - if (empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { + if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { $parents[] = $parent->post; } From 586ebe96993bcf8ee3be35c13b2475cb1d527287 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 23 Oct 2024 12:14:40 +0000 Subject: [PATCH 118/294] Bluesky: "block" now works / label names are now displayed --- bluesky/bluesky.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 95857b01..894b64d9 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -278,14 +278,12 @@ function bluesky_block(array &$hook_data) return; } - Logger::debug('Check if contact is bluesky', ['data' => $hook_data]); - $contact = DBA::selectFirst('contact', [], ['network' => Protocol::BLUESKY, 'url' => $hook_data['url'], 'uid' => [0, $hook_data['uid']]]); - if (empty($contact)) { + if ($hook_data['contact']['network'] != Protocol::BLUESKY) { return; } $record = [ - 'subject' => $contact['url'], + 'subject' => $hook_data['contact']['url'], 'createdAt' => DateTimeFormat::utcNow(DateTimeFormat::ATOM), '$type' => 'app.bsky.graph.block' ]; @@ -1297,6 +1295,7 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui // When "ver" is set to "1" it was flagged by some automated process. if (empty($label->ver)) { $item['sensitive'] = true; + $item['content-warning'] = $label->val ?? ''; Logger::debug('Sensitive content', ['uri-id' => $item['uri-id'], 'label' => $label]); } } From 8b694fbb4c6ee0a19fd7c3b30edca30d916523a9 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 27 Oct 2024 04:50:45 +0000 Subject: [PATCH 119/294] Bluesky: Fix following of a contact and adding a post --- bluesky/bluesky.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 894b64d9..45a56792 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -139,7 +139,7 @@ function bluesky_probe_detect(array &$hookData) return; } } elseif (Network::isValidHttpUrl($hookData['uri'])) { - $did = bluesky_get_did_by_profile($hookData['uri']); + $did = bluesky_get_did_by_profile($hookData['uri'], $pconfig['uid']); if (empty($did)) { return; } @@ -181,21 +181,21 @@ function bluesky_item_by_link(array &$hookData) return; } - $did = bluesky_get_did_by_profile($hookData['uri']); + if (!preg_match('#/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + return; + } + + $did = bluesky_get_did($matches[1], $hookData['uid']); if (empty($did)) { return; } - if (!preg_match('#/profile/.+/post/(.+)#', $hookData['uri'], $matches)) { - return; - } + Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[1]]); - - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[1]; + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); - Logger::debug('Got post', ['did' => $did, 'cid' => $matches[1], 'result' => $uri]); + Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -1831,8 +1831,14 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } -function bluesky_get_did_by_profile(string $url): string +function bluesky_get_did_by_profile(string $url, int $uid): string { + if (preg_match('#/profile/(.+)#', $url, $matches)) { + $did = bluesky_get_did($matches[1], $uid); + if (!empty($did)) { + return $did; + } + } try { $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); } catch (\Throwable $th) { @@ -1941,13 +1947,6 @@ function bluesky_get_did(string $handle, int $uid): string return $did; } - // The profile page can contain hints to the DID as well - $did = bluesky_get_did_by_profile('https://' . $handle); - if ($did != '') { - Logger::debug('Got DID by profile page', ['handle' => $handle, 'did' => $did]); - return $did; - } - // And finally we use the default PDS from Bluesky. $data = bluesky_get(BLUESKY_PDS . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); if (!empty($data) && !empty($data->did)) { From 4165479079faf4a8bb63d08574e0ff10cd4950ab Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 30 Oct 2024 05:11:50 +0000 Subject: [PATCH 120/294] Bluesky: Fix probe mistake --- bluesky/bluesky.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 45a56792..af7d9ac7 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -181,7 +181,7 @@ function bluesky_item_by_link(array &$hookData) return; } - if (!preg_match('#/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { return; } @@ -1833,7 +1833,7 @@ function bluesky_get_preferences(int $uid): ?stdClass function bluesky_get_did_by_profile(string $url, int $uid): string { - if (preg_match('#/profile/(.+)#', $url, $matches)) { + if (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $url, $matches)) { $did = bluesky_get_did($matches[1], $uid); if (!empty($did)) { return $did; From e89b5b1466811a28c28cd95bd81417735809018f Mon Sep 17 00:00:00 2001 From: Tobias Diekershoff Date: Wed, 13 Nov 2024 10:10:25 +0100 Subject: [PATCH 121/294] deprecate fancybox addon replaces #1562 --- fancybox/fancybox.php | 1 + 1 file changed, 1 insertion(+) diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 1a9ff634..73bbdab9 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -4,6 +4,7 @@ * Description: Open media attachments of posts into a fancybox overlay. * Version: 1.05 * Author: Grischa Brockhaus + * Status: Unsupported */ use Friendica\App; From 6a1cbe9040d13de472f4924f4fe44ee1e2524ffc Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 6 Nov 2024 17:45:30 +0000 Subject: [PATCH 122/294] Bluesky/Tumblr: Add "connector" parcel to each incoming post --- bluesky/bluesky.php | 7 +++++-- tumblr/tumblr.php | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index af7d9ac7..4882a263 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -38,6 +38,7 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\GServer; use Friendica\Model\Item; use Friendica\Model\ItemURI; @@ -1058,6 +1059,7 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) $item = [ 'network' => Protocol::BLUESKY, + 'protocol' => Conversation::PARCEL_CONNECTOR, 'uid' => $uid, 'wall' => false, 'uri' => $reason->by->did . '/app.bsky.feed.repost/' . $reason->indexedAt, @@ -1257,6 +1259,7 @@ function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_ui $contact = bluesky_get_contact($post->author, $uid, $fetch_uid); $item = [ 'network' => Protocol::BLUESKY, + 'protocol' => Conversation::PARCEL_CONNECTOR, 'uid' => $uid, 'wall' => false, 'uri' => $uri, @@ -1459,8 +1462,8 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le 'url' => $embed->playlist, 'preview' => $embed->thumbnail, 'description' => $embed->alt ?? '', - 'height' => $embed->aspectRatio->height, - 'width' => $embed->aspectRatio->width, + 'height' => $embed->aspectRatio->height ?? null, + 'width' => $embed->aspectRatio->width ?? null, ]; Post\Media::insert($media); break; diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index dd34bd41..390c3c6c 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -22,6 +22,7 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; +use Friendica\Model\Conversation; use Friendica\Model\Item; use Friendica\Model\Photo; use Friendica\Model\Post; @@ -31,7 +32,6 @@ use Friendica\Network\HTTPClient\Client\HttpClientAccept; use Friendica\Network\HTTPClient\Client\HttpClientOptions; use Friendica\Protocol\Activity; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Network; use Friendica\Util\Strings; use GuzzleHttp\Client; use GuzzleHttp\Exception\RequestException; @@ -850,6 +850,7 @@ function tumblr_get_header(stdClass $post, string $uri, int $uid): array $contact = tumblr_get_contact($post->blog, $uid); $item = [ 'network' => Protocol::TUMBLR, + 'protocol' => Conversation::PARCEL_CONNECTOR, 'uid' => $uid, 'wall' => false, 'uri' => $uri, From c22e0ae8310e80c83373f608ab4e5b21660c594d Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 16 Nov 2024 05:42:00 +0000 Subject: [PATCH 123/294] Fix handling of the 'private' field / reformatted code --- bluesky/bluesky.php | 32 +++++++++++++++++----------- diaspora/diaspora.php | 47 ++++++++++++++++++++--------------------- dwpost/dwpost.php | 29 ++++++++++++------------- ijpost/ijpost.php | 22 ++++++++----------- libertree/libertree.php | 47 ++++++++++++++++++----------------------- ljpost/ljpost.php | 41 +++++++++++++++++------------------ pnut/pnut.php | 17 ++++++--------- pumpio/pumpio.php | 8 +++---- statusnet/statusnet.php | 10 +++++---- tumblr/tumblr.php | 14 +++++------- twitter/twitter.php | 6 +++--- wppost/wppost.php | 19 +++++------------ 12 files changed, 135 insertions(+), 157 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 4882a263..d719eecb 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -587,13 +587,13 @@ function bluesky_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'bluesky', 'import')) { // Don't post if it isn't a reply to a bluesky post - if (($post['parent'] != $post['id']) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { + if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { Logger::notice('No bluesky parent found', ['item' => $post['id']]); $b['execute'] = false; return; } - } elseif (!strstr($post['postopts'] ?? '', 'bluesky') || ($post['parent'] != $post['id']) || $post['private']) { - DI::logger()->info('Activities are never exported when we don\'t import the bluesky timeline', ['uid' => $post['uid']]); + } elseif (!strstr($post['postopts'] ?? '', 'bluesky') || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { + DI::logger()->info('Post will not be exported', ['uid' => $post['uid'], 'postopts' => $post['postopts'], 'gravity' => $post['gravity'], 'private' => $post['private']]); $b['execute'] = false; return; } @@ -601,15 +601,11 @@ function bluesky_hook_fork(array &$b) function bluesky_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -667,7 +663,7 @@ function bluesky_send(array &$b) bluesky_create_activity($b, $parent); } return; - } elseif ($b['private'] || !strstr($b['postopts'], 'bluesky')) { + } elseif (($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'bluesky')) { return; } @@ -1481,6 +1477,18 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le case 'app.bsky.embed.record#view': $original_uri = $uri = bluesky_get_uri($embed->record); + $type = '$type'; + if (!empty($embed->record->record->$type)) { + $embed_type = $embed->record->record->$type; + if ($embed_type == 'app.bsky.graph.starterpack') { + Logger::debug('Starterpacks are not fetched like posts', ['original-uri' => $original_uri]); + if (empty($item['body'])) { + // @todo process starterpack + $item['body'] = '[url=' . $embed->record->record->list . ']' . $embed->record->record->name . '[/url]'; + } + break; + } + } $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); if ($uri) { $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); @@ -1603,13 +1611,13 @@ function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $ if (!empty($data->thread->parent)) { $parents = bluesky_fetch_parents($data->thread->parent, $uid); - + foreach ($parents as $parent) { $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll); Logger::debug('Parent created', ['uri-id' => $uri_id]); } } - + return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll); } @@ -1618,7 +1626,7 @@ function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): if (!empty($parent->parent)) { $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); } - + if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { $parents[] = $parent->post; } diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index cb2eb996..979204ba 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -17,6 +17,7 @@ use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Core\Worker; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; function diaspora_install() @@ -120,15 +121,15 @@ function diaspora_settings(array &$data) function diaspora_settings_post(array &$b) { if (!empty($_POST['diaspora-submit'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'post' , intval($_POST['enabled'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'post', intval($_POST['enabled'])); if (intval($_POST['enabled'])) { if (isset($_POST['handle'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'handle' , trim($_POST['handle'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'password' , trim($_POST['password'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'handle', trim($_POST['handle'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'password', trim($_POST['password'])); } if (!empty($_POST['aspect'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'aspect' , trim($_POST['aspect'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'diaspora', 'post_by_default', intval($_POST['post_by_default'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'aspect', trim($_POST['aspect'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'diaspora', 'post_by_default', intval($_POST['post_by_default'])); } } else { DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'diaspora', 'password'); @@ -144,8 +145,10 @@ function diaspora_hook_fork(array &$b) $post = $b['data']; - if ($post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || - !strstr($post['postopts'] ?? '', 'diaspora') || ($post['parent'] != $post['id'])) { + if ( + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || + !strstr($post['postopts'] ?? '', 'diaspora') || ($post['gravity'] != Item::GRAVITY_PARENT) + ) { $b['execute'] = false; return; } @@ -153,23 +156,19 @@ function diaspora_hook_fork(array &$b) function diaspora_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $diaspora_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'diaspora','post')); + $diaspora_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'diaspora', 'post')); $diaspora_enable = (($diaspora_post && !empty($_REQUEST['diaspora_enable'])) ? intval($_REQUEST['diaspora_enable']) : 0); - if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'diaspora','post_by_default'))) { + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'diaspora', 'post_by_default'))) { $diaspora_enable = 1; } @@ -190,11 +189,11 @@ function diaspora_send(array &$b) Logger::notice('diaspora_send: invoked'); - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } - if (!strstr($b['postopts'],'diaspora')) { + if (!strstr($b['postopts'], 'diaspora')) { return; } @@ -214,9 +213,9 @@ function diaspora_send(array &$b) Logger::info('diaspora_send: prepare posting'); - $handle = DI::pConfig()->get($b['uid'],'diaspora','handle'); - $password = DI::pConfig()->get($b['uid'],'diaspora','password'); - $aspect = DI::pConfig()->get($b['uid'],'diaspora','aspect'); + $handle = DI::pConfig()->get($b['uid'], 'diaspora', 'handle'); + $password = DI::pConfig()->get($b['uid'], 'diaspora', 'password'); + $aspect = DI::pConfig()->get($b['uid'], 'diaspora', 'aspect'); if ($handle && $password) { Logger::info('diaspora_send: all values seem to be okay'); @@ -230,7 +229,7 @@ function diaspora_send(array &$b) // Removal of tags and mentions // #-tags $body = preg_replace('/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$2', $body); - // @-mentions + // @-mentions $body = preg_replace('/@\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '@$2', $body); // remove multiple newlines @@ -244,7 +243,7 @@ function diaspora_send(array &$b) // Adding the title if (strlen($title)) { - $body = "## ".html_entity_decode($title)."\n\n".$body; + $body = "## " . html_entity_decode($title) . "\n\n" . $body; } require_once "addon/diaspora/diasphp.php"; @@ -252,9 +251,9 @@ function diaspora_send(array &$b) try { Logger::info('diaspora_send: prepare'); $conn = new Diaspora_Connection($handle, $password); - Logger::info('diaspora_send: try to log in '.$handle); + Logger::info('diaspora_send: try to log in ' . $handle); $conn->logIn(); - Logger::info('diaspora_send: try to send '.$body); + Logger::info('diaspora_send: try to send ' . $body); $conn->provider = $hostname; $conn->postStatusMessage($body, $aspect); @@ -263,7 +262,7 @@ function diaspora_send(array &$b) } catch (Exception $e) { Logger::notice("diaspora_send: Error submitting the post: " . $e->getMessage()); - Logger::info('diaspora_send: requeueing '.$b['uid']); + Logger::info('diaspora_send: requeueing ' . $b['uid']); Worker::defer(); } diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 4ad5021f..1ecd9764 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -14,6 +14,7 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; @@ -88,24 +89,20 @@ function dwpost_settings_post(array &$b) function dwpost_post_local(array &$b) { - // This can probably be changed to allow editing by pointing to a different API endpoint - if ($b['edit']) { - return; - } - if ((!DI::userSession()->getLocalUserId()) || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $dw_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'dwpost','post')); + $dw_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'dwpost', 'post')); $dw_enable = (($dw_post && !empty($_REQUEST['dwpost_enable'])) ? intval($_REQUEST['dwpost_enable']) : 0); - if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'dwpost','post_by_default'))) { + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'dwpost', 'post_by_default'))) { $dw_enable = 1; } @@ -122,7 +119,7 @@ function dwpost_post_local(array &$b) function dwpost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } @@ -145,8 +142,8 @@ function dwpost_send(array &$b) $user = User::getById($b['uid']); $tz = $user['timezone'] ?: 'UTC'; - $dw_username = DI::pConfig()->get($b['uid'],'dwpost','dw_username'); - $dw_password = DI::pConfig()->get($b['uid'],'dwpost','dw_password'); + $dw_username = DI::pConfig()->get($b['uid'], 'dwpost', 'dw_username'); + $dw_password = DI::pConfig()->get($b['uid'], 'dwpost', 'dw_password'); $dw_blog = 'http://www.dreamwidth.org/interface/xmlrpc'; if ($dw_username && $dw_password && $dw_blog) { @@ -156,11 +153,11 @@ function dwpost_send(array &$b) $tags = Tag::getCSVByURIId($b['uri-id'], [Tag::HASHTAG]); $date = DateTimeFormat::convert($b['created'], $tz); - $year = intval(substr($date,0,4)); - $mon = intval(substr($date,5,2)); - $day = intval(substr($date,8,2)); - $hour = intval(substr($date,11,2)); - $min = intval(substr($date,14,2)); + $year = intval(substr($date, 0, 4)); + $mon = intval(substr($date, 5, 2)); + $day = intval(substr($date, 8, 2)); + $hour = intval(substr($date, 11, 2)); + $min = intval(substr($date, 14, 2)); $xml = <<< EOT diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index 885bc289..f22dfff2 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -14,6 +14,7 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Tag; use Friendica\Model\User; use Friendica\Util\DateTimeFormat; @@ -85,17 +86,12 @@ function ijpost_settings_post(array &$b) function ijpost_post_local(array &$b) { - // This can probably be changed to allow editing by pointing to a different API endpoint - - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -120,7 +116,7 @@ function ijpost_post_local(array &$b) function ijpost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } @@ -150,11 +146,11 @@ function ijpost_send(array &$b) $tags = Tag::getCSVByURIId($b['uri-id'], [Tag::HASHTAG]); $date = DateTimeFormat::convert($b['created'], $tz); - $year = intval(substr($date,0,4)); - $mon = intval(substr($date,5,2)); - $day = intval(substr($date,8,2)); - $hour = intval(substr($date,11,2)); - $min = intval(substr($date,14,2)); + $year = intval(substr($date, 0, 4)); + $mon = intval(substr($date, 5, 2)); + $day = intval(substr($date, 8, 2)); + $hour = intval(substr($date, 11, 2)); + $min = intval(substr($date, 14, 2)); $xml = <<< EOT diff --git a/libertree/libertree.php b/libertree/libertree.php index f69c0aab..1d997123 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -13,6 +13,7 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; function libertree_install() @@ -74,13 +75,11 @@ function libertree_settings(array &$data) function libertree_settings_post(array &$b) { if (!empty($_POST['libertree-submit'])) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','post',intval($_POST['libertree'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','post_by_default',intval($_POST['libertree_bydefault'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','libertree_api_token',trim($_POST['libertree_api_token'])); - DI::pConfig()->set(DI::userSession()->getLocalUserId(),'libertree','libertree_url',trim($_POST['libertree_url'])); - + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'post', intval($_POST['libertree'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'post_by_default', intval($_POST['libertree_bydefault'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'libertree_api_token', trim($_POST['libertree_api_token'])); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'libertree', 'libertree_url', trim($_POST['libertree_url'])); } - } function libertree_hook_fork(array &$b) @@ -91,8 +90,10 @@ function libertree_hook_fork(array &$b) $post = $b['data']; - if ($post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || - !strstr($post['postopts'], 'libertree') || ($post['parent'] != $post['id'])) { + if ( + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || + !strstr($post['postopts'], 'libertree') || ($post['gravity'] != Item::GRAVITY_PARENT) + ) { $b['execute'] = false; return; } @@ -100,26 +101,20 @@ function libertree_hook_fork(array &$b) function libertree_post_local(array &$b) { - - // This can probably be changed to allow editing by pointing to a different API endpoint - - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $ltree_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'libertree','post')); + $ltree_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'libertree', 'post')); $ltree_enable = (($ltree_post && !empty($_REQUEST['libertree_enable'])) ? intval($_REQUEST['libertree_enable']) : 0); - if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'libertree','post_by_default'))) { + if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'libertree', 'post_by_default'))) { $ltree_enable = 1; } @@ -138,11 +133,11 @@ function libertree_send(array &$b) { Logger::notice('libertree_send: invoked'); - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } - if (! strstr($b['postopts'],'libertree')) { + if (! strstr($b['postopts'], 'libertree')) { return; } @@ -159,15 +154,15 @@ function libertree_send(array &$b) $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); - $ltree_api_token = DI::pConfig()->get($b['uid'],'libertree','libertree_api_token'); - $ltree_url = DI::pConfig()->get($b['uid'],'libertree','libertree_url'); + $ltree_api_token = DI::pConfig()->get($b['uid'], 'libertree', 'libertree_api_token'); + $ltree_url = DI::pConfig()->get($b['uid'], 'libertree', 'libertree_url'); $ltree_blog = "$ltree_url/api/v1/posts/create/?token=$ltree_api_token"; $ltree_source = DI::baseUrl()->getHost(); if ($b['app'] != "") - $ltree_source .= " (".$b['app'].")"; + $ltree_source .= " (" . $b['app'] . ")"; - if($ltree_url && $ltree_api_token && $ltree_blog && $ltree_source) { + if ($ltree_url && $ltree_api_token && $ltree_blog && $ltree_source) { $title = $b['title']; $body = $b['body']; // Insert a newline before and after a quote @@ -177,7 +172,7 @@ function libertree_send(array &$b) // Removal of tags and mentions // #-tags $body = preg_replace('/#\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '#$2', $body); - // @-mentions + // @-mentions $body = preg_replace('/@\[url\=(\w+.*?)\](\w+.*?)\[\/url\]/i', '@$2', $body); // remove multiple newlines @@ -198,7 +193,7 @@ function libertree_send(array &$b) $params = [ 'text' => $body, 'source' => $ltree_source - // 'token' => $ltree_api_token + // 'token' => $ltree_api_token ]; $result = DI::httpClient()->post($ltree_blog, $params)->getBodyString(); diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index fac44767..7acc6589 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -14,6 +14,7 @@ use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Tag; use Friendica\Model\User; @@ -35,7 +36,7 @@ function ljpost_jot_nets(array &$jotnets_fields) return; } - if (DI::pConfig()->get(DI::userSession()->getLocalUserId(),'ljpost','post')) { + if (DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post')) { $jotnets_fields[] = [ 'type' => 'checkbox', 'field' => [ @@ -57,7 +58,7 @@ function ljpost_settings(array &$data) $ij_username = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'ij_username'); $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post_by_default'); - $t= Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/ljpost/'); + $t = Renderer::getMarkupTemplate('connector_settings.tpl', 'addon/ljpost/'); $html = Renderer::replaceMacros($t, [ '$enabled' => ['ljpost', DI::l10n()->t('Enable LiveJournal Post Addon'), $enabled], '$username' => ['ij_username', DI::l10n()->t('LiveJournal username'), $ij_username], @@ -86,20 +87,16 @@ function ljpost_settings_post(array &$b) function ljpost_post_local(array &$b) { - // This can probably be changed to allow editing by pointing to a different API endpoint - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } - $lj_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(),'ljpost','post')); + $lj_post = intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post')); $lj_enable = (($lj_post && !empty($_REQUEST['ljpost_enable'])) ? intval($_REQUEST['ljpost_enable']) : 0); if ($b['api_source'] && intval(DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'ljpost', 'post_by_default'))) { @@ -118,11 +115,11 @@ function ljpost_post_local(array &$b) function ljpost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } - if (!strstr($b['postopts'],'ljpost')) { + if (!strstr($b['postopts'], 'ljpost')) { return; } @@ -139,13 +136,13 @@ function ljpost_send(array &$b) $user = User::getById($b['uid']); $tz = $user['timezone'] ?: 'UTC'; - $lj_username = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_username')); - $lj_password = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_password')); - $lj_journal = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_journal')); -// if(! $lj_journal) -// $lj_journal = $lj_username; + $lj_username = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_username')); + $lj_password = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_password')); + $lj_journal = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_journal')); + // if(! $lj_journal) + // $lj_journal = $lj_username; - $lj_blog = XML::escape(DI::pConfig()->get($b['uid'],'ljpost','lj_blog')); + $lj_blog = XML::escape(DI::pConfig()->get($b['uid'], 'ljpost', 'lj_blog')); if (!strlen($lj_blog)) { $lj_blog = XML::escape('http://www.livejournal.com/interface/xmlrpc'); } @@ -157,11 +154,11 @@ function ljpost_send(array &$b) $tags = Tag::getCSVByURIId($b['uri-id'], [Tag::HASHTAG]); $date = DateTimeFormat::convert($b['created'], $tz); - $year = intval(substr($date,0,4)); - $mon = intval(substr($date,5,2)); - $day = intval(substr($date,8,2)); - $hour = intval(substr($date,11,2)); - $min = intval(substr($date,14,2)); + $year = intval(substr($date, 0, 4)); + $mon = intval(substr($date, 5, 2)); + $day = intval(substr($date, 8, 2)); + $hour = intval(substr($date, 11, 2)); + $min = intval(substr($date, 14, 2)); $xml = <<< EOT diff --git a/pnut/pnut.php b/pnut/pnut.php index e84f208b..32f60f6d 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -18,6 +18,7 @@ use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; +use Friendica\Model\Item; use Friendica\Model\Photo; use phpnut\phpnutException; @@ -82,7 +83,7 @@ function pnut_connect() $o = DI::l10n()->t('Error fetching token. Please try again.', ['code' => $e->getCode(), 'message' => $e->getMessage()]); } - $o .= '
' . DI::l10n()->t("return to the connector page").''; + $o .= '
' . DI::l10n()->t("return to the connector page") . ''; return $o; } @@ -119,14 +120,14 @@ function pnut_settings(array &$data) } $redirectUri = DI::baseUrl() . '/pnut/connect'; - $scope = ['write_post','files']; + $scope = ['write_post', 'files']; $enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post') ?? false; $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'post_by_default') ?? false; $client_id = DI::config()->get('pnut', 'client_id'); $client_secret = DI::config()->get('pnut', 'client_secret'); $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'access_token'); - + $user_client = empty($client_id) || empty($client_secret); if ($user_client) { $client_id = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pnut', 'client_id'); @@ -221,7 +222,7 @@ function pnut_hook_fork(array &$b) return; } - if (!strstr($post['postopts'] ?? '', 'pnut') || ($post['parent'] != $post['id']) || $post['private']) { + if (!strstr($post['postopts'] ?? '', 'pnut') || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { $b['execute'] = false; return; } @@ -229,15 +230,11 @@ function pnut_hook_fork(array &$b) function pnut_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -265,7 +262,7 @@ function pnut_post_hook(array &$b) /** * Post to pnut.io */ - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index 6600696e..2a8a530e 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -345,14 +345,14 @@ function pumpio_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'pumpio', 'import')) { // Don't fork if it isn't a reply to a pump.io post - if (($post['parent'] != $post['id']) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { + if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { Logger::notice('No pump.io parent found for item ' . $post['id']); $b['execute'] = false; return; } } else { // Comments are never exported when we don't import the pumpio timeline - if (!strstr($post['postopts'], 'pumpio') || ($post['parent'] != $post['id']) || $post['private']) { + if (!strstr($post['postopts'], 'pumpio') || ($post['gravity'] != Item::GRAVITY_PARENT)|| ($post['private'] == Item::PRIVATE)) { $b['execute'] = false; return; } @@ -412,7 +412,7 @@ function pumpio_send(array &$b) Logger::notice('pumpio_send: receiver ', $receiver); - if (!count($receiver) && ($b['private'] || !strstr($b['postopts'], 'pumpio'))) { + if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio'))) { return; } @@ -1319,7 +1319,7 @@ function pumpio_getreceiver(array $b) { $receiver = []; - if (!$b['private']) { + if ($b['private'] != Item::PRIVATE)) { if (!strstr($b['postopts'], 'pumpio')) { return $receiver; } diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index f0372852..4bc32050 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -296,7 +296,7 @@ function statusnet_hook_fork(array &$b) $post = $b['data']; - if ($post['deleted'] || ($post['created'] !== $post['edited']) || strpos($post['postopts'] ?? '', 'statusnet') === false || ($post['parent'] != $post['id']) || $post['private']) { + if ($post['deleted'] || ($post['created'] !== $post['edited']) || strpos($post['postopts'] ?? '', 'statusnet') === false || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { $b['execute'] = false; return; } @@ -336,7 +336,7 @@ function statusnet_post_hook(array &$b) /** * Post to GNU Social */ - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } @@ -439,11 +439,13 @@ function statusnet_addon_admin_post() $secret = trim($_POST['secret'][$id]); $key = trim($_POST['key'][$id]); //$applicationname = (!empty($_POST['applicationname']) ? Strings::escapeTags(trim($_POST['applicationname'][$id])):''); - if ($sitename != '' && + if ( + $sitename != '' && $apiurl != '' && $secret != '' && $key != '' && - empty($_POST['delete'][$id])) { + empty($_POST['delete'][$id]) + ) { $sites[] = [ 'sitename' => $sitename, diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 390c3c6c..1e9f5c7f 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -477,13 +477,13 @@ function tumblr_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'tumblr', 'import')) { // Don't post if it isn't a reply to a tumblr post - if (($post['parent'] != $post['id']) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { + if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { Logger::notice('No tumblr parent found', ['item' => $post['id']]); $b['execute'] = false; return; } - } elseif (!strstr($post['postopts'] ?? '', 'tumblr') || ($post['parent'] != $post['id']) || $post['private']) { - DI::logger()->info('Activities are never exported when we don\'t import the tumblr timeline', ['uid' => $post['uid']]); + } elseif (!strstr($post['postopts'] ?? '', 'tumblr') || ($post['gravity'] != Item::GRAVITY_PARENT) || ($post['private'] == Item::PRIVATE)) { + DI::logger()->info('Post will not be exported', ['uid' => $post['uid'], 'postopts' => $post['postopts'], 'gravity' => $post['gravity'], 'private' => $post['private']]); $b['execute'] = false; return; } @@ -491,15 +491,11 @@ function tumblr_hook_fork(array &$b) function tumblr_post_local(array &$b) { - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -575,7 +571,7 @@ function tumblr_send(array &$b) } } return; - } elseif ($b['private'] || !strstr($b['postopts'], 'tumblr')) { + } elseif (($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'tumblr')) { return; } diff --git a/twitter/twitter.php b/twitter/twitter.php index 11c163ef..10f8a2fb 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -170,7 +170,7 @@ function twitter_hook_fork(array &$b) $post = $b['data']; if ( - $post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || !strstr($post['postopts'], 'twitter') || ($post['gravity'] != Item::GRAVITY_PARENT) ) { $b['execute'] = false; @@ -184,7 +184,7 @@ function twitter_post_local(array &$b) return; } - if ($b['edit'] || $b['private'] || $b['parent']) { + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -211,7 +211,7 @@ function twitter_post_hook(array &$b) { DI::logger()->debug('Invoke post hook', $b); - if (($b['gravity'] != Item::GRAVITY_PARENT) || !strstr($b['postopts'], 'twitter') || $b['private'] || $b['deleted'] || ($b['created'] !== $b['edited'])) { + if (($b['gravity'] != Item::GRAVITY_PARENT) || !strstr($b['postopts'], 'twitter') || ($b['private'] == Item::PRIVATE) || $b['deleted'] || ($b['created'] !== $b['edited'])) { return; } diff --git a/wppost/wppost.php b/wppost/wppost.php index e27079aa..dba738de 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -108,8 +108,8 @@ function wppost_hook_fork(array &$b) $post = $b['data']; if ( - $post['deleted'] || $post['private'] || ($post['created'] !== $post['edited']) || - !strstr($post['postopts'] ?? '', 'wppost') || ($post['parent'] != $post['id']) + $post['deleted'] || ($post['private'] == Item::PRIVATE) || ($post['created'] !== $post['edited']) || + !strstr($post['postopts'] ?? '', 'wppost') || ($post['gravity'] != Item::GRAVITY_PARENT) ) { $b['execute'] = false; return; @@ -118,18 +118,12 @@ function wppost_hook_fork(array &$b) function wppost_post_local(array &$b) { - - // This can probably be changed to allow editing by pointing to a different API endpoint - - if ($b['edit']) { - return; - } - if (!DI::userSession()->getLocalUserId() || (DI::userSession()->getLocalUserId() != $b['uid'])) { return; } - if ($b['private'] || $b['parent']) { + // This can probably be changed to allow editing by pointing to a different API endpoint + if ($b['edit'] || ($b['private'] == Item::PRIVATE) || ($b['gravity'] != Item::GRAVITY_PARENT)) { return; } @@ -152,12 +146,9 @@ function wppost_post_local(array &$b) $b['postopts'] .= 'wppost'; } - - - function wppost_send(array &$b) { - if ($b['deleted'] || $b['private'] || ($b['created'] !== $b['edited'])) { + if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; } From aa5130247b27093fbca5fa1126b857c83446eb14 Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sat, 16 Nov 2024 21:19:06 -0500 Subject: [PATCH 124/294] [pumpio] Remove two superfluous parentheses - Thanks to @SteffenK9 for the report! --- pumpio/pumpio.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index 2a8a530e..5e053d7c 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -412,7 +412,7 @@ function pumpio_send(array &$b) Logger::notice('pumpio_send: receiver ', $receiver); - if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio'))) { + if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio')) { return; } @@ -1319,7 +1319,7 @@ function pumpio_getreceiver(array $b) { $receiver = []; - if ($b['private'] != Item::PRIVATE)) { + if ($b['private'] != Item::PRIVATE) { if (!strstr($b['postopts'], 'pumpio')) { return $receiver; } From a0c727ac35d3dadb3be077527af97612656c674f Mon Sep 17 00:00:00 2001 From: Hypolite Petovan Date: Sun, 17 Nov 2024 13:23:16 +0000 Subject: [PATCH 125/294] [advancedcontentfilter] Remove unused vendor files Thanks to @Art4 for the initial submission in https://github.com/friendica/friendica-addons/pull/1363 --- advancedcontentfilter/vendor/autoload.php | 18 + .../vendor/composer/ClassLoader.php | 202 +- .../vendor/composer/InstalledVersions.php | 359 +++ .../vendor/composer/autoload_classmap.php | 6 +- .../vendor/composer/autoload_files.php | 2 +- .../vendor/composer/autoload_namespaces.php | 2 +- .../vendor/composer/autoload_psr4.php | 4 +- .../vendor/composer/autoload_real.php | 53 +- .../vendor/composer/autoload_static.php | 8 +- .../vendor/composer/installed.json | 2354 +++++++++-------- .../vendor/composer/installed.php | 203 ++ .../vendor/composer/platform_check.php | 26 + .../vendor/psr/simple-cache/.editorconfig | 12 - .../vendor/psr/simple-cache/LICENSE.md | 21 - .../vendor/psr/simple-cache/README.md | 8 - .../vendor/psr/simple-cache/composer.json | 25 - .../psr/simple-cache/src/CacheException.php | 10 - .../psr/simple-cache/src/CacheInterface.php | 114 - .../src/InvalidArgumentException.php | 13 - .../vendor/symfony/cache/.gitignore | 3 - .../Adapter/AbstractRedisAdapterTest.php | 47 - .../cache/Tests/Adapter/AdapterTestCase.php | 175 -- .../cache/Tests/Adapter/ApcuAdapterTest.php | 124 - .../cache/Tests/Adapter/ArrayAdapterTest.php | 56 - .../cache/Tests/Adapter/ChainAdapterTest.php | 233 -- .../Tests/Adapter/DoctrineAdapterTest.php | 32 - .../Tests/Adapter/FilesystemAdapterTest.php | 61 - .../Tests/Adapter/MaxIdLengthAdapterTest.php | 87 - .../Tests/Adapter/MemcachedAdapterTest.php | 204 -- .../Adapter/NamespacedProxyAdapterTest.php | 26 - .../cache/Tests/Adapter/NullAdapterTest.php | 128 - .../cache/Tests/Adapter/PdoAdapterTest.php | 73 - .../Tests/Adapter/PdoDbalAdapterTest.php | 48 - .../Tests/Adapter/PhpArrayAdapterTest.php | 135 - .../PhpArrayAdapterWithFallbackTest.php | 51 - .../Tests/Adapter/PhpFilesAdapterTest.php | 47 - .../cache/Tests/Adapter/PredisAdapterTest.php | 53 - .../Adapter/PredisClusterAdapterTest.php | 26 - .../Adapter/PredisRedisClusterAdapterTest.php | 28 - .../cache/Tests/Adapter/ProxyAdapterTest.php | 69 - .../cache/Tests/Adapter/RedisAdapterTest.php | 92 - .../Tests/Adapter/RedisArrayAdapterTest.php | 24 - .../Tests/Adapter/RedisClusterAdapterTest.php | 27 - .../Tests/Adapter/SimpleCacheAdapterTest.php | 41 - .../Tests/Adapter/TagAwareAdapterTest.php | 338 --- ...TagAwareAndProxyAdapterIntegrationTest.php | 38 - .../Tests/Adapter/TraceableAdapterTest.php | 191 -- .../Adapter/TraceableTagAwareAdapterTest.php | 37 - .../symfony/cache/Tests/CacheItemTest.php | 77 - .../cache/Tests/DoctrineProviderTest.php | 45 - .../cache/Tests/Fixtures/ArrayCache.php | 52 - .../cache/Tests/Fixtures/ExternalAdapter.php | 76 - .../Tests/Simple/AbstractRedisCacheTest.php | 47 - .../cache/Tests/Simple/ApcuCacheTest.php | 35 - .../cache/Tests/Simple/ArrayCacheTest.php | 25 - .../cache/Tests/Simple/CacheTestCase.php | 150 -- .../cache/Tests/Simple/ChainCacheTest.php | 113 - .../cache/Tests/Simple/DoctrineCacheTest.php | 31 - .../Tests/Simple/FilesystemCacheTest.php | 34 - .../cache/Tests/Simple/MemcachedCacheTest.php | 178 -- .../Simple/MemcachedCacheTextModeTest.php | 25 - .../cache/Tests/Simple/NullCacheTest.php | 96 - .../cache/Tests/Simple/PdoCacheTest.php | 47 - .../cache/Tests/Simple/PdoDbalCacheTest.php | 48 - .../cache/Tests/Simple/PhpArrayCacheTest.php | 145 - .../Simple/PhpArrayCacheWithFallbackTest.php | 57 - .../cache/Tests/Simple/PhpFilesCacheTest.php | 42 - .../cache/Tests/Simple/Psr6CacheTest.php | 30 - .../Tests/Simple/RedisArrayCacheTest.php | 24 - .../cache/Tests/Simple/RedisCacheTest.php | 82 - .../Tests/Simple/RedisClusterCacheTest.php | 27 - .../cache/Tests/Simple/TraceableCacheTest.php | 171 -- .../cache/Tests/Traits/PdoPruneableTrait.php | 34 - .../vendor/symfony/cache/phpunit.xml.dist | 50 - .../vendor/symfony/polyfill-apcu/Apcu.php | 106 - .../vendor/symfony/polyfill-apcu/LICENSE | 19 - .../vendor/symfony/polyfill-apcu/README.md | 12 - .../symfony/polyfill-apcu/bootstrap.php | 83 - .../symfony/polyfill-apcu/bootstrap80.php | 75 - .../symfony/polyfill-apcu/composer.json | 35 - 80 files changed, 1986 insertions(+), 6019 deletions(-) create mode 100644 advancedcontentfilter/vendor/composer/InstalledVersions.php create mode 100644 advancedcontentfilter/vendor/composer/installed.php create mode 100644 advancedcontentfilter/vendor/composer/platform_check.php delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/.editorconfig delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/README.md delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/composer.json delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/src/CacheInterface.php delete mode 100644 advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/.gitignore delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AbstractRedisAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php delete mode 100644 advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php delete mode 100644 advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json diff --git a/advancedcontentfilter/vendor/autoload.php b/advancedcontentfilter/vendor/autoload.php index 3e6193fa..2d273a02 100644 --- a/advancedcontentfilter/vendor/autoload.php +++ b/advancedcontentfilter/vendor/autoload.php @@ -2,6 +2,24 @@ // autoload.php @generated by Composer +if (PHP_VERSION_ID < 50600) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + $err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL; + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, $err); + } elseif (!headers_sent()) { + echo $err; + } + } + trigger_error( + $err, + E_USER_ERROR + ); +} + require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitAdvancedContentFilterAddon::getLoader(); diff --git a/advancedcontentfilter/vendor/composer/ClassLoader.php b/advancedcontentfilter/vendor/composer/ClassLoader.php index 03b9bb9c..7824d8f7 100644 --- a/advancedcontentfilter/vendor/composer/ClassLoader.php +++ b/advancedcontentfilter/vendor/composer/ClassLoader.php @@ -37,26 +37,81 @@ namespace Composer\Autoload; * * @author Fabien Potencier * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ */ class ClassLoader { + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + // PSR-4 + /** + * @var array> + */ private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ private $prefixDirsPsr4 = array(); + /** + * @var list + */ private $fallbackDirsPsr4 = array(); // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ private $prefixesPsr0 = array(); + /** + * @var list + */ private $fallbackDirsPsr0 = array(); + /** @var bool */ private $useIncludePath = false; + + /** + * @var array + */ private $classMap = array(); + + /** @var bool */ private $classMapAuthoritative = false; + + /** + * @var array + */ private $missingClasses = array(); + + /** @var string|null */ private $apcuPrefix; + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ public function getPrefixes() { if (!empty($this->prefixesPsr0)) { @@ -66,28 +121,42 @@ class ClassLoader return array(); } + /** + * @return array> + */ public function getPrefixesPsr4() { return $this->prefixDirsPsr4; } + /** + * @return list + */ public function getFallbackDirs() { return $this->fallbackDirsPsr0; } + /** + * @return list + */ public function getFallbackDirsPsr4() { return $this->fallbackDirsPsr4; } + /** + * @return array Array of classname => path + */ public function getClassMap() { return $this->classMap; } /** - * @param array $classMap Class to filename map + * @param array $classMap Class to filename map + * + * @return void */ public function addClassMap(array $classMap) { @@ -102,22 +171,25 @@ class ClassLoader * 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 + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void */ public function add($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { if ($prepend) { $this->fallbackDirsPsr0 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr0 ); } else { $this->fallbackDirsPsr0 = array_merge( $this->fallbackDirsPsr0, - (array) $paths + $paths ); } @@ -126,19 +198,19 @@ class ClassLoader $first = $prefix[0]; if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; + $this->prefixesPsr0[$first][$prefix] = $paths; return; } if ($prepend) { $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixesPsr0[$first][$prefix] ); } else { $this->prefixesPsr0[$first][$prefix] = array_merge( $this->prefixesPsr0[$first][$prefix], - (array) $paths + $paths ); } } @@ -147,25 +219,28 @@ class ClassLoader * 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 + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories * * @throws \InvalidArgumentException + * + * @return void */ public function addPsr4($prefix, $paths, $prepend = false) { + $paths = (array) $paths; if (!$prefix) { // Register directories for the root namespace. if ($prepend) { $this->fallbackDirsPsr4 = array_merge( - (array) $paths, + $paths, $this->fallbackDirsPsr4 ); } else { $this->fallbackDirsPsr4 = array_merge( $this->fallbackDirsPsr4, - (array) $paths + $paths ); } } elseif (!isset($this->prefixDirsPsr4[$prefix])) { @@ -175,18 +250,18 @@ class ClassLoader 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; + $this->prefixDirsPsr4[$prefix] = $paths; } elseif ($prepend) { // Prepend directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, + $paths, $this->prefixDirsPsr4[$prefix] ); } else { // Append directories for an already registered namespace. $this->prefixDirsPsr4[$prefix] = array_merge( $this->prefixDirsPsr4[$prefix], - (array) $paths + $paths ); } } @@ -195,8 +270,10 @@ class ClassLoader * 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 + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void */ public function set($prefix, $paths) { @@ -211,10 +288,12 @@ class ClassLoader * 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 + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories * * @throws \InvalidArgumentException + * + * @return void */ public function setPsr4($prefix, $paths) { @@ -234,6 +313,8 @@ class ClassLoader * Turns on searching the include path for class files. * * @param bool $useIncludePath + * + * @return void */ public function setUseIncludePath($useIncludePath) { @@ -256,6 +337,8 @@ class ClassLoader * that have not been registered with the class map. * * @param bool $classMapAuthoritative + * + * @return void */ public function setClassMapAuthoritative($classMapAuthoritative) { @@ -276,6 +359,8 @@ class ClassLoader * APCu prefix to use to cache found/not-found classes, if the extension is enabled. * * @param string|null $apcuPrefix + * + * @return void */ public function setApcuPrefix($apcuPrefix) { @@ -296,33 +381,55 @@ class ClassLoader * Registers this instance as an autoloader. * * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void */ 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. + * + * @return void */ 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 + * @return true|null True if loaded, null otherwise */ public function loadClass($class) { if ($file = $this->findFile($class)) { - includeFile($file); + $includeFile = self::$includeFile; + $includeFile($file); return true; } + + return null; } /** @@ -367,6 +474,21 @@ class ClassLoader return $file; } + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ private function findFileWithExtension($class, $ext) { // PSR-4 lookup @@ -432,14 +554,26 @@ class ClassLoader return false; } -} -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } } diff --git a/advancedcontentfilter/vendor/composer/InstalledVersions.php b/advancedcontentfilter/vendor/composer/InstalledVersions.php new file mode 100644 index 00000000..51e734a7 --- /dev/null +++ b/advancedcontentfilter/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + 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))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + 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'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + 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'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + 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'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + 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'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + 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')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/advancedcontentfilter/vendor/composer/autoload_classmap.php b/advancedcontentfilter/vendor/composer/autoload_classmap.php index 9f79be5c..fe2a622a 100644 --- a/advancedcontentfilter/vendor/composer/autoload_classmap.php +++ b/advancedcontentfilter/vendor/composer/autoload_classmap.php @@ -2,11 +2,12 @@ // autoload_classmap.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'FastRoute\\BadRouteException' => $vendorDir . '/nikic/fast-route/src/BadRouteException.php', 'FastRoute\\DataGenerator' => $vendorDir . '/nikic/fast-route/src/DataGenerator.php', 'FastRoute\\DataGenerator\\CharCountBased' => $vendorDir . '/nikic/fast-route/src/DataGenerator/CharCountBased.php', @@ -154,7 +155,6 @@ return array( 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => $vendorDir . '/symfony/cache/Adapter/TagAwareAdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableAdapter.php', - 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapterEvent' => $vendorDir . '/symfony/cache/Adapter/TraceableAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => $vendorDir . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php', 'Symfony\\Component\\Cache\\CacheItem' => $vendorDir . '/symfony/cache/CacheItem.php', 'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => $vendorDir . '/symfony/cache/DataCollector/CacheDataCollector.php', @@ -188,7 +188,6 @@ return array( 'Symfony\\Component\\Cache\\Simple\\Psr6Cache' => $vendorDir . '/symfony/cache/Simple/Psr6Cache.php', 'Symfony\\Component\\Cache\\Simple\\RedisCache' => $vendorDir . '/symfony/cache/Simple/RedisCache.php', 'Symfony\\Component\\Cache\\Simple\\TraceableCache' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php', - 'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => $vendorDir . '/symfony/cache/Simple/TraceableCache.php', 'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => $vendorDir . '/symfony/cache/Traits/AbstractAdapterTrait.php', 'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => $vendorDir . '/symfony/cache/Traits/AbstractTrait.php', 'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => $vendorDir . '/symfony/cache/Traits/ApcuTrait.php', @@ -197,7 +196,6 @@ return array( 'Symfony\\Component\\Cache\\Traits\\DoctrineTrait' => $vendorDir . '/symfony/cache/Traits/DoctrineTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemCommonTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemTrait.php', - 'Symfony\\Component\\Cache\\Traits\\LazyValue' => $vendorDir . '/symfony/cache/Traits/PhpFilesTrait.php', 'Symfony\\Component\\Cache\\Traits\\MemcachedTrait' => $vendorDir . '/symfony/cache/Traits/MemcachedTrait.php', 'Symfony\\Component\\Cache\\Traits\\PdoTrait' => $vendorDir . '/symfony/cache/Traits/PdoTrait.php', 'Symfony\\Component\\Cache\\Traits\\PhpArrayTrait' => $vendorDir . '/symfony/cache/Traits/PhpArrayTrait.php', diff --git a/advancedcontentfilter/vendor/composer/autoload_files.php b/advancedcontentfilter/vendor/composer/autoload_files.php index a5d3b964..aafd69e1 100644 --- a/advancedcontentfilter/vendor/composer/autoload_files.php +++ b/advancedcontentfilter/vendor/composer/autoload_files.php @@ -2,7 +2,7 @@ // autoload_files.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/advancedcontentfilter/vendor/composer/autoload_namespaces.php b/advancedcontentfilter/vendor/composer/autoload_namespaces.php index b7fc0125..15a2ff3a 100644 --- a/advancedcontentfilter/vendor/composer/autoload_namespaces.php +++ b/advancedcontentfilter/vendor/composer/autoload_namespaces.php @@ -2,7 +2,7 @@ // autoload_namespaces.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( diff --git a/advancedcontentfilter/vendor/composer/autoload_psr4.php b/advancedcontentfilter/vendor/composer/autoload_psr4.php index 3d716d56..4bf247ce 100644 --- a/advancedcontentfilter/vendor/composer/autoload_psr4.php +++ b/advancedcontentfilter/vendor/composer/autoload_psr4.php @@ -2,7 +2,7 @@ // autoload_psr4.php @generated by Composer -$vendorDir = dirname(dirname(__FILE__)); +$vendorDir = dirname(__DIR__); $baseDir = dirname($vendorDir); return array( @@ -16,7 +16,7 @@ return array( 'Slim\\' => array($vendorDir . '/slim/slim/Slim'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'Psr\\Http\\Server\\' => array($vendorDir . '/psr/http-server-handler/src', $vendorDir . '/psr/http-server-middleware/src'), - 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), + 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src', $vendorDir . '/psr/http-factory/src'), 'Psr\\Container\\' => array($vendorDir . '/psr/container/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'FastRoute\\' => array($vendorDir . '/nikic/fast-route/src'), diff --git a/advancedcontentfilter/vendor/composer/autoload_real.php b/advancedcontentfilter/vendor/composer/autoload_real.php index d6532d7d..b305aa00 100644 --- a/advancedcontentfilter/vendor/composer/autoload_real.php +++ b/advancedcontentfilter/vendor/composer/autoload_real.php @@ -22,52 +22,29 @@ class ComposerAutoloaderInitAdvancedContentFilterAddon return self::$loader; } + require __DIR__ . '/platform_check.php'; + spl_autoload_register(array('ComposerAutoloaderInitAdvancedContentFilterAddon', 'loadClassLoader'), true, true); - self::$loader = $loader = new \Composer\Autoload\ClassLoader(); + self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__)); spl_autoload_unregister(array('ComposerAutoloaderInitAdvancedContentFilterAddon', 'loadClassLoader')); - $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); - if ($useStaticLoader) { - require_once __DIR__ . '/autoload_static.php'; - - call_user_func(\Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::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); - } - } + require __DIR__ . '/autoload_static.php'; + call_user_func(\Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::getInitializer($loader)); $loader->register(true); - if ($useStaticLoader) { - $includeFiles = Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::$files; - } else { - $includeFiles = require __DIR__ . '/autoload_files.php'; - } - foreach ($includeFiles as $fileIdentifier => $file) { - composerRequireAdvancedContentFilterAddon($fileIdentifier, $file); + $filesToLoad = \Composer\Autoload\ComposerStaticInitAdvancedContentFilterAddon::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); } return $loader; } } - -function composerRequireAdvancedContentFilterAddon($fileIdentifier, $file) -{ - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - require $file; - - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - } -} diff --git a/advancedcontentfilter/vendor/composer/autoload_static.php b/advancedcontentfilter/vendor/composer/autoload_static.php index 57172a1a..8cc48b1a 100644 --- a/advancedcontentfilter/vendor/composer/autoload_static.php +++ b/advancedcontentfilter/vendor/composer/autoload_static.php @@ -83,8 +83,8 @@ class ComposerStaticInitAdvancedContentFilterAddon ), 'Psr\\Http\\Message\\' => array ( - 0 => __DIR__ . '/..' . '/psr/http-factory/src', - 1 => __DIR__ . '/..' . '/psr/http-message/src', + 0 => __DIR__ . '/..' . '/psr/http-message/src', + 1 => __DIR__ . '/..' . '/psr/http-factory/src', ), 'Psr\\Container\\' => array ( @@ -102,6 +102,7 @@ class ComposerStaticInitAdvancedContentFilterAddon public static $classMap = array ( 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'FastRoute\\BadRouteException' => __DIR__ . '/..' . '/nikic/fast-route/src/BadRouteException.php', 'FastRoute\\DataGenerator' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator.php', 'FastRoute\\DataGenerator\\CharCountBased' => __DIR__ . '/..' . '/nikic/fast-route/src/DataGenerator/CharCountBased.php', @@ -249,7 +250,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface' => __DIR__ . '/..' . '/symfony/cache/Adapter/TagAwareAdapterInterface.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableAdapter.php', - 'Symfony\\Component\\Cache\\Adapter\\TraceableAdapterEvent' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableAdapter.php', 'Symfony\\Component\\Cache\\Adapter\\TraceableTagAwareAdapter' => __DIR__ . '/..' . '/symfony/cache/Adapter/TraceableTagAwareAdapter.php', 'Symfony\\Component\\Cache\\CacheItem' => __DIR__ . '/..' . '/symfony/cache/CacheItem.php', 'Symfony\\Component\\Cache\\DataCollector\\CacheDataCollector' => __DIR__ . '/..' . '/symfony/cache/DataCollector/CacheDataCollector.php', @@ -283,7 +283,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Symfony\\Component\\Cache\\Simple\\Psr6Cache' => __DIR__ . '/..' . '/symfony/cache/Simple/Psr6Cache.php', 'Symfony\\Component\\Cache\\Simple\\RedisCache' => __DIR__ . '/..' . '/symfony/cache/Simple/RedisCache.php', 'Symfony\\Component\\Cache\\Simple\\TraceableCache' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php', - 'Symfony\\Component\\Cache\\Simple\\TraceableCacheEvent' => __DIR__ . '/..' . '/symfony/cache/Simple/TraceableCache.php', 'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractAdapterTrait.php', 'Symfony\\Component\\Cache\\Traits\\AbstractTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractTrait.php', 'Symfony\\Component\\Cache\\Traits\\ApcuTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ApcuTrait.php', @@ -292,7 +291,6 @@ class ComposerStaticInitAdvancedContentFilterAddon 'Symfony\\Component\\Cache\\Traits\\DoctrineTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/DoctrineTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemCommonTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemTrait.php', - 'Symfony\\Component\\Cache\\Traits\\LazyValue' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpFilesTrait.php', 'Symfony\\Component\\Cache\\Traits\\MemcachedTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/MemcachedTrait.php', 'Symfony\\Component\\Cache\\Traits\\PdoTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PdoTrait.php', 'Symfony\\Component\\Cache\\Traits\\PhpArrayTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/PhpArrayTrait.php', diff --git a/advancedcontentfilter/vendor/composer/installed.json b/advancedcontentfilter/vendor/composer/installed.json index 07e02c7f..70c2dc41 100644 --- a/advancedcontentfilter/vendor/composer/installed.json +++ b/advancedcontentfilter/vendor/composer/installed.json @@ -1,1190 +1,1212 @@ -[ - { - "name": "nikic/fast-route", - "version": "v1.3.0", - "version_normalized": "1.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/FastRoute.git", - "reference": "181d480e08d9476e61381e04a71b34dc0432e812" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", - "reference": "181d480e08d9476e61381e04a71b34dc0432e812", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35|~5.7" - }, - "time": "2018-02-13T20:26:39+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "FastRoute\\": "src/" +{ + "packages": [ + { + "name": "nikic/fast-route", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812" }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov", - "email": "nikic@php.net" - } - ], - "description": "Fast request router for PHP", - "keywords": [ - "router", - "routing" - ] - }, - { - "name": "psr/cache", - "version": "1.0.1", - "version_normalized": "1.0.1.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2016-08-06T20:24:11+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ] - }, - { - "name": "psr/container", - "version": "1.1.2", - "version_normalized": "1.1.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "time": "2021-11-05T16:50:12+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ] - }, - { - "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", - "shasum": "" - }, - "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:10:41+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": "https://www.php-fig.org/" - } - ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/http-message", - "version": "2.0", - "version_normalized": "2.0.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "time": "2023-04-04T09:54:51+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.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": "https://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" - ] - }, - { - "name": "psr/http-server-handler", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-server-handler.git", - "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", - "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "psr/http-message": "^1.0 || ^2.0" - }, - "time": "2023-04-10T20:06:20+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP server-side request handler", - "keywords": [ - "handler", - "http", - "http-interop", - "psr", - "psr-15", - "psr-7", - "request", - "response", - "server" - ] - }, - { - "name": "psr/http-server-middleware", - "version": "1.0.2", - "version_normalized": "1.0.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/http-server-middleware.git", - "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", - "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", - "shasum": "" - }, - "require": { - "php": ">=7.0", - "psr/http-message": "^1.0 || ^2.0", - "psr/http-server-handler": "^1.0" - }, - "time": "2023-04-11T06:14:47+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Http\\Server\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for HTTP server-side middleware", - "keywords": [ - "http", - "http-interop", - "middleware", - "psr", - "psr-15", - "psr-7", - "request", - "response" - ] - }, - { - "name": "psr/log", - "version": "1.1.4", - "version_normalized": "1.1.4.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "time": "2021-05-03T11:20:27+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ] - }, - { - "name": "slim/slim", - "version": "4.13.0", - "version_normalized": "4.13.0.0", - "source": { - "type": "git", - "url": "https://github.com/slimphp/Slim.git", - "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/slimphp/Slim/zipball/038fd5713d5a41636fdff0e8dcceedecdd17fc17", - "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17", - "shasum": "" - }, - "require": { - "ext-json": "*", - "nikic/fast-route": "^1.3", - "php": "^7.4 || ^8.0", - "psr/container": "^1.0 || ^2.0", - "psr/http-factory": "^1.0", - "psr/http-message": "^1.1 || ^2.0", - "psr/http-server-handler": "^1.0", - "psr/http-server-middleware": "^1.0", - "psr/log": "^1.1 || ^2.0 || ^3.0" - }, - "require-dev": { - "adriansuter/php-autoload-override": "^1.4", - "ext-simplexml": "*", - "guzzlehttp/psr7": "^2.6", - "httpsoft/http-message": "^1.1", - "httpsoft/http-server-request": "^1.1", - "laminas/laminas-diactoros": "^2.17 || ^3", - "nyholm/psr7": "^1.8", - "nyholm/psr7-server": "^1.1", - "phpspec/prophecy": "^1.19", - "phpspec/prophecy-phpunit": "^2.1", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.6", - "slim/http": "^1.3", - "slim/psr7": "^1.6", - "squizlabs/php_codesniffer": "^3.9" - }, - "suggest": { - "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", - "ext-xml": "Needed to support XML format in BodyParsingMiddleware", - "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", - "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." - }, - "time": "2024-03-03T21:25:30+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Slim\\": "Slim" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Josh Lockhart", - "email": "hello@joshlockhart.com", - "homepage": "https://joshlockhart.com" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812", + "shasum": "" }, - { - "name": "Andrew Smith", - "email": "a.smith@silentworks.co.uk", - "homepage": "http://silentworks.co.uk" + "require": { + "php": ">=5.4.0" }, - { - "name": "Rob Allen", - "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" + "require-dev": { + "phpunit/phpunit": "^4.8.35|~5.7" }, - { - "name": "Pierre Berube", - "email": "pierre@lgse.com", - "homepage": "http://www.lgse.com" + "time": "2018-02-13T20:26:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "FastRoute\\": "src/" + }, + "files": [ + "src/functions.php" + ] }, - { - "name": "Gabriel Manricks", - "email": "gmanricks@me.com", - "homepage": "http://gabrielmanricks.com" - } - ], - "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", - "homepage": "https://www.slimframework.com", - "keywords": [ - "api", - "framework", - "micro", - "router" - ], - "funding": [ - { - "url": "https://opencollective.com/slimphp", - "type": "open_collective" - }, - { - "url": "https://tidelift.com/funding/github/packagist/slim/slim", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/cache", - "version": "v4.4.48", - "version_normalized": "4.4.48.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache.git", - "reference": "3b98ed664887ad197b8ede3da2432787212eb915" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/3b98ed664887ad197b8ede3da2432787212eb915", - "reference": "3b98ed664887ad197b8ede3da2432787212eb915", - "shasum": "" - }, - "require": { - "php": ">=7.1.3", - "psr/cache": "^1.0|^2.0", - "psr/log": "^1|^2|^3", - "symfony/cache-contracts": "^1.1.7|^2", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.2|^5.0" - }, - "conflict": { - "doctrine/dbal": "<2.7", - "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<4.4|>=5.0", - "symfony/var-dumper": "<4.4" - }, - "provide": { - "psr/cache-implementation": "1.0|2.0", - "psr/simple-cache-implementation": "1.0|2.0", - "symfony/cache-implementation": "1.0|2.0" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/cache": "^1.6|^2.0", - "doctrine/dbal": "^2.7|^3.0", - "predis/predis": "^1.1", - "psr/simple-cache": "^1.0|^2.0", - "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^3.4|^4.1|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/var-dumper": "^4.4|^5.0" - }, - "time": "2022-10-17T20:21:54+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\Cache\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", - "homepage": "https://symfony.com", - "keywords": [ - "caching", - "psr6" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/cache-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache-contracts.git", - "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", - "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0|^2.0|^3.0" - }, - "suggest": { - "symfony/cache-implementation": "" - }, - "time": "2022-01-02T09:53:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Cache\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to caching", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/deprecation-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2022-01-02T09:53:40+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "function.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "A generic function and convention to trigger deprecation notices", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/expression-language", - "version": "v3.4.47", - "version_normalized": "3.4.47.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/expression-language.git", - "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", - "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", - "shasum": "" - }, - "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/cache": "~3.1|~4.0", - "symfony/polyfill-php70": "~1.6" - }, - "time": "2020-10-24T10:57:07+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\ExpressionLanguage\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony ExpressionLanguage Component", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.20.0", - "version_normalized": "1.20.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2020-10-23T14:02:19+00:00", - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2024-01-29T20:11:03+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2024-01-29T20:11:03+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "install-path": "../nikic/fast-route" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" + { + "name": "psr/cache", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "require": { + "php": ">=5.3.0" }, - { - "url": "https://github.com/fabpot", - "type": "github" + "time": "2016-08-06T20:24:11+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/service-contracts", - "version": "v2.5.2", - "version_normalized": "2.5.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/service-contracts.git", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" - }, - "conflict": { - "ext-psr": "<1.1|>=2" - }, - "suggest": { - "symfony/service-implementation": "" - }, - "time": "2022-05-30T19:17:29+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "install-path": "../psr/cache" }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Service\\": "" - } + { + "name": "psr/container", + "version": "1.1.2", + "version_normalized": "1.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "time": "2021-11-05T16:50:12+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "install-path": "../psr/container" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + { + "name": "psr/http-factory", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "e616d01114759c4c489f93b099585439f795fe35" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to writing services", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", + "reference": "e616d01114759c4c489f93b099585439f795fe35", + "shasum": "" }, - { - "url": "https://github.com/fabpot", - "type": "github" + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0 || ^2.0" }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - }, - { - "name": "symfony/var-exporter", - "version": "v5.4.35", - "version_normalized": "5.4.35.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-exporter.git", - "reference": "abb0a151b62d6b07e816487e20040464af96cae7" + "time": "2023-04-10T20:10:41+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": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-factory" }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7", - "reference": "abb0a151b62d6b07e816487e20040464af96cae7", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" - }, - "time": "2024-01-23T13:51:25+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Symfony\\Component\\VarExporter\\": "" + { + "name": "psr/http-message", + "version": "2.0", + "version_normalized": "2.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, - "exclude-from-classmap": [ - "/Tests/" - ] + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2023-04-04T09:54:51+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.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": "https://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" + ], + "install-path": "../psr/http-message" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + { + "name": "psr/http-server-handler", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-handler.git", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4" }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows exporting any serializable PHP data structure to plain PHP code", - "homepage": "https://symfony.com", - "keywords": [ - "clone", - "construct", - "export", - "hydrate", - "instantiate", - "serialize" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4", + "reference": "84c4fb66179be4caaf8e97bd239203245302e7d4", + "shasum": "" }, - { - "url": "https://github.com/fabpot", - "type": "github" + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0" }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ] - } -] + "time": "2023-04-10T20:06:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side request handler", + "keywords": [ + "handler", + "http", + "http-interop", + "psr", + "psr-15", + "psr-7", + "request", + "response", + "server" + ], + "install-path": "../psr/http-server-handler" + }, + { + "name": "psr/http-server-middleware", + "version": "1.0.2", + "version_normalized": "1.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-server-middleware.git", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "reference": "c1481f747daaa6a0782775cd6a8c26a1bf4a3829", + "shasum": "" + }, + "require": { + "php": ">=7.0", + "psr/http-message": "^1.0 || ^2.0", + "psr/http-server-handler": "^1.0" + }, + "time": "2023-04-11T06:14:47+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Http\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP server-side middleware", + "keywords": [ + "http", + "http-interop", + "middleware", + "psr", + "psr-15", + "psr-7", + "request", + "response" + ], + "install-path": "../psr/http-server-middleware" + }, + { + "name": "psr/log", + "version": "1.1.4", + "version_normalized": "1.1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2021-05-03T11:20:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "install-path": "../psr/log" + }, + { + "name": "slim/slim", + "version": "4.13.0", + "version_normalized": "4.13.0.0", + "source": { + "type": "git", + "url": "https://github.com/slimphp/Slim.git", + "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slimphp/Slim/zipball/038fd5713d5a41636fdff0e8dcceedecdd17fc17", + "reference": "038fd5713d5a41636fdff0e8dcceedecdd17fc17", + "shasum": "" + }, + "require": { + "ext-json": "*", + "nikic/fast-route": "^1.3", + "php": "^7.4 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "adriansuter/php-autoload-override": "^1.4", + "ext-simplexml": "*", + "guzzlehttp/psr7": "^2.6", + "httpsoft/http-message": "^1.1", + "httpsoft/http-server-request": "^1.1", + "laminas/laminas-diactoros": "^2.17 || ^3", + "nyholm/psr7": "^1.8", + "nyholm/psr7-server": "^1.1", + "phpspec/prophecy": "^1.19", + "phpspec/prophecy-phpunit": "^2.1", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.6", + "slim/http": "^1.3", + "slim/psr7": "^1.6", + "squizlabs/php_codesniffer": "^3.9" + }, + "suggest": { + "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", + "ext-xml": "Needed to support XML format in BodyParsingMiddleware", + "php-di/php-di": "PHP-DI is the recommended container library to be used with Slim", + "slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information." + }, + "time": "2024-03-03T21:25:30+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Slim\\": "Slim" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Josh Lockhart", + "email": "hello@joshlockhart.com", + "homepage": "https://joshlockhart.com" + }, + { + "name": "Andrew Smith", + "email": "a.smith@silentworks.co.uk", + "homepage": "http://silentworks.co.uk" + }, + { + "name": "Rob Allen", + "email": "rob@akrabat.com", + "homepage": "http://akrabat.com" + }, + { + "name": "Pierre Berube", + "email": "pierre@lgse.com", + "homepage": "http://www.lgse.com" + }, + { + "name": "Gabriel Manricks", + "email": "gmanricks@me.com", + "homepage": "http://gabrielmanricks.com" + } + ], + "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs", + "homepage": "https://www.slimframework.com", + "keywords": [ + "api", + "framework", + "micro", + "router" + ], + "funding": [ + { + "url": "https://opencollective.com/slimphp", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slim/slim", + "type": "tidelift" + } + ], + "install-path": "../slim/slim" + }, + { + "name": "symfony/cache", + "version": "v4.4.48", + "version_normalized": "4.4.48.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "3b98ed664887ad197b8ede3da2432787212eb915" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/3b98ed664887ad197b8ede3da2432787212eb915", + "reference": "3b98ed664887ad197b8ede3da2432787212eb915", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/cache": "^1.0|^2.0", + "psr/log": "^1|^2|^3", + "symfony/cache-contracts": "^1.1.7|^2", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.2|^5.0" + }, + "conflict": { + "doctrine/dbal": "<2.7", + "symfony/dependency-injection": "<3.4", + "symfony/http-kernel": "<4.4|>=5.0", + "symfony/var-dumper": "<4.4" + }, + "provide": { + "psr/cache-implementation": "1.0|2.0", + "psr/simple-cache-implementation": "1.0|2.0", + "symfony/cache-implementation": "1.0|2.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/cache": "^1.6|^2.0", + "doctrine/dbal": "^2.7|^3.0", + "predis/predis": "^1.1", + "psr/simple-cache": "^1.0|^2.0", + "symfony/config": "^4.2|^5.0", + "symfony/dependency-injection": "^3.4|^4.1|^5.0", + "symfony/filesystem": "^4.4|^5.0", + "symfony/http-kernel": "^4.4", + "symfony/var-dumper": "^4.4|^5.0" + }, + "time": "2022-10-17T20:21:54+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/cache" + }, + { + "name": "symfony/cache-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", + "reference": "64be4a7acb83b6f2bf6de9a02cee6dad41277ebc", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/cache": "^1.0|^2.0|^3.0" + }, + "suggest": { + "symfony/cache-implementation": "" + }, + "time": "2022-01-02T09:53:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/cache-contracts" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2022-01-02T09:53:40+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/deprecation-contracts" + }, + { + "name": "symfony/expression-language", + "version": "v3.4.47", + "version_normalized": "3.4.47.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/expression-language.git", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/expression-language/zipball/de38e66398fca1fcb9c48e80279910e6889cb28f", + "reference": "de38e66398fca1fcb9c48e80279910e6889cb28f", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/cache": "~3.1|~4.0", + "symfony/polyfill-php70": "~1.6" + }, + "time": "2020-10-24T10:57:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\ExpressionLanguage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony ExpressionLanguage Component", + "homepage": "https://symfony.com", + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/expression-language" + }, + { + "name": "symfony/polyfill-php70", + "version": "v1.20.0", + "version_normalized": "1.20.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", + "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2020-10-23T14:02:19+00:00", + "type": "metapackage", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": null + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.29.0", + "version_normalized": "1.29.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", + "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2024-01-29T20:11:03+00:00", + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-php73" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.29.0", + "version_normalized": "1.29.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2024-01-29T20:11:03+00:00", + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-php80" + }, + { + "name": "symfony/service-contracts", + "version": "v2.5.2", + "version_normalized": "2.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "time": "2022-05-30T19:17:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/service-contracts" + }, + { + "name": "symfony/var-exporter", + "version": "v5.4.35", + "version_normalized": "5.4.35.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "abb0a151b62d6b07e816487e20040464af96cae7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/abb0a151b62d6b07e816487e20040464af96cae7", + "reference": "abb0a151b62d6b07e816487e20040464af96cae7", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "symfony/var-dumper": "^4.4.9|^5.0.9|^6.0" + }, + "time": "2024-01-23T13:51:25+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "serialize" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/var-exporter" + } + ], + "dev": false, + "dev-package-names": [] +} diff --git a/advancedcontentfilter/vendor/composer/installed.php b/advancedcontentfilter/vendor/composer/installed.php new file mode 100644 index 00000000..010b1da9 --- /dev/null +++ b/advancedcontentfilter/vendor/composer/installed.php @@ -0,0 +1,203 @@ + array( + 'name' => 'friendica-addons/advancedcontentfilter', + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => 'feb7722f723b21e76fdf20a7ce4b42fa5ffcdcb9', + 'type' => 'friendica-addon', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => false, + ), + 'versions' => array( + 'friendica-addons/advancedcontentfilter' => array( + 'pretty_version' => 'dev-develop', + 'version' => 'dev-develop', + 'reference' => 'feb7722f723b21e76fdf20a7ce4b42fa5ffcdcb9', + 'type' => 'friendica-addon', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'nikic/fast-route' => array( + 'pretty_version' => 'v1.3.0', + 'version' => '1.3.0.0', + 'reference' => '181d480e08d9476e61381e04a71b34dc0432e812', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nikic/fast-route', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/cache' => array( + 'pretty_version' => '1.0.1', + 'version' => '1.0.1.0', + 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0|2.0', + ), + ), + 'psr/container' => array( + 'pretty_version' => '1.1.2', + 'version' => '1.1.2.0', + 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/container', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-factory' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-factory', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-message' => array( + 'pretty_version' => '2.0', + 'version' => '2.0.0.0', + 'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-message', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-server-handler' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => '84c4fb66179be4caaf8e97bd239203245302e7d4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-server-handler', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/http-server-middleware' => array( + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'c1481f747daaa6a0782775cd6a8c26a1bf4a3829', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/http-server-middleware', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/log' => array( + 'pretty_version' => '1.1.4', + 'version' => '1.1.4.0', + 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'type' => 'library', + 'install_path' => __DIR__ . '/../psr/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'psr/simple-cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0|2.0', + ), + ), + 'slim/slim' => array( + 'pretty_version' => '4.13.0', + 'version' => '4.13.0.0', + 'reference' => '038fd5713d5a41636fdff0e8dcceedecdd17fc17', + 'type' => 'library', + 'install_path' => __DIR__ . '/../slim/slim', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/cache' => array( + 'pretty_version' => 'v4.4.48', + 'version' => '4.4.48.0', + 'reference' => '3b98ed664887ad197b8ede3da2432787212eb915', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/cache-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => '64be4a7acb83b6f2bf6de9a02cee6dad41277ebc', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/cache-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/cache-implementation' => array( + 'dev_requirement' => false, + 'provided' => array( + 0 => '1.0|2.0', + ), + ), + 'symfony/deprecation-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/expression-language' => array( + 'pretty_version' => 'v3.4.47', + 'version' => '3.4.47.0', + 'reference' => 'de38e66398fca1fcb9c48e80279910e6889cb28f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/expression-language', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php70' => array( + 'pretty_version' => 'v1.20.0', + 'version' => '1.20.0.0', + 'reference' => '5f03a781d984aae42cebd18e7912fa80f02ee644', + 'type' => 'metapackage', + 'install_path' => null, + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php73' => array( + 'pretty_version' => 'v1.29.0', + 'version' => '1.29.0.0', + 'reference' => '21bd091060673a1177ae842c0ef8fe30893114d2', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php73', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php80' => array( + 'pretty_version' => 'v1.29.0', + 'version' => '1.29.0.0', + 'reference' => '87b68208d5c1188808dd7839ee1e6c8ec3b02f1b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php80', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/service-contracts' => array( + 'pretty_version' => 'v2.5.2', + 'version' => '2.5.2.0', + 'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/service-contracts', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/var-exporter' => array( + 'pretty_version' => 'v5.4.35', + 'version' => '5.4.35.0', + 'reference' => 'abb0a151b62d6b07e816487e20040464af96cae7', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/var-exporter', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/advancedcontentfilter/vendor/composer/platform_check.php b/advancedcontentfilter/vendor/composer/platform_check.php new file mode 100644 index 00000000..580fa960 --- /dev/null +++ b/advancedcontentfilter/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70400)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.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/advancedcontentfilter/vendor/psr/simple-cache/.editorconfig b/advancedcontentfilter/vendor/psr/simple-cache/.editorconfig deleted file mode 100644 index 48542cbb..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -; This file is for unifying the coding style for different editors and IDEs. -; More information at http://editorconfig.org - -root = true - -[*] -charset = utf-8 -indent_size = 4 -indent_style = space -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true diff --git a/advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md b/advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md deleted file mode 100644 index e49a7c85..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -# The MIT License (MIT) - -Copyright (c) 2016 PHP Framework Interoperability Group - -> 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/advancedcontentfilter/vendor/psr/simple-cache/README.md b/advancedcontentfilter/vendor/psr/simple-cache/README.md deleted file mode 100644 index 43641d17..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/README.md +++ /dev/null @@ -1,8 +0,0 @@ -PHP FIG Simple Cache PSR -======================== - -This repository holds all interfaces related to PSR-16. - -Note that this is not a cache implementation of its own. It is merely an interface that describes a cache implementation. See [the specification](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-16-simple-cache.md) for more details. - -You can find implementations of the specification by looking for packages providing the [psr/simple-cache-implementation](https://packagist.org/providers/psr/simple-cache-implementation) virtual package. diff --git a/advancedcontentfilter/vendor/psr/simple-cache/composer.json b/advancedcontentfilter/vendor/psr/simple-cache/composer.json deleted file mode 100644 index 2978fa55..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/composer.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "psr/simple-cache", - "description": "Common interfaces for simple caching", - "keywords": ["psr", "psr-16", "cache", "simple-cache", "caching"], - "license": "MIT", - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "require": { - "php": ">=5.3.0" - }, - "autoload": { - "psr-4": { - "Psr\\SimpleCache\\": "src/" - } - }, - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - } -} diff --git a/advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php b/advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php deleted file mode 100644 index eba53815..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/src/CacheException.php +++ /dev/null @@ -1,10 +0,0 @@ - value pairs. Cache keys that do not exist or are stale will have $default as value. - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if $keys is neither an array nor a Traversable, - * or if any of the $keys are not a legal value. - */ - public function getMultiple($keys, $default = null); - - /** - * Persists a set of key => value pairs in the cache, with an optional TTL. - * - * @param iterable $values A list of key => value pairs for a multiple-set operation. - * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and - * the driver supports TTL then the library may set a default value - * for it or let the driver take care of that. - * - * @return bool True on success and false on failure. - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if $values is neither an array nor a Traversable, - * or if any of the $values are not a legal value. - */ - public function setMultiple($values, $ttl = null); - - /** - * Deletes multiple cache items in a single operation. - * - * @param iterable $keys A list of string-based keys to be deleted. - * - * @return bool True if the items were successfully removed. False if there was an error. - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if $keys is neither an array nor a Traversable, - * or if any of the $keys are not a legal value. - */ - public function deleteMultiple($keys); - - /** - * Determines whether an item is present in the cache. - * - * NOTE: It is recommended that has() is only to be used for cache warming type purposes - * and not to be used within your live applications operations for get/set, as this method - * is subject to a race condition where your has() will return true and immediately after, - * another script can remove it making the state of your app out of date. - * - * @param string $key The cache item key. - * - * @return bool - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * MUST be thrown if the $key string is not a legal value. - */ - public function has($key); -} diff --git a/advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php b/advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php deleted file mode 100644 index 6a9524a2..00000000 --- a/advancedcontentfilter/vendor/psr/simple-cache/src/InvalidArgumentException.php +++ /dev/null @@ -1,13 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\RedisAdapter; - -abstract class AbstractRedisAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testExpiration' => 'Testing expiration slows down the test suite', - 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $redis; - - public function createCachePool($defaultLifetime = 0) - { - return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public static function setUpBeforeClass() - { - if (!\extension_loaded('redis')) { - self::markTestSkipped('Extension redis required.'); - } - try { - (new \Redis())->connect(getenv('REDIS_HOST')); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php deleted file mode 100644 index 5758a286..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/AdapterTestCase.php +++ /dev/null @@ -1,175 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Cache\IntegrationTests\CachePoolTest; -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\PruneableInterface; - -abstract class AdapterTestCase extends CachePoolTest -{ - protected function setUp() - { - parent::setUp(); - - if (!\array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && \defined('HHVM_VERSION')) { - $this->skippedTests['testDeferredSaveWithoutCommit'] = 'Destructors are called late on HHVM.'; - } - - if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) { - $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; - } - } - - public function testDefaultLifeTime() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createCachePool(2); - - $item = $cache->getItem('key.dlt'); - $item->set('value'); - $cache->save($item); - sleep(1); - - $item = $cache->getItem('key.dlt'); - $this->assertTrue($item->isHit()); - - sleep(2); - $item = $cache->getItem('key.dlt'); - $this->assertFalse($item->isHit()); - } - - public function testExpiration() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createCachePool(); - $cache->save($cache->getItem('k1')->set('v1')->expiresAfter(2)); - $cache->save($cache->getItem('k2')->set('v2')->expiresAfter(366 * 86400)); - - sleep(3); - $item = $cache->getItem('k1'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit() is false."); - - $item = $cache->getItem('k2'); - $this->assertTrue($item->isHit()); - $this->assertSame('v2', $item->get()); - } - - public function testNotUnserializable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createCachePool(); - - $item = $cache->getItem('foo'); - $cache->save($item->set(new NotUnserializable())); - - $item = $cache->getItem('foo'); - $this->assertFalse($item->isHit()); - - foreach ($cache->getItems(['foo']) as $item) { - } - $cache->save($item->set(new NotUnserializable())); - - foreach ($cache->getItems(['foo']) as $item) { - } - $this->assertFalse($item->isHit()); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - if (!method_exists($this, 'isPruned')) { - $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); - } - - /** @var PruneableInterface|CacheItemPoolInterface $cache */ - $cache = $this->createCachePool(); - - $doSet = function ($name, $value, \DateInterval $expiresAfter = null) use ($cache) { - $item = $cache->getItem($name); - $item->set($value); - - if ($expiresAfter) { - $item->expiresAfter($expiresAfter); - } - - $cache->save($item); - }; - - $doSet('foo', 'foo-val', new \DateInterval('PT05S')); - $doSet('bar', 'bar-val', new \DateInterval('PT10S')); - $doSet('baz', 'baz-val', new \DateInterval('PT15S')); - $doSet('qux', 'qux-val', new \DateInterval('PT20S')); - - sleep(30); - $cache->prune(); - $this->assertTrue($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertTrue($this->isPruned($cache, 'qux')); - - $doSet('foo', 'foo-val'); - $doSet('bar', 'bar-val', new \DateInterval('PT20S')); - $doSet('baz', 'baz-val', new \DateInterval('PT40S')); - $doSet('qux', 'qux-val', new \DateInterval('PT80S')); - - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertFalse($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'qux')); - } -} - -class NotUnserializable implements \Serializable -{ - public function serialize() - { - return serialize(123); - } - - public function unserialize($ser) - { - throw new \Exception(__CLASS__); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php deleted file mode 100644 index f55a1b9b..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ApcuAdapterTest.php +++ /dev/null @@ -1,124 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Log\NullLogger; -use Symfony\Component\Cache\Adapter\ApcuAdapter; - -class ApcuAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testExpiration' => 'Testing expiration slows down the test suite', - 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - public function createCachePool($defaultLifetime = 0) - { - if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN)) { - $this->markTestSkipped('APCu extension is required.'); - } - if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) { - if ('testWithCliSapi' !== $this->getName()) { - $this->markTestSkipped('apc.enable_cli=1 is required.'); - } - } - if ('\\' === \DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Fails transiently on Windows.'); - } - - return new ApcuAdapter(str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public function testUnserializable() - { - $pool = $this->createCachePool(); - - $item = $pool->getItem('foo'); - $item->set(function () {}); - - $this->assertFalse($pool->save($item)); - - $item = $pool->getItem('foo'); - $this->assertFalse($item->isHit()); - } - - public function testVersion() - { - $namespace = str_replace('\\', '.', static::class); - - $pool1 = new ApcuAdapter($namespace, 0, 'p1'); - - $item = $pool1->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertTrue($pool1->save($item->set('bar'))); - - $item = $pool1->getItem('foo'); - $this->assertTrue($item->isHit()); - $this->assertSame('bar', $item->get()); - - $pool2 = new ApcuAdapter($namespace, 0, 'p2'); - - $item = $pool2->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get()); - - $item = $pool1->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get()); - } - - public function testNamespace() - { - $namespace = str_replace('\\', '.', static::class); - - $pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1'); - - $item = $pool1->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertTrue($pool1->save($item->set('bar'))); - - $item = $pool1->getItem('foo'); - $this->assertTrue($item->isHit()); - $this->assertSame('bar', $item->get()); - - $pool2 = new ApcuAdapter($namespace.'_2', 0, 'p1'); - - $item = $pool2->getItem('foo'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get()); - - $item = $pool1->getItem('foo'); - $this->assertTrue($item->isHit()); - $this->assertSame('bar', $item->get()); - } - - public function testWithCliSapi() - { - try { - // disable PHPUnit error handler to mimic a production environment - $isCalled = false; - set_error_handler(function () use (&$isCalled) { - $isCalled = true; - }); - $pool = new ApcuAdapter(str_replace('\\', '.', __CLASS__)); - $pool->setLogger(new NullLogger()); - - $item = $pool->getItem('foo'); - $item->isHit(); - $pool->save($item->set('bar')); - $this->assertFalse($isCalled); - } finally { - restore_error_handler(); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php deleted file mode 100644 index e6adc9d0..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ArrayAdapterTest.php +++ /dev/null @@ -1,56 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\ArrayAdapter; - -/** - * @group time-sensitive - */ -class ArrayAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', - 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new ArrayAdapter($defaultLifetime); - } - - public function testGetValuesHitAndMiss() - { - /** @var ArrayAdapter $cache */ - $cache = $this->createCachePool(); - - // Hit - $item = $cache->getItem('foo'); - $item->set('4711'); - $cache->save($item); - - $fooItem = $cache->getItem('foo'); - $this->assertTrue($fooItem->isHit()); - $this->assertEquals('4711', $fooItem->get()); - - // Miss (should be present as NULL in $values) - $cache->getItem('bar'); - - $values = $cache->getValues(); - - $this->assertCount(2, $values); - $this->assertArrayHasKey('foo', $values); - $this->assertSame(serialize('4711'), $values['foo']); - $this->assertArrayHasKey('bar', $values); - $this->assertNull($values['bar']); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php deleted file mode 100644 index be811d6f..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ChainAdapterTest.php +++ /dev/null @@ -1,233 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\MockObject\MockObject; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ChainAdapter; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter; - -/** - * @author Kévin Dunglas - * @group time-sensitive - */ -class ChainAdapterTest extends AdapterTestCase -{ - public function createCachePool($defaultLifetime = 0) - { - return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime); - } - - public function testEmptyAdaptersException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('At least one adapter must be specified.'); - new ChainAdapter([]); - } - - public function testInvalidAdapterException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('The class "stdClass" does not implement'); - new ChainAdapter([new \stdClass()]); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = new ChainAdapter([ - $this->getPruneableMock(), - $this->getNonPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertTrue($cache->prune()); - - $cache = new ChainAdapter([ - $this->getPruneableMock(), - $this->getFailingPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertFalse($cache->prune()); - } - - public function testMultipleCachesExpirationWhenCommonTtlIsNotSet() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $adapter1 = new ArrayAdapter(4); - $adapter2 = new ArrayAdapter(2); - - $cache = new ChainAdapter([$adapter1, $adapter2]); - - $cache->save($cache->getItem('key')->set('value')); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertFalse($item->isHit()); - - $adapter2->save($adapter2->getItem('key1')->set('value1')); - - $item = $cache->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - $item = $adapter2->getItem('key1'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertFalse($item->isHit()); - } - - public function testMultipleCachesExpirationWhenCommonTtlIsSet() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $adapter1 = new ArrayAdapter(4); - $adapter2 = new ArrayAdapter(2); - - $cache = new ChainAdapter([$adapter1, $adapter2], 6); - - $cache->save($cache->getItem('key')->set('value')); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value', $item->get()); - - $item = $adapter2->getItem('key'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key'); - $this->assertFalse($item->isHit()); - - $adapter2->save($adapter2->getItem('key1')->set('value1')); - - $item = $cache->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - $item = $adapter2->getItem('key1'); - $this->assertFalse($item->isHit()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertTrue($item->isHit()); - $this->assertEquals('value1', $item->get()); - - sleep(2); - - $item = $adapter1->getItem('key1'); - $this->assertFalse($item->isHit()); - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(true); - - return $pruneable; - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getFailingPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(false); - - return $pruneable; - } - - /** - * @return MockObject|AdapterInterface - */ - private function getNonPruneableMock() - { - return $this - ->getMockBuilder(AdapterInterface::class) - ->getMock(); - } -} - -interface PruneableCacheInterface extends PruneableInterface, AdapterInterface -{ -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php deleted file mode 100644 index 8f520cb5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/DoctrineAdapterTest.php +++ /dev/null @@ -1,32 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\DoctrineAdapter; -use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; - -/** - * @group time-sensitive - */ -class DoctrineAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayCache is not.', - 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayCache is not.', - 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new DoctrineAdapter(new ArrayCache($defaultLifetime), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php deleted file mode 100644 index fa830682..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/FilesystemAdapterTest.php +++ /dev/null @@ -1,61 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; - -/** - * @group time-sensitive - */ -class FilesystemAdapterTest extends AdapterTestCase -{ - public function createCachePool($defaultLifetime = 0) - { - return new FilesystemAdapter('', $defaultLifetime); - } - - public static function tearDownAfterClass() - { - self::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - - public static function rmdir($dir) - { - if (!file_exists($dir)) { - return; - } - if (!$dir || 0 !== strpos(\dirname($dir), sys_get_temp_dir())) { - throw new \Exception(__METHOD__."() operates only on subdirs of system's temp dir"); - } - $children = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST - ); - foreach ($children as $child) { - if ($child->isDir()) { - rmdir($child); - } else { - unlink($child); - } - } - rmdir($dir); - } - - protected function isPruned(CacheItemPoolInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php deleted file mode 100644 index 536e2c2d..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MaxIdLengthAdapterTest.php +++ /dev/null @@ -1,87 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\Adapter\AbstractAdapter; - -class MaxIdLengthAdapterTest extends TestCase -{ - public function testLongKey() - { - $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs([str_repeat('-', 10)]) - ->setMethods(['doHave', 'doFetch', 'doDelete', 'doSave', 'doClear']) - ->getMock(); - - $cache->expects($this->exactly(2)) - ->method('doHave') - ->withConsecutive( - [$this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')], - [$this->equalTo('----------:---------------------------------------')] - ); - - $cache->hasItem(str_repeat('-', 40)); - $cache->hasItem(str_repeat('-', 39)); - } - - public function testLongKeyVersioning() - { - $cache = $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs([str_repeat('-', 26)]) - ->getMock(); - - $cache - ->method('doFetch') - ->willReturn(['2:']); - - $reflectionClass = new \ReflectionClass(AbstractAdapter::class); - - $reflectionMethod = $reflectionClass->getMethod('getId'); - $reflectionMethod->setAccessible(true); - - // No versioning enabled - $this->assertEquals('--------------------------:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); - - $reflectionProperty = $reflectionClass->getProperty('versioningIsEnabled'); - $reflectionProperty->setAccessible(true); - $reflectionProperty->setValue($cache, true); - - // Versioning enabled - $this->assertEquals('--------------------------:2:------------', $reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)])); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 12)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 23)]))); - $this->assertLessThanOrEqual(50, \strlen($reflectionMethod->invokeArgs($cache, [str_repeat('-', 40)]))); - } - - public function testTooLongNamespace() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Namespace must be 26 chars max, 40 given ("----------------------------------------")'); - $this->getMockBuilder(MaxIdLengthAdapter::class) - ->setConstructorArgs([str_repeat('-', 40)]) - ->getMock(); - } -} - -abstract class MaxIdLengthAdapter extends AbstractAdapter -{ - protected $maxIdLength = 50; - - public function __construct($ns) - { - parent::__construct($ns); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php deleted file mode 100644 index a9a397dd..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/MemcachedAdapterTest.php +++ /dev/null @@ -1,204 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Adapter\MemcachedAdapter; - -class MemcachedAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testHasItemReturnsFalseWhenDeferredItemIsExpired' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $client; - - public static function setUpBeforeClass() - { - if (!MemcachedAdapter::isSupported()) { - self::markTestSkipped('Extension memcached >=2.2.0 required.'); - } - self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); - self::$client->get('foo'); - $code = self::$client->getResultCode(); - - if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) { - self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage())); - } - } - - public function createCachePool($defaultLifetime = 0) - { - $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')) : self::$client; - - return new MemcachedAdapter($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public function testOptions() - { - $client = MemcachedAdapter::createConnection([], [ - 'libketama_compatible' => false, - 'distribution' => 'modula', - 'compression' => true, - 'serializer' => 'php', - 'hash' => 'md5', - ]); - - $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); - $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION)); - } - - /** - * @dataProvider provideBadOptions - */ - public function testBadOptions($name, $value) - { - if (\PHP_VERSION_ID < 80000) { - $this->expectException('ErrorException'); - $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); - } else { - $this->expectException('Error'); - $this->expectExceptionMessage('Undefined constant Memcached::'); - } - - MemcachedAdapter::createConnection([], [$name => $value]); - } - - public function provideBadOptions() - { - return [ - ['foo', 'bar'], - ['hash', 'zyx'], - ['serializer', 'zyx'], - ['distribution', 'zyx'], - ]; - } - - public function testDefaultOptions() - { - $this->assertTrue(MemcachedAdapter::isSupported()); - - $client = MemcachedAdapter::createConnection([]); - - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_TCP_NODELAY)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - } - - public function testOptionSerializer() - { - $this->expectException('Symfony\Component\Cache\Exception\CacheException'); - $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); - if (!\Memcached::HAVE_JSON) { - $this->markTestSkipped('Memcached::HAVE_JSON required'); - } - - new MemcachedAdapter(MemcachedAdapter::createConnection([], ['serializer' => 'json'])); - } - - /** - * @dataProvider provideServersSetting - */ - public function testServersSetting($dsn, $host, $port) - { - $client1 = MemcachedAdapter::createConnection($dsn); - $client2 = MemcachedAdapter::createConnection([$dsn]); - $client3 = MemcachedAdapter::createConnection([[$host, $port]]); - $expect = [ - 'host' => $host, - 'port' => $port, - ]; - - $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; - $this->assertSame([$expect], array_map($f, $client1->getServerList())); - $this->assertSame([$expect], array_map($f, $client2->getServerList())); - $this->assertSame([$expect], array_map($f, $client3->getServerList())); - } - - public function provideServersSetting() - { - yield [ - 'memcached://127.0.0.1/50', - '127.0.0.1', - 11211, - ]; - yield [ - 'memcached://localhost:11222?weight=25', - 'localhost', - 11222, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@127.0.0.1?weight=50', - '127.0.0.1', - 11211, - ]; - } - yield [ - 'memcached:///var/run/memcached.sock?weight=25', - '/var/run/memcached.sock', - 0, - ]; - yield [ - 'memcached:///var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@/var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - } - } - - /** - * @dataProvider provideDsnWithOptions - */ - public function testDsnWithOptions($dsn, array $options, array $expectedOptions) - { - $client = MemcachedAdapter::createConnection($dsn, $options); - - foreach ($expectedOptions as $option => $expect) { - $this->assertSame($expect, $client->getOption($option)); - } - } - - public function provideDsnWithOptions() - { - if (!class_exists('\Memcached')) { - self::markTestSkipped('Extension memcached required.'); - } - - yield [ - 'memcached://localhost:11222?retry_timeout=10', - [\Memcached::OPT_RETRY_TIMEOUT => 8], - [\Memcached::OPT_RETRY_TIMEOUT => 10], - ]; - yield [ - 'memcached://localhost:11222?socket_recv_size=1&socket_send_size=2', - [\Memcached::OPT_RETRY_TIMEOUT => 8], - [\Memcached::OPT_SOCKET_RECV_SIZE => 1, \Memcached::OPT_SOCKET_SEND_SIZE => 2, \Memcached::OPT_RETRY_TIMEOUT => 8], - ]; - } - - public function testClear() - { - $this->assertTrue($this->createCachePool()->clear()); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php deleted file mode 100644 index c2714033..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NamespacedProxyAdapterTest.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ProxyAdapter; - -/** - * @group time-sensitive - */ -class NamespacedProxyAdapterTest extends ProxyAdapterTest -{ - public function createCachePool($defaultLifetime = 0) - { - return new ProxyAdapter(new ArrayAdapter($defaultLifetime), 'foo', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php deleted file mode 100644 index b771fa0e..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/NullAdapterTest.php +++ /dev/null @@ -1,128 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\TestCase; -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\NullAdapter; - -/** - * @group time-sensitive - */ -class NullAdapterTest extends TestCase -{ - public function createCachePool() - { - return new NullAdapter(); - } - - public function testGetItem() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - } - - public function testHasItem() - { - $this->assertFalse($this->createCachePool()->hasItem('key')); - } - - public function testGetItems() - { - $adapter = $this->createCachePool(); - - $keys = ['foo', 'bar', 'baz', 'biz']; - - /** @var CacheItemInterface[] $items */ - $items = $adapter->getItems($keys); - $count = 0; - - foreach ($items as $key => $item) { - $itemKey = $item->getKey(); - - $this->assertEquals($itemKey, $key, 'Keys must be preserved when fetching multiple items'); - $this->assertContains($key, $keys, 'Cache key can not change.'); - $this->assertFalse($item->isHit()); - - // Remove $key for $keys - foreach ($keys as $k => $v) { - if ($v === $key) { - unset($keys[$k]); - } - } - - ++$count; - } - - $this->assertSame(4, $count); - } - - public function testIsHit() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - } - - public function testClear() - { - $this->assertTrue($this->createCachePool()->clear()); - } - - public function testDeleteItem() - { - $this->assertTrue($this->createCachePool()->deleteItem('key')); - } - - public function testDeleteItems() - { - $this->assertTrue($this->createCachePool()->deleteItems(['key', 'foo', 'bar'])); - } - - public function testSave() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - - $this->assertFalse($adapter->save($item)); - } - - public function testDeferredSave() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - - $this->assertFalse($adapter->saveDeferred($item)); - } - - public function testCommit() - { - $adapter = $this->createCachePool(); - - $item = $adapter->getItem('key'); - $this->assertFalse($item->isHit()); - $this->assertNull($item->get(), "Item's value must be null when isHit is false."); - - $this->assertFalse($adapter->saveDeferred($item)); - $this->assertFalse($this->createCachePool()->commit()); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php deleted file mode 100644 index dd2a9118..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoAdapterTest.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\PdoAdapter; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoAdapterTest extends AdapterTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoAdapter('sqlite:'.self::$dbFile); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createCachePool($defaultLifetime = 0) - { - return new PdoAdapter('sqlite:'.self::$dbFile, 'ns', $defaultLifetime); - } - - public function testCleanupExpiredItems() - { - $pdo = new \PDO('sqlite:'.self::$dbFile); - - $getCacheItemCount = function () use ($pdo) { - return (int) $pdo->query('SELECT COUNT(*) FROM cache_items')->fetch(\PDO::FETCH_COLUMN); - }; - - $this->assertSame(0, $getCacheItemCount()); - - $cache = $this->createCachePool(); - - $item = $cache->getItem('some_nice_key'); - $item->expiresAfter(1); - $item->set(1); - - $cache->save($item); - $this->assertSame(1, $getCacheItemCount()); - - sleep(2); - - $newItem = $cache->getItem($item->getKey()); - $this->assertFalse($newItem->isHit()); - $this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items'); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php deleted file mode 100644 index aa53958c..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PdoDbalAdapterTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Doctrine\DBAL\DriverManager; -use Symfony\Component\Cache\Adapter\PdoAdapter; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoDbalAdapterTest extends AdapterTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createCachePool($defaultLifetime = 0) - { - return new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php deleted file mode 100644 index f88a7187..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterTest.php +++ /dev/null @@ -1,135 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\NullAdapter; -use Symfony\Component\Cache\Adapter\PhpArrayAdapter; - -/** - * @group time-sensitive - */ -class PhpArrayAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testBasicUsage' => 'PhpArrayAdapter is read-only.', - 'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.', - 'testClear' => 'PhpArrayAdapter is read-only.', - 'testClearWithDeferredItems' => 'PhpArrayAdapter is read-only.', - 'testDeleteItem' => 'PhpArrayAdapter is read-only.', - 'testSaveExpired' => 'PhpArrayAdapter is read-only.', - 'testSaveWithoutExpire' => 'PhpArrayAdapter is read-only.', - 'testDeferredSave' => 'PhpArrayAdapter is read-only.', - 'testDeferredSaveWithoutCommit' => 'PhpArrayAdapter is read-only.', - 'testDeleteItems' => 'PhpArrayAdapter is read-only.', - 'testDeleteDeferredItem' => 'PhpArrayAdapter is read-only.', - 'testCommit' => 'PhpArrayAdapter is read-only.', - 'testSaveDeferredWhenChangingValues' => 'PhpArrayAdapter is read-only.', - 'testSaveDeferredOverwrite' => 'PhpArrayAdapter is read-only.', - 'testIsHitDeferred' => 'PhpArrayAdapter is read-only.', - - 'testExpiresAt' => 'PhpArrayAdapter does not support expiration.', - 'testExpiresAtWithNull' => 'PhpArrayAdapter does not support expiration.', - 'testExpiresAfterWithNull' => 'PhpArrayAdapter does not support expiration.', - 'testDeferredExpired' => 'PhpArrayAdapter does not support expiration.', - 'testExpiration' => 'PhpArrayAdapter does not support expiration.', - - 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - - 'testDefaultLifeTime' => 'PhpArrayAdapter does not allow configuring a default lifetime.', - 'testPrune' => 'PhpArrayAdapter just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createCachePool()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createCachePool() - { - return new PhpArrayAdapterWrapper(self::$file, new NullAdapter()); - } - - public function testStore() - { - $arrayWithRefs = []; - $arrayWithRefs[0] = 123; - $arrayWithRefs[1] = &$arrayWithRefs[0]; - - $object = (object) [ - 'foo' => 'bar', - 'foo2' => 'bar2', - ]; - - $expected = [ - 'null' => null, - 'serializedString' => serialize($object), - 'arrayWithRefs' => $arrayWithRefs, - 'object' => $object, - 'arrayWithObject' => ['bar' => $object], - ]; - - $adapter = $this->createCachePool(); - $adapter->warmUp($expected); - - foreach ($expected as $key => $value) { - $this->assertSame(serialize($value), serialize($adapter->getItem($key)->get()), 'Warm up should create a PHP file that OPCache can load in memory'); - } - } - - public function testStoredFile() - { - $expected = [ - 'integer' => 42, - 'float' => 42.42, - 'boolean' => true, - 'array_simple' => ['foo', 'bar'], - 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], - ]; - - $adapter = $this->createCachePool(); - $adapter->warmUp($expected); - - $values = eval(substr(file_get_contents(self::$file), 6)); - - $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); - } -} - -class PhpArrayAdapterWrapper extends PhpArrayAdapter -{ - public function save(CacheItemInterface $item) - { - \call_user_func(\Closure::bind(function () use ($item) { - $this->values[$item->getKey()] = $item->get(); - $this->warmUp($this->values); - $this->values = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayAdapter::class)); - - return true; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php deleted file mode 100644 index 0bfd5c39..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpArrayAdapterWithFallbackTest.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\PhpArrayAdapter; - -/** - * @group time-sensitive - */ -class PhpArrayAdapterWithFallbackTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testGetItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testGetItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testHasItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testDeleteItemsInvalidKeys' => 'PhpArrayAdapter does not throw exceptions on invalid key.', - 'testPrune' => 'PhpArrayAdapter just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createCachePool()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createCachePool($defaultLifetime = 0) - { - return new PhpArrayAdapter(self::$file, new FilesystemAdapter('php-array-fallback', $defaultLifetime)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php deleted file mode 100644 index 247160d5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PhpFilesAdapterTest.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\PhpFilesAdapter; - -/** - * @group time-sensitive - */ -class PhpFilesAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDefaultLifeTime' => 'PhpFilesAdapter does not allow configuring a default lifetime.', - ]; - - public function createCachePool() - { - if (!PhpFilesAdapter::isSupported()) { - $this->markTestSkipped('OPcache extension is not enabled.'); - } - - return new PhpFilesAdapter('sf-cache'); - } - - public static function tearDownAfterClass() - { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - - protected function isPruned(CacheItemPoolInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php deleted file mode 100644 index 6aadbf26..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisAdapterTest.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Predis\Connection\StreamConnection; -use Symfony\Component\Cache\Adapter\RedisAdapter; - -class PredisAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]); - } - - public function testCreateConnection() - { - $redisHost = getenv('REDIS_HOST'); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/1', ['class' => \Predis\Client::class, 'timeout' => 3]); - $this->assertInstanceOf(\Predis\Client::class, $redis); - - $connection = $redis->getConnection(); - $this->assertInstanceOf(StreamConnection::class, $connection); - - $params = [ - 'scheme' => 'tcp', - 'host' => $redisHost, - 'path' => '', - 'dbindex' => '1', - 'port' => 6379, - 'class' => 'Predis\Client', - 'timeout' => 3, - 'persistent' => 0, - 'persistent_id' => null, - 'read_timeout' => 0, - 'retry_interval' => 0, - 'lazy' => false, - 'database' => '1', - 'password' => null, - ]; - $this->assertSame($params, $connection->getParameters()->toArray()); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php deleted file mode 100644 index 1afabaf1..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisClusterAdapterTest.php +++ /dev/null @@ -1,26 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class PredisClusterAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]); - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php deleted file mode 100644 index 5b09919e..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/PredisRedisClusterAdapterTest.php +++ /dev/null @@ -1,28 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { - self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); - } - self::$redis = new \Predis\Client(explode(' ', $hosts), ['cluster' => 'redis']); - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php deleted file mode 100644 index 810cb31a..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/ProxyAdapterTest.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\ProxyAdapter; -use Symfony\Component\Cache\CacheItem; - -/** - * @group time-sensitive - */ -class ProxyAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.', - 'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.', - 'testPrune' => 'ProxyAdapter just proxies', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new ProxyAdapter(new ArrayAdapter(), '', $defaultLifetime); - } - - public function testProxyfiedItem() - { - $this->expectException('Exception'); - $this->expectExceptionMessage('OK bar'); - $item = new CacheItem(); - $pool = new ProxyAdapter(new TestingArrayAdapter($item)); - - $proxyItem = $pool->getItem('foo'); - - $this->assertNotSame($item, $proxyItem); - $pool->save($proxyItem->set('bar')); - } -} - -class TestingArrayAdapter extends ArrayAdapter -{ - private $item; - - public function __construct(CacheItemInterface $item) - { - $this->item = $item; - } - - public function getItem($key) - { - return $this->item; - } - - public function save(CacheItemInterface $item) - { - if ($item === $this->item) { - throw new \Exception('OK '.$item->get()); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php deleted file mode 100644 index 6ec6321a..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisAdapterTest.php +++ /dev/null @@ -1,92 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Adapter\RedisAdapter; -use Symfony\Component\Cache\Traits\RedisProxy; - -class RedisAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setUpBeforeClass(); - self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]); - } - - public function createCachePool($defaultLifetime = 0) - { - $adapter = parent::createCachePool($defaultLifetime); - $this->assertInstanceOf(RedisProxy::class, self::$redis); - - return $adapter; - } - - public function testCreateConnection() - { - $redisHost = getenv('REDIS_HOST'); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost); - $this->assertInstanceOf(\Redis::class, $redis); - $this->assertTrue($redis->isConnected()); - $this->assertSame(0, $redis->getDbNum()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2'); - $this->assertSame(2, $redis->getDbNum()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]); - $this->assertEquals(3, $redis->getTimeout()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4'); - $this->assertEquals(4, $redis->getTimeout()); - - $redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); - $this->assertEquals(5, $redis->getReadTimeout()); - } - - /** - * @dataProvider provideFailedCreateConnection - */ - public function testFailedCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Redis connection '); - RedisAdapter::createConnection($dsn); - } - - public function provideFailedCreateConnection() - { - return [ - ['redis://localhost:1234'], - ['redis://foo@localhost'], - ['redis://localhost/123'], - ]; - } - - /** - * @dataProvider provideInvalidCreateConnection - */ - public function testInvalidCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Invalid Redis DSN'); - RedisAdapter::createConnection($dsn); - } - - public function provideInvalidCreateConnection() - { - return [ - ['foo://localhost'], - ['redis://'], - ]; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php deleted file mode 100644 index bd9def32..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisArrayAdapterTest.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class RedisArrayAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - parent::setupBeforeClass(); - if (!class_exists('RedisArray')) { - self::markTestSkipped('The RedisArray class is required.'); - } - self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php deleted file mode 100644 index 9c339d2d..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/RedisClusterAdapterTest.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -class RedisClusterAdapterTest extends AbstractRedisAdapterTest -{ - public static function setUpBeforeClass() - { - if (!class_exists('RedisCluster')) { - self::markTestSkipped('The RedisCluster class is required.'); - } - if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { - self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); - } - - self::$redis = new \RedisCluster(null, explode(' ', $hosts)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php deleted file mode 100644 index d8470a2e..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/SimpleCacheAdapterTest.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\SimpleCacheAdapter; -use Symfony\Component\Cache\Simple\ArrayCache; -use Symfony\Component\Cache\Simple\FilesystemCache; - -/** - * @group time-sensitive - */ -class SimpleCacheAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'SimpleCache just proxies', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new SimpleCacheAdapter(new FilesystemCache(), '', $defaultLifetime); - } - - public function testValidCacheKeyWithNamespace() - { - $cache = new SimpleCacheAdapter(new ArrayCache(), 'some_namespace', 0); - $item = $cache->getItem('my_key'); - $item->set('someValue'); - $cache->save($item); - - $this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.'); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php deleted file mode 100644 index 11907a03..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAdapterTest.php +++ /dev/null @@ -1,338 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use PHPUnit\Framework\MockObject\MockObject; -use Psr\Cache\CacheItemInterface; -use Symfony\Component\Cache\Adapter\AdapterInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\TagAwareAdapter; - -/** - * @group time-sensitive - */ -class TagAwareAdapterTest extends AdapterTestCase -{ - public function createCachePool($defaultLifetime = 0) - { - return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime)); - } - - public static function tearDownAfterClass() - { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - - public function testInvalidTag() - { - $this->expectException('Psr\Cache\InvalidArgumentException'); - $pool = $this->createCachePool(); - $item = $pool->getItem('foo'); - $item->tag(':'); - } - - public function testInvalidateTags() - { - $pool = $this->createCachePool(); - - $i0 = $pool->getItem('i0'); - $i1 = $pool->getItem('i1'); - $i2 = $pool->getItem('i2'); - $i3 = $pool->getItem('i3'); - $foo = $pool->getItem('foo'); - - $pool->save($i0->tag('bar')); - $pool->save($i1->tag('foo')); - $pool->save($i2->tag('foo')->tag('bar')); - $pool->save($i3->tag('foo')->tag('baz')); - $pool->save($foo); - - $pool->invalidateTags(['bar']); - - $this->assertFalse($pool->getItem('i0')->isHit()); - $this->assertTrue($pool->getItem('i1')->isHit()); - $this->assertFalse($pool->getItem('i2')->isHit()); - $this->assertTrue($pool->getItem('i3')->isHit()); - $this->assertTrue($pool->getItem('foo')->isHit()); - - $pool->invalidateTags(['foo']); - - $this->assertFalse($pool->getItem('i1')->isHit()); - $this->assertFalse($pool->getItem('i3')->isHit()); - $this->assertTrue($pool->getItem('foo')->isHit()); - - $anotherPoolInstance = $this->createCachePool(); - - $this->assertFalse($anotherPoolInstance->getItem('i1')->isHit()); - $this->assertFalse($anotherPoolInstance->getItem('i3')->isHit()); - $this->assertTrue($anotherPoolInstance->getItem('foo')->isHit()); - } - - public function testInvalidateCommits() - { - $pool1 = $this->createCachePool(); - - $foo = $pool1->getItem('foo'); - $foo->tag('tag'); - - $pool1->saveDeferred($foo->set('foo')); - $pool1->invalidateTags(['tag']); - - $pool2 = $this->createCachePool(); - $foo = $pool2->getItem('foo'); - - $this->assertTrue($foo->isHit()); - } - - public function testTagsAreCleanedOnSave() - { - $pool = $this->createCachePool(); - - $i = $pool->getItem('k'); - $pool->save($i->tag('foo')); - - $i = $pool->getItem('k'); - $pool->save($i->tag('bar')); - - $pool->invalidateTags(['foo']); - $this->assertTrue($pool->getItem('k')->isHit()); - } - - public function testTagsAreCleanedOnDelete() - { - $pool = $this->createCachePool(); - - $i = $pool->getItem('k'); - $pool->save($i->tag('foo')); - $pool->deleteItem('k'); - - $pool->save($pool->getItem('k')); - $pool->invalidateTags(['foo']); - - $this->assertTrue($pool->getItem('k')->isHit()); - } - - public function testTagItemExpiry() - { - $pool = $this->createCachePool(10); - - $item = $pool->getItem('foo'); - $item->tag(['baz']); - $item->expiresAfter(100); - - $pool->save($item); - $pool->invalidateTags(['baz']); - $this->assertFalse($pool->getItem('foo')->isHit()); - - sleep(20); - - $this->assertFalse($pool->getItem('foo')->isHit()); - } - - public function testGetPreviousTags() - { - $pool = $this->createCachePool(); - - $i = $pool->getItem('k'); - $pool->save($i->tag('foo')); - - $i = $pool->getItem('k'); - $this->assertSame(['foo' => 'foo'], $i->getPreviousTags()); - } - - public function testPrune() - { - $cache = new TagAwareAdapter($this->getPruneableMock()); - $this->assertTrue($cache->prune()); - - $cache = new TagAwareAdapter($this->getNonPruneableMock()); - $this->assertFalse($cache->prune()); - - $cache = new TagAwareAdapter($this->getFailingPruneableMock()); - $this->assertFalse($cache->prune()); - } - - public function testKnownTagVersionsTtl() - { - $itemsPool = new FilesystemAdapter('', 10); - $tagsPool = $this - ->getMockBuilder(AdapterInterface::class) - ->getMock(); - - $pool = new TagAwareAdapter($itemsPool, $tagsPool, 10); - - $item = $pool->getItem('foo'); - $item->tag(['baz']); - $item->expiresAfter(100); - - $tag = $this->getMockBuilder(CacheItemInterface::class)->getMock(); - $tag->expects(self::exactly(2))->method('get')->willReturn(10); - - $tagsPool->expects(self::exactly(2))->method('getItems')->willReturn([ - 'baz'.TagAwareAdapter::TAGS_PREFIX => $tag, - ]); - - $pool->save($item); - $this->assertTrue($pool->getItem('foo')->isHit()); - $this->assertTrue($pool->getItem('foo')->isHit()); - - sleep(20); - - $this->assertTrue($pool->getItem('foo')->isHit()); - - sleep(5); - - $this->assertTrue($pool->getItem('foo')->isHit()); - } - - public function testTagEntryIsCreatedForItemWithoutTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $adapter = new FilesystemAdapter(); - $this->assertTrue($adapter->hasItem(TagAwareAdapter::TAGS_PREFIX.$itemKey)); - } - - public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair - - $this->assertFalse($anotherPool->hasItem($itemKey)); - } - - public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem(TagAwareAdapter::TAGS_PREFIX.$itemKey); //simulate item losing tags pair - - $item = $anotherPool->getItem($itemKey); - $this->assertFalse($item->isHit()); - } - - public function testHasItemReturnsFalseWhenPoolDoesNotHaveItemAndOnlyHasTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem($itemKey); //simulate losing item but keeping tags - - $this->assertFalse($anotherPool->hasItem($itemKey)); - } - - public function testInvalidateTagsWithArrayAdapter() - { - $adapter = new TagAwareAdapter(new ArrayAdapter()); - - $item = $adapter->getItem('foo'); - - $this->assertFalse($item->isHit()); - - $item->tag('bar'); - $item->expiresAfter(100); - $adapter->save($item); - - $this->assertTrue($adapter->getItem('foo')->isHit()); - - $adapter->invalidateTags(['bar']); - - $this->assertFalse($adapter->getItem('foo')->isHit()); - } - - public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags() - { - $pool = $this->createCachePool(); - - $itemKey = 'foo'; - $item = $pool->getItem($itemKey); - $pool->save($item); - - $anotherPool = $this->createCachePool(); - - $adapter = new FilesystemAdapter(); - $adapter->deleteItem($itemKey); //simulate losing item but keeping tags - - $item = $anotherPool->getItem($itemKey); - $this->assertFalse($item->isHit()); - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(true); - - return $pruneable; - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getFailingPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(false); - - return $pruneable; - } - - /** - * @return MockObject|AdapterInterface - */ - private function getNonPruneableMock() - { - return $this - ->getMockBuilder(AdapterInterface::class) - ->getMock(); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php deleted file mode 100644 index b11c1f28..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TagAwareAndProxyAdapterIntegrationTest.php +++ /dev/null @@ -1,38 +0,0 @@ -getItem('foo'); - $item->tag(['tag1', 'tag2']); - $item->set('bar'); - $cache->save($item); - - $this->assertSame('bar', $cache->getItem('foo')->get()); - } - - public function dataProvider() - { - return [ - [new ArrayAdapter()], - // also testing with a non-AdapterInterface implementation - // because the ProxyAdapter behaves slightly different for those - [new ExternalAdapter()], - ]; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php deleted file mode 100644 index 35eba7d7..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableAdapterTest.php +++ /dev/null @@ -1,191 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\TraceableAdapter; - -/** - * @group time-sensitive - */ -class TraceableAdapterTest extends AdapterTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'TraceableAdapter just proxies', - ]; - - public function createCachePool($defaultLifetime = 0) - { - return new TraceableAdapter(new FilesystemAdapter('', $defaultLifetime)); - } - - public function testGetItemMissTrace() - { - $pool = $this->createCachePool(); - $pool->getItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('getItem', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(1, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testGetItemHitTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->save($item); - $pool->getItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(3, $calls); - - $call = $calls[2]; - $this->assertSame(1, $call->hits); - $this->assertSame(0, $call->misses); - } - - public function testGetItemsMissTrace() - { - $pool = $this->createCachePool(); - $arg = ['k0', 'k1']; - $items = $pool->getItems($arg); - foreach ($items as $item) { - } - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('getItems', $call->name); - $this->assertSame(['k0' => false, 'k1' => false], $call->result); - $this->assertSame(2, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasItemMissTrace() - { - $pool = $this->createCachePool(); - $pool->hasItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('hasItem', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasItemHitTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->save($item); - $pool->hasItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(3, $calls); - - $call = $calls[2]; - $this->assertSame('hasItem', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteItemTrace() - { - $pool = $this->createCachePool(); - $pool->deleteItem('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('deleteItem', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteItemsTrace() - { - $pool = $this->createCachePool(); - $arg = ['k0', 'k1']; - $pool->deleteItems($arg); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('deleteItems', $call->name); - $this->assertSame(['keys' => $arg, 'result' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testSaveTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->save($item); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('save', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testSaveDeferredTrace() - { - $pool = $this->createCachePool(); - $item = $pool->getItem('k')->set('foo'); - $pool->saveDeferred($item); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('saveDeferred', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testCommitTrace() - { - $pool = $this->createCachePool(); - $pool->commit(); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('commit', $call->name); - $this->assertTrue($call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php deleted file mode 100644 index 5cd4185c..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Adapter/TraceableTagAwareAdapterTest.php +++ /dev/null @@ -1,37 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Adapter; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Adapter\TagAwareAdapter; -use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter; - -/** - * @group time-sensitive - */ -class TraceableTagAwareAdapterTest extends TraceableAdapterTest -{ - public function testInvalidateTags() - { - $pool = new TraceableTagAwareAdapter(new TagAwareAdapter(new FilesystemAdapter())); - $pool->invalidateTags(['foo']); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('invalidateTags', $call->name); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php deleted file mode 100644 index 28c681d1..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/CacheItemTest.php +++ /dev/null @@ -1,77 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\CacheItem; - -class CacheItemTest extends TestCase -{ - public function testValidKey() - { - $this->assertSame('foo', CacheItem::validateKey('foo')); - } - - /** - * @dataProvider provideInvalidKey - */ - public function testInvalidKey($key) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Cache key'); - CacheItem::validateKey($key); - } - - public function provideInvalidKey() - { - return [ - [''], - ['{'], - ['}'], - ['('], - [')'], - ['/'], - ['\\'], - ['@'], - [':'], - [true], - [null], - [1], - [1.1], - [[[]]], - [new \Exception('foo')], - ]; - } - - public function testTag() - { - $item = new CacheItem(); - - $this->assertSame($item, $item->tag('foo')); - $this->assertSame($item, $item->tag(['bar', 'baz'])); - - \call_user_func(\Closure::bind(function () use ($item) { - $this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->tags); - }, $this, CacheItem::class)); - } - - /** - * @dataProvider provideInvalidKey - */ - public function testInvalidTag($tag) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Cache tag'); - $item = new CacheItem(); - $item->tag($tag); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php deleted file mode 100644 index 91a5516a..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/DoctrineProviderTest.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests; - -use Doctrine\Common\Cache\CacheProvider; -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\Adapter\ArrayAdapter; -use Symfony\Component\Cache\DoctrineProvider; - -class DoctrineProviderTest extends TestCase -{ - public function testProvider() - { - $pool = new ArrayAdapter(); - $cache = new DoctrineProvider($pool); - - $this->assertInstanceOf(CacheProvider::class, $cache); - - $key = '{}()/\@:'; - - $this->assertTrue($cache->delete($key)); - $this->assertFalse($cache->contains($key)); - - $this->assertTrue($cache->save($key, 'bar')); - $this->assertTrue($cache->contains($key)); - $this->assertSame('bar', $cache->fetch($key)); - - $this->assertTrue($cache->delete($key)); - $this->assertFalse($cache->fetch($key)); - $this->assertTrue($cache->save($key, 'bar')); - - $cache->flushAll(); - $this->assertFalse($cache->fetch($key)); - $this->assertFalse($cache->contains($key)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php deleted file mode 100644 index 13b4f330..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ArrayCache.php +++ /dev/null @@ -1,52 +0,0 @@ -doContains($id) ? $this->data[$id][0] : false; - } - - protected function doContains($id) - { - if (!isset($this->data[$id])) { - return false; - } - - $expiry = $this->data[$id][1]; - - return !$expiry || time() < $expiry || !$this->doDelete($id); - } - - protected function doSave($id, $data, $lifeTime = 0) - { - $this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false]; - - return true; - } - - protected function doDelete($id) - { - unset($this->data[$id]); - - return true; - } - - protected function doFlush() - { - $this->data = []; - - return true; - } - - protected function doGetStats() - { - return null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php deleted file mode 100644 index be1f9901..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Fixtures/ExternalAdapter.php +++ /dev/null @@ -1,76 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Fixtures; - -use Psr\Cache\CacheItemInterface; -use Psr\Cache\CacheItemPoolInterface; -use Symfony\Component\Cache\Adapter\ArrayAdapter; - -/** - * Adapter not implementing the {@see \Symfony\Component\Cache\Adapter\AdapterInterface}. - * - * @author Kévin Dunglas - */ -class ExternalAdapter implements CacheItemPoolInterface -{ - private $cache; - - public function __construct($defaultLifetime = 0) - { - $this->cache = new ArrayAdapter($defaultLifetime); - } - - public function getItem($key) - { - return $this->cache->getItem($key); - } - - public function getItems(array $keys = []) - { - return $this->cache->getItems($keys); - } - - public function hasItem($key) - { - return $this->cache->hasItem($key); - } - - public function clear() - { - return $this->cache->clear(); - } - - public function deleteItem($key) - { - return $this->cache->deleteItem($key); - } - - public function deleteItems(array $keys) - { - return $this->cache->deleteItems($keys); - } - - public function save(CacheItemInterface $item) - { - return $this->cache->save($item); - } - - public function saveDeferred(CacheItemInterface $item) - { - return $this->cache->saveDeferred($item); - } - - public function commit() - { - return $this->cache->commit(); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php deleted file mode 100644 index 7a6cabe8..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/AbstractRedisCacheTest.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\RedisCache; - -abstract class AbstractRedisCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testSetTtl' => 'Testing expiration slows down the test suite', - 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $redis; - - public function createSimpleCache($defaultLifetime = 0) - { - return new RedisCache(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public static function setUpBeforeClass() - { - if (!\extension_loaded('redis')) { - self::markTestSkipped('Extension redis required.'); - } - try { - (new \Redis())->connect(getenv('REDIS_HOST')); - } catch (\Exception $e) { - self::markTestSkipped($e->getMessage()); - } - } - - public static function tearDownAfterClass() - { - self::$redis = null; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php deleted file mode 100644 index fad0c043..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ApcuCacheTest.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\ApcuCache; - -class ApcuCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testSetTtl' => 'Testing expiration slows down the test suite', - 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) { - $this->markTestSkipped('APCu extension is required.'); - } - if ('\\' === \DIRECTORY_SEPARATOR) { - $this->markTestSkipped('Fails transiently on Windows.'); - } - - return new ApcuCache(str_replace('\\', '.', __CLASS__), $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php deleted file mode 100644 index 26c3e14d..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ArrayCacheTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\ArrayCache; - -/** - * @group time-sensitive - */ -class ArrayCacheTest extends CacheTestCase -{ - public function createSimpleCache($defaultLifetime = 0) - { - return new ArrayCache($defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php deleted file mode 100644 index ff9944a3..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/CacheTestCase.php +++ /dev/null @@ -1,150 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Cache\IntegrationTests\SimpleCacheTest; -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\PruneableInterface; - -abstract class CacheTestCase extends SimpleCacheTest -{ - protected function setUp() - { - parent::setUp(); - - if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createSimpleCache() instanceof PruneableInterface) { - $this->skippedTests['testPrune'] = 'Not a pruneable cache pool.'; - } - } - - public static function validKeys() - { - if (\defined('HHVM_VERSION')) { - return parent::validKeys(); - } - - return array_merge(parent::validKeys(), [["a\0b"]]); - } - - public function testDefaultLifeTime() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createSimpleCache(2); - $cache->clear(); - - $cache->set('key.dlt', 'value'); - sleep(1); - - $this->assertSame('value', $cache->get('key.dlt')); - - sleep(2); - $this->assertNull($cache->get('key.dlt')); - - $cache->clear(); - } - - public function testNotUnserializable() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = $this->createSimpleCache(); - $cache->clear(); - - $cache->set('foo', new NotUnserializable()); - - $this->assertNull($cache->get('foo')); - - $cache->setMultiple(['foo' => new NotUnserializable()]); - - foreach ($cache->getMultiple(['foo']) as $value) { - } - $this->assertNull($value); - - $cache->clear(); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - if (!method_exists($this, 'isPruned')) { - $this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.'); - } - - /** @var PruneableInterface|CacheInterface $cache */ - $cache = $this->createSimpleCache(); - $cache->clear(); - - $cache->set('foo', 'foo-val', new \DateInterval('PT05S')); - $cache->set('bar', 'bar-val', new \DateInterval('PT10S')); - $cache->set('baz', 'baz-val', new \DateInterval('PT15S')); - $cache->set('qux', 'qux-val', new \DateInterval('PT20S')); - - sleep(30); - $cache->prune(); - $this->assertTrue($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertTrue($this->isPruned($cache, 'qux')); - - $cache->set('foo', 'foo-val'); - $cache->set('bar', 'bar-val', new \DateInterval('PT20S')); - $cache->set('baz', 'baz-val', new \DateInterval('PT40S')); - $cache->set('qux', 'qux-val', new \DateInterval('PT80S')); - - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertFalse($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'bar')); - $this->assertFalse($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'baz')); - $this->assertFalse($this->isPruned($cache, 'qux')); - - sleep(30); - $cache->prune(); - $this->assertFalse($this->isPruned($cache, 'foo')); - $this->assertTrue($this->isPruned($cache, 'qux')); - - $cache->clear(); - } -} - -class NotUnserializable implements \Serializable -{ - public function serialize() - { - return serialize(123); - } - - public function unserialize($ser) - { - throw new \Exception(__CLASS__); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php deleted file mode 100644 index f216bc1f..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/ChainCacheTest.php +++ /dev/null @@ -1,113 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use PHPUnit\Framework\MockObject\MockObject; -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\PruneableInterface; -use Symfony\Component\Cache\Simple\ArrayCache; -use Symfony\Component\Cache\Simple\ChainCache; -use Symfony\Component\Cache\Simple\FilesystemCache; - -/** - * @group time-sensitive - */ -class ChainCacheTest extends CacheTestCase -{ - public function createSimpleCache($defaultLifetime = 0) - { - return new ChainCache([new ArrayCache($defaultLifetime), new FilesystemCache('', $defaultLifetime)], $defaultLifetime); - } - - public function testEmptyCachesException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('At least one cache must be specified.'); - new ChainCache([]); - } - - public function testInvalidCacheException() - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('The class "stdClass" does not implement'); - new ChainCache([new \stdClass()]); - } - - public function testPrune() - { - if (isset($this->skippedTests[__FUNCTION__])) { - $this->markTestSkipped($this->skippedTests[__FUNCTION__]); - } - - $cache = new ChainCache([ - $this->getPruneableMock(), - $this->getNonPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertTrue($cache->prune()); - - $cache = new ChainCache([ - $this->getPruneableMock(), - $this->getFailingPruneableMock(), - $this->getPruneableMock(), - ]); - $this->assertFalse($cache->prune()); - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(true); - - return $pruneable; - } - - /** - * @return MockObject|PruneableCacheInterface - */ - private function getFailingPruneableMock() - { - $pruneable = $this - ->getMockBuilder(PruneableCacheInterface::class) - ->getMock(); - - $pruneable - ->expects($this->atLeastOnce()) - ->method('prune') - ->willReturn(false); - - return $pruneable; - } - - /** - * @return MockObject|CacheInterface - */ - private function getNonPruneableMock() - { - return $this - ->getMockBuilder(CacheInterface::class) - ->getMock(); - } -} - -interface PruneableCacheInterface extends PruneableInterface, CacheInterface -{ -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php deleted file mode 100644 index af4331d6..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/DoctrineCacheTest.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\DoctrineCache; -use Symfony\Component\Cache\Tests\Fixtures\ArrayCache; - -/** - * @group time-sensitive - */ -class DoctrineCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testObjectDoesNotChangeInCache' => 'ArrayCache does not use serialize/unserialize', - 'testNotUnserializable' => 'ArrayCache does not use serialize/unserialize', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - return new DoctrineCache(new ArrayCache($defaultLifetime), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php deleted file mode 100644 index 620305a5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/FilesystemCacheTest.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\Simple\FilesystemCache; - -/** - * @group time-sensitive - */ -class FilesystemCacheTest extends CacheTestCase -{ - public function createSimpleCache($defaultLifetime = 0) - { - return new FilesystemCache('', $defaultLifetime); - } - - protected function isPruned(CacheInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php deleted file mode 100644 index 6df682e9..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTest.php +++ /dev/null @@ -1,178 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Simple\MemcachedCache; - -class MemcachedCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testSetTtl' => 'Testing expiration slows down the test suite', - 'testSetMultipleTtl' => 'Testing expiration slows down the test suite', - 'testDefaultLifeTime' => 'Testing expiration slows down the test suite', - ]; - - protected static $client; - - public static function setUpBeforeClass() - { - if (!MemcachedCache::isSupported()) { - self::markTestSkipped('Extension memcached >=2.2.0 required.'); - } - self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST')); - self::$client->get('foo'); - $code = self::$client->getResultCode(); - - if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) { - self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage())); - } - } - - public function createSimpleCache($defaultLifetime = 0) - { - $client = $defaultLifetime ? AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]) : self::$client; - - return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } - - public function testCreatePersistentConnectionShouldNotDupServerList() - { - $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); - $this->assertCount(1, $instance->getServerList()); - - $instance = MemcachedCache::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['persistent_id' => 'persistent']); - $this->assertCount(1, $instance->getServerList()); - } - - public function testOptions() - { - $client = MemcachedCache::createConnection([], [ - 'libketama_compatible' => false, - 'distribution' => 'modula', - 'compression' => true, - 'serializer' => 'php', - 'hash' => 'md5', - ]); - - $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER)); - $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH)); - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION)); - } - - /** - * @dataProvider provideBadOptions - */ - public function testBadOptions($name, $value) - { - if (\PHP_VERSION_ID < 80000) { - $this->expectException('ErrorException'); - $this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::'); - } else { - $this->expectException('Error'); - $this->expectExceptionMessage('Undefined constant Memcached::'); - } - - MemcachedCache::createConnection([], [$name => $value]); - } - - public function provideBadOptions() - { - return [ - ['foo', 'bar'], - ['hash', 'zyx'], - ['serializer', 'zyx'], - ['distribution', 'zyx'], - ]; - } - - public function testDefaultOptions() - { - $this->assertTrue(MemcachedCache::isSupported()); - - $client = MemcachedCache::createConnection([]); - - $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL)); - $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE)); - } - - public function testOptionSerializer() - { - $this->expectException('Symfony\Component\Cache\Exception\CacheException'); - $this->expectExceptionMessage('MemcachedAdapter: "serializer" option must be "php" or "igbinary".'); - if (!\Memcached::HAVE_JSON) { - $this->markTestSkipped('Memcached::HAVE_JSON required'); - } - - new MemcachedCache(MemcachedCache::createConnection([], ['serializer' => 'json'])); - } - - /** - * @dataProvider provideServersSetting - */ - public function testServersSetting($dsn, $host, $port) - { - $client1 = MemcachedCache::createConnection($dsn); - $client2 = MemcachedCache::createConnection([$dsn]); - $client3 = MemcachedCache::createConnection([[$host, $port]]); - $expect = [ - 'host' => $host, - 'port' => $port, - ]; - - $f = function ($s) { return ['host' => $s['host'], 'port' => $s['port']]; }; - $this->assertSame([$expect], array_map($f, $client1->getServerList())); - $this->assertSame([$expect], array_map($f, $client2->getServerList())); - $this->assertSame([$expect], array_map($f, $client3->getServerList())); - } - - public function provideServersSetting() - { - yield [ - 'memcached://127.0.0.1/50', - '127.0.0.1', - 11211, - ]; - yield [ - 'memcached://localhost:11222?weight=25', - 'localhost', - 11222, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@127.0.0.1?weight=50', - '127.0.0.1', - 11211, - ]; - } - yield [ - 'memcached:///var/run/memcached.sock?weight=25', - '/var/run/memcached.sock', - 0, - ]; - yield [ - 'memcached:///var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) { - yield [ - 'memcached://user:password@/var/local/run/memcached.socket?weight=25', - '/var/local/run/memcached.socket', - 0, - ]; - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php deleted file mode 100644 index 13865a60..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/MemcachedCacheTextModeTest.php +++ /dev/null @@ -1,25 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Adapter\AbstractAdapter; -use Symfony\Component\Cache\Simple\MemcachedCache; - -class MemcachedCacheTextModeTest extends MemcachedCacheTest -{ - public function createSimpleCache($defaultLifetime = 0) - { - $client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'), ['binary_protocol' => false]); - - return new MemcachedCache($client, str_replace('\\', '.', __CLASS__), $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php deleted file mode 100644 index 31f42c32..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/NullCacheTest.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use PHPUnit\Framework\TestCase; -use Symfony\Component\Cache\Simple\NullCache; - -/** - * @group time-sensitive - */ -class NullCacheTest extends TestCase -{ - public function createCachePool() - { - return new NullCache(); - } - - public function testGetItem() - { - $cache = $this->createCachePool(); - - $this->assertNull($cache->get('key')); - } - - public function testHas() - { - $this->assertFalse($this->createCachePool()->has('key')); - } - - public function testGetMultiple() - { - $cache = $this->createCachePool(); - - $keys = ['foo', 'bar', 'baz', 'biz']; - - $default = new \stdClass(); - $items = $cache->getMultiple($keys, $default); - $count = 0; - - foreach ($items as $key => $item) { - $this->assertContains($key, $keys, 'Cache key can not change.'); - $this->assertSame($default, $item); - - // Remove $key for $keys - foreach ($keys as $k => $v) { - if ($v === $key) { - unset($keys[$k]); - } - } - - ++$count; - } - - $this->assertSame(4, $count); - } - - public function testClear() - { - $this->assertTrue($this->createCachePool()->clear()); - } - - public function testDelete() - { - $this->assertTrue($this->createCachePool()->delete('key')); - } - - public function testDeleteMultiple() - { - $this->assertTrue($this->createCachePool()->deleteMultiple(['key', 'foo', 'bar'])); - } - - public function testSet() - { - $cache = $this->createCachePool(); - - $this->assertFalse($cache->set('key', 'val')); - $this->assertNull($cache->get('key')); - } - - public function testSetMultiple() - { - $cache = $this->createCachePool(); - - $this->assertFalse($cache->setMultiple(['key' => 'val'])); - $this->assertNull($cache->get('key')); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php deleted file mode 100644 index f5a26341..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoCacheTest.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\PdoCache; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoCacheTest extends CacheTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoCache('sqlite:'.self::$dbFile); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createSimpleCache($defaultLifetime = 0) - { - return new PdoCache('sqlite:'.self::$dbFile, 'ns', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php deleted file mode 100644 index 4da2b603..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PdoDbalCacheTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Doctrine\DBAL\DriverManager; -use Symfony\Component\Cache\Simple\PdoCache; -use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait; - -/** - * @group time-sensitive - */ -class PdoDbalCacheTest extends CacheTestCase -{ - use PdoPruneableTrait; - - protected static $dbFile; - - public static function setUpBeforeClass() - { - if (!\extension_loaded('pdo_sqlite')) { - self::markTestSkipped('Extension pdo_sqlite required.'); - } - - self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache'); - - $pool = new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile])); - $pool->createTable(); - } - - public static function tearDownAfterClass() - { - @unlink(self::$dbFile); - } - - public function createSimpleCache($defaultLifetime = 0) - { - return new PdoCache(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]), '', $defaultLifetime); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php deleted file mode 100644 index bcd7dea5..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheTest.php +++ /dev/null @@ -1,145 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\NullCache; -use Symfony\Component\Cache\Simple\PhpArrayCache; -use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; - -/** - * @group time-sensitive - */ -class PhpArrayCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testBasicUsageWithLongKey' => 'PhpArrayCache does no writes', - - 'testDelete' => 'PhpArrayCache does no writes', - 'testDeleteMultiple' => 'PhpArrayCache does no writes', - 'testDeleteMultipleGenerator' => 'PhpArrayCache does no writes', - - 'testSetTtl' => 'PhpArrayCache does no expiration', - 'testSetMultipleTtl' => 'PhpArrayCache does no expiration', - 'testSetExpiredTtl' => 'PhpArrayCache does no expiration', - 'testSetMultipleExpiredTtl' => 'PhpArrayCache does no expiration', - - 'testGetInvalidKeys' => 'PhpArrayCache does no validation', - 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetInvalidTtl' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', - 'testHasInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetValidData' => 'PhpArrayCache does no validation', - - 'testDefaultLifeTime' => 'PhpArrayCache does not allow configuring a default lifetime.', - 'testPrune' => 'PhpArrayCache just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createSimpleCache()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createSimpleCache() - { - return new PhpArrayCacheWrapper(self::$file, new NullCache()); - } - - public function testStore() - { - $arrayWithRefs = []; - $arrayWithRefs[0] = 123; - $arrayWithRefs[1] = &$arrayWithRefs[0]; - - $object = (object) [ - 'foo' => 'bar', - 'foo2' => 'bar2', - ]; - - $expected = [ - 'null' => null, - 'serializedString' => serialize($object), - 'arrayWithRefs' => $arrayWithRefs, - 'object' => $object, - 'arrayWithObject' => ['bar' => $object], - ]; - - $cache = new PhpArrayCache(self::$file, new NullCache()); - $cache->warmUp($expected); - - foreach ($expected as $key => $value) { - $this->assertSame(serialize($value), serialize($cache->get($key)), 'Warm up should create a PHP file that OPCache can load in memory'); - } - } - - public function testStoredFile() - { - $expected = [ - 'integer' => 42, - 'float' => 42.42, - 'boolean' => true, - 'array_simple' => ['foo', 'bar'], - 'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'], - ]; - - $cache = new PhpArrayCache(self::$file, new NullCache()); - $cache->warmUp($expected); - - $values = eval(substr(file_get_contents(self::$file), 6)); - - $this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory'); - } -} - -class PhpArrayCacheWrapper extends PhpArrayCache -{ - public function set($key, $value, $ttl = null) - { - \call_user_func(\Closure::bind(function () use ($key, $value) { - $this->values[$key] = $value; - $this->warmUp($this->values); - $this->values = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayCache::class)); - - return true; - } - - public function setMultiple($values, $ttl = null) - { - if (!\is_array($values) && !$values instanceof \Traversable) { - return parent::setMultiple($values, $ttl); - } - \call_user_func(\Closure::bind(function () use ($values) { - foreach ($values as $key => $value) { - $this->values[$key] = $value; - } - $this->warmUp($this->values); - $this->values = eval(substr(file_get_contents($this->file), 6)); - }, $this, PhpArrayCache::class)); - - return true; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php deleted file mode 100644 index b08c1604..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpArrayCacheWithFallbackTest.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\FilesystemCache; -use Symfony\Component\Cache\Simple\PhpArrayCache; -use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest; - -/** - * @group time-sensitive - */ -class PhpArrayCacheWithFallbackTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testGetInvalidKeys' => 'PhpArrayCache does no validation', - 'testGetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteInvalidKeys' => 'PhpArrayCache does no validation', - 'testDeleteMultipleInvalidKeys' => 'PhpArrayCache does no validation', - //'testSetValidData' => 'PhpArrayCache does no validation', - 'testSetInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetInvalidTtl' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidKeys' => 'PhpArrayCache does no validation', - 'testSetMultipleInvalidTtl' => 'PhpArrayCache does no validation', - 'testHasInvalidKeys' => 'PhpArrayCache does no validation', - 'testPrune' => 'PhpArrayCache just proxies', - ]; - - protected static $file; - - public static function setUpBeforeClass() - { - self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php'; - } - - protected function tearDown() - { - $this->createSimpleCache()->clear(); - - if (file_exists(sys_get_temp_dir().'/symfony-cache')) { - FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache'); - } - } - - public function createSimpleCache($defaultLifetime = 0) - { - return new PhpArrayCache(self::$file, new FilesystemCache('php-array-fallback', $defaultLifetime)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php deleted file mode 100644 index 936f29a4..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/PhpFilesCacheTest.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Psr\SimpleCache\CacheInterface; -use Symfony\Component\Cache\Simple\PhpFilesCache; - -/** - * @group time-sensitive - */ -class PhpFilesCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testDefaultLifeTime' => 'PhpFilesCache does not allow configuring a default lifetime.', - ]; - - public function createSimpleCache() - { - if (!PhpFilesCache::isSupported()) { - $this->markTestSkipped('OPcache extension is not enabled.'); - } - - return new PhpFilesCache('sf-cache'); - } - - protected function isPruned(CacheInterface $cache, $name) - { - $getFileMethod = (new \ReflectionObject($cache))->getMethod('getFile'); - $getFileMethod->setAccessible(true); - - return !file_exists($getFileMethod->invoke($cache, $name)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php deleted file mode 100644 index 1bc75c90..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/Psr6CacheTest.php +++ /dev/null @@ -1,30 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use Symfony\Component\Cache\Simple\Psr6Cache; - -/** - * @group time-sensitive - */ -class Psr6CacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'Psr6Cache just proxies', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php deleted file mode 100644 index ec5e4c06..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisArrayCacheTest.php +++ /dev/null @@ -1,24 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -class RedisArrayCacheTest extends AbstractRedisCacheTest -{ - public static function setUpBeforeClass() - { - parent::setupBeforeClass(); - if (!class_exists('RedisArray')) { - self::markTestSkipped('The RedisArray class is required.'); - } - self::$redis = new \RedisArray([getenv('REDIS_HOST')], ['lazy_connect' => true]); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php deleted file mode 100644 index 8e3f6088..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisCacheTest.php +++ /dev/null @@ -1,82 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\RedisCache; - -class RedisCacheTest extends AbstractRedisCacheTest -{ - public static function setUpBeforeClass() - { - parent::setupBeforeClass(); - self::$redis = RedisCache::createConnection('redis://'.getenv('REDIS_HOST')); - } - - public function testCreateConnection() - { - $redisHost = getenv('REDIS_HOST'); - - $redis = RedisCache::createConnection('redis://'.$redisHost); - $this->assertInstanceOf(\Redis::class, $redis); - $this->assertTrue($redis->isConnected()); - $this->assertSame(0, $redis->getDbNum()); - - $redis = RedisCache::createConnection('redis://'.$redisHost.'/2'); - $this->assertSame(2, $redis->getDbNum()); - - $redis = RedisCache::createConnection('redis://'.$redisHost, ['timeout' => 3]); - $this->assertEquals(3, $redis->getTimeout()); - - $redis = RedisCache::createConnection('redis://'.$redisHost.'?timeout=4'); - $this->assertEquals(4, $redis->getTimeout()); - - $redis = RedisCache::createConnection('redis://'.$redisHost, ['read_timeout' => 5]); - $this->assertEquals(5, $redis->getReadTimeout()); - } - - /** - * @dataProvider provideFailedCreateConnection - */ - public function testFailedCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Redis connection '); - RedisCache::createConnection($dsn); - } - - public function provideFailedCreateConnection() - { - return [ - ['redis://localhost:1234'], - ['redis://foo@localhost'], - ['redis://localhost/123'], - ]; - } - - /** - * @dataProvider provideInvalidCreateConnection - */ - public function testInvalidCreateConnection($dsn) - { - $this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException'); - $this->expectExceptionMessage('Invalid Redis DSN'); - RedisCache::createConnection($dsn); - } - - public function provideInvalidCreateConnection() - { - return [ - ['foo://localhost'], - ['redis://'], - ]; - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php deleted file mode 100644 index 6b7f8039..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/RedisClusterCacheTest.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -class RedisClusterCacheTest extends AbstractRedisCacheTest -{ - public static function setUpBeforeClass() - { - if (!class_exists('RedisCluster')) { - self::markTestSkipped('The RedisCluster class is required.'); - } - if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) { - self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.'); - } - - self::$redis = new \RedisCluster(null, explode(' ', $hosts)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php deleted file mode 100644 index e684caf3..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Simple/TraceableCacheTest.php +++ /dev/null @@ -1,171 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Simple; - -use Symfony\Component\Cache\Simple\FilesystemCache; -use Symfony\Component\Cache\Simple\TraceableCache; - -/** - * @group time-sensitive - */ -class TraceableCacheTest extends CacheTestCase -{ - protected $skippedTests = [ - 'testPrune' => 'TraceableCache just proxies', - ]; - - public function createSimpleCache($defaultLifetime = 0) - { - return new TraceableCache(new FilesystemCache('', $defaultLifetime)); - } - - public function testGetMissTrace() - { - $pool = $this->createSimpleCache(); - $pool->get('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('get', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(1, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testGetHitTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k', 'foo'); - $pool->get('k'); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame(1, $call->hits); - $this->assertSame(0, $call->misses); - } - - public function testGetMultipleMissTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k1', 123); - $values = $pool->getMultiple(['k0', 'k1']); - foreach ($values as $value) { - } - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('getMultiple', $call->name); - $this->assertSame(['k1' => true, 'k0' => false], $call->result); - $this->assertSame(1, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasMissTrace() - { - $pool = $this->createSimpleCache(); - $pool->has('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('has', $call->name); - $this->assertSame(['k' => false], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testHasHitTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k', 'foo'); - $pool->has('k'); - $calls = $pool->getCalls(); - $this->assertCount(2, $calls); - - $call = $calls[1]; - $this->assertSame('has', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteTrace() - { - $pool = $this->createSimpleCache(); - $pool->delete('k'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('delete', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testDeleteMultipleTrace() - { - $pool = $this->createSimpleCache(); - $arg = ['k0', 'k1']; - $pool->deleteMultiple($arg); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('deleteMultiple', $call->name); - $this->assertSame(['keys' => $arg, 'result' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testTraceSetTrace() - { - $pool = $this->createSimpleCache(); - $pool->set('k', 'foo'); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('set', $call->name); - $this->assertSame(['k' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } - - public function testSetMultipleTrace() - { - $pool = $this->createSimpleCache(); - $pool->setMultiple(['k' => 'foo']); - $calls = $pool->getCalls(); - $this->assertCount(1, $calls); - - $call = $calls[0]; - $this->assertSame('setMultiple', $call->name); - $this->assertSame(['keys' => ['k'], 'result' => true], $call->result); - $this->assertSame(0, $call->hits); - $this->assertSame(0, $call->misses); - $this->assertNotEmpty($call->start); - $this->assertNotEmpty($call->end); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php b/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php deleted file mode 100644 index c405de70..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/Tests/Traits/PdoPruneableTrait.php +++ /dev/null @@ -1,34 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Cache\Tests\Traits; - -trait PdoPruneableTrait -{ - protected function isPruned($cache, $name) - { - $o = new \ReflectionObject($cache); - - if (!$o->hasMethod('getConnection')) { - self::fail('Cache does not have "getConnection()" method.'); - } - - $getPdoConn = $o->getMethod('getConnection'); - $getPdoConn->setAccessible(true); - - /** @var \Doctrine\DBAL\Statement|\PDOStatement $select */ - $select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id'); - $select->bindValue(':id', sprintf('%%%s', $name)); - $result = $select->execute(); - - return 1 !== (int) (\is_object($result) ? $result->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN)); - } -} diff --git a/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist b/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist deleted file mode 100644 index c35458ca..00000000 --- a/advancedcontentfilter/vendor/symfony/cache/phpunit.xml.dist +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - ./Tests/ - - - - - - ./ - - ./Tests - ./vendor - - - - - - - - - - - Cache\IntegrationTests - Doctrine\Common\Cache - Symfony\Component\Cache - Symfony\Component\Cache\Tests\Fixtures - Symfony\Component\Cache\Traits - - - - - - - diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php deleted file mode 100644 index 4dc5bf9a..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/Apcu.php +++ /dev/null @@ -1,106 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Apcu; - -/** - * Apcu for Zend Server Data Cache. - * - * @author Kate Gray - * @author Nicolas Grekas - * - * @internal - */ -final class Apcu -{ - public static function apcu_add($key, $var = null, $ttl = 0) - { - if (!\is_array($key)) { - return apc_add($key, $var, $ttl); - } - - $errors = []; - foreach ($key as $k => $v) { - if (!apc_add($k, $v, $ttl)) { - $errors[$k] = -1; - } - } - - return $errors; - } - - public static function apcu_store($key, $var = null, $ttl = 0) - { - if (!\is_array($key)) { - return apc_store($key, $var, $ttl); - } - - $errors = []; - foreach ($key as $k => $v) { - if (!apc_store($k, $v, $ttl)) { - $errors[$k] = -1; - } - } - - return $errors; - } - - public static function apcu_exists($keys) - { - if (!\is_array($keys)) { - return apc_exists($keys); - } - - $existing = []; - foreach ($keys as $k) { - if (apc_exists($k)) { - $existing[$k] = true; - } - } - - return $existing; - } - - public static function apcu_fetch($key, &$success = null) - { - if (!\is_array($key)) { - return apc_fetch($key, $success); - } - - $succeeded = true; - $values = []; - foreach ($key as $k) { - $v = apc_fetch($k, $success); - if ($success) { - $values[$k] = $v; - } else { - $succeeded = false; - } - } - $success = $succeeded; - - return $values; - } - - public static function apcu_delete($key) - { - if (!\is_array($key)) { - return apc_delete($key); - } - - $success = true; - foreach ($key as $k) { - $success = apc_delete($k) && $success; - } - - return $success; - } -} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE b/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE deleted file mode 100644 index 6e3afce6..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-present Fabien Potencier - -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/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md b/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md deleted file mode 100644 index 57f4bf6b..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Symfony Polyfill / APCu -======================== - -This component provides `apcu_*` functions and the `APCuIterator` class to users of the legacy APC extension. - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php deleted file mode 100644 index 96b2706a..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap.php +++ /dev/null @@ -1,83 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Apcu as p; - -if (!extension_loaded('apc') && !extension_loaded('apcu')) { - return; -} - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (extension_loaded('Zend Data Cache')) { - if (!function_exists('apcu_add')) { - function apcu_add($key, $value = null, $ttl = 0) { return p\Apcu::apcu_add($key, $value, $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key) { return p\Apcu::apcu_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key) { return p\Apcu::apcu_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null) { return p\Apcu::apcu_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, $value = null, $ttl = 0) { return p\Apcu::apcu_store($key, $value, $ttl); } - } -} else { - if (!function_exists('apcu_add')) { - function apcu_add($key, $value = null, $ttl = 0) { return apc_add($key, $value, $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key) { return apc_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key) { return apc_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, $value = null, $ttl = 0) { return apc_store($key, $value, $ttl); } - } -} - -if (!function_exists('apcu_cache_info')) { - function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } -} -if (!function_exists('apcu_cas')) { - function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } -} -if (!function_exists('apcu_clear_cache')) { - function apcu_clear_cache() { return apc_clear_cache('user'); } -} -if (!function_exists('apcu_dec')) { - function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } -} -if (!function_exists('apcu_inc')) { - function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } -} -if (!function_exists('apcu_sma_info')) { - function apcu_sma_info($limited = false) { return apc_sma_info($limited); } -} - -if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { - class APCuIterator extends APCIterator - { - public function __construct($search = null, $format = \APC_ITER_ALL, $chunk_size = 100, $list = \APC_LIST_ACTIVE) - { - parent::__construct('user', $search, $format, $chunk_size, $list); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php b/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php deleted file mode 100644 index 69e9f160..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/bootstrap80.php +++ /dev/null @@ -1,75 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Apcu as p; - -if (extension_loaded('Zend Data Cache')) { - if (!function_exists('apcu_add')) { - function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_add($key, $value, (int) $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key): array|bool { return p\Apcu::apcu_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key): array|bool { return p\Apcu::apcu_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null): mixed { return p\Apcu::apcu_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return p\Apcu::apcu_store($key, $value, (int) $ttl); } - } -} else { - if (!function_exists('apcu_add')) { - function apcu_add($key, mixed $value, ?int $ttl = 0): array|bool { return apc_add($key, $value, (int) $ttl); } - } - if (!function_exists('apcu_delete')) { - function apcu_delete($key): array|bool { return apc_delete($key); } - } - if (!function_exists('apcu_exists')) { - function apcu_exists($key): array|bool { return apc_exists($key); } - } - if (!function_exists('apcu_fetch')) { - function apcu_fetch($key, &$success = null) { return apc_fetch($key, $success); } - } - if (!function_exists('apcu_store')) { - function apcu_store($key, mixed $value, ?int $ttl = 0): array|bool { return apc_store($key, $value, (int) $ttl); } - } -} - -if (!function_exists('apcu_cache_info')) { - function apcu_cache_info($limited = false) { return apc_cache_info('user', $limited); } -} -if (!function_exists('apcu_cas')) { - function apcu_cas($key, $old, $new) { return apc_cas($key, $old, $new); } -} -if (!function_exists('apcu_clear_cache')) { - function apcu_clear_cache() { return apc_clear_cache('user'); } -} -if (!function_exists('apcu_dec')) { - function apcu_dec($key, $step = 1, &$success = false) { return apc_dec($key, $step, $success); } -} -if (!function_exists('apcu_inc')) { - function apcu_inc($key, $step = 1, &$success = false) { return apc_inc($key, $step, $success); } -} -if (!function_exists('apcu_sma_info')) { - function apcu_sma_info($limited = false) { return apc_sma_info($limited); } -} - -if (!class_exists('APCuIterator', false) && class_exists('APCIterator', false)) { - class APCuIterator extends APCIterator - { - public function __construct($search = null, $format = APC_ITER_ALL, $chunk_size = 100, $list = APC_LIST_ACTIVE) - { - parent::__construct('user', $search, $format, $chunk_size, $list); - } - } -} diff --git a/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json b/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json deleted file mode 100644 index e92524f3..00000000 --- a/advancedcontentfilter/vendor/symfony/polyfill-apcu/composer.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "symfony/polyfill-apcu", - "type": "library", - "description": "Symfony polyfill backporting apcu_* functions to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable", "apcu"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Apcu\\": "" }, - "files": [ "bootstrap.php" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} From 7fcbd76c6b9a0d2b8a704fc5739c4f2d31f15c9f Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 Nov 2024 07:03:42 +0000 Subject: [PATCH 126/294] Bluesky: Improved handling of starter packs --- bluesky/bluesky.php | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index d719eecb..a78480b6 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1481,11 +1481,7 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le if (!empty($embed->record->record->$type)) { $embed_type = $embed->record->record->$type; if ($embed_type == 'app.bsky.graph.starterpack') { - Logger::debug('Starterpacks are not fetched like posts', ['original-uri' => $original_uri]); - if (empty($item['body'])) { - // @todo process starterpack - $item['body'] = '[url=' . $embed->record->record->list . ']' . $embed->record->record->name . '[/url]'; - } + bluesky_add_starterpack($item, $embed->record); break; } } @@ -1523,6 +1519,30 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le return $item; } +function bluesky_add_starterpack(array $item, stdClass $record) +{ + Logger::debug('Received starterpack', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'uri' => $record->uri]); + if (!preg_match('#^at://(.+)/app.bsky.graph.starterpack/(.+)#', $record->uri, $matches)) { + return; + } + + $media = [ + 'uri-id' => $item['uri-id'], + 'type' => Post\Media::HTML, + 'url' => 'https://bsky.app/starter-pack/' . $matches[1] . '/' . $matches[2], + 'name' => $record->record->name, + 'description' => $record->record->description, + ]; + + Post\Media::insert($media); + + $fields = [ + 'name' => $record->record->name, + 'description' => $record->record->description, + ]; + Post\Media::update($fields, ['uri-id' => $media['uri-id'], 'url' => $media['url']]); +} + function bluesky_get_uri(stdClass $post): string { if (empty($post->cid)) { From f52bb75c97125045e6e5b2f9d1d743639120eb99 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 20 Nov 2024 21:39:09 +0000 Subject: [PATCH 127/294] Blockbot: Drupal added --- blockbot/blockbot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index adf0a7c2..022f188d 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -461,7 +461,7 @@ function blockbot_is_social_media(array $parts): bool $agents = [ 'facebookexternalhit', 'twitterbot', 'mastodon', 'facebookexternalua', - 'friendica', 'diasporafederation', 'buzzrelay', 'activityrelay', + 'friendica', 'diasporafederation', 'buzzrelay', 'activityrelay', 'drupal', 'aoderelay', 'ap-relay', 'peertube', 'misskey', 'pleroma', 'foundkey', 'akkoma', 'lemmy', 'calckey', 'mobilizon', 'zot', 'camo-rs', 'gotosocial', 'pixelfed', 'pixelfedbot', 'app.wafrn.net', 'go-camo', 'http://a.gup.pe', 'iceshrimp', From 2ea40dc897c90d65c7be085fbd66fb5cc8d70c96 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 23 Nov 2024 22:28:59 +0100 Subject: [PATCH 128/294] Remove unused App paramter in securemail addon --- securemail/securemail.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/securemail/securemail.php b/securemail/securemail.php index 5390ebd1..61125587 100644 --- a/securemail/securemail.php +++ b/securemail/securemail.php @@ -82,7 +82,7 @@ function securemail_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'securemail', 'enable', $enable); if (!empty($_POST['securemail-test'])) { - $res = DI::emailer()->send(new SecureTestEmail(DI::app(), DI::config(), DI::pConfig(), DI::baseUrl())); + $res = DI::emailer()->send(new SecureTestEmail(DI::config(), DI::pConfig(), DI::baseUrl())); // revert to saved value DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'securemail', 'enable', $enable); From ecf0edb520c50edca5512f0c450761c5d9d56121 Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 23 Nov 2024 09:32:43 +0100 Subject: [PATCH 129/294] Remove unused parameter webdav_storage addon --- webdav_storage/webdav_storage.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/webdav_storage/webdav_storage.php b/webdav_storage/webdav_storage.php index adcbea29..fd2eb0d9 100644 --- a/webdav_storage/webdav_storage.php +++ b/webdav_storage/webdav_storage.php @@ -8,11 +8,10 @@ use Friendica\Addon\webdav_storage\src\WebDav; use Friendica\Addon\webdav_storage\src\WebDavConfig; -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; -function webdav_storage_install($a) +function webdav_storage_install() { Hook::register('storage_instance' , __FILE__, 'webdav_storage_instance'); Hook::register('storage_config' , __FILE__, 'webdav_storage_config'); From bf679262b0b238378a75ed0c7f7436cfe999ac7d Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Sat, 23 Nov 2024 22:42:52 +0100 Subject: [PATCH 130/294] Remove unused parameter in saml addon --- saml/saml.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/saml/saml.php b/saml/saml.php index 56dd0f5d..9f065355 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -161,7 +161,7 @@ function saml_sso_reply() } if (!empty($user['uid'])) { - DI::auth()->setForUser(DI::app(), $user); + DI::auth()->setForUser($user); } if (isset($_POST['RelayState']) && Utils::getSelfURL() != $_POST['RelayState']) { From 348c44c972e54090f329511e992c7ea5618dd862 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sun, 24 Nov 2024 15:36:37 +0000 Subject: [PATCH 131/294] inline slim routes and middlewares into advancedcontentfilter addon --- .../advancedcontentfilter.php | 25 +++++++++++-- advancedcontentfilter/src/middlewares.php | 32 ----------------- advancedcontentfilter/src/routes.php | 36 ------------------- 3 files changed, 23 insertions(+), 70 deletions(-) delete mode 100644 advancedcontentfilter/src/middlewares.php delete mode 100644 advancedcontentfilter/src/routes.php diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index 418b253e..84eb468c 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -192,9 +192,30 @@ function advancedcontentfilter_init() if (DI::args()->getArgc() > 1 && DI::args()->getArgv()[1] == 'api') { $slim = \Slim\Factory\AppFactory::create(); - require __DIR__ . '/src/middlewares.php'; + /** + * The routing middleware should be added before the ErrorMiddleware + * Otherwise exceptions thrown from it will not be handled + */ + $slim->addRoutingMiddleware(); + + $slim->addErrorMiddleware(true, true, true, DI::logger()); + + // register routes + $slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->get('', 'advancedcontentfilter_get_rules'); + $app->post('', 'advancedcontentfilter_post_rules'); + + $app->get('/{id}', 'advancedcontentfilter_get_rules_id'); + $app->put('/{id}', 'advancedcontentfilter_put_rules_id'); + $app->delete('/{id}', 'advancedcontentfilter_delete_rules_id'); + }); + + $app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) { + $app->get('/{guid}', 'advancedcontentfilter_get_variables_guid'); + }); + }); - require __DIR__ . '/src/routes.php'; $slim->run(); exit; diff --git a/advancedcontentfilter/src/middlewares.php b/advancedcontentfilter/src/middlewares.php deleted file mode 100644 index 2b831473..00000000 --- a/advancedcontentfilter/src/middlewares.php +++ /dev/null @@ -1,32 +0,0 @@ -. - * - */ - -use Friendica\DI; - -/** @var $slim \Slim\App */ - -/** - * The routing middleware should be added before the ErrorMiddleware - * Otherwise exceptions thrown from it will not be handled - */ -$slim->addRoutingMiddleware(); - -$errorMiddleware = $slim->addErrorMiddleware(true, true, true, DI::logger()); diff --git a/advancedcontentfilter/src/routes.php b/advancedcontentfilter/src/routes.php deleted file mode 100644 index a46f1b4b..00000000 --- a/advancedcontentfilter/src/routes.php +++ /dev/null @@ -1,36 +0,0 @@ -. - * - */ - -/* @var $slim Slim\App */ -$slim->group('/advancedcontentfilter/api', function (\Slim\Routing\RouteCollectorProxy $app) { - $app->group('/rules', function (\Slim\Routing\RouteCollectorProxy $app) { - $app->get('', 'advancedcontentfilter_get_rules'); - $app->post('', 'advancedcontentfilter_post_rules'); - - $app->get('/{id}', 'advancedcontentfilter_get_rules_id'); - $app->put('/{id}', 'advancedcontentfilter_put_rules_id'); - $app->delete('/{id}', 'advancedcontentfilter_delete_rules_id'); - }); - - $app->group('/variables', function (\Slim\Routing\RouteCollectorProxy $app) { - $app->get('/{guid}', 'advancedcontentfilter_get_variables_guid'); - }); -}); From e9d3afb483eff053d0e53d2f55d9d59cd6d7f29e Mon Sep 17 00:00:00 2001 From: Art4 Date: Sun, 24 Nov 2024 19:51:37 +0000 Subject: [PATCH 132/294] Fix errors in tictac addon --- tictac/tictac.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tictac/tictac.php b/tictac/tictac.php index 0f9f4fb6..dc9f0348 100644 --- a/tictac/tictac.php +++ b/tictac/tictac.php @@ -70,6 +70,7 @@ class tictac { private $dimen; private $first_move = true; private $handicap = 0; + private $mefirst; private $yours; private $mine; private $winning_play; @@ -161,10 +162,10 @@ class tictac { ]; - function __construct($dimen,$handicap,$mefirst,$yours,$mine) { + function __construct($dimen, $handicap, $mefirst, $yours, $mine) { $this->dimen = 3; - $this->handicap = (($handicap) ? 1 : 0); - $this->mefirst = (($mefirst) ? 1 : 0); + $this->handicap = $handicap ? 1 : 0; + $this->mefirst = $mefirst ? 1 : 0; $this->yours = str_replace('XXX','',$yours); $this->mine = $mine; $this->you = $this->parse_moves('you'); @@ -175,6 +176,7 @@ class tictac { } function play() { + $o = ''; if($this->first_move) { if(rand(0,1) == 1) { From 6df91dd37bd96bac74a2e347640b0a81684c3028 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sun, 24 Nov 2024 19:55:54 +0000 Subject: [PATCH 133/294] Fix errors in statusnet addon --- statusnet/library/codebirdsn.php | 7 +++---- tictac/tictac.php | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/statusnet/library/codebirdsn.php b/statusnet/library/codebirdsn.php index 020c69c4..325bcb07 100644 --- a/statusnet/library/codebirdsn.php +++ b/statusnet/library/codebirdsn.php @@ -762,13 +762,13 @@ class CodebirdSN * @param string $method The API method to call * @param array $params The parameters to send along * - * @return void + * @return string */ protected function _buildMultipart($method, $params) { // well, files will only work in multipart methods if (! $this->_detectMultipart($method)) { - return; + return ''; } // only check specific parameters @@ -783,7 +783,7 @@ class CodebirdSN ); // method might have files? if (! in_array($method, array_keys($possible_files))) { - return; + return ''; } $possible_files = explode(' ', $possible_files[$method]); @@ -794,7 +794,6 @@ class CodebirdSN // is it an array? if (is_array($value)) { throw new \Exception('Using URL-encoded parameters is not supported for uploading media.'); - continue; } // check for filenames diff --git a/tictac/tictac.php b/tictac/tictac.php index dc9f0348..10103835 100644 --- a/tictac/tictac.php +++ b/tictac/tictac.php @@ -631,7 +631,7 @@ function winning_move() { function draw_board() { if(! strlen($this->yours)) $this->yours = 'XXX'; - $o .= "

handicap}/{$this->mefirst}/{$this->dimen}/{$this->yours}/{$this->mine}\" method=\"post\" />"; + $o = "handicap}/{$this->mefirst}/{$this->dimen}/{$this->yours}/{$this->mine}\" method=\"post\" />"; for($x = 0; $x < $this->dimen; $x ++) { $o .= ''; for($y = 0; $y < $this->dimen; $y ++) { From 422e4fd48f80487bf751acc3b19ebe6b5b1d8fc2 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 24 Nov 2024 09:11:25 +0000 Subject: [PATCH 134/294] Bluesky: Fetch quoted post for "uid=0" --- bluesky/bluesky.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index a78480b6..74d4fee8 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1036,7 +1036,7 @@ function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $ } if ($complete) { - $uri = bluesky_fetch_missing_post($post->uri, $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); + $uri = bluesky_fetch_missing_post(bluesky_get_uri($post), $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); $uri_id = bluesky_fetch_uri_id($uri, $uid); } else { $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll); @@ -1060,7 +1060,6 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) 'wall' => false, 'uri' => $reason->by->did . '/app.bsky.feed.repost/' . $reason->indexedAt, 'private' => Item::UNLISTED, - 'verb' => Activity::POST, 'contact-id' => $contact['id'], 'author-name' => $contact['name'], 'author-link' => $contact['url'], @@ -1485,7 +1484,12 @@ function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $le break; } } - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); + $fetched_uri = bluesky_fetch_post($uri, $item['uid']); + if (!$fetched_uri) { + $uri = bluesky_fetch_missing_post($uri, 0, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); + } else { + $uri = $fetched_uri; + } if ($uri) { $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); $uri_id = $shared['uri-id'] ?? 0; From d7d6a43655734a1ebeb0d70481452447baf5a80e Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 26 Nov 2024 07:55:01 +0000 Subject: [PATCH 135/294] Add checks for CLD2Detector ans CLD2Encoding classes --- cld/cld.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/cld/cld.php b/cld/cld.php index 5ca4c932..83361e2b 100644 --- a/cld/cld.php +++ b/cld/cld.php @@ -22,6 +22,16 @@ function cld_detect_languages(array &$data) return; } + if (!class_exists('CLD2Detector')) { + Logger::warning('CLD2Detector class does not exist.'); + return; + } + + if (!class_exists('CLD2Encoding')) { + Logger::warning('CLD2Encoding class does not exist.'); + return; + } + $cld2 = new \CLD2Detector(); $cld2->setEncodingHint(CLD2Encoding::UTF8); // optional, hints about text encoding From fc0dda0cd9b607dc8d87f73644108f922f6bb1e1 Mon Sep 17 00:00:00 2001 From: Art4 Date: Tue, 26 Nov 2024 08:23:27 +0000 Subject: [PATCH 136/294] refactor convert addon, replace each() calls with foreach loop --- convert/convert.php | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/convert/convert.php b/convert/convert.php index 57ce6ea8..2c97e2aa 100644 --- a/convert/convert.php +++ b/convert/convert.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; function convert_install() { @@ -26,7 +25,7 @@ function convert_content() { // @TODO Let's one day rewrite this to a modern composer package include 'UnitConvertor.php'; - class TP_Converter extends UnitConvertor + $conv = new class('en') extends UnitConvertor { public function __construct(string $lang = 'en') { @@ -43,7 +42,7 @@ function convert_content() { private function findBaseUnit($from, $to) { - while (list($skey, $sval) = each($this->bases)) { + foreach ($this->bases as $skey => $sval) { if ($skey == $from || $to == $skey || in_array($to, $sval) || in_array($from, $sval)) { return $skey; } @@ -63,7 +62,7 @@ function convert_content() { $cells[] = $cell; // We now have the base unit and value now lets produce the table; - while (list($key, $val) = each($this->bases[$base_unit])) { + foreach ($this->bases[$base_unit] as $val) { $cell ['value'] = $this->convert($value, $from_unit, $val, $precision) . ' ' . $val; $cell ['class'] = ($val == $from_unit || $val == $to_unit) ? 'framedred' : ''; $cells[] = $cell; @@ -86,9 +85,7 @@ function convert_content() { return $string; } - } - - $conv = new TP_Converter('en'); + }; $conversions = [ 'Temperature' => ['base' => 'Celsius', @@ -176,10 +173,10 @@ function convert_content() { ] ]; - while (list($key, $val) = each($conversions)) { + foreach ($conversions as $key => $val) { $conv->addConversion($val['base'], $val['conv']); $list[$key][] = $val['base']; - while (list($ukey, $uval) = each($val['conv'])) { + foreach ($val['conv'] as $ukey => $uval) { $list[$key][] = $ukey; } } @@ -202,10 +199,9 @@ function convert_content() { $o .= ''; $o .= ''; $o .= '
- {{foreach $th_users as $k=>$th}} - {{if $k < 2 || $order_users == $th.1 || ($k==5 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1])) }} + {{if $k < 2 || $order_users == $th.1 || ($k==4 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.5.1])) }} {{/if}} - {{if $order_users == $th_users.4.1}} - - {{/if}} - - {{if !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.4.1]) }} + {{if $order_users == $th_users.5.1}} From 46b38367209b8c5c6f084454d5a9ea9eb322a8d9 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:39:20 +0100 Subject: [PATCH 215/294] Ratioed: remove create user button --- ratioed/templates/ratioed.tpl | 3 --- 1 file changed, 3 deletions(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index d634993e..c64cb1dc 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -6,9 +6,6 @@ {{$title}} - {{$page}} ({{$count}}) -

- {{$h_newuser}} -

+
@@ -323,7 +322,7 @@ $o .= <<< EOT - + @@ -345,13 +344,13 @@ $o .= <<< EOT - +
diff --git a/catavatar/catavatar.php b/catavatar/catavatar.php index 2116ac44..2bdf0cca 100644 --- a/catavatar/catavatar.php +++ b/catavatar/catavatar.php @@ -6,11 +6,9 @@ * Author: Fabio */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; diff --git a/cookienotice/cookienotice.php b/cookienotice/cookienotice.php index 2bd6f9b1..bc9d2416 100644 --- a/cookienotice/cookienotice.php +++ b/cookienotice/cookienotice.php @@ -7,7 +7,6 @@ * Author: Peter Liebetrau */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index 979204ba..d6c98e34 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -9,7 +9,6 @@ require_once 'addon/diaspora/Diaspora_Connection.php'; -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/discourse/discourse.php b/discourse/discourse.php index 298b3f3e..e97a4fd8 100644 --- a/discourse/discourse.php +++ b/discourse/discourse.php @@ -8,7 +8,6 @@ * */ -use Friendica\App; use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 1ecd9764..7ce30086 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -8,7 +8,6 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 73bbdab9..8608bcd7 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -7,7 +7,6 @@ * Status: Unsupported */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/fromapp/fromapp.php b/fromapp/fromapp.php index 0d5a5b16..8bd27606 100644 --- a/fromapp/fromapp.php +++ b/fromapp/fromapp.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -76,6 +75,6 @@ function fromapp_post_hook(&$item) $apps = explode(',', $app); $item['app'] = trim($apps[mt_rand(0, count($apps)-1)]); - + return; } diff --git a/geocoordinates/geocoordinates.php b/geocoordinates/geocoordinates.php index 5cb90efd..eb56f093 100644 --- a/geocoordinates/geocoordinates.php +++ b/geocoordinates/geocoordinates.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/geonames/geonames.php b/geonames/geonames.php index dcbd65f8..668eb0e7 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/gnot/gnot.php b/gnot/gnot.php index 15fb4da0..5d0919cb 100644 --- a/gnot/gnot.php +++ b/gnot/gnot.php @@ -4,11 +4,10 @@ * Description: Thread email comment notifications on Gmail and anonymise them * Version: 1.0 * Author: Mike Macgirvin - * + * * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -38,7 +37,7 @@ function gnot_settings_post($post) { } /** - * Called from the Addon Setting form. + * Called from the Addon Setting form. * Add our own settings info to the page. */ function gnot_settings(array &$data) diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index 356ce68c..b83a9cf9 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index 83a8fbb9..ca5eaaf0 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -6,15 +6,12 @@ * Author: Klaus Weidenbach */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Database\DBA; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; -use Friendica\Util\Strings; /** * Installs the addon hook diff --git a/group_text/group_text.php b/group_text/group_text.php index 02e9fd0a..e5067fb5 100644 --- a/group_text/group_text.php +++ b/group_text/group_text.php @@ -8,9 +8,7 @@ * Note: Please use Circle Text instead */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/highlightjs/highlightjs.php b/highlightjs/highlightjs.php index 097d34c7..c1c2aac8 100644 --- a/highlightjs/highlightjs.php +++ b/highlightjs/highlightjs.php @@ -6,7 +6,6 @@ * Author: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/ifttt/ifttt.php b/ifttt/ifttt.php index 6d4f402c..51fa8db8 100644 --- a/ifttt/ifttt.php +++ b/ifttt/ifttt.php @@ -6,7 +6,6 @@ * Version: 0.1 * Author: Michael Vogel */ -use Friendica\App; use Friendica\Content\PageInfo; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index f22dfff2..37c3cd45 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -8,7 +8,6 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/impressum/impressum.php b/impressum/impressum.php index 754cb828..19ade933 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -7,7 +7,6 @@ * License: 3-clause BSD license */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php b/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php index aff7aec0..9eb6ab36 100644 --- a/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php +++ b/infiniteimprobabilitydrive/infiniteimprobabilitydrive.php @@ -6,7 +6,6 @@ * Author: Thomas Willingham */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/irc/irc.php b/irc/irc.php index d4435851..db808a99 100644 --- a/irc/irc.php +++ b/irc/irc.php @@ -7,7 +7,6 @@ * Author: Tobias Diekershoff */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/krynn/krynn.php b/krynn/krynn.php index f7e77c26..fa9db133 100644 --- a/krynn/krynn.php +++ b/krynn/krynn.php @@ -10,7 +10,6 @@ *"My body was my sacrifice... for my magic. This damage is permanent." - Raistlin Majere */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index 38e2d6a1..14686e99 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -29,7 +29,6 @@ * The configuration options for this module are described in the config/ldapauth.config.php file */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Database\DBA; diff --git a/libertree/libertree.php b/libertree/libertree.php index 1d997123..c138e597 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -6,7 +6,6 @@ * Author: Tony Baldwin */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index 54594b88..b0b2c214 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -6,7 +6,6 @@ * Author: Klaus Weidenbach */ -use Friendica\App; use Friendica\Core\Addon; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/markdown/markdown.php b/markdown/markdown.php index 6f459244..0822ac83 100644 --- a/markdown/markdown.php +++ b/markdown/markdown.php @@ -5,7 +5,6 @@ * Version: 0.1 * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Content\Text\Markdown; use Friendica\Core\Renderer; diff --git a/mathjax/mathjax.php b/mathjax/mathjax.php index d0046cf7..e96aaddf 100644 --- a/mathjax/mathjax.php +++ b/mathjax/mathjax.php @@ -8,7 +8,6 @@ * License: 3-clause BSD license */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/morechoice/morechoice.php b/morechoice/morechoice.php index fe726d27..fbb88ce1 100644 --- a/morechoice/morechoice.php +++ b/morechoice/morechoice.php @@ -8,7 +8,6 @@ * Status: Deprecated */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/morepokes/morepokes.php b/morepokes/morepokes.php index abe59a6e..2ac09a73 100644 --- a/morepokes/morepokes.php +++ b/morepokes/morepokes.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/newmemberwidget/newmemberwidget.php b/newmemberwidget/newmemberwidget.php index 01977d0c..d3b68807 100644 --- a/newmemberwidget/newmemberwidget.php +++ b/newmemberwidget/newmemberwidget.php @@ -6,7 +6,6 @@ * Author: Tobias Diekershoff ***/ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/nitter/nitter.php b/nitter/nitter.php index 946b18c0..adbfd6b0 100644 --- a/nitter/nitter.php +++ b/nitter/nitter.php @@ -25,7 +25,6 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/nominatim/nominatim.php b/nominatim/nominatim.php index 6ad4a8a3..a3d14af5 100644 --- a/nominatim/nominatim.php +++ b/nominatim/nominatim.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/notifyall/notifyall.php b/notifyall/notifyall.php index 966a9184..d37bac56 100644 --- a/notifyall/notifyall.php +++ b/notifyall/notifyall.php @@ -9,9 +9,7 @@ */ use Friendica\Addon\notifyall\NotifyAllEmail; -use Friendica\App; use Friendica\Database\DBA; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/numfriends/numfriends.php b/numfriends/numfriends.php index 538a4a3e..66c9b74a 100644 --- a/numfriends/numfriends.php +++ b/numfriends/numfriends.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -39,7 +38,7 @@ function numfriends_settings_post($post) { /** * - * Called from the Addon Setting form. + * Called from the Addon Setting form. * Add our own settings info to the page. * */ @@ -50,7 +49,7 @@ function numfriends_settings(array &$data) } $numfriends = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'system', 'display_friend_count', 24); - + $t = Renderer::getMarkupTemplate('settings.tpl', 'addon/numfriends/'); $html = Renderer::replaceMacros($t, [ '$numfriends' => ['numfriends', DI::l10n()->t('How many contacts to display on profile sidebar'), $numfriends], diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index ae22aff0..c520514c 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -9,7 +9,6 @@ * */ -use Friendica\App; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/opmlexport/opmlexport.php b/opmlexport/opmlexport.php index fdfacc3e..3df71275 100644 --- a/opmlexport/opmlexport.php +++ b/opmlexport/opmlexport.php @@ -8,12 +8,8 @@ */ use Friendica\DI; -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; -use Friendica\Network\HTTPException; -use Friendica\Database\DBA; -use Friendica\Core\Renderer; use Friendica\Core\Protocol; use Friendica\Model\Contact; use Friendica\Model\User; diff --git a/pageheader/pageheader.php b/pageheader/pageheader.php index 057bb863..d729acc1 100644 --- a/pageheader/pageheader.php +++ b/pageheader/pageheader.php @@ -5,10 +5,9 @@ * Version: 1.1 * Author: Keith Fernie * Hauke Altmann - * + * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/phpmailer/phpmailer.php b/phpmailer/phpmailer.php index 4c12709d..5e137b94 100644 --- a/phpmailer/phpmailer.php +++ b/phpmailer/phpmailer.php @@ -7,7 +7,6 @@ * Maintainer: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; use Friendica\Object\EMail\IEmail; diff --git a/piwik/piwik.php b/piwik/piwik.php index fd6d5fc9..b7b49bd4 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -35,7 +35,6 @@ * setting. */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -76,7 +75,7 @@ function piwik_analytics(string &$b) * Add the Piwik tracking code for the site. * If async is set to true use asynchronous tracking */ - + $scriptAsyncValue = $async ? 'true' : 'false'; $scriptPhpEndpoint = $shortendpoint ? 'js/' : 'piwik.php'; $scriptJsEndpoint = $shortendpoint ? 'js/' : 'piwik.js'; diff --git a/planets/planets.php b/planets/planets.php index 8a206fb5..d96e33a6 100644 --- a/planets/planets.php +++ b/planets/planets.php @@ -7,7 +7,6 @@ * Author: Tony Baldwin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/public_server/public_server.php b/public_server/public_server.php index 7591c7d0..5834f42a 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -6,7 +6,6 @@ * Author: Keith Fernie */ -use Friendica\App; use Friendica\BaseModule; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/qcomment/qcomment.php b/qcomment/qcomment.php index 1b8bfcbf..f7126531 100644 --- a/qcomment/qcomment.php +++ b/qcomment/qcomment.php @@ -18,7 +18,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/randplace/randplace.php b/randplace/randplace.php index 34f48c6c..5cb07597 100644 --- a/randplace/randplace.php +++ b/randplace/randplace.php @@ -19,7 +19,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; diff --git a/rendertime/rendertime.php b/rendertime/rendertime.php index 731cf003..1cce5b1b 100644 --- a/rendertime/rendertime.php +++ b/rendertime/rendertime.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/s3_storage/s3_storage.php b/s3_storage/s3_storage.php index 361577be..c08c3172 100644 --- a/s3_storage/s3_storage.php +++ b/s3_storage/s3_storage.php @@ -8,7 +8,6 @@ use Friendica\Addon\s3_storage\src\S3Client; use Friendica\Addon\s3_storage\src\S3Config; -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/securemail/SecureTestEmail.php b/securemail/SecureTestEmail.php index c614104f..32510091 100644 --- a/securemail/SecureTestEmail.php +++ b/securemail/SecureTestEmail.php @@ -21,7 +21,6 @@ namespace Friendica\Addon\securemail; -use Friendica\App; use Friendica\App\BaseURL; use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; diff --git a/securemail/securemail.php b/securemail/securemail.php index 61125587..b56c0cbc 100644 --- a/securemail/securemail.php +++ b/securemail/securemail.php @@ -7,7 +7,6 @@ */ use Friendica\Addon\securemail\SecureTestEmail; -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -32,8 +31,6 @@ function securemail_install() * @link https://github.com/friendica/friendica/blob/develop/doc/Addons.md#addon_settings 'addon_settings' hook * * @param array $data - * - * @see App */ function securemail_settings(array &$data) { @@ -67,8 +64,6 @@ function securemail_settings(array &$data) * @link https://github.com/friendica/friendica/blob/develop/doc/Addons.md#addon_settings_post 'addon_settings_post' hook * * @param array $b hook data - * - * @see App */ function securemail_settings_post(array &$b) { @@ -102,8 +97,6 @@ function securemail_settings_post(array &$b) * @link https://github.com/friendica/friendica/blob/develop/doc/Addons.md#emailer_send_prepare 'emailer_send_prepare' hook * * @param IEmail $email Email - * - * @see App */ function securemail_emailer_send_prepare(IEmail &$email) { diff --git a/showmore_dyn/showmore_dyn.php b/showmore_dyn/showmore_dyn.php index 7cb64bcc..4c2e62f5 100644 --- a/showmore_dyn/showmore_dyn.php +++ b/showmore_dyn/showmore_dyn.php @@ -7,12 +7,8 @@ * */ -use Friendica\App; use Friendica\Core\Hook; -use Friendica\Core\L10n; -use Friendica\Core\Logger; use Friendica\Core\Renderer; -use Friendica\Database\DBA; use Friendica\DI; function showmore_dyn_install() diff --git a/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php b/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php index 38b208da..0f41101d 100644 --- a/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php +++ b/smiley_pack/lang/smiley_pack_es/smiley_pack_es.php @@ -3,11 +3,10 @@ * Name: Smiley Pack (Español) * Description: Pack of smileys that make master too AOLish. * Version: 1.02 - * Author: Thomas Willingham (based on Mike Macgirvin's Adult Smile template) + * Author: Thomas Willingham (based on Mike Macgirvin's Adult Smile template) * All smileys from sites offering them as Public Domain */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -19,7 +18,7 @@ function smiley_pack_smilies_es(array &$b) { #Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. -#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : +#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : #when all else fails. @@ -49,7 +48,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':vaca'; $b['icons'][] = '' . ':vaca' . ''; - + $b['texts'][] = ':cangrejo'; $b['icons'][] = '' . ':cangrejo' . ''; @@ -70,7 +69,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':caballo'; $b['icons'][] = '' . ':caballo' . ''; - + $b['texts'][] = ':loro'; $b['icons'][] = '' . ':loro' . ''; @@ -107,7 +106,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':cuna'; $b['icons'][] = '' . ':cuna' . ''; - + $b['texts'][] = ':embarazada'; $b['icons'][] = '' . ':embarazada' . ''; @@ -116,10 +115,10 @@ function smiley_pack_smilies_es(array &$b) { $b['icons'][] = '' . ':cigüeña' . ''; -#Confused Smileys +#Confused Smileys $b['texts'][] = ':confundido'; $b['icons'][] = '' . ':confundido' . ''; - + $b['texts'][] = ':encogehombros'; $b['icons'][] = '' . ':encogehombros' . ''; @@ -154,13 +153,13 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':diabólico'; $b['icons'][] = '' . ':diabólico' . ''; - + $b['texts'][] = ':adbalancín'; $b['icons'][] = '' . ':adbalancín' . ''; $b['texts'][] = ':vuelvedemonio'; $b['icons'][] = '' . ':vuelvedemonio' . ''; - + $b['texts'][] = ':santo'; $b['icons'][] = '' . ':santo' . ''; @@ -242,7 +241,7 @@ function smiley_pack_smilies_es(array &$b) { $b['texts'][] = ':billar'; $b['icons'][] = '' . ':billar' . ''; - + $b['texts'][] = ':tenis'; $b['icons'][] = '' . ':tenis' . ''; diff --git a/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php b/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php index 63cf613e..c5474e3c 100644 --- a/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php +++ b/smiley_pack/lang/smiley_pack_fr/smiley_pack_fr.php @@ -9,7 +9,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -23,7 +22,7 @@ function smiley_pack_fr_smilies(array &$b) #Smileys are split into various directories by the intended range of emotions. This is in case we get too big and need to modularise things. We can then cut and paste the right lines, move the right directory, and just change the name of the addon to happy_smilies or whatever. -#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : +#Be careful with invocation strings. If you have a smiley called foo, and another called foobar, typing :foobar will call foo. Avoid this with clever naming, using ~ instead of : #when all else fails. @@ -56,7 +55,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':vache'; $b['icons'][] = '' . ':vache' . ''; - + $b['texts'][] = ':crabe'; $b['icons'][] = '' . ':crabe' . ''; @@ -74,7 +73,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':cheval'; $b['icons'][] = '' . ':cheval' . ''; - + $b['texts'][] = ':perroquet'; $b['icons'][] = '' . ':perroquet' . ''; @@ -108,7 +107,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':litbébé'; $b['icons'][] = '' . ':litbébé' . ''; - + $b['texts'][] = ':enceinte'; $b['icons'][] = '' . ':enceinte' . ''; @@ -117,10 +116,10 @@ function smiley_pack_fr_smilies(array &$b) $b['icons'][] = '' . ':cigogne' . ''; -#Confused Smileys +#Confused Smileys $b['texts'][] = ':paumé'; $b['icons'][] = '' . ':paumé' . ''; - + $b['texts'][] = ':hausseépaules'; $b['icons'][] = '' . ':hausseépaules' . ''; @@ -152,13 +151,13 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':démoniaque'; $b['icons'][] = '' . ':démoniaque' . ''; - + $b['texts'][] = ':bascule'; $b['icons'][] = '' . ':bascule' . ''; $b['texts'][] = ':possédé'; $b['icons'][] = '' . ':possédé' . ''; - + $b['texts'][] = ':tombe'; $b['icons'][] = '' . ':tombe' . ''; @@ -225,7 +224,7 @@ function smiley_pack_fr_smilies(array &$b) $b['texts'][] = ':billard'; $b['icons'][] = '' . ':billard' . ''; - + $b['texts'][] = ':équitation'; $b['icons'][] = '' . ':équitation' . ''; diff --git a/smileybutton/smileybutton.php b/smileybutton/smileybutton.php index 1df717b7..ae0e783b 100644 --- a/smileybutton/smileybutton.php +++ b/smileybutton/smileybutton.php @@ -7,7 +7,6 @@ * Maintainer: Hypolite Petovan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/smilies_adult/smilies_adult.php b/smilies_adult/smilies_adult.php index e8af21e1..4a80168d 100644 --- a/smilies_adult/smilies_adult.php +++ b/smilies_adult/smilies_adult.php @@ -4,12 +4,11 @@ * Description: Smily icons that could or should not be included in core * Version: 1.0 * Author: Mike Macgirvin - * + * * This is a template for how to extend the "smily" code. - * + * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/startpage/startpage.php b/startpage/startpage.php index e4d80c0c..558af473 100644 --- a/startpage/startpage.php +++ b/startpage/startpage.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index 48f9c254..bd115115 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -38,7 +38,6 @@ define('STATUSNET_DEFAULT_POLL_INTERVAL', 5); // given in minutes require_once __DIR__ . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . 'statusnetoauth.php'; use CodebirdSN\CodebirdSN; -use Friendica\App; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; use Friendica\Core\Logger; diff --git a/testdrive/testdrive.php b/testdrive/testdrive.php index 55645284..40f22e0a 100644 --- a/testdrive/testdrive.php +++ b/testdrive/testdrive.php @@ -6,7 +6,6 @@ * Author: Mike Macgirvin */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Search; use Friendica\Database\DBA; diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 22ee3439..b39c6f10 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -7,7 +7,6 @@ * Author: Matthias Ebers */ -use Friendica\App; use Friendica\Content\Smilies; use Friendica\Core\Hook; @@ -691,7 +690,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':custard:', '🍮'); Smilies::add($b, ':honey pot:', '🍯'); -// drink +// drink Smilies::add($b, ':baby bottle:', '🍼'); Smilies::add($b, ':glass of milk:', '🥛'); Smilies::add($b, ':hot beverage:', '☕'); @@ -1123,7 +1122,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':control knobs:', '🎛'); Smilies::add($b, ':microphone:', '🎤'); Smilies::add($b, ':headphone:', '🎧'); - Smilies::add($b, ':radio:', '📻'); + Smilies::add($b, ':radio:', '📻'); // musical-instrument Smilies::add($b, ':saxophone:', '🎷'); @@ -1529,7 +1528,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':O button (blood type):', '🅾'); Smilies::add($b, ':OK button:', '🆗'); Smilies::add($b, ':P button:', '🅿'); - Smilies::add($b, ':SOS button:', '🆘'); + Smilies::add($b, ':SOS button:', '🆘'); Smilies::add($b, ':UP! button:', '🆙'); Smilies::add($b, ':VS button:', '🆚'); Smilies::add($b, ':Japanese “here” button:', '🈁'); diff --git a/viewsrc/viewsrc.php b/viewsrc/viewsrc.php index c4d21ccb..bd07b541 100644 --- a/viewsrc/viewsrc.php +++ b/viewsrc/viewsrc.php @@ -7,7 +7,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; diff --git a/webrtc/webrtc.php b/webrtc/webrtc.php index e142b374..e5d4ce6e 100644 --- a/webrtc/webrtc.php +++ b/webrtc/webrtc.php @@ -7,7 +7,6 @@ * Author: Tobias Diekershoff */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; From 84659fc1ad339b0f7cee0b8d11ede9ea9aafba07 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 11 Dec 2024 21:47:10 +0000 Subject: [PATCH 182/294] Replace DI::app() with DI::appHelper() --- advancedcontentfilter/advancedcontentfilter.php | 2 +- bluesky/bluesky.php | 2 +- fancybox/fancybox.php | 2 +- geonames/geonames.php | 2 +- gravatar/gravatar.php | 2 +- highlightjs/highlightjs.php | 2 +- impressum/impressum.php | 2 +- ldapauth/ldapauth.php | 2 +- libravatar/libravatar.php | 2 +- openstreetmap/openstreetmap.php | 2 +- phpmailer/phpmailer.php | 2 +- piwik/piwik.php | 2 +- pnut/pnut.php | 2 +- public_server/public_server.php | 2 +- pumpio/pumpio.php | 2 +- smileybutton/smileybutton.php | 6 +++--- testdrive/testdrive.php | 2 +- tumblr/tumblr.php | 2 +- twitter/twitter.php | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index 329156f1..c03034cd 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -271,7 +271,7 @@ function advancedcontentfilter_content() 'rule_expression' => DI::l10n()->t('Rule Expression'), 'cancel' => DI::l10n()->t('Cancel'), ], - '$current_theme' => DI::app()->getCurrentTheme(), + '$current_theme' => DI::appHelper()->getCurrentTheme(), '$rules' => DBA::toArray(DBA::select('advancedcontentfilter_rules', [], ['uid' => DI::userSession()->getLocalUserId()])), '$form_security_token' => BaseModule::getFormSecurityToken() ]); diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 91e524fe..aa4bc340 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -98,7 +98,7 @@ function bluesky_install() function bluesky_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('bluesky'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function bluesky_check_item_notification(array &$notification_data) diff --git a/fancybox/fancybox.php b/fancybox/fancybox.php index 8608bcd7..b1a1ff35 100644 --- a/fancybox/fancybox.php +++ b/fancybox/fancybox.php @@ -39,7 +39,7 @@ function fancybox_render(array &$b){ function ($text) use ($gallery) { // This processes images inlined in posts // Frio / Vier hooks für lightbox are un-hooked in fancybox-config.js. So this works for them, too! - //if (!in_array(DI::app()->getCurrentTheme(),['vier','frio'])) + //if (!in_array(DI::appHelper()->getCurrentTheme(),['vier','frio'])) $text = preg_replace( '#]*href="([^"]*)"[^>]*>(]*src="[^"]*"[^>]*>)#', '$2', diff --git a/geonames/geonames.php b/geonames/geonames.php index 668eb0e7..d14b1e8f 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -34,7 +34,7 @@ function geonames_install() function geonames_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('geonames'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function geonames_post_hook(array &$item) diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index ca5eaaf0..6007c433 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -25,7 +25,7 @@ function gravatar_install() { function gravatar_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('gravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/highlightjs/highlightjs.php b/highlightjs/highlightjs.php index c1c2aac8..762f4117 100644 --- a/highlightjs/highlightjs.php +++ b/highlightjs/highlightjs.php @@ -17,7 +17,7 @@ function highlightjs_install() function highlightjs_head(string &$str) { - if (DI::app()->getCurrentTheme() == 'frio') { + if (DI::appHelper()->getCurrentTheme() == 'frio') { $style = 'bootstrap'; } else { $style = 'default'; diff --git a/impressum/impressum.php b/impressum/impressum.php index 19ade933..f61d7182 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -55,7 +55,7 @@ function impressum_footer(string &$body) function impressum_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('impressum'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('impressum'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function impressum_show(string &$body) diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index 14686e99..f834b4d5 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -44,7 +44,7 @@ function ldapauth_install() function ldapauth_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('ldapauth'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('ldapauth'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function ldapauth_hook_authenticate(array &$b) diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index b0b2c214..4cd72c83 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -25,7 +25,7 @@ function libravatar_install() function libravatar_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('libravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('libravatar'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index c520514c..fc5ebbbe 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -36,7 +36,7 @@ function openstreetmap_install() function openstreetmap_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('openstreetmap'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('openstreetmap'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function openstreetmap_alterheader(&$navHtml) diff --git a/phpmailer/phpmailer.php b/phpmailer/phpmailer.php index 5e137b94..f4bb7753 100644 --- a/phpmailer/phpmailer.php +++ b/phpmailer/phpmailer.php @@ -24,7 +24,7 @@ function phpmailer_install() function phpmailer_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('phpmailer'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('phpmailer'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } /** diff --git a/piwik/piwik.php b/piwik/piwik.php index b7b49bd4..fc459a87 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -50,7 +50,7 @@ function piwik_install() { function piwik_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('piwik'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('piwik'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function piwik_analytics(string &$b) diff --git a/pnut/pnut.php b/pnut/pnut.php index 32f60f6d..f298997b 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -90,7 +90,7 @@ function pnut_connect() function pnut_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('pnut'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function pnut_addon_admin(string &$o) diff --git a/public_server/public_server.php b/public_server/public_server.php index 5834f42a..eb7af1e7 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -28,7 +28,7 @@ function public_server_install() function public_server_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('public_server'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('public_server'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function public_server_register_account($b) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index d7c2ac32..ffe5f187 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -319,7 +319,7 @@ function pumpio_settings_post(array &$b) function pumpio_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('pumpio'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('pumpio'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function pumpio_hook_fork(array &$b) diff --git a/smileybutton/smileybutton.php b/smileybutton/smileybutton.php index ae0e783b..4d0a8d42 100644 --- a/smileybutton/smileybutton.php +++ b/smileybutton/smileybutton.php @@ -19,7 +19,7 @@ function smileybutton_install() function smileybutton_jot_tool(string &$body) { // Disable if theme is quattro - if (DI::app()->getCurrentTheme() == 'quattro') { + if (DI::appHelper()->getCurrentTheme() == 'quattro') { return; } @@ -96,7 +96,7 @@ function smileybutton_jot_tool(string &$body) $s .= '
'; //Add css to header - $css_file = __DIR__ . '/view/' . DI::app()->getCurrentTheme() . '.css'; + $css_file = __DIR__ . '/view/' . DI::appHelper()->getCurrentTheme() . '.css'; if (!file_exists($css_file)) { $css_file = __DIR__ . '/view/default.css'; } @@ -104,7 +104,7 @@ function smileybutton_jot_tool(string &$body) DI::page()->registerStylesheet($css_file); //Get the correct image for the theme - $image = 'addon/smileybutton/view/' . DI::app()->getCurrentTheme() . '.png'; + $image = 'addon/smileybutton/view/' . DI::appHelper()->getCurrentTheme() . '.png'; if (!file_exists($image)) { $image = 'addon/smileybutton/view/default.png'; } diff --git a/testdrive/testdrive.php b/testdrive/testdrive.php index 40f22e0a..90fb5918 100644 --- a/testdrive/testdrive.php +++ b/testdrive/testdrive.php @@ -26,7 +26,7 @@ function testdrive_install() function testdrive_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('testdrive'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('testdrive'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function testdrive_globaldir_update(array &$b) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 1e9f5c7f..580d73e6 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -65,7 +65,7 @@ function tumblr_install() function tumblr_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('tumblr'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('tumblr'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function tumblr_check_item_notification(array &$notification_data) diff --git a/twitter/twitter.php b/twitter/twitter.php index 10f8a2fb..ea4ae356 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -67,7 +67,7 @@ function twitter_install() function twitter_load_config(ConfigFileManager $loader) { - DI::app()->getConfigCache()->load($loader->loadAddonConfig('twitter'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); + DI::appHelper()->getConfigCache()->load($loader->loadAddonConfig('twitter'), \Friendica\Core\Config\ValueObject\Cache::SOURCE_STATIC); } function twitter_jot_nets(array &$jotnets_fields) From 31198294c787497d0c5cb4bcf081e5a15db084e5 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 29 Nov 2024 22:36:05 +0000 Subject: [PATCH 183/294] Fix error in bluesky addon --- bluesky/bluesky.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 38934feb..8e2c1ca0 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -1563,7 +1563,7 @@ function bluesky_get_uri_class(string $uri): ?stdClass } $elements = explode(':', $uri); - if (empty($elements) || ($elements[0] != 'at')) { + if ($elements[0] !== 'at') { $post = Post::selectFirstPost(['extid'], ['uri' => $uri]); return bluesky_get_uri_class($post['extid'] ?? ''); } From cf8a7870f3765db549ec961cf28f7fc7b8e466ad Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:27:45 +0000 Subject: [PATCH 184/294] Fix errors in bluesky addon --- bluesky/bluesky.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 8e2c1ca0..91e524fe 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -683,6 +683,8 @@ function bluesky_create_activity(array $item, stdClass $parent = null) return; } + $post = []; + if ($item['verb'] == Activity::LIKE) { $record = [ 'subject' => $parent, From 1860e732aee24ee9b1f6677e7b8f5c503f226db6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:28:38 +0000 Subject: [PATCH 185/294] Fix errors in convert addon --- convert/convert.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/convert/convert.php b/convert/convert.php index 2c97e2aa..2545974c 100644 --- a/convert/convert.php +++ b/convert/convert.php @@ -181,7 +181,7 @@ function convert_content() { } } - $o .= '

Unit Conversions

'; + $o = '

Unit Conversions

'; if (isset($_POST['from_unit']) && isset($_POST['value'])) { $o .= ($conv->getTable(intval($_POST['value']), $_POST['from_unit'], $_POST['to_unit'], 5)) . '

'; From 81f232d57e8991ca342751d0db2d2680ec7bc7c8 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:30:39 +0000 Subject: [PATCH 186/294] Fix errors in js_upload addon --- .../file-uploader/tests/action-acceptance.php | 16 ++++++++-------- .../tests/action-handler-queue-test.php | 8 ++++---- .../file-uploader/tests/action-handler-test.php | 8 ++++---- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/js_upload/file-uploader/tests/action-acceptance.php b/js_upload/file-uploader/tests/action-acceptance.php index fc9583f2..172b8857 100644 --- a/js_upload/file-uploader/tests/action-acceptance.php +++ b/js_upload/file-uploader/tests/action-acceptance.php @@ -2,12 +2,12 @@ usleep(100000); -$fileName; -$fileSize; +$fileName = ''; +$fileSize = 0;; if (isset($_GET['qqfile'])){ $fileName = $_GET['qqfile']; - + // xhr request $headers = apache_request_headers(); $fileSize = (int)$headers['Content-Length']; @@ -34,13 +34,13 @@ if ($fileSize > 9 * 1024){ die ('{error: "server-error file size is bigger than 9kB"}'); } -if (count($_GET)){ +if (count($_GET)){ array_merge($_GET, array('fileName'=>$fileName)); - + $response = array_merge($_GET, array('success'=>true, 'fileName'=>$fileName)); - - // to pass data through iframe you will need to encode all html tags - echo htmlspecialchars(json_encode($response), ENT_NOQUOTES); + + // to pass data through iframe you will need to encode all html tags + echo htmlspecialchars(json_encode($response), ENT_NOQUOTES); } else { die ('{error: "server-error query params not passed"}'); } diff --git a/js_upload/file-uploader/tests/action-handler-queue-test.php b/js_upload/file-uploader/tests/action-handler-queue-test.php index ff13576d..78760d64 100644 --- a/js_upload/file-uploader/tests/action-handler-queue-test.php +++ b/js_upload/file-uploader/tests/action-handler-queue-test.php @@ -2,11 +2,11 @@ sleep(4); -$fileName; +$fileName = ''; if (isset($_GET['qqfile'])){ $fileName = $_GET['qqfile']; - + // xhr request $headers = apache_request_headers(); if ((int)$headers['Content-Length'] == 0){ @@ -14,7 +14,7 @@ if (isset($_GET['qqfile'])){ } } elseif (isset($_FILES['qqfile'])){ $fileName = basename($_FILES['qqfile']['name']); - + // form request if ($_FILES['qqfile']['size'] == 0){ die ('{error: "file size is zero"}'); @@ -25,7 +25,7 @@ if (isset($_GET['qqfile'])){ if (count($_GET)){ $_GET['success'] = true; - echo json_encode(array_merge($_GET)); + echo json_encode(array_merge($_GET)); } else { die ('{error: "query params not passed"}'); } diff --git a/js_upload/file-uploader/tests/action-handler-test.php b/js_upload/file-uploader/tests/action-handler-test.php index 24466b12..9fa72023 100644 --- a/js_upload/file-uploader/tests/action-handler-test.php +++ b/js_upload/file-uploader/tests/action-handler-test.php @@ -2,11 +2,11 @@ usleep(300); -$fileName; +$fileName = ''; if (isset($_GET['qqfile'])){ $fileName = $_GET['qqfile']; - + // xhr request $headers = apache_request_headers(); if ((int)$headers['Content-Length'] == 0){ @@ -14,7 +14,7 @@ if (isset($_GET['qqfile'])){ } } elseif (isset($_FILES['qqfile'])){ $fileName = basename($_FILES['qqfile']['name']); - + // form request if ($_FILES['qqfile']['size'] == 0){ die ('{error: "file size is zero"}'); @@ -25,7 +25,7 @@ if (isset($_GET['qqfile'])){ if (count($_GET)){ //return query params - echo json_encode(array_merge($_GET, array('fileName'=>$fileName))); + echo json_encode(array_merge($_GET, array('fileName'=>$fileName))); } else { die ('{error: "query params not passed"}'); } From 3cf53a334d3d04df83b35423f31a916eea0ab492 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:32:07 +0000 Subject: [PATCH 187/294] Fix errors in keycloakpassword addon --- keycloakpassword/keycloakpassword.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/keycloakpassword/keycloakpassword.php b/keycloakpassword/keycloakpassword.php index bfff4ea4..e9809f86 100644 --- a/keycloakpassword/keycloakpassword.php +++ b/keycloakpassword/keycloakpassword.php @@ -6,7 +6,6 @@ * Author: Ryan */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Renderer; @@ -92,7 +91,7 @@ function keycloakpassword_authenticate(array &$b) $client_id, $secret, $endpoint . '/logout', - [ 'refresh_token' => res['refresh_token'] ] + [ 'refresh_token' => $res['refresh_token'] ] ); } } From a53d5ae29b1ec11d4063d636ec6c27074855576b Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:35:19 +0000 Subject: [PATCH 188/294] Fix errors in langfilter addon --- langfilter/langfilter.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/langfilter/langfilter.php b/langfilter/langfilter.php index e5efa8fb..2bf986f0 100644 --- a/langfilter/langfilter.php +++ b/langfilter/langfilter.php @@ -7,7 +7,6 @@ * License: MIT */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Renderer; @@ -148,6 +147,8 @@ function langfilter_prepare_body_content_filter(&$hook_data) $iso639 = new Matriphe\ISO639\ISO639; + $confidence = null; + // Extract the language of the post if (!empty($hook_data['item']['language'])) { $languages = json_decode($hook_data['item']['language'], true); From ee1a917612fb1c014eecce9d37b7dbcfa166aaa9 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:37:58 +0000 Subject: [PATCH 189/294] Fix errors in leistungsschutzrecht addon --- leistungsschutzrecht/leistungsschutzrecht.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/leistungsschutzrecht/leistungsschutzrecht.php b/leistungsschutzrecht/leistungsschutzrecht.php index f6c65399..ec8091ac 100644 --- a/leistungsschutzrecht/leistungsschutzrecht.php +++ b/leistungsschutzrecht/leistungsschutzrecht.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\DI; @@ -149,7 +148,7 @@ function leistungsschutzrecht_is_member_site(string $url): bool $cleanedurlpart = explode('%', $urldata['host']); $hostname = explode('.', $cleanedurlpart[0]); - if (empty($hostname)) { + if ($hostname === false || $hostname === '') { return false; } From d08a280ba6d51ea1671b62a65ee72f221f83106c Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:41:11 +0000 Subject: [PATCH 190/294] Fix errors in libravatar addon --- libravatar/Services/Libravatar.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libravatar/Services/Libravatar.php b/libravatar/Services/Libravatar.php index 70fcfe39..e51ef070 100644 --- a/libravatar/Services/Libravatar.php +++ b/libravatar/Services/Libravatar.php @@ -401,9 +401,8 @@ class Services_Libravatar */ protected function srvGet($domain, $https = false) { - // Are we going secure? Set up a fallback too. - if (isset($https) && $https === true) { + if ($https === true) { $subdomain = '_avatars-sec._tcp.'; $fallback = 'seccdn.'; } else { @@ -426,6 +425,7 @@ class Services_Libravatar $top = $srv[0]; $sum = 0; + $pri = []; // Try to adhere to RFC2782's weighting algorithm, page 3 // "arrange all SRV RRs (that have not been ordered yet) in any order, From 984e7c5e5d133ab4305c766a924d2517a03bbd2c Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:42:40 +0000 Subject: [PATCH 191/294] Fix errors in ljpost addon --- ljpost/ljpost.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index 7acc6589..b416c605 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -8,7 +8,6 @@ * Author: Cat Gray */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; use Friendica\Core\Logger; @@ -203,10 +202,12 @@ EOT; Logger::debug('ljpost: data: ' . $xml); + $x = ''; + if ($lj_blog !== 'test') { $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to livejournal: ' . ($x) ? $x : ''); + Logger::info('posted to livejournal: ' . $x); } } From 6b1b043dd8fc48511f9288249cd18322b8a709b4 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:48:49 +0000 Subject: [PATCH 192/294] fix errors in mailstream addon --- mailstream/phpmailer/class.phpmailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailstream/phpmailer/class.phpmailer.php b/mailstream/phpmailer/class.phpmailer.php index ff3d81e3..dcf02361 100644 --- a/mailstream/phpmailer/class.phpmailer.php +++ b/mailstream/phpmailer/class.phpmailer.php @@ -3287,7 +3287,7 @@ class PHPMailer $result = 'localhost.localdomain'; if (!empty($this->Hostname)) { $result = $this->Hostname; - } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { + } elseif (array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } elseif (function_exists('gethostname') && gethostname() !== false) { $result = gethostname(); From c0971779c6091f0d3621c38df30d77f4f1b7e021 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:50:06 +0000 Subject: [PATCH 193/294] Fix errors in nsfw addon --- nsfw/nsfw.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nsfw/nsfw.php b/nsfw/nsfw.php index 4a54d899..674fc201 100644 --- a/nsfw/nsfw.php +++ b/nsfw/nsfw.php @@ -8,7 +8,6 @@ * */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\Core\Renderer; use Friendica\DI; @@ -119,7 +118,9 @@ function nsfw_prepare_body_content_filter(&$hook_data) $word_list = ['nsfw']; } - $found = false; + $found = false; + $tag_search = false; + if (count($word_list)) { $body = $hook_data['item']['title'] . "\n" . nsfw_extract_photos($hook_data['item']['body']); @@ -129,7 +130,6 @@ function nsfw_prepare_body_content_filter(&$hook_data) continue; } - $tag_search = false; switch ($word[0]) { case '/'; // Regular expression $found = @preg_match($word, $body); From 7fa2dfc608d9ac30253ac257c020dfda3061ec8b Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 19:51:18 +0000 Subject: [PATCH 194/294] Fix errors in pnut addon --- pnut/lib/phpnut.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pnut/lib/phpnut.php b/pnut/lib/phpnut.php index 5794d795..89d5e5f8 100644 --- a/pnut/lib/phpnut.php +++ b/pnut/lib/phpnut.php @@ -1339,6 +1339,8 @@ class phpnut */ protected function updateUserImage(string $image, string $which='avatar') { + $mimeType = ''; + $test = @getimagesize($image); if ($test && array_key_exists('mime', $test)) { $mimeType = $test['mime']; From bda683c56b1800d1c2b3847e44074d554ac34c4b Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:12:23 +0000 Subject: [PATCH 195/294] fix errors in pumpio addon --- pumpio/pumpio.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index 5e053d7c..d7c2ac32 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -6,7 +6,6 @@ * Author: Michael Vogel */ -use Friendica\App; use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Addon; @@ -582,6 +581,8 @@ function pumpio_action(int $uid, string $uri, string $action, string $content = $uri = $orig_post['uri']; } + $objectType = ''; + if (($orig_post['object-type'] != '') && (strstr($orig_post['object-type'], ActivityNamespace::ACTIVITY_SCHEMA))) { $objectType = str_replace(ActivityNamespace::ACTIVITY_SCHEMA, '', $orig_post['object-type']); } elseif (strstr($uri, '/api/comment/')) { @@ -827,6 +828,7 @@ function pumpio_dounlike(int $uid, array $self, $post, string $own_id) } $contactid = 0; + $contact = []; if (Strings::compareLink($post->actor->url, $own_id)) { $contactid = $self['id']; @@ -1430,6 +1432,8 @@ function pumpio_fetchallcomments($uid, $id) Logger::notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); + $item = new \stdClass(); + if (pumpio_reachable($url)) { $success = $client->CallAPI($url, 'GET', [], ['FailOnAccessError' => true], $item); } else { From 5b623c83686b1ac4ac72d15f2072cb380b872ee2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:13:41 +0000 Subject: [PATCH 196/294] fix errors in ratioed addon --- ratioed/RatioedPanel.php | 1 + 1 file changed, 1 insertion(+) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index e25c7f34..bd9b44dc 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -26,6 +26,7 @@ class RatioedPanel extends Active $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; + $user = []; if ($uid) { $user = User::getById($uid, ['username', 'blocked']); From 8e778593ca014916297ad234587f5cbfb426f4f2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:27:57 +0000 Subject: [PATCH 197/294] fix errors in statusnet addon --- statusnet/library/codebirdsn.php | 13 +++++++------ statusnet/statusnet.php | 2 ++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/statusnet/library/codebirdsn.php b/statusnet/library/codebirdsn.php index 325bcb07..91e256be 100644 --- a/statusnet/library/codebirdsn.php +++ b/statusnet/library/codebirdsn.php @@ -31,11 +31,10 @@ use Friendica\Core\System; /** * Define constants */ -$constants = explode(' ', 'OBJECT ARRAY JSON'); -foreach ($constants as $i => $id) { - $id = 'CODEBIRD_RETURNFORMAT_' . $id; - defined($id) or define($id, $i); -} +defined('CODEBIRD_RETURNFORMAT_ARRAY') or define('CODEBIRD_RETURNFORMAT_ARRAY', 0); +defined('CODEBIRD_RETURNFORMAT_JSON') or define('CODEBIRD_RETURNFORMAT_JSON', 1); +defined('CODEBIRD_RETURNFORMAT_OBJECT') or define('CODEBIRD_RETURNFORMAT_OBJECT', 2); + $constants = array( 'CURLE_SSL_CERTPROBLEM' => 58, 'CURLE_SSL_CACERT' => 60, @@ -788,6 +787,8 @@ class CodebirdSN $possible_files = explode(' ', $possible_files[$method]); + $data = ''; + $multipart_border = '--------------------' . $this->_nonce(); $multipart_request = ''; foreach ($params as $key => $value) { @@ -917,7 +918,7 @@ class CodebirdSN $authorization = 'Authorization: Bearer ' . self::$_oauth_bearer_token; } $request_headers = array(); - if (isset($authorization)) { + if ($authorization !== '') { $request_headers[] = $authorization; $request_headers[] = 'Expect:'; } diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index 4bc32050..48f9c254 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -366,6 +366,8 @@ function statusnet_post_hook(array &$b) $otoken = DI::pConfig()->get($b['uid'], 'statusnet', 'oauthtoken'); $osecret = DI::pConfig()->get($b['uid'], 'statusnet', 'oauthsecret'); + $iscomment = null; + if ($ckey && $csecret && $otoken && $osecret) { $dent = new StatusNetOAuth($api, $ckey, $csecret, $otoken, $osecret); $max_char = $dent->get_maxlength(); // max. length for a dent From 2f89827deaa09de0cf8bf2a803645441f424cd9a Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:36:07 +0000 Subject: [PATCH 198/294] fix errors in tictac addon --- tictac/tictac.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tictac/tictac.php b/tictac/tictac.php index 10103835..082b58c1 100644 --- a/tictac/tictac.php +++ b/tictac/tictac.php @@ -7,7 +7,6 @@ * Status: unsupported */ -use Friendica\App; use Friendica\Core\Hook; use Friendica\DI; @@ -30,7 +29,12 @@ function tictac_module() {} function tictac_content() { - $o = ''; + $o = ''; + $dimen = 3; + $handicap = 0; + $mefirst = 0; + $yours = ''; + $mine = ''; if($_POST['move']) { $handicap = DI::args()->get(1); @@ -45,9 +49,6 @@ function tictac_content() { $handicap = DI::args()->get(1); $dimen = 3; } - else { - $dimen = 3; - } $o .= '

' . DI::l10n()->t('3D Tic-Tac-Toe') . '


'; @@ -163,7 +164,7 @@ class tictac { ]; function __construct($dimen, $handicap, $mefirst, $yours, $mine) { - $this->dimen = 3; + $this->dimen = $dimen; $this->handicap = $handicap ? 1 : 0; $this->mefirst = $mefirst ? 1 : 0; $this->yours = str_replace('XXX','',$yours); @@ -228,6 +229,8 @@ class tictac { } function parse_moves($player) { + $str = ''; + if($player == 'me') $str = $this->mine; if($player == 'you') From a71db771d9473852786cc7435e9b1178b842880f Mon Sep 17 00:00:00 2001 From: Art4 Date: Sat, 30 Nov 2024 20:36:58 +0000 Subject: [PATCH 199/294] Fix errors in wppost addon --- wppost/wppost.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wppost/wppost.php b/wppost/wppost.php index dba738de..f2ee5d21 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -259,9 +259,11 @@ EOT; Logger::debug('wppost: data: ' . $xml); + $x = ''; + if ($wp_blog !== 'test') { $x = DI::httpClient()->post($wp_blog, $xml)->getBodyString(); } - Logger::info('posted to wordpress: ' . (($x) ? $x : '')); + Logger::info('posted to wordpress: ' . $x); } } From 729b6e52107dd1f3ce870b2fa45b7a8e1f60cc4d Mon Sep 17 00:00:00 2001 From: Artur Weigandt Date: Thu, 5 Dec 2024 18:23:51 +0100 Subject: [PATCH 200/294] Update mailstream/phpmailer/class.phpmailer.php Co-authored-by: Hypolite Petovan --- mailstream/phpmailer/class.phpmailer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailstream/phpmailer/class.phpmailer.php b/mailstream/phpmailer/class.phpmailer.php index dcf02361..1d9df9af 100644 --- a/mailstream/phpmailer/class.phpmailer.php +++ b/mailstream/phpmailer/class.phpmailer.php @@ -3287,7 +3287,7 @@ class PHPMailer $result = 'localhost.localdomain'; if (!empty($this->Hostname)) { $result = $this->Hostname; - } elseif (array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) { + } elseif (!empty($_SERVER['SERVER_NAME'])) { $result = $_SERVER['SERVER_NAME']; } elseif (function_exists('gethostname') && gethostname() !== false) { $result = gethostname(); From 3719d1eee5d67424e9bb144a47fe06ba5e87d2a0 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 6 Dec 2024 06:46:36 +0000 Subject: [PATCH 201/294] Set extid via guid, nit via id --- bluesky/bluesky.php | 4 ++-- tumblr/tumblr.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index dfd7fe06..26ecb967 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -715,7 +715,7 @@ function bluesky_create_activity(array $item, stdClass $parent = null) } Logger::debug('Activity done', ['return' => $activity]); $uri = bluesky_get_uri($activity); - Item::update(['extid' => $uri], ['id' => $item['id']]); + Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } @@ -806,7 +806,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { $uri = bluesky_get_uri($parent); - Item::update(['extid' => $uri], ['id' => $item['id']]); + Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } } diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 1e9f5c7f..ecd6f862 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -564,7 +564,7 @@ function tumblr_send(array &$b) if ($result->meta->status < 400) { Logger::info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); if (!$b['deleted'] && !empty($result->response->id_string)) { - Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['id' => $b['id']]); + Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['guid' => $b['guid']]); } } else { Logger::notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); From f29908464b87916948ce3e6763c01195290b624f Mon Sep 17 00:00:00 2001 From: Michael Date: Thu, 12 Dec 2024 20:20:44 +0000 Subject: [PATCH 202/294] Bluesky: Fix token problems --- bluesky/bluesky.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 26ecb967..6451f3fa 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -416,7 +416,7 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p switch ($status) { case BLUEKSY_STATUS_TOKEN_OK: - return DI::l10n()->t("You are authenticated to Bluesky. For security reasons the password isn't stored."); + return DI::l10n()->t("You are authenticated to Bluesky."); case BLUEKSY_STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); case BLUEKSY_STATUS_API_FAIL; @@ -447,6 +447,7 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post', intval($_POST['bluesky'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'password', $_POST['bluesky_password']); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads'])); @@ -466,6 +467,7 @@ function bluesky_settings_post(array &$b) } else { DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'did'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); + DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'password'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'refresh_token'); DI::pConfig()->delete(DI::userSession()->getLocalUserId(), 'bluesky', 'token_created'); @@ -2108,6 +2110,11 @@ function bluesky_refresh_token(int $uid): string $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); if (empty($data) || empty($data->accessJwt)) { + Logger::debug('Refresh failed', ['return' => $data]); + $password = DI::pConfig()->get($uid, 'bluesky', 'password'); + if (!empty($password)) { + return bluesky_create_token($uid, $password); + } DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); return ''; } @@ -2174,7 +2181,11 @@ function bluesky_post(int $uid, string $url, string $params, array $headers): ?s $data->code = $curlResult->getReturnCode(); } - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); + if (!empty($data->code) && ($data->code >= 200) && ($data->code < 400)) { + DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); + } else { + DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); + } return $data; } @@ -2197,7 +2208,9 @@ function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdCl } $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); - DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); + if ($uid != 0) { + DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); + } return $data; } From 52b18c7d9a7df1dcd6adb1f1d4d25fa0653c76cc Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 14 Dec 2024 19:03:15 +0000 Subject: [PATCH 203/294] Bluesky: Functionality moved to the core --- bluesky/bluesky.php | 1267 ++++--------------------------------------- 1 file changed, 91 insertions(+), 1176 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 6451f3fa..c9c7dc67 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -26,7 +26,6 @@ */ use Friendica\Content\Text\BBCode; -use Friendica\Content\Text\HTML; use Friendica\Content\Text\Plaintext; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; @@ -39,42 +38,20 @@ use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\Contact; use Friendica\Model\Conversation; -use Friendica\Model\GServer; use Friendica\Model\Item; -use Friendica\Model\ItemURI; use Friendica\Model\Photo; use Friendica\Model\Post; -use Friendica\Model\Tag; use Friendica\Model\User; -use Friendica\Network\HTTPClient\Client\HttpClientAccept; -use Friendica\Network\HTTPClient\Client\HttpClientOptions; -use Friendica\Network\HTTPClient\Client\HttpClientRequest; use Friendica\Object\Image; use Friendica\Protocol\Activity; +use Friendica\Protocol\ATProtocol; use Friendica\Protocol\Relay; use Friendica\Util\DateTimeFormat; -use Friendica\Util\Network; use Friendica\Util\Strings; const BLUESKY_DEFAULT_POLL_INTERVAL = 10; // given in minutes const BLUESKY_IMAGE_SIZE = [1000000, 500000, 100000, 50000]; -const BLUEKSY_STATUS_UNKNOWN = 0; -const BLUEKSY_STATUS_TOKEN_OK = 1; -const BLUEKSY_STATUS_SUCCESS = 2; -const BLUEKSY_STATUS_API_FAIL = 10; -const BLUEKSY_STATUS_DID_FAIL = 11; -const BLUEKSY_STATUS_PDS_FAIL = 12; -const BLUEKSY_STATUS_TOKEN_FAIL = 13; - -/* - * (Currently) hard wired paths for Bluesky services - */ -const BLUESKY_APPVIEW_API = 'https://public.api.bsky.app'; // Path to the public Bluesky AppView API. -const BLUESKY_DIRECTORY = 'https://plc.directory'; // Path to the directory server service to fetch the PDS of a given DID -const BLUESKY_WEB = 'https://bsky.app'; // Path to the web interface with the user profile and posts -const BLUESKY_HOSTNAME = 'bsky.social'; // Host name to be added to the handle if incomplete - function bluesky_install() { Hook::register('load_config', __FILE__, 'bluesky_load_config'); @@ -86,13 +63,11 @@ function bluesky_install() Hook::register('connector_settings_post', __FILE__, 'bluesky_settings_post'); Hook::register('cron', __FILE__, 'bluesky_cron'); Hook::register('support_follow', __FILE__, 'bluesky_support_follow'); - Hook::register('support_probe', __FILE__, 'bluesky_support_probe'); Hook::register('follow', __FILE__, 'bluesky_follow'); Hook::register('unfollow', __FILE__, 'bluesky_unfollow'); Hook::register('block', __FILE__, 'bluesky_block'); Hook::register('unblock', __FILE__, 'bluesky_unblock'); Hook::register('check_item_notification', __FILE__, 'bluesky_check_item_notification'); - Hook::register('probe_detect', __FILE__, 'bluesky_probe_detect'); Hook::register('item_by_link', __FILE__, 'bluesky_item_by_link'); } @@ -107,7 +82,7 @@ function bluesky_check_item_notification(array &$notification_data) return; } - $did = bluesky_get_user_did($notification_data['uid']); + $did = DI::atProtocol()->getUserDid($notification_data['uid']); if (empty($did)) { return; } @@ -115,61 +90,6 @@ function bluesky_check_item_notification(array &$notification_data) $notification_data['profiles'][] = $did; } -function bluesky_probe_detect(array &$hookData) -{ - // Don't overwrite an existing result - if (isset($hookData['result'])) { - return; - } - - // Avoid a lookup for the wrong network - if (!in_array($hookData['network'], ['', Protocol::BLUESKY])) { - return; - } - - $pconfig = DBA::selectFirst('pconfig', ['uid'], ["`cat` = ? AND `k` = ? AND `v` != ?", 'bluesky', 'access_token', '']); - if (empty($pconfig['uid'])) { - return; - } - - if (parse_url($hookData['uri'], PHP_URL_SCHEME) == 'did') { - $did = $hookData['uri']; - } elseif (parse_url($hookData['uri'], PHP_URL_PATH) == $hookData['uri'] && strpos($hookData['uri'], '@') === false) { - $did = bluesky_get_did($hookData['uri'], $pconfig['uid']); - if (empty($did)) { - return; - } - } elseif (Network::isValidHttpUrl($hookData['uri'])) { - $did = bluesky_get_did_by_profile($hookData['uri'], $pconfig['uid']); - if (empty($did)) { - return; - } - } else { - return; - } - - $token = bluesky_get_token($pconfig['uid']); - if (empty($token)) { - return; - } - - $data = bluesky_xrpc_get($pconfig['uid'], 'app.bsky.actor.getProfile', ['actor' => $did]); - if (empty($data) || empty($data->did)) { - return; - } - - $hookData['result'] = bluesky_get_contact_fields($data, 0, $pconfig['uid'], true); - - // Preparing probe data. This differs slightly from the contact array - $hookData['result']['photo'] = $data->avatar ?? ''; - $hookData['result']['batch'] = ''; - $hookData['result']['notify'] = ''; - $hookData['result']['poll'] = ''; - $hookData['result']['poco'] = ''; - $hookData['result']['priority'] = 0; - $hookData['result']['guid'] = ''; -} - function bluesky_item_by_link(array &$hookData) { // Don't overwrite an existing result @@ -177,16 +97,17 @@ function bluesky_item_by_link(array &$hookData) return; } - $token = bluesky_get_token($hookData['uid']); + $token = DI::atProtocol()->getUserToken($hookData['uid']); if (empty($token)) { return; } - if (!preg_match('#^' . BLUESKY_WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + // @todo also support the URI format (at://did/app.bsky.feed.post/cid) + if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { return; } - $did = bluesky_get_did($matches[1], $hookData['uid']); + $did = DI::atProtocol()->getDid($matches[1]); if (empty($did)) { return; } @@ -195,7 +116,7 @@ function bluesky_item_by_link(array &$hookData) $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; - $uri = bluesky_fetch_missing_post($uri, $hookData['uid'], $hookData['uid'], Item::PR_FETCHED, 0, 0, 0); + $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); @@ -212,16 +133,9 @@ function bluesky_support_follow(array &$data) } } -function bluesky_support_probe(array &$data) -{ - if ($data['protocol'] == Protocol::BLUESKY) { - $data['result'] = true; - } -} - function bluesky_follow(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -240,11 +154,11 @@ function bluesky_follow(array &$hook_data) $post = [ 'collection' => 'app.bsky.graph.follow', - 'repo' => bluesky_get_user_did($hook_data['uid']), + 'repo' => DI::atProtocol()->getUserDid($hook_data['uid']), 'record' => $record ]; - $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $hook_data['contact'] = $contact; Logger::debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); @@ -253,7 +167,7 @@ function bluesky_follow(array &$hook_data) function bluesky_unfollow(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -262,7 +176,7 @@ function bluesky_unfollow(array &$hook_data) return; } - $data = bluesky_xrpc_get($hook_data['uid'], 'app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']]); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']], $hook_data['uid']); if (empty($data->viewer) || empty($data->viewer->following)) { return; } @@ -274,7 +188,7 @@ function bluesky_unfollow(array &$hook_data) function bluesky_block(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -291,11 +205,11 @@ function bluesky_block(array &$hook_data) $post = [ 'collection' => 'app.bsky.graph.block', - 'repo' => bluesky_get_user_did($hook_data['uid']), + 'repo' => DI::atProtocol()->getUserDid($hook_data['uid']), 'record' => $record ]; - $activity = bluesky_xrpc_post($hook_data['uid'], 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $ucid = Contact::getUserContactId($hook_data['contact']['id'], $hook_data['uid']); if ($ucid) { @@ -307,7 +221,7 @@ function bluesky_block(array &$hook_data) function bluesky_unblock(array &$hook_data) { - $token = bluesky_get_token($hook_data['uid']); + $token = DI::atProtocol()->getUserToken($hook_data['uid']); if (empty($token)) { return; } @@ -316,7 +230,7 @@ function bluesky_unblock(array &$hook_data) return; } - $data = bluesky_xrpc_get($hook_data['uid'], 'app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']]); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getProfile', ['actor' => $hook_data['contact']['url']], $hook_data['uid']); if (empty($data->viewer) || empty($data->viewer->blocking)) { return; } @@ -351,7 +265,7 @@ function bluesky_settings(array &$data) $def_enabled = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default') ?? false; $pds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'pds'); $handle = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'handle'); - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId()); + $did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId()); $token = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'access_token'); $import = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import') ?? false; $import_feeds = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds') ?? false; @@ -399,33 +313,33 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p return DI::l10n()->t('You are not authenticated. Please enter your handle and the app password.'); } - $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? BLUEKSY_STATUS_UNKNOWN; + $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; // Fallback mechanism for connection that had been established before the introduction of the status - if ($status == BLUEKSY_STATUS_UNKNOWN) { + if ($status == ATProtocol::STATUS_UNKNOWN) { if (empty($did)) { - $status = BLUEKSY_STATUS_DID_FAIL; + $status = ATProtocol::STATUS_DID_FAIL; } elseif (empty($pds)) { - $status = BLUEKSY_STATUS_PDS_FAIL; + $status = ATProtocol::STATUS_PDS_FAIL; } elseif (!empty($token)) { - $status = BLUEKSY_STATUS_TOKEN_OK; + $status = ATProtocol::STATUS_TOKEN_OK; } else { - $status = BLUEKSY_STATUS_TOKEN_FAIL; + $status = ATProtocol::STATUS_TOKEN_FAIL; } } switch ($status) { - case BLUEKSY_STATUS_TOKEN_OK: + case ATProtocol::STATUS_TOKEN_OK: return DI::l10n()->t("You are authenticated to Bluesky."); - case BLUEKSY_STATUS_SUCCESS: + case ATProtocol::STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); - case BLUEKSY_STATUS_API_FAIL; + case ATProtocol::STATUS_API_FAIL; return DI::l10n()->t('Communication issues with the personal data server service (PDS).'); - case BLUEKSY_STATUS_DID_FAIL: + case ATProtocol::STATUS_DID_FAIL: return DI::l10n()->t('The DID for the provided handle could not be detected. Please check if you entered the correct handle.'); - case BLUEKSY_STATUS_PDS_FAIL: + case ATProtocol::STATUS_PDS_FAIL: return DI::l10n()->t('The personal data server service (PDS) could not be detected.'); - case BLUEKSY_STATUS_TOKEN_FAIL: + case ATProtocol::STATUS_TOKEN_FAIL: return DI::l10n()->t('The authentication with the provided handle and password failed. Please check if you entered the correct password.'); default: return ''; @@ -454,11 +368,11 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'friendica_handle', intval($_POST['bluesky_friendica_handle'] ?? false)); if (!empty($handle)) { - $did = bluesky_get_user_did(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); + $did = DI::atProtocol()->getUserDid(DI::userSession()->getLocalUserId(), empty($old_did) || $old_handle != $handle); if (!empty($did) && (empty($old_pds) || $old_handle != $handle)) { - $pds = bluesky_get_pds($did); + $pds = DI::atProtocol()->getPdsOfDid($did); if (empty($pds)) { - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'status', BLUEKSY_STATUS_PDS_FAIL); + DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'status', ATProtocol::STATUS_PDS_FAIL); } DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'pds', $pds); } else { @@ -475,7 +389,7 @@ function bluesky_settings_post(array &$b) } if (!empty($did) && !empty($pds) && !empty($_POST['bluesky_password'])) { - bluesky_create_token(DI::userSession()->getLocalUserId(), $_POST['bluesky_password']); + DI::atProtocol()->createUserToken(DI::userSession()->getLocalUserId(), $_POST['bluesky_password']); } } @@ -524,7 +438,7 @@ function bluesky_cron() $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { - if (empty(bluesky_get_user_did($pconfig['uid']))) { + if (empty(DI::atProtocol()->getUserDid($pconfig['uid']))) { Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]); continue; } @@ -538,7 +452,13 @@ function bluesky_cron() // Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); - bluesky_get_token($pconfig['uid']); + DI::atProtocol()->getUserToken($pconfig['uid']); + + $last_sync = DI::pConfig()->get($pconfig['uid'], 'bluesky', 'last_contact_sync'); + if ($last_sync < (time() - 86400)) { + DI::atpActor()->syncContacts($pconfig['uid']); + DI::pConfig()->set($pconfig['uid'], 'bluesky', 'last_contact_sync', time()); + } Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_notifications.php', $pconfig['uid']); if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import')) { @@ -640,7 +560,7 @@ function bluesky_send(array &$b) Logger::debug('Got comment', ['item' => $b]); if ($b['deleted']) { - $uri = bluesky_get_uri_class($b['uri']); + $uri = DI::atpProcessor()->getUriClass($b['uri']); if (empty($uri)) { Logger::debug('Not a bluesky post', ['uri' => $b['uri']]); return; @@ -649,8 +569,8 @@ function bluesky_send(array &$b) return; } - $root = bluesky_get_uri_class($b['parent-uri']); - $parent = bluesky_get_uri_class($b['thr-parent']); + $root = DI::atpProcessor()->getUriClass($b['parent-uri']); + $parent = DI::atpProcessor()->getUriClass($b['thr-parent']); if (empty($root) || empty($parent)) { Logger::debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); @@ -675,12 +595,12 @@ function bluesky_send(array &$b) function bluesky_create_activity(array $item, stdClass $parent = null) { $uid = $item['uid']; - $token = bluesky_get_token($uid); + $token = DI::atProtocol()->getUserToken($uid); if (empty($token)) { return; } - $did = bluesky_get_user_did($uid); + $did = DI::atProtocol()->getUserDid($uid); if (empty($did)) { return; } @@ -711,12 +631,12 @@ function bluesky_create_activity(array $item, stdClass $parent = null) ]; } - $activity = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); + $activity = DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.createRecord', $post); if (empty($activity->uri)) { return; } Logger::debug('Activity done', ['return' => $activity]); - $uri = bluesky_get_uri($activity); + $uri = DI::atpProcessor()->getUri($activity); Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } @@ -724,7 +644,7 @@ function bluesky_create_activity(array $item, stdClass $parent = null) function bluesky_create_post(array $item, stdClass $root = null, stdClass $parent = null) { $uid = $item['uid']; - $token = bluesky_get_token($uid); + $token = DI::atProtocol()->getUserToken($uid); if (empty($token)) { return; } @@ -791,11 +711,11 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $post = [ 'collection' => 'app.bsky.feed.post', - 'repo' => bluesky_get_user_did($uid), + 'repo' => DI::atProtocol()->getUserDid($uid), 'record' => $record ]; - $parent = bluesky_xrpc_post($uid, 'com.atproto.repo.createRecord', $post); + $parent = DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.createRecord', $post); if (empty($parent->uri)) { if ($part == 0) { Worker::defer(); @@ -807,7 +727,7 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren $root = $parent; } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { - $uri = bluesky_get_uri($parent); + $uri = DI::atpProcessor()->getUri($parent); Item::update(['extid' => $uri], ['guid' => $item['guid']]); Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } @@ -973,7 +893,7 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); - $data = bluesky_post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); + $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; @@ -986,18 +906,18 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass function bluesky_delete_post(string $uri, int $uid) { - $parts = bluesky_get_uri_parts($uri); + $parts = DI::atpProcessor()->getUriParts($uri); if (empty($parts)) { Logger::debug('No uri delected', ['uri' => $uri]); return; } - bluesky_xrpc_post($uid, 'com.atproto.repo.deleteRecord', $parts); + DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.deleteRecord', $parts); Logger::debug('Deleted', ['parts' => $parts]); } function bluesky_fetch_timeline(int $uid) { - $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getTimeline'); + $data = DI::atProtocol()->XRPCGet('app.bsky.feed.getTimeline', [], $uid); if (empty($data)) { return; } @@ -1006,42 +926,39 @@ function bluesky_fetch_timeline(int $uid) return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - foreach (array_reverse($data->feed) as $entry) { - $causer = bluesky_get_contact($entry->post->author, 0, $uid); + $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0, true); if (!empty($entry->reply)) { if (!empty($entry->reply->root)) { - bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + bluesky_complete_post($entry->reply->root, $uid, Item::PR_COMMENT, $causer['id'], Conversation::PARCEL_CONNECTOR); } if (!empty($entry->reply->parent)) { - bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + bluesky_complete_post($entry->reply->parent, $uid, Item::PR_COMMENT, $causer['id'], Conversation::PARCEL_CONNECTOR); } } - bluesky_process_post($entry->post, $uid, $uid, Item::PR_NONE, 0, 0, $last_poll, Conversation::PARCEL_CONNECTOR); + DI::atpProcessor()->processPost($entry->post, $uid, Item::PR_NONE, 0, 0, Conversation::PARCEL_CONNECTOR); if (!empty($entry->reason)) { - bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); + bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); } } } -function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $last_poll, int $protocol): int +function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $causer, int $protocol): int { $complete = DI::pConfig()->get($uid, 'bluesky', 'complete_threads'); - $existing_uri = bluesky_fetch_post(bluesky_get_uri($post), $uid); + $existing_uri = DI::atpProcessor()->getPostUri(DI::atpProcessor()->getUri($post), $uid); if (!empty($existing_uri)) { $comments = Post::countPosts(['thr-parent' => $existing_uri, 'gravity' => Item::GRAVITY_COMMENT]); if (($post->replyCount <= $comments) || !$complete) { - return bluesky_fetch_uri_id($existing_uri, $uid); + return DI::atpProcessor()->fetchUriId($existing_uri, $uid); } } if ($complete) { - $uri = bluesky_fetch_missing_post(bluesky_get_uri($post), $uid, $uid, $post_reason, $causer, 0, $last_poll, '', true); - $uri_id = bluesky_fetch_uri_id($uri, $uid); + $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true); + $uri_id = DI::atpProcessor()->fetchUriId($uri, $uid); } else { - $uri_id = bluesky_process_post($post, $uid, $uid, $post_reason, $causer, 0, $last_poll, $protocol); + $uri_id = DI::atpProcessor()->processPost($post, $uid, $post_reason, $causer, 0, $protocol); } return $uri_id; } @@ -1053,7 +970,7 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) return; } - $contact = bluesky_get_contact($reason->by, $uid, $uid); + $contact = DI::atpActor()->getContactByDID($reason->by->did, $uid, 0); $item = [ 'network' => Protocol::BLUESKY, @@ -1089,16 +1006,13 @@ function bluesky_process_reason(stdClass $reason, string $uri, int $uid) function bluesky_fetch_notifications(int $uid) { - $data = bluesky_xrpc_get($uid, 'app.bsky.notification.listNotifications'); + $data = DI::atProtocol()->XRPCGet('app.bsky.notification.listNotifications', [], $uid); if (empty($data->notifications)) { return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - foreach ($data->notifications as $notification) { - $uri = bluesky_get_uri($notification); + $uri = DI::atpProcessor()->getUri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { Logger::debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); continue; @@ -1106,11 +1020,11 @@ function bluesky_fetch_notifications(int $uid) Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': - $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll, Conversation::PARCEL_CONNECTOR); + $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::LIKE; - $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject); + $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); @@ -1120,11 +1034,11 @@ function bluesky_fetch_notifications(int $uid) break; case 'repost': - $item = bluesky_get_header($notification, $uri, $uid, $uid, $last_poll, Conversation::PARCEL_CONNECTOR); + $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); $item['gravity'] = Item::GRAVITY_ACTIVITY; $item['body'] = $item['verb'] = Activity::ANNOUNCE; - $item['thr-parent'] = bluesky_get_uri($notification->record->subject); - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $uid, Item::PR_FETCHED, $item['contact-id'], 0, $last_poll); + $item['thr-parent'] = DI::atpProcessor()->getUri($notification->record->subject); + $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); @@ -1134,25 +1048,25 @@ function bluesky_fetch_notifications(int $uid) break; case 'follow': - $contact = bluesky_get_contact($notification->author, $uid, $uid); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, $uid); Logger::debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); break; case 'mention': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_TO, $contact['id'], 0, $last_poll); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0); Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_COMMENT, $contact['id'], 0, $last_poll); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0); Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': - $contact = bluesky_get_contact($notification->author, 0, $uid); - $result = bluesky_fetch_missing_post($uri, $uid, $uid, Item::PR_PUSHED, $contact['id'], 0, $last_poll); + $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); + $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0); Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; @@ -1165,7 +1079,7 @@ function bluesky_fetch_notifications(int $uid) function bluesky_fetch_feed(int $uid, string $feed) { - $data = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeed', ['feed' => $feed]); + $data = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeed', ['feed' => $feed], $uid); if (empty($data)) { return; } @@ -1174,10 +1088,7 @@ function bluesky_fetch_feed(int $uid, string $feed) return; } - $last_post = DBA::selectFirst('post-thread-user', ['received'], ['network' => Protocol::BLUESKY, 'uid' => $uid], ['order' => ['received' => true]]); - $last_poll = !empty($last_post['received']) ? strtotime($last_post['received']) : 0; - - $feeddata = bluesky_xrpc_get($uid, 'app.bsky.feed.getFeedGenerator', ['feed' => $feed]); + $feeddata = DI::atProtocol()->XRPCGet('app.bsky.feed.getFeedGenerator', ['feed' => $feed], $uid); if (!empty($feeddata) && !empty($feeddata->view)) { $feedurl = $feeddata->view->uri; $feedname = $feeddata->view->displayName; @@ -1187,15 +1098,15 @@ function bluesky_fetch_feed(int $uid, string $feed) } foreach (array_reverse($data->feed) as $entry) { - $contact = bluesky_get_contact($entry->post->author, 0, $uid); + $contact = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } - $causer = bluesky_get_contact($entry->post->author, 0, $uid); - $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], $last_poll, Conversation::PARCEL_CONNECTOR); + $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); + $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], Conversation::PARCEL_CONNECTOR); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); @@ -1203,641 +1114,11 @@ function bluesky_fetch_feed(int $uid, string $feed) Logger::notice('Post not found', ['entry' => $entry]); } if (!empty($entry->reason)) { - bluesky_process_reason($entry->reason, bluesky_get_uri($entry->post), $uid); + bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); } } } -function bluesky_process_post(stdClass $post, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, int $protocol): int -{ - $uri = bluesky_get_uri($post); - - if ($uri_id = bluesky_fetch_uri_id($uri, $uid)) { - return $uri_id; - } - - if (empty($post->record)) { - Logger::debug('Invalid post', ['uri' => $uri]); - return 0; - } - - Logger::debug('Importing post', ['uid' => $uid, 'indexedAt' => $post->indexedAt, 'uri' => $post->uri, 'cid' => $post->cid, 'root' => $post->record->reply->root ?? '']); - - $item = bluesky_get_header($post, $uri, $uid, $fetch_uid, $last_poll, $protocol); - $item = bluesky_get_content($item, $post->record, $uri, $uid, $fetch_uid, $level, $last_poll); - if (empty($item)) { - return 0; - } - - if (!empty($post->embed)) { - $item = bluesky_add_media($post->embed, $item, $uid, $level, $last_poll); - } - - $item['restrictions'] = bluesky_get_restrictions_for_user($post, $item, $post_reason); - - if (empty($item['post-reason'])) { - $item['post-reason'] = $post_reason; - } - - if ($causer != 0) { - $item['causer-id'] = $causer; - } - - Item::insert($item); - return bluesky_fetch_uri_id($uri, $uid); -} - -function bluesky_get_header(stdClass $post, string $uri, int $uid, int $fetch_uid, int $last_poll, int $protocol): array -{ - $parts = bluesky_get_uri_parts($uri); - if (empty($post->author) || empty($post->cid) || empty($parts->rkey)) { - return []; - } - $contact = bluesky_get_contact($post->author, $uid, $fetch_uid); - $item = [ - 'network' => Protocol::BLUESKY, - 'protocol' => $protocol, - 'uid' => $uid, - 'wall' => false, - 'uri' => $uri, - 'guid' => $post->cid, - 'received' => DateTimeFormat::utc($post->indexedAt, DateTimeFormat::MYSQL), - 'private' => Item::UNLISTED, - 'verb' => Activity::POST, - 'contact-id' => $contact['id'], - 'author-name' => $contact['name'], - 'author-link' => $contact['url'], - 'author-avatar' => $contact['avatar'], - 'plink' => $contact['alias'] . '/post/' . $parts->rkey, - 'source' => json_encode($post), - ]; - - if (($last_poll != 0) && strtotime($item['received']) < $last_poll) { - unset($item['received']); - } - - $account = Contact::selectFirstAccountUser(['pid'], ['id' => $contact['id']]); - - $item['author-id'] = $account['pid']; - $item['uri-id'] = ItemURI::getIdByURI($uri); - $item['owner-id'] = $item['author-id']; - $item['owner-name'] = $item['author-name']; - $item['owner-link'] = $item['author-link']; - $item['owner-avatar'] = $item['author-avatar']; - - if (in_array($contact['rel'], [Contact::SHARING, Contact::FRIEND])) { - $item['post-reason'] = Item::PR_FOLLOWER; - } - - if (!empty($post->labels)) { - foreach ($post->labels as $label) { - // Only flag posts as sensitive based on labels that had been provided by the author. - // When "ver" is set to "1" it was flagged by some automated process. - if (empty($label->ver)) { - $item['sensitive'] = true; - $item['content-warning'] = $label->val ?? ''; - Logger::debug('Sensitive content', ['uri-id' => $item['uri-id'], 'label' => $label]); - } - } - } - - return $item; -} - -function bluesky_get_restrictions_for_user(stdClass $post, array $item, int $post_reason): ?int -{ - if (!empty($post->viewer->replyDisabled)) { - return Item::CANT_REPLY; - } - - if (empty($post->threadgate)) { - return null; - } - - if (!isset($post->threadgate->record->allow)) { - return null; - } - - if ($item['uid'] == 0) { - return Item::CANT_REPLY; - } - - $restrict = true; - $type = '$type'; - foreach ($post->threadgate->record->allow as $allow) { - switch ($allow->$type) { - case 'app.bsky.feed.threadgate#followingRule': - // Only followers can reply. - if (Contact::isFollower($item['author-id'], $item['uid'])) { - $restrict = false; - } - break; - case 'app.bsky.feed.threadgate#mentionRule': - // Only mentioned accounts can reply. - if ($post_reason == Item::PR_TO) { - $restrict = false; - } - break; - case 'app.bsky.feed.threadgate#listRule'; - // Only accounts in the provided list can reply. We don't support this at the moment. - break; - } - } - - return $restrict ? Item::CANT_REPLY : null; -} - -function bluesky_get_content(array $item, stdClass $record, string $uri, int $uid, int $fetch_uid, int $level, int $last_poll): array -{ - if (empty($item)) { - return []; - } - - if (!empty($record->reply)) { - $item['parent-uri'] = bluesky_get_uri($record->reply->root); - if ($item['parent-uri'] != $uri) { - $item['parent-uri'] = bluesky_fetch_missing_post($item['parent-uri'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - if (empty($item['parent-uri'])) { - return []; - } - } - - $item['thr-parent'] = bluesky_get_uri($record->reply->parent); - if (!in_array($item['thr-parent'], [$uri, $item['parent-uri']])) { - $item['thr-parent'] = bluesky_fetch_missing_post($item['thr-parent'], $uid, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll, $item['parent-uri']); - if (empty($item['thr-parent'])) { - return []; - } - } - } - - $item['body'] = bluesky_get_text($record, $item['uri-id']); - $item['created'] = DateTimeFormat::utc($record->createdAt, DateTimeFormat::MYSQL); - $item['transmitted-languages'] = $record->langs ?? []; - - return $item; -} - -function bluesky_get_text(stdClass $record, int $uri_id): string -{ - $text = $record->text ?? ''; - - if (empty($record->facets)) { - return $text; - } - - $facets = []; - foreach ($record->facets as $facet) { - $facets[$facet->index->byteStart] = $facet; - } - krsort($facets); - - foreach ($facets as $facet) { - $prefix = substr($text, 0, $facet->index->byteStart); - $linktext = substr($text, $facet->index->byteStart, $facet->index->byteEnd - $facet->index->byteStart); - $suffix = substr($text, $facet->index->byteEnd); - - $url = ''; - $type = '$type'; - foreach ($facet->features as $feature) { - - switch ($feature->$type) { - case 'app.bsky.richtext.facet#link': - $url = $feature->uri; - break; - - case 'app.bsky.richtext.facet#mention': - $contact = Contact::getByURL($feature->did, null, ['id']); - if (!empty($contact['id'])) { - $url = DI::baseUrl() . '/contact/' . $contact['id']; - if (substr($linktext, 0, 1) == '@') { - $prefix .= '@'; - $linktext = substr($linktext, 1); - } - } - break; - - case 'app.bsky.richtext.facet#tag'; - Tag::store($uri_id, Tag::HASHTAG, $feature->tag); - $url = DI::baseUrl() . '/search?tag=' . urlencode($feature->tag); - $linktext = '#' . $feature->tag; - break; - - default: - Logger::notice('Unhandled feature type', ['type' => $feature->$type, 'feature' => $feature, 'record' => $record]); - break; - } - } - if (!empty($url)) { - $text = $prefix . '[url=' . $url . ']' . $linktext . '[/url]' . $suffix; - } - } - return $text; -} - -function bluesky_add_media(stdClass $embed, array $item, int $fetch_uid, int $level, int $last_poll): array -{ - $type = '$type'; - switch ($embed->$type) { - case 'app.bsky.embed.images#view': - foreach ($embed->images as $image) { - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::IMAGE, - 'url' => $image->fullsize, - 'preview' => $image->thumb, - 'description' => $image->alt, - ]; - Post\Media::insert($media); - } - break; - - case 'app.bsky.embed.video#view': - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HLS, - 'url' => $embed->playlist, - 'preview' => $embed->thumbnail, - 'description' => $embed->alt ?? '', - 'height' => $embed->aspectRatio->height ?? null, - 'width' => $embed->aspectRatio->width ?? null, - ]; - Post\Media::insert($media); - break; - - case 'app.bsky.embed.external#view': - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HTML, - 'url' => $embed->external->uri, - 'name' => $embed->external->title, - 'description' => $embed->external->description, - ]; - Post\Media::insert($media); - break; - - case 'app.bsky.embed.record#view': - $original_uri = $uri = bluesky_get_uri($embed->record); - $type = '$type'; - if (!empty($embed->record->record->$type)) { - $embed_type = $embed->record->record->$type; - if ($embed_type == 'app.bsky.graph.starterpack') { - bluesky_add_starterpack($item, $embed->record); - break; - } - } - $fetched_uri = bluesky_fetch_post($uri, $item['uid']); - if (!$fetched_uri) { - $uri = bluesky_fetch_missing_post($uri, 0, $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - } else { - $uri = $fetched_uri; - } - if ($uri) { - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); - $uri_id = $shared['uri-id'] ?? 0; - } - if (!empty($uri_id)) { - $item['quote-uri-id'] = $uri_id; - } else { - Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); - } - break; - - case 'app.bsky.embed.recordWithMedia#view': - bluesky_add_media($embed->media, $item, $fetch_uid, $level, $last_poll); - $original_uri = $uri = bluesky_get_uri($embed->record->record); - $uri = bluesky_fetch_missing_post($uri, $item['uid'], $fetch_uid, Item::PR_FETCHED, $item['contact-id'], $level, $last_poll); - if ($uri) { - $shared = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$item['uid'], 0]]); - $uri_id = $shared['uri-id'] ?? 0; - } - if (!empty($uri_id)) { - $item['quote-uri-id'] = $uri_id; - } else { - Logger::debug('Quoted post could not be fetched', ['original-uri' => $original_uri, 'uri' => $uri]); - } - break; - - default: - Logger::notice('Unhandled embed type', ['uri-id' => $item['uri-id'], 'type' => $embed->$type, 'embed' => $embed]); - break; - } - return $item; -} - -function bluesky_add_starterpack(array $item, stdClass $record) -{ - Logger::debug('Received starterpack', ['uri-id' => $item['uri-id'], 'guid' => $item['guid'], 'uri' => $record->uri]); - if (!preg_match('#^at://(.+)/app.bsky.graph.starterpack/(.+)#', $record->uri, $matches)) { - return; - } - - $media = [ - 'uri-id' => $item['uri-id'], - 'type' => Post\Media::HTML, - 'url' => 'https://bsky.app/starter-pack/' . $matches[1] . '/' . $matches[2], - 'name' => $record->record->name, - 'description' => $record->record->description, - ]; - - Post\Media::insert($media); - - $fields = [ - 'name' => $record->record->name, - 'description' => $record->record->description, - ]; - Post\Media::update($fields, ['uri-id' => $media['uri-id'], 'url' => $media['url']]); -} - -function bluesky_get_uri(stdClass $post): string -{ - if (empty($post->cid)) { - Logger::info('Invalid URI', ['post' => $post]); - return ''; - } - return $post->uri . ':' . $post->cid; -} - -function bluesky_get_uri_class(string $uri): ?stdClass -{ - if (empty($uri)) { - return null; - } - - $elements = explode(':', $uri); - if (empty($elements) || ($elements[0] != 'at')) { - $post = Post::selectFirstPost(['extid'], ['uri' => $uri]); - return bluesky_get_uri_class($post['extid'] ?? ''); - } - - $class = new stdClass; - - $class->cid = array_pop($elements); - $class->uri = implode(':', $elements); - - if ((substr_count($class->uri, '/') == 2) && (substr_count($class->cid, '/') == 2)) { - $class->uri .= ':' . $class->cid; - $class->cid = ''; - } - - return $class; -} - -function bluesky_get_uri_parts(string $uri): ?stdClass -{ - $class = bluesky_get_uri_class($uri); - if (empty($class)) { - return null; - } - - $parts = explode('/', substr($class->uri, 5)); - - $class = new stdClass; - - $class->repo = $parts[0]; - $class->collection = $parts[1]; - $class->rkey = $parts[2]; - - return $class; -} - -function bluesky_fetch_missing_post(string $uri, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, string $fallback = '', bool $always_fetch = false, int $Protocol = Conversation::PARCEL_CONNECTOR): string -{ - $fetched_uri = bluesky_fetch_post($uri, $uid); - if (!$always_fetch && !empty($fetched_uri)) { - return $fetched_uri; - } - - if (++$level > 100) { - Logger::info('Recursion level too deep', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); - // When the level is too deep we will fallback to the parent uri. - // Allthough the threading won't be correct, we at least had stored all posts and won't try again - return $fallback; - } - - $class = bluesky_get_uri_class($uri); - if (empty($class)) { - return $fallback; - } - - $fetch_uri = $class->uri; - - Logger::debug('Fetch missing post', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); - $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.feed.getPostThread', ['uri' => $fetch_uri]); - if (empty($data) || empty($data->thread)) { - Logger::info('Thread was not fetched', ['level' => $level, 'uid' => $uid, 'uri' => $uri, 'fallback' => $fallback]); - return $fallback; - } - - Logger::debug('Reply count', ['level' => $level, 'uid' => $uid, 'uri' => $uri]); - - if ($causer != 0) { - $causer = Contact::getPublicContactId($causer, $uid); - } - - if (!empty($data->thread->parent)) { - $parents = bluesky_fetch_parents($data->thread->parent, $uid); - - foreach ($parents as $parent) { - $uri_id = bluesky_process_post($parent, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll, $Protocol); - Logger::debug('Parent created', ['uri-id' => $uri_id]); - } - } - - return bluesky_process_thread($data->thread, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll, $Protocol); -} - -function bluesky_fetch_parents(stdClass $parent, int $uid, array $parents = []): array -{ - if (!empty($parent->parent)) { - $parents = bluesky_fetch_parents($parent->parent, $uid, $parents); - } - - if (!empty($parent->post) && empty(bluesky_fetch_post(bluesky_get_uri($parent->post), $uid))) { - $parents[] = $parent->post; - } - - return $parents; -} - -function bluesky_fetch_post(string $uri, int $uid): string -{ - if (Post::exists(['uri' => $uri, 'uid' => [$uid, 0]])) { - Logger::debug('Post exists', ['uri' => $uri]); - return $uri; - } - - $reply = Post::selectFirst(['uri'], ['extid' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri']; - } - return ''; -} - -function bluesky_fetch_uri_id(string $uri, int $uid): string -{ - $reply = Post::selectFirst(['uri-id'], ['uri' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri-id'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri-id']; - } - $reply = Post::selectFirst(['uri-id'], ['extid' => $uri, 'uid' => [$uid, 0]]); - if (!empty($reply['uri-id'])) { - Logger::debug('Post with extid exists', ['uri' => $uri]); - return $reply['uri-id']; - } - return 0; -} - -function bluesky_process_thread(stdClass $thread, int $uid, int $fetch_uid, int $post_reason, int $causer, int $level, int $last_poll, int $protocol): string -{ - if (empty($thread->post)) { - Logger::info('Invalid post', ['post' => $thread]); - return ''; - } - $uri = bluesky_get_uri($thread->post); - - $fetched_uri = bluesky_fetch_post($uri, $uid); - if (empty($fetched_uri)) { - $uri_id = bluesky_process_post($thread->post, $uid, $fetch_uid, $post_reason, $causer, $level, $last_poll, $protocol); - if ($uri_id) { - Logger::debug('Post has been processed and stored', ['uri-id' => $uri_id, 'uri' => $uri]); - return $uri; - } else { - Logger::info('Post has not not been stored', ['uri' => $uri]); - return ''; - } - } else { - Logger::debug('Post exists', ['uri' => $uri]); - $uri = $fetched_uri; - } - - foreach ($thread->replies ?? [] as $reply) { - $reply_uri = bluesky_process_thread($reply, $uid, $fetch_uid, Item::PR_FETCHED, $causer, $level, $last_poll, $protocol); - Logger::debug('Reply has been processed', ['uri' => $uri, 'reply' => $reply_uri]); - } - - return $uri; -} - -function bluesky_get_contact(stdClass $author, int $uid, int $fetch_uid): array -{ - $condition = ['network' => Protocol::BLUESKY, 'uid' => 0, 'nurl' => $author->did]; - $contact = Contact::selectFirst(['id', 'updated'], $condition); - - $update = empty($contact) || $contact['updated'] < DateTimeFormat::utc('now -24 hours'); - - $public_fields = $fields = bluesky_get_contact_fields($author, $uid, $fetch_uid, $update); - - $public_fields['uid'] = 0; - $public_fields['rel'] = Contact::NOTHING; - - if (empty($contact)) { - $cid = Contact::insert($public_fields); - } else { - $cid = $contact['id']; - Logger::debug('Update contact', ['fields' => $public_fields, 'id' => $cid]); - Contact::update($public_fields, ['id' => $cid], true); - } - - if ($uid != 0) { - $condition = ['network' => Protocol::BLUESKY, 'uid' => $uid, 'nurl' => $author->did]; - - $contact = Contact::selectFirst(['id', 'rel', 'uid'], $condition); - if (!isset($fields['rel']) && isset($contact['rel'])) { - $fields['rel'] = $contact['rel']; - } elseif (!isset($fields['rel'])) { - $fields['rel'] = Contact::NOTHING; - } - } - - if (($uid != 0) && ($fields['rel'] != Contact::NOTHING)) { - if (empty($contact)) { - $cid = Contact::insert($fields); - } else { - $cid = $contact['id']; - Logger::debug('Update contact', ['fields' => $fields, 'id' => $cid]); - Contact::update($fields, ['id' => $cid], true); - } - Logger::debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); - } else { - Logger::debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); - } - if (!empty($author->avatar)) { - Contact::updateAvatar($cid, $author->avatar); - } - - return Contact::getById($cid); -} - -function bluesky_get_contact_fields(stdClass $author, int $uid, int $fetch_uid, bool $update): array -{ - $nick = $author->handle ?? $author->did; - $name = $author->displayName ?? $nick; - $fields = [ - 'uid' => $uid, - 'network' => Protocol::BLUESKY, - 'priority' => 1, - 'writable' => true, - 'blocked' => false, - 'readonly' => false, - 'pending' => false, - 'url' => $author->did, - 'nurl' => $author->did, - 'alias' => BLUESKY_WEB . '/profile/' . $nick, - 'name' => $name ?: $nick, - 'nick' => $nick, - 'addr' => $nick, - ]; - - if (!$update) { - Logger::debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url'], 'fields' => $fields]); - return $fields; - } - - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $author->did); - if (!empty($data)) { - $fields['baseurl'] = bluesky_get_pds('', $data); - if (!empty($fields['baseurl'])) { - GServer::check($fields['baseurl'], Protocol::BLUESKY); - $fields['gsid'] = GServer::getID($fields['baseurl'], true); - } - $fields['pubkey'] = bluesky_get_public_key('', $data); - } - - $data = bluesky_xrpc_get($fetch_uid, 'app.bsky.actor.getProfile', ['actor' => $author->did]); - if (empty($data)) { - Logger::debug('Error fetching contact fields', ['uid' => $uid, 'url' => $fields['url']]); - return $fields; - } - - $fields['updated'] = DateTimeFormat::utcNow(DateTimeFormat::MYSQL); - - if (!empty($data->description)) { - $fields['about'] = HTML::toBBCode($data->description); - } - - if (!empty($data->banner)) { - $fields['header'] = $data->banner; - } - - if (!empty($data->viewer)) { - if (!empty($data->viewer->following) && !empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::FRIEND; - } elseif (!empty($data->viewer->following) && empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::SHARING; - } elseif (empty($data->viewer->following) && !empty($data->viewer->followedBy)) { - $fields['rel'] = Contact::FOLLOWER; - } else { - $fields['rel'] = Contact::NOTHING; - } - } - - Logger::debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); - return $fields; -} - function bluesky_get_feeds(int $uid): array { $type = '$type'; @@ -1861,7 +1142,7 @@ function bluesky_get_preferences(int $uid): ?stdClass return $data; } - $data = bluesky_xrpc_get($uid, 'app.bsky.actor.getPreferences'); + $data = DI::atProtocol()->XRPCGet('app.bsky.actor.getPreferences', [], $uid); if (empty($data)) { return null; } @@ -1869,369 +1150,3 @@ function bluesky_get_preferences(int $uid): ?stdClass DI::cache()->set($cachekey, $data, Duration::HOUR); return $data; } - -function bluesky_get_did_by_profile(string $url, int $uid): string -{ - if (preg_match('#^' . BLUESKY_WEB . '/profile/(.+)#', $url, $matches)) { - $did = bluesky_get_did($matches[1], $uid); - if (!empty($did)) { - return $did; - } - } - try { - $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::REQUEST => HttpClientRequest::CONTACTINFO]); - } catch (\Throwable $th) { - return ''; - } - if (!$curlResult->isSuccess()) { - return ''; - } - $profile = $curlResult->getBodyString(); - if (empty($profile)) { - return ''; - } - - $doc = new DOMDocument(); - try { - @$doc->loadHTML($profile); - } catch (\Throwable $th) { - return ''; - } - $xpath = new DOMXPath($doc); - $list = $xpath->query('//p[@id]'); - foreach ($list as $node) { - foreach ($node->attributes as $attribute) { - if ($attribute->name == 'id') { - $ids[$attribute->value] = $node->textContent; - } - } - } - - if (empty($ids['bsky_handle']) || empty($ids['bsky_did'])) { - return ''; - } - - if (!bluesky_valid_did($ids['bsky_did'], $ids['bsky_handle'])) { - Logger::notice('Invalid DID', ['handle' => $ids['bsky_handle'], 'did' => $ids['bsky_did']]); - return ''; - } - - return $ids['bsky_did']; -} - -function bluesky_get_did_by_wellknown(string $handle): string -{ - $curlResult = DI::httpClient()->get('http://' . $handle . '/.well-known/atproto-did'); - if ($curlResult->isSuccess() && substr($curlResult->getBodyString(), 0, 4) == 'did:') { - $did = $curlResult->getBodyString(); - if (!bluesky_valid_did($did, $handle)) { - Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); - return ''; - } - return $did; - } - return ''; -} - -function bluesky_get_did_by_dns(string $handle): string -{ - $records = @dns_get_record('_atproto.' . $handle . '.', DNS_TXT); - if (empty($records)) { - return ''; - } - foreach ($records as $record) { - if (!empty($record['txt']) && substr($record['txt'], 0, 4) == 'did=') { - $did = substr($record['txt'], 4); - if (!bluesky_valid_did($did, $handle)) { - Logger::notice('Invalid DID', ['handle' => $handle, 'did' => $did]); - return ''; - } - return $did; - } - } - return ''; -} - -function bluesky_get_did(string $handle, int $uid): string -{ - if ($handle == '') { - return ''; - } - - if (strpos($handle, '.') === false) { - $handle .= '.' . BLUESKY_HOSTNAME; - } - - // At first we use the user PDS. That should cover most cases. - $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); - if (!empty($pds)) { - $data = bluesky_get($pds . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by user PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; - } - } - - // Then we query the DNS, which is used for third party handles (DNS should be faster than wellknown) - $did = bluesky_get_did_by_dns($handle); - if ($did != '') { - Logger::debug('Got DID by DNS', ['handle' => $handle, 'did' => $did]); - return $did; - } - - // Then we query wellknown, which should mostly cover the rest. - $did = bluesky_get_did_by_wellknown($handle); - if ($did != '') { - Logger::debug('Got DID by wellknown', ['handle' => $handle, 'did' => $did]); - return $did; - } - - // And finally we use the AppView API. - $data = bluesky_get(BLUESKY_APPVIEW_API . '/xrpc/com.atproto.identity.resolveHandle?handle=' . urlencode($handle)); - if (!empty($data) && !empty($data->did)) { - Logger::debug('Got DID by system PDS call', ['handle' => $handle, 'did' => $data->did]); - return $data->did; - } - - Logger::notice('No DID detected', ['handle' => $handle]); - return ''; -} - -function bluesky_get_user_did(int $uid, bool $refresh = false): ?string -{ - if (!$refresh) { - $did = DI::pConfig()->get($uid, 'bluesky', 'did'); - if (!empty($did)) { - return $did; - } - } - - $handle = DI::pConfig()->get($uid, 'bluesky', 'handle'); - if (empty($handle)) { - return null; - } - - $did = bluesky_get_did($handle, $uid); - if (empty($did)) { - return null; - } - - Logger::debug('Got DID for user', ['uid' => $uid, 'handle' => $handle, 'did' => $did]); - DI::pConfig()->set($uid, 'bluesky', 'did', $did); - return $did; -} - -function bluesky_get_user_pds(int $uid): ?string -{ - if ($uid == 0) { - return BLUESKY_APPVIEW_API; - } - - $pds = DI::pConfig()->get($uid, 'bluesky', 'pds'); - if (!empty($pds)) { - return $pds; - } - - $did = bluesky_get_user_did($uid); - if (empty($did)) { - return null; - } - - $pds = bluesky_get_pds($did); - if (empty($pds)) { - return null; - } - - DI::pConfig()->set($uid, 'bluesky', 'pds', $pds); - return $pds; -} - -function bluesky_get_pds(string $did, stdClass $data = null): ?string -{ - if (empty($data)) { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - } - if (empty($data) || empty($data->service)) { - return null; - } - - foreach ($data->service as $service) { - if (($service->id == '#atproto_pds') && ($service->type == 'AtprotoPersonalDataServer') && !empty($service->serviceEndpoint)) { - return $service->serviceEndpoint; - } - } - - return null; -} - -function bluesky_get_public_key(string $did, stdClass $data = null): ?string -{ - if (empty($data)) { - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - } - if (empty($data) || empty($data->verificationMethod)) { - return null; - } - foreach ($data->verificationMethod as $method) { - if (!empty($method->publicKeyMultibase)) { - return $method->publicKeyMultibase; - } - } - return null; -} - -function bluesky_valid_did(string $did, string $handle): bool -{ - $data = bluesky_get(BLUESKY_DIRECTORY . '/' . $did); - if (empty($data) || empty($data->alsoKnownAs)) { - return false; - } - - return in_array('at://' . $handle, $data->alsoKnownAs); -} - -function bluesky_get_token(int $uid): string -{ - $token = DI::pConfig()->get($uid, 'bluesky', 'access_token'); - $created = DI::pConfig()->get($uid, 'bluesky', 'token_created'); - if (empty($token)) { - return ''; - } - - if ($created + 300 < time()) { - return bluesky_refresh_token($uid); - } - return $token; -} - -function bluesky_refresh_token(int $uid): string -{ - $token = DI::pConfig()->get($uid, 'bluesky', 'refresh_token'); - - $data = bluesky_post($uid, '/xrpc/com.atproto.server.refreshSession', '', ['Authorization' => ['Bearer ' . $token]]); - if (empty($data) || empty($data->accessJwt)) { - Logger::debug('Refresh failed', ['return' => $data]); - $password = DI::pConfig()->get($uid, 'bluesky', 'password'); - if (!empty($password)) { - return bluesky_create_token($uid, $password); - } - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); - return ''; - } - - Logger::debug('Refreshed token', ['return' => $data]); - DI::pConfig()->set($uid, 'bluesky', 'access_token', $data->accessJwt); - DI::pConfig()->set($uid, 'bluesky', 'refresh_token', $data->refreshJwt); - DI::pConfig()->set($uid, 'bluesky', 'token_created', time()); - return $data->accessJwt; -} - -function bluesky_create_token(int $uid, string $password): string -{ - $did = bluesky_get_user_did($uid); - if (empty($did)) { - return ''; - } - - $data = bluesky_post($uid, '/xrpc/com.atproto.server.createSession', json_encode(['identifier' => $did, 'password' => $password]), ['Content-type' => 'application/json']); - if (empty($data) || empty($data->accessJwt)) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_FAIL); - return ''; - } - - Logger::debug('Created token', ['return' => $data]); - DI::pConfig()->set($uid, 'bluesky', 'access_token', $data->accessJwt); - DI::pConfig()->set($uid, 'bluesky', 'refresh_token', $data->refreshJwt); - DI::pConfig()->set($uid, 'bluesky', 'token_created', time()); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_TOKEN_OK); - return $data->accessJwt; -} - -function bluesky_xrpc_post(int $uid, string $url, $parameters): ?stdClass -{ - $data = bluesky_post($uid, '/xrpc/' . $url, json_encode($parameters), ['Content-type' => 'application/json', 'Authorization' => ['Bearer ' . bluesky_get_token($uid)]]); - if (!empty($data)) { - Item::incrementOutbound(Protocol::BLUESKY); - } - return $data; -} - -function bluesky_post(int $uid, string $url, string $params, array $headers): ?stdClass -{ - $pds = bluesky_get_user_pds($uid); - if (empty($pds)) { - return null; - } - - try { - $curlResult = DI::httpClient()->post($pds . $url, $params, $headers); - } catch (\Exception $e) { - Logger::notice('Exception on post', ['exception' => $e]); - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; - } - - $data = json_decode($curlResult->getBodyString()); - if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); - if (!$data) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - return null; - } - $data->code = $curlResult->getReturnCode(); - } - - if (!empty($data->code) && ($data->code >= 200) && ($data->code < 400)) { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_SUCCESS); - } else { - DI::pConfig()->set($uid, 'bluesky', 'status', BLUEKSY_STATUS_API_FAIL); - } - return $data; -} - -function bluesky_xrpc_get(int $uid, string $url, array $parameters = []): ?stdClass -{ - if (!empty($parameters)) { - $url .= '?' . http_build_query($parameters); - } - - $pds = bluesky_get_user_pds($uid); - if (empty($pds)) { - return null; - } - - $headers = ['Authorization' => ['Bearer ' . bluesky_get_token($uid)]]; - - $languages = User::getWantedLanguages($uid); - if (!empty($languages)) { - $headers['Accept-Language'] = implode(',', $languages); - } - - $data = bluesky_get($pds . '/xrpc/' . $url, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => $headers]); - if ($uid != 0) { - DI::pConfig()->set($uid, 'bluesky', 'status', is_null($data) ? BLUEKSY_STATUS_API_FAIL : BLUEKSY_STATUS_SUCCESS); - } - return $data; -} - -function bluesky_get(string $url, string $accept_content = HttpClientAccept::DEFAULT, array $opts = []): ?stdClass -{ - try { - $curlResult = DI::httpClient()->get($url, $accept_content, $opts); - } catch (\Exception $e) { - Logger::notice('Exception on get', ['url' => $url, 'exception' => $e]); - return null; - } - - $data = json_decode($curlResult->getBodyString()); - if (!$curlResult->isSuccess()) { - Logger::notice('API Error', ['url' => $url, 'code' => $curlResult->getReturnCode(), 'error' => $data ?: $curlResult->getBodyString()]); - if (!$data) { - return null; - } - $data->code = $curlResult->getReturnCode(); - } - - Item::incrementInbound(Protocol::BLUESKY); - return $data; -} From 01ec6ecb8ea98555d744949305a60e12e2fdb76c Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 17 Dec 2024 04:50:54 +0000 Subject: [PATCH 204/294] Bluesky: Handle problems when uploading pictures --- bluesky/bluesky.php | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index c9c7dc67..d6b7624b 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -313,7 +313,8 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p return DI::l10n()->t('You are not authenticated. Please enter your handle and the app password.'); } - $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; + $status = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status') ?? ATProtocol::STATUS_UNKNOWN; + $message = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'bluesky', 'status-message') ?? ''; // Fallback mechanism for connection that had been established before the introduction of the status if ($status == ATProtocol::STATUS_UNKNOWN) { @@ -330,11 +331,11 @@ function bluesky_get_status(string $handle = null, string $did = null, string $p switch ($status) { case ATProtocol::STATUS_TOKEN_OK: - return DI::l10n()->t("You are authenticated to Bluesky."); + return DI::l10n()->t("You are authenticated to Bluesky. For security reasons the password isn't stored."); case ATProtocol::STATUS_SUCCESS: return DI::l10n()->t('The communication with the personal data server service (PDS) is established.'); case ATProtocol::STATUS_API_FAIL; - return DI::l10n()->t('Communication issues with the personal data server service (PDS).'); + return DI::l10n()->t('Communication issues with the personal data server service (PDS): %s', $message); case ATProtocol::STATUS_DID_FAIL: return DI::l10n()->t('The DID for the provided handle could not be detected. Please check if you entered the correct handle.'); case ATProtocol::STATUS_PDS_FAIL: @@ -361,7 +362,6 @@ function bluesky_settings_post(array &$b) DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post', intval($_POST['bluesky'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'post_by_default', intval($_POST['bluesky_bydefault'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'handle', $handle); - DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'password', $_POST['bluesky_password']); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import', intval($_POST['bluesky_import'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'import_feeds', intval($_POST['bluesky_import_feeds'])); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'bluesky', 'complete_threads', intval($_POST['bluesky_complete_threads'])); @@ -850,7 +850,14 @@ function bluesky_add_embed(int $uid, array $msg, array $record): array if (empty($blob)) { return []; } - $images[] = ['alt' => $image['description'] ?? '', 'image' => $blob]; + $images[] = [ + 'alt' => $image['description'] ?? '', + 'image' => $blob, + 'aspectRatio' => [ + 'width' => $photo['width'], + 'height' => $photo['height'], + ] + ]; } if (!empty($images)) { $record['embed'] = ['$type' => 'app.bsky.embed.images', 'images' => $images]; @@ -888,10 +895,15 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass $picture = Photo::resizeToFileSize($picture, BLUESKY_IMAGE_SIZE[$retrial]); $new_height = $picture->getHeight(); $new_width = $picture->getWidth(); - $content = $picture->asString(); + $content = (string)$picture->asString(); $new_size = strlen($content); - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + if (($size != 0) && ($new_size == 0) && ($retrial == 0)) { + Logger::warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + $content = Photo::getImageForPhoto($photo); + } else { + Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + } $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { @@ -955,7 +967,7 @@ function bluesky_complete_post(stdClass $post, int $uid, int $post_reason, int $ } if ($complete) { - $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true); + $uri = DI::atpProcessor()->fetchMissingPost(DI::atpProcessor()->getUri($post), $uid, $post_reason, $causer, 0, '', true, $protocol); $uri_id = DI::atpProcessor()->fetchUriId($uri, $uid); } else { $uri_id = DI::atpProcessor()->processPost($post, $uid, $post_reason, $causer, 0, $protocol); From 16e06f9b2b85dba28a109ec85aaccc75509f2209 Mon Sep 17 00:00:00 2001 From: loma-one Date: Sun, 17 Nov 2024 08:20:49 +0100 Subject: [PATCH 205/294] Small bug fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Close the Uni-Code Smilies link with a ’;’ --- unicode_smilies/unicode_smilies.php | 3099 +++++++++++++-------------- 1 file changed, 1548 insertions(+), 1551 deletions(-) diff --git a/unicode_smilies/unicode_smilies.php b/unicode_smilies/unicode_smilies.php index 22ee3439..8d55c4be 100644 --- a/unicode_smilies/unicode_smilies.php +++ b/unicode_smilies/unicode_smilies.php @@ -2,7 +2,7 @@ /* * Name: Unicode Smilies * Description: Smilies based on the unicode emojis - On Linux use https://github.com/eosrei/emojione-color-font to see them in color and http://www.unicode.org/emoji/charts/full-emoji-list.html - * Version: 1.1.2 + * Version: 1.1.3 * Author: Michael Vogel * Author: Matthias Ebers */ @@ -25,7 +25,7 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':-D', '😁'); Smilies::add($b, ':D', '😁'); Smilies::add($b, ';-)', '😉'); - // Smilies::add($b, ';)', '😉'); // Deactivated since this leads to disturbed html entities +// Smilies::add($b, ';)', '😉'); // Deactivated since this leads to disturbed html entities Smilies::add($b, ':-P', '😛'); Smilies::add($b, ':-p', '😛'); Smilies::add($b, ':P', '😛'); @@ -54,353 +54,350 @@ function unicode_smilies_smilies(array &$b) // Smilies::add($b, 'O_o', '&#x;'); // face-smiling - Smilies::add($b, ':grinning face:', '😀'); - Smilies::add($b, ':grinning face with big eyes:', '😃'); - Smilies::add($b, ':grinning face with smiling eyes:', '😄'); - Smilies::add($b, ':beaming face with smiling eyes:', '😁'); - Smilies::add($b, ':grinning squinting face:', '😆'); - Smilies::add($b, ':laughing:', '😆'); - Smilies::add($b, ':grinning face with sweat:', '😅'); - Smilies::add($b, ':rolling on the floor laughing:', '🤣'); + Smilies::add($b, ':grinning face:', '😀'); + Smilies::add($b, ':grinning face with big eyes:', '😃'); + Smilies::add($b, ':grinning face with smiling eyes:', '😄'); + Smilies::add($b, ':beaming face with smiling eyes:', '😁'); + Smilies::add($b, ':grinning squinting face:', '😆'); + Smilies::add($b, ':laughing:', '😆'); + Smilies::add($b, ':grinning face with sweat:', '😅'); + Smilies::add($b, ':rolling on the floor laughing:', '🤣'); Smilies::add($b, ':rofl:', '🤣'); - Smilies::add($b, ':face with tears of joy:', '😂'); + Smilies::add($b, ':face with tears of joy:', '😂'); Smilies::add($b, ':tearsofjoy:', '😂'); - Smilies::add($b, ':slightly smiling face:', '🙂'); - Smilies::add($b, ':upside-down face:', '🙃'); - Smilies::add($b, ':winking face:', '😉'); - Smilies::add($b, ':smiling face with smiling eyes:', '😊'); - Smilies::add($b, ':smiling face with halo:', '😇'); + Smilies::add($b, ':slightly smiling face:', '🙂'); + Smilies::add($b, ':upside-down face:', '🙃'); + Smilies::add($b, ':winking face:', '😉'); + Smilies::add($b, ':smiling face with smiling eyes:', '😊'); + Smilies::add($b, ':smiling face with halo:', '😇'); // face-affection - Smilies::add($b, ':smiling face with hearts:', '🥰'); - Smilies::add($b, ':smiling face with heart-eyes:', '😍'); - Smilies::add($b, ':star-struck:', '🤩'); - Smilies::add($b, ':face blowing a kiss:', '😘'); - Smilies::add($b, ':kissing face:', '😗'); - Smilies::add($b, ':smiling face:', '☺'); - Smilies::add($b, ':kissing face with closed eyes:', '😚'); - Smilies::add($b, ':kissing face with smiling eyes:', '😙'); + Smilies::add($b, ':smiling face with hearts:', '🥰'); + Smilies::add($b, ':smiling face with heart-eyes:', '😍'); + Smilies::add($b, ':star-struck:', '🤩'); + Smilies::add($b, ':face blowing a kiss:', '😘'); + Smilies::add($b, ':kissing face:', '😗'); + Smilies::add($b, ':smiling face:', '☺'); + Smilies::add($b, ':kissing face with closed eyes:', '😚'); + Smilies::add($b, ':kissing face with smiling eyes:', '😙'); // face-tongue - Smilies::add($b, ':face savoring food:', '😋'); - Smilies::add($b, ':face with tongue:', '😛'); - Smilies::add($b, ':winking face with tongue:', '😜'); - Smilies::add($b, ':zany face:', '🤪'); - Smilies::add($b, ':squinting face with tongue:', '😝'); - Smilies::add($b, ':money-mouth face:', '🤑'); + Smilies::add($b, ':face savoring food:', '😋'); + Smilies::add($b, ':face with tongue:', '😛'); + Smilies::add($b, ':winking face with tongue:', '😜'); + Smilies::add($b, ':zany face:', '🤪'); + Smilies::add($b, ':squinting face with tongue:', '😝'); + Smilies::add($b, ':money-mouth face:', '🤑'); // face-hand - Smilies::add($b, ':hugging face:', '🤗'); - Smilies::add($b, ':face with hand over mouth:', '🤭'); - Smilies::add($b, ':shushing face:', '🤫'); - Smilies::add($b, ':thinking face:', '🤔'); + Smilies::add($b, ':hugging face:', '🤗'); + Smilies::add($b, ':face with hand over mouth:', '🤭'); + Smilies::add($b, ':shushing face:', '🤫'); + Smilies::add($b, ':thinking face:', '🤔'); // face-neutral-skeptical - Smilies::add($b, ':zipper-mouth face:', '🤐'); - Smilies::add($b, ':face with raised eyebrow:', '🤨'); - Smilies::add($b, ':neutral face:', '😐'); - Smilies::add($b, ':expressionless face:', '😑'); - Smilies::add($b, ':face without mouth:', '😶'); - Smilies::add($b, ':smirking face:', '😏'); - Smilies::add($b, ':unamused face:', '😒'); - Smilies::add($b, ':face with rolling eyes:', '🙄'); - Smilies::add($b, ':grimacing face:', '😬'); - Smilies::add($b, ':lying face:', '🤥'); + Smilies::add($b, ':zipper-mouth face:', '🤐'); + Smilies::add($b, ':face with raised eyebrow:', '🤨'); + Smilies::add($b, ':neutral face:', '😐'); + Smilies::add($b, ':expressionless face:', '😑'); + Smilies::add($b, ':face without mouth:', '😶'); + Smilies::add($b, ':smirking face:', '😏'); + Smilies::add($b, ':unamused face:', '😒'); + Smilies::add($b, ':face with rolling eyes:', '🙄'); + Smilies::add($b, ':grimacing face:', '😬'); + Smilies::add($b, ':lying face:', '🤥'); // face-sleepy - Smilies::add($b, ':relieved face:', '😌'); - Smilies::add($b, ':pensive face:', '😔'); - Smilies::add($b, ':sleepy face:', '😪'); - Smilies::add($b, ':drooling face:', '🤤'); + Smilies::add($b, ':relieved face:', '😌'); + Smilies::add($b, ':pensive face:', '😔'); + Smilies::add($b, ':sleepy face:', '😪'); + Smilies::add($b, ':drooling face:', '🤤'); Smilies::add($b, ':drool:', '🤤'); - Smilies::add($b, ':sleeping face:', '😴'); + Smilies::add($b, ':sleeping face:', '😴'); // face-unwell - Smilies::add($b, ':face with medical mask:', '😷'); - Smilies::add($b, ':face with thermometer:', '🤒'); - Smilies::add($b, ':face with head-bandage:', '🤕'); - Smilies::add($b, ':nauseated face:', '🤢'); - Smilies::add($b, ':face vomiting:', '🤮'); + Smilies::add($b, ':face with medical mask:', '😷'); + Smilies::add($b, ':face with thermometer:', '🤒'); + Smilies::add($b, ':face with head-bandage:', '🤕'); + Smilies::add($b, ':nauseated face:', '🤢'); + Smilies::add($b, ':face vomiting:', '🤮'); Smilies::add($b, ':vomit:', '🤮'); - Smilies::add($b, ':sneezing face:', '🤧'); - Smilies::add($b, ':hot face:', '🥵'); - Smilies::add($b, ':cold face:', '🥶'); - Smilies::add($b, ':woozy face:', '🥴'); - Smilies::add($b, ':dizzy face:', '😵'); + Smilies::add($b, ':sneezing face:', '🤧'); + Smilies::add($b, ':hot face:', '🥵'); + Smilies::add($b, ':cold face:', '🥶'); + Smilies::add($b, ':woozy face:', '🥴'); + Smilies::add($b, ':dizzy face:', '😵'); Smilies::add($b, ':dead:', '😵'); - Smilies::add($b, ':exploding head:', '🤯'); + Smilies::add($b, ':exploding head:', '🤯'); // face-hat - Smilies::add($b, ':cowboy hat face:', '🤠'); - Smilies::add($b, ':partying face:', '🥳'); + Smilies::add($b, ':cowboy hat face:', '🤠'); + Smilies::add($b, ':partying face:', '🥳'); // face-glasses - Smilies::add($b, ':smiling face with sunglasses:', '😎'); - Smilies::add($b, ':nerd face:', '🤓'); - Smilies::add($b, ':face with monocle:', '🧐'); + Smilies::add($b, ':smiling face with sunglasses:', '😎'); + Smilies::add($b, ':nerd face:', '🤓'); + Smilies::add($b, ':face with monocle:', '🧐'); // face-concerned - Smilies::add($b, ':confused face:', '😕'); - Smilies::add($b, ':worried face:', '😟'); - Smilies::add($b, ':slightly frowning face:', '🙁'); - Smilies::add($b, ':frowning face:', '☹'); - Smilies::add($b, ':face with open mouth:', '😮'); - Smilies::add($b, ':hushed face:', '😯'); - Smilies::add($b, ':astonished face:', '😲'); - Smilies::add($b, ':flushed face:', '😳'); + Smilies::add($b, ':confused face:', '😕'); + Smilies::add($b, ':worried face:', '😟'); + Smilies::add($b, ':slightly frowning face:', '🙁'); + Smilies::add($b, ':frowning face:', '☹'); + Smilies::add($b, ':face with open mouth:', '😮'); + Smilies::add($b, ':hushed face:', '😯'); + Smilies::add($b, ':astonished face:', '😲'); + Smilies::add($b, ':flushed face:', '😳'); Smilies::add($b, ':dazed:', '😳'); - Smilies::add($b, ':pleading face:', '🥺'); - Smilies::add($b, ':frowning face with open mouth:', '😦'); - Smilies::add($b, ':anguished face:', '😧'); - Smilies::add($b, ':fearful face:', '😨'); - Smilies::add($b, ':anxious face with sweat:', '😰'); - Smilies::add($b, ':sad but relieved face:', '😥'); - Smilies::add($b, ':crying face:', '😢'); - Smilies::add($b, ':loudly crying face:', '😭'); - Smilies::add($b, ':face screaming in fear:', '😱'); - Smilies::add($b, ':confounded face:', '😖'); - Smilies::add($b, ':persevering face:', '😣'); - Smilies::add($b, ':disappointed face:', '😞'); + Smilies::add($b, ':pleading face:', '🥺'); + Smilies::add($b, ':frowning face with open mouth:', '😦'); + Smilies::add($b, ':anguished face:', '😧'); + Smilies::add($b, ':fearful face:', '😨'); + Smilies::add($b, ':anxious face with sweat:', '😰'); + Smilies::add($b, ':sad but relieved face:', '😥'); + Smilies::add($b, ':crying face:', '😢'); + Smilies::add($b, ':loudly crying face:', '😭'); + Smilies::add($b, ':face screaming in fear:', '😱'); + Smilies::add($b, ':confounded face:', '😖'); + Smilies::add($b, ':persevering face:', '😣'); + Smilies::add($b, ':disappointed face:', '😞'); // face-negative - Smilies::add($b, ':face with steam from nose:', '😤'); - Smilies::add($b, ':pouting face:', '😡'); - Smilies::add($b, ':angry face:', '😠'); - Smilies::add($b, ':face with symbols on mouth:', '🤬'); - Smilies::add($b, ':smiling face with horns:', '😈'); - Smilies::add($b, ':angry face with horns:', '👿'); - Smilies::add($b, ':skull:', '💀'); - Smilies::add($b, ':skull and crossbones:', '☠'); + Smilies::add($b, ':face with steam from nose:', '😤'); + Smilies::add($b, ':pouting face:', '😡'); + Smilies::add($b, ':angry face:', '😠'); + Smilies::add($b, ':face with symbols on mouth:', '🤬'); + Smilies::add($b, ':smiling face with horns:', '😈'); + Smilies::add($b, ':angry face with horns:', '👿'); + Smilies::add($b, ':skull:', '💀'); + Smilies::add($b, ':skull and crossbones:', '☠'); // face-costume - Smilies::add($b, ':pile of poo:', '💩'); - Smilies::add($b, ':clown face:', '🤡'); - Smilies::add($b, ':ogre:', '👹'); - Smilies::add($b, ':goblin:', '👺'); - Smilies::add($b, ':ghost:', '👻'); - Smilies::add($b, ':alien:', '👽'); - Smilies::add($b, ':alien monster:', '👾'); - Smilies::add($b, ':robot:', '🤖'); + Smilies::add($b, ':pile of poo:', '💩'); + Smilies::add($b, ':clown face:', '🤡'); + Smilies::add($b, ':ogre:', '👹'); + Smilies::add($b, ':goblin:', '👺'); + Smilies::add($b, ':ghost:', '👻'); + Smilies::add($b, ':alien:', '👽'); + Smilies::add($b, ':alien monster:', '👾'); + Smilies::add($b, ':robot:', '🤖'); // cat-face - Smilies::add($b, ':grinning cat:', '😺'); - Smilies::add($b, ':grinning cat with smiling eyes:', '😸'); - Smilies::add($b, ':cat with tears of joy:', '😹'); - Smilies::add($b, ':smiling cat with heart-eyes:', '😻'); - Smilies::add($b, ':cat with wry smile:', '😼'); - Smilies::add($b, ':kissing cat:', '😽'); - Smilies::add($b, ':weary cat:', '🙀'); - Smilies::add($b, ':crying cat:', '😿'); - Smilies::add($b, ':pouting cat:', '😾'); + Smilies::add($b, ':grinning cat:', '😺'); + Smilies::add($b, ':grinning cat with smiling eyes:', '😸'); + Smilies::add($b, ':cat with tears of joy:', '😹'); + Smilies::add($b, ':smiling cat with heart-eyes:', '😻'); + Smilies::add($b, ':cat with wry smile:', '😼'); + Smilies::add($b, ':kissing cat:', '😽'); + Smilies::add($b, ':weary cat:', '🙀'); + Smilies::add($b, ':crying cat:', '😿'); + Smilies::add($b, ':pouting cat:', '😾'); // monkey-face - Smilies::add($b, ':see-no-evil monkey:', '🙈'); - Smilies::add($b, ':hear-no-evil monkey:', '🙉'); - Smilies::add($b, ':speak-no-evil monkey:', '🙊'); + Smilies::add($b, ':see-no-evil monkey:', '🙈'); + Smilies::add($b, ':hear-no-evil monkey:', '🙉'); + Smilies::add($b, ':speak-no-evil monkey:', '🙊'); //emotion - Smilies::add($b, ':kiss mark:', '💋'); - Smilies::add($b, ':love letter:', '💌'); - Smilies::add($b, ':heart with arrow:', '💘'); - Smilies::add($b, ':heart with ribbon:', '💝'); - Smilies::add($b, ':sparkling heart:', '💖'); - Smilies::add($b, ':loveheart:', '💖'); - Smilies::add($b, ':growing heart:', '💗'); - Smilies::add($b, ':beating heart:', '💓'); - Smilies::add($b, ':revolving hearts:', '💞'); - Smilies::add($b, ':two hearts:', '💕'); - Smilies::add($b, ':heart decoration:', '💟'); - Smilies::add($b, ':heart exclamation:', '❣'); - Smilies::add($b, ':broken heart:', '💔'); - Smilies::add($b, ':red heart:', '❤'); - Smilies::add($b, ':orange heart:', '🧡'); - Smilies::add($b, ':yellow heart:', '💛'); - Smilies::add($b, ':green heart:', '💚'); - Smilies::add($b, ':blue heart:', '💙'); - Smilies::add($b, ':purple heart:', '💜'); - Smilies::add($b, ':brown heart:', '🤎'); - Smilies::add($b, ':black heart:', '🖤'); - Smilies::add($b, ':white heart:', '🤍'); - Smilies::add($b, ':hundred points:', '💯'); - Smilies::add($b, ':anger symbol:', '💢'); - Smilies::add($b, ':collision:', '💥'); - Smilies::add($b, ':dizzy:', '💫'); - Smilies::add($b, ':sweat droplets:', '💦'); - Smilies::add($b, ':dashing away:', '💨'); - Smilies::add($b, ':hole:', '🕳'); - Smilies::add($b, ':bomb:', '💣'); - Smilies::add($b, ':speech balloon:', '💬'); - Smilies::add($b, ':left speech bubble:', '🗨'); - Smilies::add($b, ':right anger bubble:', '🗯'); - Smilies::add($b, ':thought balloon:', '💭'); - Smilies::add($b, ':zzz:', '💤'); + Smilies::add($b, ':kiss mark:', '💋'); + Smilies::add($b, ':love letter:', '💌'); + Smilies::add($b, ':heart with arrow:', '💘'); + Smilies::add($b, ':heart with ribbon:', '💝'); + Smilies::add($b, ':sparkling heart:', '💖'); + Smilies::add($b, ':loveheart:', '💖'); + Smilies::add($b, ':growing heart:', '💗'); + Smilies::add($b, ':beating heart:', '💓'); + Smilies::add($b, ':revolving hearts:', '💞'); + Smilies::add($b, ':two hearts:', '💕'); + Smilies::add($b, ':heart decoration:', '💟'); + Smilies::add($b, ':heart exclamation:', '❣'); + Smilies::add($b, ':broken heart:', '💔'); + Smilies::add($b, ':red heart:', '❤'); + Smilies::add($b, ':orange heart:', '🧡'); + Smilies::add($b, ':yellow heart:', '💛'); + Smilies::add($b, ':green heart:', '💚'); + Smilies::add($b, ':blue heart:', '💙'); + Smilies::add($b, ':purple heart:', '💜'); + Smilies::add($b, ':brown heart:', '🤎'); + Smilies::add($b, ':black heart:', '🖤'); + Smilies::add($b, ':white heart:', '🤍'); + Smilies::add($b, ':hundred points:', '💯'); + Smilies::add($b, ':anger symbol:', '💢'); + Smilies::add($b, ':collision:', '💥'); + Smilies::add($b, ':dizzy:', '💫'); + Smilies::add($b, ':sweat droplets:', '💦'); + Smilies::add($b, ':dashing away:', '💨'); + Smilies::add($b, ':hole:', '🕳'); + Smilies::add($b, ':bomb:', '💣'); + Smilies::add($b, ':speech balloon:', '💬'); + Smilies::add($b, ':left speech bubble:', '🗨'); + Smilies::add($b, ':right anger bubble:', '🗯'); + Smilies::add($b, ':thought balloon:', '💭'); + Smilies::add($b, ':zzz:', '💤'); // People & Body // hand-fingers-open - Smilies::add($b, ':waving hand:', '👋'); - Smilies::add($b, ':raised back of hand:', '🤚'); - Smilies::add($b, ':hand with fingers splayed:', '🖐'); - Smilies::add($b, ':raised hand:', '✋'); - Smilies::add($b, ':vulcan salute:', '🖖'); + Smilies::add($b, ':waving hand:', '👋'); + Smilies::add($b, ':raised back of hand:', '🤚'); + Smilies::add($b, ':hand with fingers splayed:', '🖐'); + Smilies::add($b, ':raised hand:', '✋'); + Smilies::add($b, ':vulcan salute:', '🖖'); // hand-fingers-partial - Smilies::add($b, ':OK hand:', '👌'); -// Smilies::add($b, ':pinching hand:', '🤏'); - Smilies::add($b, ':victory hand:', '✌'); - Smilies::add($b, ':crossed fingers:', '🤞'); - Smilies::add($b, ':love-you gesture:', '🤟'); - Smilies::add($b, ':sign of the horns:', '🤘'); - Smilies::add($b, ':call me hand:', '🤙'); + Smilies::add($b, ':OK hand:', '👌'); + Smilies::add($b, ':victory hand:', '✌'); + Smilies::add($b, ':crossed fingers:', '🤞'); + Smilies::add($b, ':love-you gesture:', '🤟'); + Smilies::add($b, ':sign of the horns:', '🤘'); + Smilies::add($b, ':call me hand:', '🤙'); // hand-single-finger - Smilies::add($b, ':backhand index pointing left:', '👈'); - Smilies::add($b, ':backhand index pointing right:', '👉'); - Smilies::add($b, ':backhand index pointing up:', '👆'); - Smilies::add($b, ':middle finger:', '🖕'); - Smilies::add($b, ':backhand index pointing down:', '👇'); - Smilies::add($b, ':index pointing up:', '☝'); + Smilies::add($b, ':backhand index pointing left:', '👈'); + Smilies::add($b, ':backhand index pointing right:', '👉'); + Smilies::add($b, ':backhand index pointing up:', '👆'); + Smilies::add($b, ':middle finger:', '🖕'); + Smilies::add($b, ':backhand index pointing down:', '👇'); + Smilies::add($b, ':index pointing up:', '☝'); // hand-fingers-closed - Smilies::add($b, ':thumbs up:', '👍'); + Smilies::add($b, ':thumbs up:', '👍'); Smilies::add($b, ':like:', '👍'); Smilies::add($b, '\\o/', '👍'); - Smilies::add($b, ':thumbs down:', '👎'); + Smilies::add($b, ':thumbs down:', '👎'); Smilies::add($b, ':dislike:', '👎'); - Smilies::add($b, ':raised fist:', '✊'); - Smilies::add($b, ':oncoming fist:', '👊'); - Smilies::add($b, ':left-facing fist:', '🤛'); - Smilies::add($b, ':right-facing fist:', '🤜'); + Smilies::add($b, ':raised fist:', '✊'); + Smilies::add($b, ':oncoming fist:', '👊'); + Smilies::add($b, ':left-facing fist:', '🤛'); + Smilies::add($b, ':right-facing fist:', '🤜'); // hands - Smilies::add($b, ':clapping hands:', '👏'); - Smilies::add($b, ':raising hands:', '🙌'); - Smilies::add($b, ':open hands:', '👐'); - Smilies::add($b, ':palms up together:', '🤲'); - Smilies::add($b, ':handshake:', '🤝'); - Smilies::add($b, ':folded hands:', '🙏'); + Smilies::add($b, ':clapping hands:', '👏'); + Smilies::add($b, ':raising hands:', '🙌'); + Smilies::add($b, ':open hands:', '👐'); + Smilies::add($b, ':palms up together:', '🤲'); + Smilies::add($b, ':handshake:', '🤝'); + Smilies::add($b, ':folded hands:', '🙏'); // hand-prop - Smilies::add($b, ':writing hand:', '✍'); - Smilies::add($b, ':nail polish:', '💅'); - Smilies::add($b, ':selfie:', '🤳'); + Smilies::add($b, ':writing hand:', '✍'); + Smilies::add($b, ':nail polish:', '💅'); + Smilies::add($b, ':selfie:', '🤳'); // body-parts - Smilies::add($b, ':flexed biceps:', '💪'); - Smilies::add($b, ':mechanical arm:', '🦾'); - Smilies::add($b, ':mechanical leg:', '🦿'); - Smilies::add($b, ':leg:', '🦵'); - Smilies::add($b, ':foot:', '🦶'); - Smilies::add($b, ':ear:', '👂'); -// Smilies::add($b, ':ear with hearing aid:', '🦻'); - Smilies::add($b, ':nose:', '👃'); - Smilies::add($b, ':brain:', '🧠'); - Smilies::add($b, ':tooth:', '🦷'); - Smilies::add($b, ':bone:', '🦴'); - Smilies::add($b, ':eyes:', '👀'); - Smilies::add($b, ':eye:', '👁'); - Smilies::add($b, ':tongue:', '👅'); - Smilies::add($b, ':mouth:', '👄'); + Smilies::add($b, ':flexed biceps:', '💪'); + Smilies::add($b, ':mechanical arm:', '🦾'); + Smilies::add($b, ':mechanical leg:', '🦿'); + Smilies::add($b, ':leg:', '🦵'); + Smilies::add($b, ':foot:', '🦶'); + Smilies::add($b, ':ear:', '👂'); + Smilies::add($b, ':brain:', '🧠'); + Smilies::add($b, ':tooth:', '🦷'); + Smilies::add($b, ':bone:', '🦴'); + Smilies::add($b, ':eyes:', '👀'); + Smilies::add($b, ':eye:', '👁'); + Smilies::add($b, ':tongue:', '👅'); + Smilies::add($b, ':mouth:', '👄'); // person - Smilies::add($b, ':baby:', '👶'); - Smilies::add($b, ':child:', '🧒'); - Smilies::add($b, ':boy:', '👦'); - Smilies::add($b, ':girl:', '👧'); - Smilies::add($b, ':person:', '🧑'); - Smilies::add($b, ':person: blond hair:', '👱'); - Smilies::add($b, ':man:', '👨'); - Smilies::add($b, ':man: beard:', '🧔'); + Smilies::add($b, ':baby:', '👶'); + Smilies::add($b, ':child:', '🧒'); + Smilies::add($b, ':boy:', '👦'); + Smilies::add($b, ':girl:', '👧'); + Smilies::add($b, ':person:', '🧑'); + Smilies::add($b, ':person: blond hair:', '👱'); + Smilies::add($b, ':man:', '👨'); + Smilies::add($b, ':man: beard:', '🧔'); Smilies::add($b, ':beard:', '🧔'); - Smilies::add($b, ':man: red hair:', '👨‍🦰'); - Smilies::add($b, ':man: curly hair:', '👨‍🦱'); - Smilies::add($b, ':man: white hair:', '👨‍🦳'); - Smilies::add($b, ':man: bald:', '👨‍🦲'); - Smilies::add($b, ':woman:', '👩'); - Smilies::add($b, ':woman: red hair:', '👩‍🦰'); - Smilies::add($b, ':person: red hair:', '🧑‍🦰'); - Smilies::add($b, ':woman: curly hair:', '👩‍🦱'); - Smilies::add($b, ':person: curly hair:', '🧑‍🦱'); - Smilies::add($b, ':woman: white hair:', '👩‍🦳'); - Smilies::add($b, ':person: white hair:', '🧑‍🦳'); - Smilies::add($b, ':woman: bald:', '👩‍🦲'); - Smilies::add($b, ':bald::', '🧑‍🦲'); - Smilies::add($b, ':woman: blond hair:', '👱‍♀️'); - Smilies::add($b, ':man: blond hair:', '👱‍♂️'); - Smilies::add($b, ':older person:', '🧓'); - Smilies::add($b, ':old man:', '👴'); - Smilies::add($b, ':old woman:', '👵'); + Smilies::add($b, ':man: red hair:', '👨‍🦰'); + Smilies::add($b, ':man: curly hair:', '👨‍🦱'); + Smilies::add($b, ':man: white hair:', '👨‍🦳'); + Smilies::add($b, ':man: bald:', '👨‍🦲'); + Smilies::add($b, ':woman:', '👩'); + Smilies::add($b, ':woman: red hair:', '👩‍🦰'); + Smilies::add($b, ':person: red hair:', '🧑‍🦰'); + Smilies::add($b, ':woman: curly hair:', '👩‍🦱'); + Smilies::add($b, ':person: curly hair:', '🧑‍🦱'); + Smilies::add($b, ':woman: white hair:', '👩‍🦳'); + Smilies::add($b, ':person: white hair:', '🧑‍🦳'); + Smilies::add($b, ':woman: bald:', '👩‍🦲'); + Smilies::add($b, ':bald::', '🧑‍🦲'); + Smilies::add($b, ':woman: blond hair:', '👱‍♀️'); + Smilies::add($b, ':man: blond hair:', '👱‍♂️'); + Smilies::add($b, ':older person:', '🧓'); + Smilies::add($b, ':old man:', '👴'); + Smilies::add($b, ':old woman:', '👵'); Smilies::add($b, ':pregnant:', '🤰'); // person-gesture - Smilies::add($b, ':person frowning:', '🙍'); - Smilies::add($b, ':man frowning:', '🙍‍♂️'); - Smilies::add($b, ':woman frowning:', '🙍‍♀️'); - Smilies::add($b, ':person pouting:', '🙎'); - Smilies::add($b, ':man pouting:', '🙎‍♂️'); - Smilies::add($b, ':woman pouting:', '🙎‍♀️'); - Smilies::add($b, ':person gesturing NO:', '🙅'); - Smilies::add($b, ':man gesturing NO:', '🙅‍♂️'); - Smilies::add($b, ':woman gesturing NO:', '🙅‍♀️'); - Smilies::add($b, ':person gesturing OK:', '🙆'); - Smilies::add($b, ':man gesturing OK:', '🙆‍♂️'); - Smilies::add($b, ':woman gesturing OK:', '🙆‍♀️'); - Smilies::add($b, ':person tipping hand:', '💁'); - Smilies::add($b, ':man tipping hand:', '💁‍♂️'); - Smilies::add($b, ':woman tipping hand:', '💁‍♀️'); - Smilies::add($b, ':person raising hand:', '🙋'); - Smilies::add($b, ':man raising hand:', '🙋‍♂️'); - Smilies::add($b, ':woman raising hand', '🙋‍♀️'); -// Smilies::add($b, ':deaf person:', '🧏'); -// Smilies::add($b, ':deaf man:', '🧏‍♂️'); -// Smilies::add($b, ':deaf woman:', '🧏‍♀️'); - Smilies::add($b, ':person bowing:', '🙇'); + Smilies::add($b, ':person frowning:', '🙍'); + Smilies::add($b, ':man frowning:', '🙍‍♂️'); + Smilies::add($b, ':woman frowning:', '🙍‍♀️'); + Smilies::add($b, ':person pouting:', '🙎'); + Smilies::add($b, ':man pouting:', '🙎‍♂️'); + Smilies::add($b, ':woman pouting:', '🙎‍♀️'); + Smilies::add($b, ':person gesturing NO:', '🙅'); + Smilies::add($b, ':man gesturing NO:', '🙅‍♂️'); + Smilies::add($b, ':woman gesturing NO:', '🙅‍♀️'); + Smilies::add($b, ':person gesturing OK:', '🙆'); + Smilies::add($b, ':man gesturing OK:', '🙆‍♂️'); + Smilies::add($b, ':woman gesturing OK:', '🙆‍♀️'); + Smilies::add($b, ':person tipping hand:', '💁'); + Smilies::add($b, ':man tipping hand:', '💁‍♂️'); + Smilies::add($b, ':woman tipping hand:', '💁‍♀️'); + Smilies::add($b, ':person raising hand:', '🙋'); + Smilies::add($b, ':man raising hand:', '🙋‍♂️'); + Smilies::add($b, ':woman raising hand', '🙋‍♀️'); +// Smilies::add($b, ':deaf person:', '🧏'); +// Smilies::add($b, ':deaf man:', '🧏‍♂️'); +// Smilies::add($b, ':deaf woman:', '🧏‍♀️'); + Smilies::add($b, ':person bowing:', '🙇'); Smilies::add($b, ':bow:', '🙇'); - Smilies::add($b, ':man bowing:', '🙇‍♂️'); - Smilies::add($b, ':woman bowing:', '🙇‍♀️'); - Smilies::add($b, ':person facepalming:', '🤦'); + Smilies::add($b, ':man bowing:', '🙇‍♂️'); + Smilies::add($b, ':woman bowing:', '🙇‍♀️'); + Smilies::add($b, ':person facepalming:', '🤦'); Smilies::add($b, ':facepalm:', '🤦'); - Smilies::add($b, ':man facepalming:', '🤦‍♂️'); - Smilies::add($b, ':woman facepalming:', '🤦‍♀️'); - Smilies::add($b, ':person shrugging:', '🤷'); + Smilies::add($b, ':man facepalming:', '🤦‍♂️'); + Smilies::add($b, ':woman facepalming:', '🤦‍♀️'); + Smilies::add($b, ':person shrugging:', '🤷'); Smilies::add($b, ':shrug:', '🤷'); - Smilies::add($b, ':man shrugging:', '🤷‍♂️'); - Smilies::add($b, ':woman shrugging:', '🤷‍♀️'); + Smilies::add($b, ':man shrugging:', '🤷‍♂️'); + Smilies::add($b, ':woman shrugging:', '🤷‍♀️'); // person-role // person-fantasy - Smilies::add($b, ':baby angel:', '👼'); + Smilies::add($b, ':baby angel:', '👼'); Smilies::add($b, ':angel:', '👼'); Smilies::add($b, ':cherub:', '👼'); - Smilies::add($b, ':Santa Claus:', '🎅'); - Smilies::add($b, ':Mrs. Claus:', '🤶'); - Smilies::add($b, ':superhero:', '🦸'); - Smilies::add($b, ':man superhero:', '🦸‍♂️'); - Smilies::add($b, ':woman superhero:', '🦸‍♀️'); - Smilies::add($b, ':supervillain:', '🦹'); - Smilies::add($b, ':man supervillain:', '🦹‍♂️'); - Smilies::add($b, ':woman supervillain:', '🦹‍♀️'); - Smilies::add($b, ':mage:', '🧙'); - Smilies::add($b, ':man mage:', '🧙‍♂️'); - Smilies::add($b, ':woman mage:', '🧙‍♀️'); - Smilies::add($b, ':fairy:', '🧚'); - Smilies::add($b, ':man fairy:', '🧚‍♂️'); - Smilies::add($b, ':woman fairy:', '🧚‍♀️'); - Smilies::add($b, ':vampire:', '🧛'); - Smilies::add($b, ':man vampire:', '🧛‍♂️'); - Smilies::add($b, ':woman vampire:', '🧛‍♀️'); - Smilies::add($b, ':merperson:', '🧜'); - Smilies::add($b, ':merman:', '🧜‍♂️'); - Smilies::add($b, ':mermaid:', '🧜‍♀️'); - Smilies::add($b, ':elf:', '🧝'); - Smilies::add($b, ':man elf:', '🧝‍♂️'); - Smilies::add($b, ':woman elf:', '🧝‍♀️'); - Smilies::add($b, ':genie:', '🧞'); - Smilies::add($b, ':man genie:', '🧞‍♂️'); - Smilies::add($b, ':woman genie:', '🧞‍♀️'); - Smilies::add($b, ':zombie:', '🧟'); - Smilies::add($b, ':man zombie:', '🧟‍♂️'); - Smilies::add($b, ':woman zombie:', '🧟‍♀️'); + Smilies::add($b, ':Santa Claus:', '🎅'); + Smilies::add($b, ':Mrs. Claus:', '🤶'); + Smilies::add($b, ':superhero:', '🦸'); + Smilies::add($b, ':man superhero:', '🦸‍♂️'); + Smilies::add($b, ':woman superhero:', '🦸‍♀️'); + Smilies::add($b, ':supervillain:', '🦹'); + Smilies::add($b, ':man supervillain:', '🦹‍♂️'); + Smilies::add($b, ':woman supervillain:', '🦹‍♀️'); + Smilies::add($b, ':mage:', '🧙'); + Smilies::add($b, ':man mage:', '🧙‍♂️'); + Smilies::add($b, ':woman mage:', '🧙‍♀️'); + Smilies::add($b, ':fairy:', '🧚'); + Smilies::add($b, ':man fairy:', '🧚‍♂️'); + Smilies::add($b, ':woman fairy:', '🧚‍♀️'); + Smilies::add($b, ':vampire:', '🧛'); + Smilies::add($b, ':man vampire:', '🧛‍♂️'); + Smilies::add($b, ':woman vampire:', '🧛‍♀️'); + Smilies::add($b, ':merperson:', '🧜'); + Smilies::add($b, ':merman:', '🧜‍♂️'); + Smilies::add($b, ':mermaid:', '🧜‍♀️'); + Smilies::add($b, ':elf:', '🧝'); + Smilies::add($b, ':man elf:', '🧝‍♂️'); + Smilies::add($b, ':woman elf:', '🧝‍♀️'); + Smilies::add($b, ':genie:', '🧞'); + Smilies::add($b, ':man genie:', '🧞‍♂️'); + Smilies::add($b, ':woman genie:', '🧞‍♀️'); + Smilies::add($b, ':zombie:', '🧟'); + Smilies::add($b, ':man zombie:', '🧟‍♂️'); + Smilies::add($b, ':woman zombie:', '🧟‍♀️'); // person-activity @@ -411,83 +408,83 @@ function unicode_smilies_smilies(array &$b) // person-resting // family - Smilies::add($b, ':people holding hands:', '🧑‍🤝‍🧑'); - Smilies::add($b, ':women holding hands:', '👭'); - Smilies::add($b, ':woman and man holding hands:', '👫'); - Smilies::add($b, ':men holding hands:', '👬'); - Smilies::add($b, ':kiss:', '💏'); - Smilies::add($b, ':couple with heart:', '💑'); - Smilies::add($b, ':family:', '👪'); + Smilies::add($b, ':people holding hands:', '🧑‍🤝‍🧑'); + Smilies::add($b, ':women holding hands:', '👭'); + Smilies::add($b, ':woman and man holding hands:', '👫'); + Smilies::add($b, ':men holding hands:', '👬'); + Smilies::add($b, ':kiss:', '💏'); + Smilies::add($b, ':couple with heart:', '💑'); + Smilies::add($b, ':family:', '👪'); // person-symbol - Smilies::add($b, ':speaking head:', '🗣'); - Smilies::add($b, ':bust in silhouette:', '👤'); - Smilies::add($b, ':busts in silhouette:', '👥'); - Smilies::add($b, ':footprints:', '👣'); + Smilies::add($b, ':speaking head:', '🗣'); + Smilies::add($b, ':bust in silhouette:', '👤'); + Smilies::add($b, ':busts in silhouette:', '👥'); + Smilies::add($b, ':footprints:', '👣'); // Component // hair-style // Animals & Nature // animal-mammal - Smilies::add($b, ':monkey face:', '🐵'); - Smilies::add($b, ':monkey:', '🐒'); - Smilies::add($b, ':gorilla:', '🦍'); - Smilies::add($b, ':orangutan:', '🦧'); - Smilies::add($b, ':dog face:', '🐶'); - Smilies::add($b, ':dog:', '🐕'); - Smilies::add($b, ':guide dog:', '🦮'); - Smilies::add($b, ':poodle:', '🐩'); - Smilies::add($b, ':wolf:', '🐺'); - Smilies::add($b, ':fox:', '🦊'); - Smilies::add($b, ':raccoon:', '🦝'); - Smilies::add($b, ':cat face:', '🐱'); - Smilies::add($b, ':cat:', '🐈'); - Smilies::add($b, ':lion:', '🦁'); - Smilies::add($b, ':tiger face:', '🐯'); - Smilies::add($b, ':tiger:', '🐅'); - Smilies::add($b, ':leopard:', '🐆'); - Smilies::add($b, ':horse face:', '🐴'); - Smilies::add($b, ':horse:', '🐎'); - Smilies::add($b, ':unicorn:', '🦄'); - Smilies::add($b, ':zebra:', '🦓'); - Smilies::add($b, ':deer:', '🦌'); - Smilies::add($b, ':cow face:', '🐮'); - Smilies::add($b, ':ox:', '🐂'); - Smilies::add($b, ':water buffalo:', '🐃'); - Smilies::add($b, ':cow:', '🐄'); - Smilies::add($b, ':pig face:', '🐷'); - Smilies::add($b, ':pig:', '🐖'); + Smilies::add($b, ':monkey face:', '🐵'); + Smilies::add($b, ':monkey:', '🐒'); + Smilies::add($b, ':gorilla:', '🦍'); + Smilies::add($b, ':orangutan:', '🦧'); + Smilies::add($b, ':dog face:', '🐶'); + Smilies::add($b, ':dog:', '🐕'); + Smilies::add($b, ':guide dog:', '🦮'); + Smilies::add($b, ':poodle:', '🐩'); + Smilies::add($b, ':wolf:', '🐺'); + Smilies::add($b, ':fox:', '🦊'); + Smilies::add($b, ':raccoon:', '🦝'); + Smilies::add($b, ':cat face:', '🐱'); + Smilies::add($b, ':cat:', '🐈'); + Smilies::add($b, ':lion:', '🦁'); + Smilies::add($b, ':tiger face:', '🐯'); + Smilies::add($b, ':tiger:', '🐅'); + Smilies::add($b, ':leopard:', '🐆'); + Smilies::add($b, ':horse face:', '🐴'); + Smilies::add($b, ':horse:', '🐎'); + Smilies::add($b, ':unicorn:', '🦄'); + Smilies::add($b, ':zebra:', '🦓'); + Smilies::add($b, ':deer:', '🦌'); + Smilies::add($b, ':cow face:', '🐮'); + Smilies::add($b, ':ox:', '🐂'); + Smilies::add($b, ':water buffalo:', '🐃'); + Smilies::add($b, ':cow:', '🐄'); + Smilies::add($b, ':pig face:', '🐷'); + Smilies::add($b, ':pig:', '🐖'); Smilies::add($b, ':boar:', '🐗'); - Smilies::add($b, ':pig nose:', '🐽'); - Smilies::add($b, ':ram:', '🐏'); - Smilies::add($b, ':sheep:', '🐑'); - Smilies::add($b, ':goat:', '🐐'); + Smilies::add($b, ':pig nose:', '🐽'); + Smilies::add($b, ':ram:', '🐏'); + Smilies::add($b, ':sheep:', '🐑'); + Smilies::add($b, ':goat:', '🐐'); Smilies::add($b, ':camel:', '🐪'); - Smilies::add($b, ':two-hump camel:', '🐫'); - Smilies::add($b, ':llama:', '🦙'); - Smilies::add($b, ':giraffe:', '🦒'); - Smilies::add($b, ':elephant:', '🐘'); - Smilies::add($b, ':rhinoceros:', '🦏'); - Smilies::add($b, ':hippopotamus:', '🦛'); - Smilies::add($b, ':mouse face:', '🐭'); - Smilies::add($b, ':mouse:', '🐁'); - Smilies::add($b, ':rat:', '🐀'); - Smilies::add($b, ':hamster:', '🐹'); - Smilies::add($b, ':rabbit face:', '🐰'); - Smilies::add($b, ':rabbit:', '🐇'); - Smilies::add($b, ':chipmunk:', '🐿'); - Smilies::add($b, ':hedgehog:', '🦔'); - Smilies::add($b, ':bat:', '🦇'); - Smilies::add($b, ':bear:', '🐻'); - Smilies::add($b, ':koala:', '🐨'); - Smilies::add($b, ':panda:', '🐼'); - Smilies::add($b, ':sloth:', '🦥'); - Smilies::add($b, ':otter:', '🦦'); - Smilies::add($b, ':skunk:', '🦨'); - Smilies::add($b, ':kangaroo:', '🦘'); - Smilies::add($b, ':badger:', '🦡'); - Smilies::add($b, ':paw prints:', '🐾'); + Smilies::add($b, ':two-hump camel:', '🐫'); + Smilies::add($b, ':llama:', '🦙'); + Smilies::add($b, ':giraffe:', '🦒'); + Smilies::add($b, ':elephant:', '🐘'); + Smilies::add($b, ':rhinoceros:', '🦏'); + Smilies::add($b, ':hippopotamus:', '🦛'); + Smilies::add($b, ':mouse face:', '🐭'); + Smilies::add($b, ':mouse:', '🐁'); + Smilies::add($b, ':rat:', '🐀'); + Smilies::add($b, ':hamster:', '🐹'); + Smilies::add($b, ':rabbit face:', '🐰'); + Smilies::add($b, ':rabbit:', '🐇'); + Smilies::add($b, ':chipmunk:', '🐿'); + Smilies::add($b, ':hedgehog:', '🦔'); + Smilies::add($b, ':bat:', '🦇'); + Smilies::add($b, ':bear:', '🐻'); + Smilies::add($b, ':koala:', '🐨'); + Smilies::add($b, ':panda:', '🐼'); + Smilies::add($b, ':sloth:', '🦥'); + Smilies::add($b, ':otter:', '🦦'); + Smilies::add($b, ':skunk:', '🦨'); + Smilies::add($b, ':kangaroo:', '🦘'); + Smilies::add($b, ':badger:', '🦡'); + Smilies::add($b, ':paw prints:', '🐾'); // Smilies::add($b, ':bunnyflowers:', '&#x;'); Smilies::add($b, ':chick:', '🐤'); Smilies::add($b, ':ladybird:', '🐞'); @@ -495,959 +492,958 @@ function unicode_smilies_smilies(array &$b) // Smilies::add($b, ':dragonfly:', '&#x;'); // animal-bird - Smilies::add($b, ':turkey:', '🦃'); - Smilies::add($b, ':chicken:', '🐔'); - Smilies::add($b, ':rooster:', '🐓'); - Smilies::add($b, ':hatching chick:', '🐣'); - Smilies::add($b, ':baby chick:', '🐤'); - Smilies::add($b, ':front-facing baby chick:', '🐥'); - Smilies::add($b, ':bird:', '🐦'); - Smilies::add($b, ':tux:', '🐧'); - Smilies::add($b, ':dove:', '🕊'); - Smilies::add($b, ':eagle:', '🦅'); - Smilies::add($b, ':duck:', '🦆'); - Smilies::add($b, ':swan:', '🦢'); - Smilies::add($b, ':owl:', '🦉'); - Smilies::add($b, ':flamingo:', '🦩'); - Smilies::add($b, ':peacock:', '🦚'); - Smilies::add($b, ':parrot:', '🦜'); + Smilies::add($b, ':turkey:', '🦃'); + Smilies::add($b, ':chicken:', '🐔'); + Smilies::add($b, ':rooster:', '🐓'); + Smilies::add($b, ':hatching chick:', '🐣'); + Smilies::add($b, ':baby chick:', '🐤'); + Smilies::add($b, ':front-facing baby chick:', '🐥'); + Smilies::add($b, ':bird:', '🐦'); + Smilies::add($b, ':tux:', '🐧'); + Smilies::add($b, ':dove:', '🕊'); + Smilies::add($b, ':eagle:', '🦅'); + Smilies::add($b, ':duck:', '🦆'); + Smilies::add($b, ':swan:', '🦢'); + Smilies::add($b, ':owl:', '🦉'); + Smilies::add($b, ':flamingo:', '🦩'); + Smilies::add($b, ':peacock:', '🦚'); + Smilies::add($b, ':parrot:', '🦜'); // animal-amphibian - Smilies::add($b, ':frog:', '🐸'); + Smilies::add($b, ':frog:', '🐸'); // animal-reptile - Smilies::add($b, ':crocodile:', '🐊'); - Smilies::add($b, ':turtle:', '🐢'); - Smilies::add($b, ':lizard:', '🦎'); - Smilies::add($b, ':snake:', '🐍'); - Smilies::add($b, ':dragon face:', '🐲'); - Smilies::add($b, ':dragon:', '🐉'); + Smilies::add($b, ':crocodile:', '🐊'); + Smilies::add($b, ':turtle:', '🐢'); + Smilies::add($b, ':lizard:', '🦎'); + Smilies::add($b, ':snake:', '🐍'); + Smilies::add($b, ':dragon face:', '🐲'); + Smilies::add($b, ':dragon:', '🐉'); Smilies::add($b, ':draco:', '🐉'); - Smilies::add($b, ':sauropod:', '🦕'); - Smilies::add($b, ':T-Rex:', '🦖'); + Smilies::add($b, ':sauropod:', '🦕'); + Smilies::add($b, ':T-Rex:', '🦖'); // animal-marine - Smilies::add($b, ':spouting whale:', '🐳'); - Smilies::add($b, ':whale:', '🐋'); - Smilies::add($b, ':dolphin:', '🐬'); - Smilies::add($b, ':fish:', '🐟'); - Smilies::add($b, ':tropical fish:', '🐠'); - Smilies::add($b, ':blowfish:', '🐡'); - Smilies::add($b, ':shark:', '🦈'); - Smilies::add($b, ':octopus:', '🐙'); - Smilies::add($b, ':spiral shell:', '🐚'); + Smilies::add($b, ':spouting whale:', '🐳'); + Smilies::add($b, ':whale:', '🐋'); + Smilies::add($b, ':dolphin:', '🐬'); + Smilies::add($b, ':fish:', '🐟'); + Smilies::add($b, ':tropical fish:', '🐠'); + Smilies::add($b, ':blowfish:', '🐡'); + Smilies::add($b, ':shark:', '🦈'); + Smilies::add($b, ':octopus:', '🐙'); + Smilies::add($b, ':spiral shell:', '🐚'); // animal-bug - Smilies::add($b, ':snail:', '🐌'); - Smilies::add($b, ':butterfly:', '🦋'); - Smilies::add($b, ':bug:', '🐛'); - Smilies::add($b, ':ant:', '🐜'); - Smilies::add($b, ':honeybee:', '🐝'); - Smilies::add($b, ':lady beetle:', '🐞'); - Smilies::add($b, ':cricket:', '🦗'); - Smilies::add($b, ':spider:', '🕷'); - Smilies::add($b, ':spider web:', '🕸'); - Smilies::add($b, ':scorpion:', '🦂'); - Smilies::add($b, ':mosquito:', '🦟'); - Smilies::add($b, ':microbe:', '🦠'); + Smilies::add($b, ':snail:', '🐌'); + Smilies::add($b, ':butterfly:', '🦋'); + Smilies::add($b, ':bug:', '🐛'); + Smilies::add($b, ':ant:', '🐜'); + Smilies::add($b, ':honeybee:', '🐝'); + Smilies::add($b, ':lady beetle:', '🐞'); + Smilies::add($b, ':cricket:', '🦗'); + Smilies::add($b, ':spider:', '🕷'); + Smilies::add($b, ':spider web:', '🕸'); + Smilies::add($b, ':scorpion:', '🦂'); + Smilies::add($b, ':mosquito:', '🦟'); + Smilies::add($b, ':microbe:', '🦠'); // plant-flower - Smilies::add($b, ':bouquet:', '💐'); - Smilies::add($b, ':cherry blossom:', '🌸'); - Smilies::add($b, ':white flower:', '💮'); - Smilies::add($b, ':rosette:', '🏵'); - Smilies::add($b, ':rose:', '🌹'); - Smilies::add($b, ':wilted flower:', '🥀'); - Smilies::add($b, ':hibiscus:', '🌺'); - Smilies::add($b, ':sunflower:', '🌻'); - Smilies::add($b, ':blossom:', '🌼'); - Smilies::add($b, ':tulip:', '🌷'); + Smilies::add($b, ':bouquet:', '💐'); + Smilies::add($b, ':cherry blossom:', '🌸'); + Smilies::add($b, ':white flower:', '💮'); + Smilies::add($b, ':rosette:', '🏵'); + Smilies::add($b, ':rose:', '🌹'); + Smilies::add($b, ':wilted flower:', '🥀'); + Smilies::add($b, ':hibiscus:', '🌺'); + Smilies::add($b, ':sunflower:', '🌻'); + Smilies::add($b, ':blossom:', '🌼'); + Smilies::add($b, ':tulip:', '🌷'); // plant-other - Smilies::add($b, ':seedling:', '🌱'); - Smilies::add($b, ':evergreen tree:', '🌲'); - Smilies::add($b, ':deciduous tree:', '🌳'); - Smilies::add($b, ':palm tree:', '🌴'); - Smilies::add($b, ':cactus:', '🌵'); - Smilies::add($b, ':sheaf of rice:', '🌾'); - Smilies::add($b, ':herb:', '🌿'); - Smilies::add($b, ':shamrock:', '☘'); - Smilies::add($b, ':four leaf clover:', '🍀'); - Smilies::add($b, ':maple leaf:', '🍁'); - Smilies::add($b, ':fallen leaf:', '🍂'); - Smilies::add($b, ':leaf fluttering in wind:', '🍃'); + Smilies::add($b, ':seedling:', '🌱'); + Smilies::add($b, ':evergreen tree:', '🌲'); + Smilies::add($b, ':deciduous tree:', '🌳'); + Smilies::add($b, ':palm tree:', '🌴'); + Smilies::add($b, ':cactus:', '🌵'); + Smilies::add($b, ':sheaf of rice:', '🌾'); + Smilies::add($b, ':herb:', '🌿'); + Smilies::add($b, ':shamrock:', '☘'); + Smilies::add($b, ':four leaf clover:', '🍀'); + Smilies::add($b, ':maple leaf:', '🍁'); + Smilies::add($b, ':fallen leaf:', '🍂'); + Smilies::add($b, ':leaf fluttering in wind:', '🍃'); // Food & Drink // food-fruit - Smilies::add($b, ':grapes:', '🍇'); - Smilies::add($b, ':melon:', '🍈'); - Smilies::add($b, ':watermelon:', '🍉'); - Smilies::add($b, ':tangerine:', '🍊'); - Smilies::add($b, ':lemon:', '🍋'); - Smilies::add($b, ':banana:', '🍌'); - Smilies::add($b, ':pineapple:', '🍍'); - Smilies::add($b, ':mango:', '🥭'); - Smilies::add($b, ':red apple:', '🍎'); + Smilies::add($b, ':grapes:', '🍇'); + Smilies::add($b, ':melon:', '🍈'); + Smilies::add($b, ':watermelon:', '🍉'); + Smilies::add($b, ':tangerine:', '🍊'); + Smilies::add($b, ':lemon:', '🍋'); + Smilies::add($b, ':banana:', '🍌'); + Smilies::add($b, ':pineapple:', '🍍'); + Smilies::add($b, ':mango:', '🥭'); + Smilies::add($b, ':red apple:', '🍎'); Smilies::add($b, ':apple:', '🍎'); - Smilies::add($b, ':green apple:', '🍏'); - Smilies::add($b, ':pear:', '🍐'); - Smilies::add($b, ':peach:', '🍑'); - Smilies::add($b, ':cherries:', '🍒'); - Smilies::add($b, ':strawberry:', '🍓'); - Smilies::add($b, ':kiwi fruit:', '🥝'); - Smilies::add($b, ':tomato:', '🍅'); - Smilies::add($b, ':coconut:', '🥥'); + Smilies::add($b, ':green apple:', '🍏'); + Smilies::add($b, ':pear:', '🍐'); + Smilies::add($b, ':peach:', '🍑'); + Smilies::add($b, ':cherries:', '🍒'); + Smilies::add($b, ':strawberry:', '🍓'); + Smilies::add($b, ':kiwi fruit:', '🥝'); + Smilies::add($b, ':tomato:', '🍅'); + Smilies::add($b, ':coconut:', '🥥'); // food-vegetable - Smilies::add($b, ':avocado:', '🥑'); - Smilies::add($b, ':eggplant:', '🍆'); - Smilies::add($b, ':potato:', '🥔'); - Smilies::add($b, ':carrot:', '🥕'); - Smilies::add($b, ':ear of corn:', '🌽'); - Smilies::add($b, ':hot pepper:', '🌶'); - Smilies::add($b, ':cucumber:', '🥒'); - Smilies::add($b, ':leafy green:', '🥬'); - Smilies::add($b, ':broccoli:', '🥦'); - Smilies::add($b, ':garlic:', '🧄'); - Smilies::add($b, ':onion:', '🧅'); - Smilies::add($b, ':mushroom:', '🍄'); - Smilies::add($b, ':peanuts:', '🥜'); - Smilies::add($b, ':chestnut:', '🌰'); + Smilies::add($b, ':avocado:', '🥑'); + Smilies::add($b, ':eggplant:', '🍆'); + Smilies::add($b, ':potato:', '🥔'); + Smilies::add($b, ':carrot:', '🥕'); + Smilies::add($b, ':ear of corn:', '🌽'); + Smilies::add($b, ':hot pepper:', '🌶'); + Smilies::add($b, ':cucumber:', '🥒'); + Smilies::add($b, ':leafy green:', '🥬'); + Smilies::add($b, ':broccoli:', '🥦'); + Smilies::add($b, ':garlic:', '🧄'); + Smilies::add($b, ':onion:', '🧅'); + Smilies::add($b, ':mushroom:', '🍄'); + Smilies::add($b, ':peanuts:', '🥜'); + Smilies::add($b, ':chestnut:', '🌰'); // food-prepared - Smilies::add($b, ':bread:', '🍞'); - Smilies::add($b, ':croissant:', '🥐'); - Smilies::add($b, ':baguette bread:', '🥖'); - Smilies::add($b, ':pretzel:', '🥨'); - Smilies::add($b, ':bagel:', '🥯'); - Smilies::add($b, ':pancakes:', '🥞'); - Smilies::add($b, ':waffle:', '🧇'); - Smilies::add($b, ':cheese wedge:', '🧀'); - Smilies::add($b, ':meat on bone:', '🍖'); - Smilies::add($b, ':poultry leg:', '🍗'); - Smilies::add($b, ':cut of meat:', '🥩'); - Smilies::add($b, ':bacon:', '🥓'); - Smilies::add($b, ':hamburger:', '🍔'); - Smilies::add($b, ':french fries:', '🍟'); - Smilies::add($b, ':pizza:', '🍕'); - Smilies::add($b, ':hot dog:', '🌭'); - Smilies::add($b, ':sandwich:', '🥪'); - Smilies::add($b, ':taco:', '🌮'); - Smilies::add($b, ':burrito:', '🌯'); - Smilies::add($b, ':stuffed flatbread:', '🥙'); - Smilies::add($b, ':falafel:', '🧆'); - Smilies::add($b, ':egg:', '🥚'); - Smilies::add($b, ':cooking:', '🍳'); + Smilies::add($b, ':bread:', '🍞'); + Smilies::add($b, ':croissant:', '🥐'); + Smilies::add($b, ':baguette bread:', '🥖'); + Smilies::add($b, ':pretzel:', '🥨'); + Smilies::add($b, ':bagel:', '🥯'); + Smilies::add($b, ':pancakes:', '🥞'); + Smilies::add($b, ':waffle:', '🧇'); + Smilies::add($b, ':cheese wedge:', '🧀'); + Smilies::add($b, ':meat on bone:', '🍖'); + Smilies::add($b, ':poultry leg:', '🍗'); + Smilies::add($b, ':cut of meat:', '🥩'); + Smilies::add($b, ':bacon:', '🥓'); + Smilies::add($b, ':hamburger:', '🍔'); + Smilies::add($b, ':french fries:', '🍟'); + Smilies::add($b, ':pizza:', '🍕'); + Smilies::add($b, ':hot dog:', '🌭'); + Smilies::add($b, ':sandwich:', '🥪'); + Smilies::add($b, ':taco:', '🌮'); + Smilies::add($b, ':burrito:', '🌯'); + Smilies::add($b, ':stuffed flatbread:', '🥙'); + Smilies::add($b, ':falafel:', '🧆'); + Smilies::add($b, ':egg:', '🥚'); + Smilies::add($b, ':cooking:', '🍳'); Smilies::add($b, ':fryegg:', '🍳'); - Smilies::add($b, ':shallow pan of food:', '🥘'); - Smilies::add($b, ':pot of food:', '🍲'); - Smilies::add($b, ':bowl with spoon:', '🥣'); - Smilies::add($b, ':green salad:', '🥗'); - Smilies::add($b, ':popcorn:', '🍿'); - Smilies::add($b, ':butter:', '🧈'); - Smilies::add($b, ':salt:', '🧂'); - Smilies::add($b, ':canned food:', '🥫'); + Smilies::add($b, ':shallow pan of food:', '🥘'); + Smilies::add($b, ':pot of food:', '🍲'); + Smilies::add($b, ':bowl with spoon:', '🥣'); + Smilies::add($b, ':green salad:', '🥗'); + Smilies::add($b, ':popcorn:', '🍿'); + Smilies::add($b, ':butter:', '🧈'); + Smilies::add($b, ':salt:', '🧂'); + Smilies::add($b, ':canned food:', '🥫'); // food-asian - Smilies::add($b, ':bento box:', '🍱'); - Smilies::add($b, ':rice cracker:', '🍘'); - Smilies::add($b, ':rice ball:', '🍙'); - Smilies::add($b, ':cooked rice:', '🍚'); - Smilies::add($b, ':curry rice:', '🍛'); - Smilies::add($b, ':steaming bowl:', '🍜'); - Smilies::add($b, ':spaghetti:', '🍝'); - Smilies::add($b, ':roasted sweet potato:', '🍠'); - Smilies::add($b, ':oden:', '🍢'); - Smilies::add($b, ':sushi:', '🍣'); - Smilies::add($b, ':fried shrimp:', '🍤'); - Smilies::add($b, ':fish cake with swirl:', '🍥'); - Smilies::add($b, ':moon cake:', '🥮'); - Smilies::add($b, ':dango:', '🍡'); - Smilies::add($b, ':dumpling:', '🥟'); - Smilies::add($b, ':fortune cookie:', '🥠'); - Smilies::add($b, ':takeout box:', '🥡'); + Smilies::add($b, ':bento box:', '🍱'); + Smilies::add($b, ':rice cracker:', '🍘'); + Smilies::add($b, ':rice ball:', '🍙'); + Smilies::add($b, ':cooked rice:', '🍚'); + Smilies::add($b, ':curry rice:', '🍛'); + Smilies::add($b, ':steaming bowl:', '🍜'); + Smilies::add($b, ':spaghetti:', '🍝'); + Smilies::add($b, ':roasted sweet potato:', '🍠'); + Smilies::add($b, ':oden:', '🍢'); + Smilies::add($b, ':sushi:', '🍣'); + Smilies::add($b, ':fried shrimp:', '🍤'); + Smilies::add($b, ':fish cake with swirl:', '🍥'); + Smilies::add($b, ':moon cake:', '🥮'); + Smilies::add($b, ':dango:', '🍡'); + Smilies::add($b, ':dumpling:', '🥟'); + Smilies::add($b, ':fortune cookie:', '🥠'); + Smilies::add($b, ':takeout box:', '🥡'); // food-marine - Smilies::add($b, ':crab:', '🦀'); - Smilies::add($b, ':lobster:', '🦞'); - Smilies::add($b, ':shrimp:', '🦐'); - Smilies::add($b, ':squid:', '🦑'); -// Smilies::add($b, ':oyster:', '🦪'); + Smilies::add($b, ':crab:', '🦀'); + Smilies::add($b, ':lobster:', '🦞'); + Smilies::add($b, ':shrimp:', '🦐'); + Smilies::add($b, ':squid:', '🦑'); +// Smilies::add($b, ':oyster:', '🦪'); // food-sweet - Smilies::add($b, ':soft ice cream:', '🍦'); - Smilies::add($b, ':shaved ice:', '🍧'); - Smilies::add($b, ':ice cream:', '🍨'); - Smilies::add($b, ':doughnut:', '🍩'); - Smilies::add($b, ':cookie:', '🍪'); - Smilies::add($b, ':birthday cake:', '🎂'); - Smilies::add($b, ':shortcake:', '🍰'); + Smilies::add($b, ':soft ice cream:', '🍦'); + Smilies::add($b, ':shaved ice:', '🍧'); + Smilies::add($b, ':ice cream:', '🍨'); + Smilies::add($b, ':doughnut:', '🍩'); + Smilies::add($b, ':cookie:', '🍪'); + Smilies::add($b, ':birthday cake:', '🎂'); + Smilies::add($b, ':shortcake:', '🍰'); Smilies::add($b, ':cake:', '🍰'); - Smilies::add($b, ':cupcake:', '🧁'); - Smilies::add($b, ':pie:', '🥧'); - Smilies::add($b, ':chocolate bar:', '🍫'); - Smilies::add($b, ':candy:', '🍬'); - Smilies::add($b, ':lollipop:', '🍭'); - Smilies::add($b, ':custard:', '🍮'); - Smilies::add($b, ':honey pot:', '🍯'); + Smilies::add($b, ':cupcake:', '🧁'); + Smilies::add($b, ':pie:', '🥧'); + Smilies::add($b, ':chocolate bar:', '🍫'); + Smilies::add($b, ':candy:', '🍬'); + Smilies::add($b, ':lollipop:', '🍭'); + Smilies::add($b, ':custard:', '🍮'); + Smilies::add($b, ':honey pot:', '🍯'); -// drink - Smilies::add($b, ':baby bottle:', '🍼'); - Smilies::add($b, ':glass of milk:', '🥛'); - Smilies::add($b, ':hot beverage:', '☕'); +// drink + Smilies::add($b, ':baby bottle:', '🍼'); + Smilies::add($b, ':glass of milk:', '🥛'); + Smilies::add($b, ':hot beverage:', '☕'); Smilies::add($b, ':coffee:', '☕'); Smilies::add($b, ':tea:', '☕'); Smilies::add($b, ':tee:', '☕'); - Smilies::add($b, ':teacup without handle:', '🍵'); - Smilies::add($b, ':sake:', '🍶'); - Smilies::add($b, ':bottle with popping cork:', '🍾'); - Smilies::add($b, ':wine glass:', '🍷'); - Smilies::add($b, ':cocktail glass:', '🍸'); - Smilies::add($b, ':tropical drink:', '🍹'); - Smilies::add($b, ':beer mug:', '🍺'); + Smilies::add($b, ':teacup without handle:', '🍵'); + Smilies::add($b, ':sake:', '🍶'); + Smilies::add($b, ':bottle with popping cork:', '🍾'); + Smilies::add($b, ':wine glass:', '🍷'); + Smilies::add($b, ':cocktail glass:', '🍸'); + Smilies::add($b, ':tropical drink:', '🍹'); + Smilies::add($b, ':beer mug:', '🍺'); Smilies::add($b, ':beer:', '🍺'); Smilies::add($b, ':homebrew:', '🍺'); - Smilies::add($b, ':clinking beer mugs:', '🍻'); - Smilies::add($b, ':clinking glasses:', '🥂'); - Smilies::add($b, ':tumbler glass:', '🥃'); - Smilies::add($b, ':cup with straw:', '🥤'); -// Smilies::add($b, ':beverage box:', '🧃'); - Smilies::add($b, ':mate:', '🧉'); - Smilies::add($b, ':ice:', '🧊'); + Smilies::add($b, ':clinking beer mugs:', '🍻'); + Smilies::add($b, ':clinking glasses:', '🥂'); + Smilies::add($b, ':tumbler glass:', '🥃'); + Smilies::add($b, ':cup with straw:', '🥤'); +// Smilies::add($b, ':beverage box:', '🧃'); + Smilies::add($b, ':mate:', '🧉'); + Smilies::add($b, ':ice:', '🧊'); // dishware - Smilies::add($b, ':chopsticks:', '🥢'); - Smilies::add($b, ':fork and knife with plate:', '🍽'); - Smilies::add($b, ':fork and knife:', '🍴'); - Smilies::add($b, ':spoon:', '🥄'); - Smilies::add($b, ':kitchen knife:', '🔪'); - Smilies::add($b, ':amphora:', '🏺'); + Smilies::add($b, ':chopsticks:', '🥢'); + Smilies::add($b, ':fork and knife with plate:', '🍽'); + Smilies::add($b, ':fork and knife:', '🍴'); + Smilies::add($b, ':spoon:', '🥄'); + Smilies::add($b, ':kitchen knife:', '🔪'); + Smilies::add($b, ':amphora:', '🏺'); // Travel & Places // place-map - Smilies::add($b, ':globe showing Europe-Africa:', '🌍'); - Smilies::add($b, ':globe showing Americas:', '🌎'); - Smilies::add($b, ':globe showing Asia-Australia:', '🌏'); - Smilies::add($b, ':globe with meridians:', '🌐'); - Smilies::add($b, ':world map:', '🗺'); - Smilies::add($b, ':map of Japan:', '🗾'); - Smilies::add($b, ':compass:', '🧭'); + Smilies::add($b, ':globe showing Europe-Africa:', '🌍'); + Smilies::add($b, ':globe showing Americas:', '🌎'); + Smilies::add($b, ':globe showing Asia-Australia:', '🌏'); + Smilies::add($b, ':globe with meridians:', '🌐'); + Smilies::add($b, ':world map:', '🗺'); + Smilies::add($b, ':map of Japan:', '🗾'); + Smilies::add($b, ':compass:', '🧭'); // place-geographic - Smilies::add($b, ':snow-capped mountain:', '🏔'); - Smilies::add($b, ':mountain:', '⛰'); - Smilies::add($b, ':volcano:', '🌋'); - Smilies::add($b, ':mount fuji:', '🗻'); - Smilies::add($b, ':camping:', '🏕'); - Smilies::add($b, ':beach with umbrella:', '🏖'); - Smilies::add($b, ':desert:', '🏜'); - Smilies::add($b, ':desert island:', '🏝'); - Smilies::add($b, ':national park:', '🏞'); + Smilies::add($b, ':snow-capped mountain:', '🏔'); + Smilies::add($b, ':mountain:', '⛰'); + Smilies::add($b, ':volcano:', '🌋'); + Smilies::add($b, ':mount fuji:', '🗻'); + Smilies::add($b, ':camping:', '🏕'); + Smilies::add($b, ':beach with umbrella:', '🏖'); + Smilies::add($b, ':desert:', '🏜'); + Smilies::add($b, ':desert island:', '🏝'); + Smilies::add($b, ':national park:', '🏞'); // place-building - Smilies::add($b, ':stadium:', '🏟'); - Smilies::add($b, ':classical building:', '🏛'); - Smilies::add($b, ':building construction:', '🏗'); - Smilies::add($b, ':brick:', '🧱'); - Smilies::add($b, ':houses:', '🏘'); - Smilies::add($b, ':derelict house:', '🏚'); - Smilies::add($b, ':house:', '🏠'); - Smilies::add($b, ':house with garden:', '🏡'); - Smilies::add($b, ':office building:', '🏢'); - Smilies::add($b, ':Japanese post office:', '🏣'); - Smilies::add($b, ':post office:', '🏤'); - Smilies::add($b, ':hospital:', '🏥'); - Smilies::add($b, ':bank:', '🏦'); - Smilies::add($b, ':hotel:', '🏨'); - Smilies::add($b, ':love hotel:', '🏩'); - Smilies::add($b, ':convenience store:', '🏪'); - Smilies::add($b, ':school:', '🏫'); - Smilies::add($b, ':department store:', '🏬'); - Smilies::add($b, ':factory:', '🏭'); - Smilies::add($b, ':Japanese castle:', '🏯'); - Smilies::add($b, ':castle:', '🏰'); - Smilies::add($b, ':wedding:', '💒'); - Smilies::add($b, ':Tokyo tower:', '🗼'); - Smilies::add($b, ':Statue of Liberty:', '🗽'); - + Smilies::add($b, ':stadium:', '🏟'); + Smilies::add($b, ':classical building:', '🏛'); + Smilies::add($b, ':building construction:', '🏗'); + Smilies::add($b, ':brick:', '🧱'); + Smilies::add($b, ':houses:', '🏘'); + Smilies::add($b, ':derelict house:', '🏚'); + Smilies::add($b, ':house:', '🏠'); + Smilies::add($b, ':house with garden:', '🏡'); + Smilies::add($b, ':office building:', '🏢'); + Smilies::add($b, ':Japanese post office:', '🏣'); + Smilies::add($b, ':post office:', '🏤'); + Smilies::add($b, ':hospital:', '🏥'); + Smilies::add($b, ':bank:', '🏦'); + Smilies::add($b, ':hotel:', '🏨'); + Smilies::add($b, ':love hotel:', '🏩'); + Smilies::add($b, ':convenience store:', '🏪'); + Smilies::add($b, ':school:', '🏫'); + Smilies::add($b, ':department store:', '🏬'); + Smilies::add($b, ':factory:', '🏭'); + Smilies::add($b, ':Japanese castle:', '🏯'); + Smilies::add($b, ':castle:', '🏰'); + Smilies::add($b, ':wedding:', '💒'); + Smilies::add($b, ':Tokyo tower:', '🗼'); + Smilies::add($b, ':Statue of Liberty:', '🗽'); // place-religious - Smilies::add($b, ':church:', '⛪'); - Smilies::add($b, ':mosque:', '🕌'); -// Smilies::add($b, ':hindu temple:', '🛕'); - Smilies::add($b, ':synagogue:', '🕍'); - Smilies::add($b, ':shinto shrine:', '⛩'); - Smilies::add($b, ':kaaba:', '🕋'); + Smilies::add($b, ':church:', '⛪'); + Smilies::add($b, ':mosque:', '🕌'); +// Smilies::add($b, ':hindu temple:', '🛕'); + Smilies::add($b, ':synagogue:', '🕍'); + Smilies::add($b, ':shinto shrine:', '⛩'); + Smilies::add($b, ':kaaba:', '🕋'); // place-other - Smilies::add($b, ':fountain:', '⛲'); - Smilies::add($b, ':tent:', '⛺'); - Smilies::add($b, ':foggy:', '🌁'); - Smilies::add($b, ':night with stars:', '🌃'); - Smilies::add($b, ':cityscape:', '🏙'); - Smilies::add($b, ':sunrise over mountains:', '🌄'); - Smilies::add($b, ':sunrise:', '🌅'); - Smilies::add($b, ':cityscape at dusk:', '🌆'); - Smilies::add($b, ':sunset:', '🌇'); - Smilies::add($b, ':bridge at night:', '🌉'); - Smilies::add($b, ':hot springs:', '♨'); - Smilies::add($b, ':carousel horse:', '🎠'); - Smilies::add($b, ':ferris wheel:', '🎡'); - Smilies::add($b, ':roller coaster:', '🎢'); - Smilies::add($b, ':barber pole:', '💈'); - Smilies::add($b, ':circus tent:', '🎪'); + Smilies::add($b, ':fountain:', '⛲'); + Smilies::add($b, ':tent:', '⛺'); + Smilies::add($b, ':foggy:', '🌁'); + Smilies::add($b, ':night with stars:', '🌃'); + Smilies::add($b, ':cityscape:', '🏙'); + Smilies::add($b, ':sunrise over mountains:', '🌄'); + Smilies::add($b, ':sunrise:', '🌅'); + Smilies::add($b, ':cityscape at dusk:', '🌆'); + Smilies::add($b, ':sunset:', '🌇'); + Smilies::add($b, ':bridge at night:', '🌉'); + Smilies::add($b, ':hot springs:', '♨'); + Smilies::add($b, ':carousel horse:', '🎠'); + Smilies::add($b, ':ferris wheel:', '🎡'); + Smilies::add($b, ':roller coaster:', '🎢'); + Smilies::add($b, ':barber pole:', '💈'); + Smilies::add($b, ':circus tent:', '🎪'); // transport-ground - Smilies::add($b, ':locomotive:', '🚂'); - Smilies::add($b, ':railway car:', '🚃'); - Smilies::add($b, ':high-speed train:', '🚄'); - Smilies::add($b, ':bullet train:', '🚅'); - Smilies::add($b, ':train:', '🚆'); - Smilies::add($b, ':metro:', '🚇'); - Smilies::add($b, ':light rail:', '🚈'); - Smilies::add($b, ':station:', '🚉'); - Smilies::add($b, ':tram:', '🚊'); - Smilies::add($b, ':monorail:', '🚝'); - Smilies::add($b, ':mountain railway:', '🚞'); - Smilies::add($b, ':tram car:', '🚋'); - Smilies::add($b, ':bus:', '🚌'); - Smilies::add($b, ':oncoming bus:', '🚍'); - Smilies::add($b, ':trolleybus:', '🚎'); - Smilies::add($b, ':minibus:', '🚐'); - Smilies::add($b, ':ambulance:', '🚑'); - Smilies::add($b, ':fire engine:', '🚒'); - Smilies::add($b, ':police car:', '🚓'); - Smilies::add($b, ':oncoming police car:', '🚔'); - Smilies::add($b, ':taxi:', '🚕'); - Smilies::add($b, ':oncoming taxi:', '🚖'); - Smilies::add($b, ':automobile:', '🚗'); - Smilies::add($b, ':oncoming automobile:', '🚘'); - Smilies::add($b, ':sport utility vehicle:', '🚙'); - Smilies::add($b, ':delivery truck:', '🚚'); - Smilies::add($b, ':articulated lorry:', '🚛'); - Smilies::add($b, ':tractor:', '🚜'); - Smilies::add($b, ':racing car:', '🏎'); - Smilies::add($b, ':motorcycle:', '🏍'); - Smilies::add($b, ':motor scooter:', '🛵'); -// Smilies::add($b, ':manual wheelchair:', '🦽'); -// Smilies::add($b, ':motorized wheelchair:', '🦼'); -// Smilies::add($b, ':auto rickshaw:', '🛺'); - Smilies::add($b, ':bicycle:', '🚲'); - Smilies::add($b, ':kick scooter:', '🛴'); - Smilies::add($b, ':skateboard:', '🛹'); - Smilies::add($b, ':bus stop:', '🚏'); - Smilies::add($b, ':motorway:', '🛣'); - Smilies::add($b, ':railway track:', '🛤'); - Smilies::add($b, ':oil drum:', '🛢'); - Smilies::add($b, ':fuel pump:', '⛽'); - Smilies::add($b, ':police car light:', '🚨'); - Smilies::add($b, ':horizontal traffic light:', '🚥'); - Smilies::add($b, ':vertical traffic light:', '🚦'); - Smilies::add($b, ':stop sign:', '🛑'); - Smilies::add($b, ':construction:', '🚧'); + Smilies::add($b, ':locomotive:', '🚂'); + Smilies::add($b, ':railway car:', '🚃'); + Smilies::add($b, ':high-speed train:', '🚄'); + Smilies::add($b, ':bullet train:', '🚅'); + Smilies::add($b, ':train:', '🚆'); + Smilies::add($b, ':metro:', '🚇'); + Smilies::add($b, ':light rail:', '🚈'); + Smilies::add($b, ':station:', '🚉'); + Smilies::add($b, ':tram:', '🚊'); + Smilies::add($b, ':monorail:', '🚝'); + Smilies::add($b, ':mountain railway:', '🚞'); + Smilies::add($b, ':tram car:', '🚋'); + Smilies::add($b, ':bus:', '🚌'); + Smilies::add($b, ':oncoming bus:', '🚍'); + Smilies::add($b, ':trolleybus:', '🚎'); + Smilies::add($b, ':minibus:', '🚐'); + Smilies::add($b, ':ambulance:', '🚑'); + Smilies::add($b, ':fire engine:', '🚒'); + Smilies::add($b, ':police car:', '🚓'); + Smilies::add($b, ':oncoming police car:', '🚔'); + Smilies::add($b, ':taxi:', '🚕'); + Smilies::add($b, ':oncoming taxi:', '🚖'); + Smilies::add($b, ':automobile:', '🚗'); + Smilies::add($b, ':oncoming automobile:', '🚘'); + Smilies::add($b, ':sport utility vehicle:', '🚙'); + Smilies::add($b, ':delivery truck:', '🚚'); + Smilies::add($b, ':articulated lorry:', '🚛'); + Smilies::add($b, ':tractor:', '🚜'); + Smilies::add($b, ':racing car:', '🏎'); + Smilies::add($b, ':motorcycle:', '🏍'); + Smilies::add($b, ':motor scooter:', '🛵'); +// Smilies::add($b, ':manual wheelchair:', '🦽'); +// Smilies::add($b, ':motorized wheelchair:', '🦼'); +// Smilies::add($b, ':auto rickshaw:', '🛺'); + Smilies::add($b, ':bicycle:', '🚲'); + Smilies::add($b, ':kick scooter:', '🛴'); + Smilies::add($b, ':skateboard:', '🛹'); + Smilies::add($b, ':bus stop:', '🚏'); + Smilies::add($b, ':motorway:', '🛣'); + Smilies::add($b, ':railway track:', '🛤'); + Smilies::add($b, ':oil drum:', '🛢'); + Smilies::add($b, ':fuel pump:', '⛽'); + Smilies::add($b, ':police car light:', '🚨'); + Smilies::add($b, ':horizontal traffic light:', '🚥'); + Smilies::add($b, ':vertical traffic light:', '🚦'); + Smilies::add($b, ':stop sign:', '🛑'); + Smilies::add($b, ':construction:', '🚧'); // transport-water - Smilies::add($b, ':anchor:', '⚓'); - Smilies::add($b, ':sailboat:', '⛵'); - Smilies::add($b, ':canoe:', '🛶'); - Smilies::add($b, ':speedboat:', '🚤'); - Smilies::add($b, ':passenger ship:', '🛳'); - Smilies::add($b, ':ferry:', '⛴'); - Smilies::add($b, ':motor boat:', '🛥'); - Smilies::add($b, ':ship:', '🚢'); + Smilies::add($b, ':anchor:', '⚓'); + Smilies::add($b, ':sailboat:', '⛵'); + Smilies::add($b, ':canoe:', '🛶'); + Smilies::add($b, ':speedboat:', '🚤'); + Smilies::add($b, ':passenger ship:', '🛳'); + Smilies::add($b, ':ferry:', '⛴'); + Smilies::add($b, ':motor boat:', '🛥'); + Smilies::add($b, ':ship:', '🚢'); // transport-air - Smilies::add($b, ':airplane:', '✈'); - Smilies::add($b, ':small airplane:', '🛩'); - Smilies::add($b, ':airplane departure:', '🛫'); - Smilies::add($b, ':airplane arrival:', '🛬'); - Smilies::add($b, ':parachute:', '🪂'); - Smilies::add($b, ':seat:', '💺'); - Smilies::add($b, ':helicopter:', '🚁'); - Smilies::add($b, ':suspension railway:', '🚟'); - Smilies::add($b, ':mountain cableway:', '🚠'); - Smilies::add($b, ':aerial tramway:', '🚡'); - Smilies::add($b, ':satellite:', '🛰'); - Smilies::add($b, ':rocket:', '🚀'); - Smilies::add($b, ':flying saucer:', '🛸'); + Smilies::add($b, ':airplane:', '✈'); + Smilies::add($b, ':small airplane:', '🛩'); + Smilies::add($b, ':airplane departure:', '🛫'); + Smilies::add($b, ':airplane arrival:', '🛬'); + Smilies::add($b, ':parachute:', '🪂'); + Smilies::add($b, ':seat:', '💺'); + Smilies::add($b, ':helicopter:', '🚁'); + Smilies::add($b, ':suspension railway:', '🚟'); + Smilies::add($b, ':mountain cableway:', '🚠'); + Smilies::add($b, ':aerial tramway:', '🚡'); + Smilies::add($b, ':satellite:', '🛰'); + Smilies::add($b, ':rocket:', '🚀'); + Smilies::add($b, ':flying saucer:', '🛸'); // hotel - Smilies::add($b, ':bellhop bell:', '🛎'); - Smilies::add($b, ':luggage:', '🧳'); + Smilies::add($b, ':bellhop bell:', '🛎'); + Smilies::add($b, ':luggage:', '🧳'); // time - Smilies::add($b, ':hourglass done:', '⌛'); - Smilies::add($b, ':hourglass not done:', '⏳'); - Smilies::add($b, ':watch:', '⌚'); - Smilies::add($b, ':alarm clock:', '⏰'); - Smilies::add($b, ':stopwatch:', '⏱'); - Smilies::add($b, ':timer clock:', '⏲'); - Smilies::add($b, ':mantelpiece clock:', '🕰'); - Smilies::add($b, ':twelve o’clock:', '🕛'); - Smilies::add($b, ':twelve-thirty:', '🕧'); - Smilies::add($b, ':one o’clock:', '🕐'); - Smilies::add($b, ':one-thirty:', '🕜'); - Smilies::add($b, ':two o’clock:', '🕑'); - Smilies::add($b, ':two-thirty:', '🕝'); - Smilies::add($b, ':three o’clock:', '🕒'); - Smilies::add($b, ':three-thirty:', '🕞'); - Smilies::add($b, ':four o’clock:', '🕓'); - Smilies::add($b, ':four-thirty:', '🕟'); - Smilies::add($b, ':five o’clock:', '🕔'); - Smilies::add($b, ':five-thirty:', '🕠'); - Smilies::add($b, ':six o’clock:', '🕕'); - Smilies::add($b, ':six-thirty:', '🕡'); - Smilies::add($b, ':seven o’clock:', '🕖'); - Smilies::add($b, ':seven-thirty:', '🕢'); - Smilies::add($b, ':eight o’clock:', '🕗'); - Smilies::add($b, ':eight-thirty:', '🕣'); - Smilies::add($b, ':nine o’clock:', '🕘'); - Smilies::add($b, ':nine-thirty:', '🕤'); - Smilies::add($b, ':ten o’clock:', '🕙'); - Smilies::add($b, ':ten-thirty:', '🕥'); - Smilies::add($b, ':eleven o’clock:', '🕚'); - Smilies::add($b, ':eleven-thirty:', '🕦'); + Smilies::add($b, ':hourglass done:', '⌛'); + Smilies::add($b, ':hourglass not done:', '⏳'); + Smilies::add($b, ':watch:', '⌚'); + Smilies::add($b, ':alarm clock:', '⏰'); + Smilies::add($b, ':stopwatch:', '⏱'); + Smilies::add($b, ':timer clock:', '⏲'); + Smilies::add($b, ':mantelpiece clock:', '🕰'); + Smilies::add($b, ':twelve o’clock:', '🕛'); + Smilies::add($b, ':twelve-thirty:', '🕧'); + Smilies::add($b, ':one o’clock:', '🕐'); + Smilies::add($b, ':one-thirty:', '🕜'); + Smilies::add($b, ':two o’clock:', '🕑'); + Smilies::add($b, ':two-thirty:', '🕝'); + Smilies::add($b, ':three o’clock:', '🕒'); + Smilies::add($b, ':three-thirty:', '🕞'); + Smilies::add($b, ':four o’clock:', '🕓'); + Smilies::add($b, ':four-thirty:', '🕟'); + Smilies::add($b, ':five o’clock:', '🕔'); + Smilies::add($b, ':five-thirty:', '🕠'); + Smilies::add($b, ':six o’clock:', '🕕'); + Smilies::add($b, ':six-thirty:', '🕡'); + Smilies::add($b, ':seven o’clock:', '🕖'); + Smilies::add($b, ':seven-thirty:', '🕢'); + Smilies::add($b, ':eight o’clock:', '🕗'); + Smilies::add($b, ':eight-thirty:', '🕣'); + Smilies::add($b, ':nine o’clock:', '🕘'); + Smilies::add($b, ':nine-thirty:', '🕤'); + Smilies::add($b, ':ten o’clock:', '🕙'); + Smilies::add($b, ':ten-thirty:', '🕥'); + Smilies::add($b, ':eleven o’clock:', '🕚'); + Smilies::add($b, ':eleven-thirty:', '🕦'); // sky & weather - Smilies::add($b, ':new moon:', '🌑'); - Smilies::add($b, ':waxing crescent moon:', '🌒'); - Smilies::add($b, ':first quarter moon:', '🌓'); - Smilies::add($b, ':waxing gibbous moon:', '🌔'); - Smilies::add($b, ':full moon:', '🌕'); - Smilies::add($b, ':waning gibbous moon:', '🌖'); - Smilies::add($b, ':last quarter moon:', '🌗'); - Smilies::add($b, ':waning crescent moon:', '🌘'); - Smilies::add($b, ':crescent moon:', '🌙'); - Smilies::add($b, ':new moon face:', '🌚'); - Smilies::add($b, ':first quarter moon face:', '🌛'); - Smilies::add($b, ':last quarter moon face:', '🌜'); - Smilies::add($b, ':thermometer:', '🌡'); - Smilies::add($b, ':sun:', '☀'); - Smilies::add($b, ':full moon face:', '🌝'); - Smilies::add($b, ':sun with face:', '🌞'); - Smilies::add($b, ':ringed planet:', '🪐'); - Smilies::add($b, ':star:', '⭐'); - Smilies::add($b, ':glowing star:', '🌟'); - Smilies::add($b, ':shooting star:', '🌠'); - Smilies::add($b, ':milky way:', '🌌'); - Smilies::add($b, ':cloud:', '☁'); - Smilies::add($b, ':sun behind cloud:', '⛅'); - Smilies::add($b, ':cloud with lightning and rain:', '⛈'); - Smilies::add($b, ':sun behind small cloud:', '🌤'); - Smilies::add($b, ':sun behind large cloud:', '🌥'); - Smilies::add($b, ':sun behind rain cloud:', '🌦'); - Smilies::add($b, ':cloud with rain:', '🌧'); - Smilies::add($b, ':cloud with snow:', '🌨'); - Smilies::add($b, ':cloud with lightning:', '🌩'); - Smilies::add($b, ':tornado:', '🌪'); - Smilies::add($b, ':fog:', '🌫'); - Smilies::add($b, ':wind face:', '🌬'); - Smilies::add($b, ':cyclone:', '🌀'); - Smilies::add($b, ':rainbow:', '🌈'); - Smilies::add($b, ':closed umbrella:', '🌂'); - Smilies::add($b, ':umbrella:', '☂'); - Smilies::add($b, ':umbrella with rain drops:', '☔'); - Smilies::add($b, ':umbrella on ground:', '⛱'); - Smilies::add($b, ':high voltage:', '⚡'); - Smilies::add($b, ':snowflake:', '❄'); - Smilies::add($b, ':snowman:', '☃'); - Smilies::add($b, ':snowman without snow:', '⛄'); - Smilies::add($b, ':comet:', '☄'); - Smilies::add($b, ':fire:', '🔥'); - Smilies::add($b, ':droplet:', '💧'); - Smilies::add($b, ':water wave:', '🌊'); + Smilies::add($b, ':new moon:', '🌑'); + Smilies::add($b, ':waxing crescent moon:', '🌒'); + Smilies::add($b, ':first quarter moon:', '🌓'); + Smilies::add($b, ':waxing gibbous moon:', '🌔'); + Smilies::add($b, ':full moon:', '🌕'); + Smilies::add($b, ':waning gibbous moon:', '🌖'); + Smilies::add($b, ':last quarter moon:', '🌗'); + Smilies::add($b, ':waning crescent moon:', '🌘'); + Smilies::add($b, ':crescent moon:', '🌙'); + Smilies::add($b, ':new moon face:', '🌚'); + Smilies::add($b, ':first quarter moon face:', '🌛'); + Smilies::add($b, ':last quarter moon face:', '🌜'); + Smilies::add($b, ':thermometer:', '🌡'); + Smilies::add($b, ':sun:', '☀'); + Smilies::add($b, ':full moon face:', '🌝'); + Smilies::add($b, ':sun with face:', '🌞'); + Smilies::add($b, ':ringed planet:', '🪐'); + Smilies::add($b, ':star:', '⭐'); + Smilies::add($b, ':glowing star:', '🌟'); + Smilies::add($b, ':shooting star:', '🌠'); + Smilies::add($b, ':milky way:', '🌌'); + Smilies::add($b, ':cloud:', '☁'); + Smilies::add($b, ':sun behind cloud:', '⛅'); + Smilies::add($b, ':cloud with lightning and rain:', '⛈'); + Smilies::add($b, ':sun behind small cloud:', '🌤'); + Smilies::add($b, ':sun behind large cloud:', '🌥'); + Smilies::add($b, ':sun behind rain cloud:', '🌦'); + Smilies::add($b, ':cloud with rain:', '🌧'); + Smilies::add($b, ':cloud with snow:', '🌨'); + Smilies::add($b, ':cloud with lightning:', '🌩'); + Smilies::add($b, ':tornado:', '🌪'); + Smilies::add($b, ':fog:', '🌫'); + Smilies::add($b, ':wind face:', '🌬'); + Smilies::add($b, ':cyclone:', '🌀'); + Smilies::add($b, ':rainbow:', '🌈'); + Smilies::add($b, ':closed umbrella:', '🌂'); + Smilies::add($b, ':umbrella:', '☂'); + Smilies::add($b, ':umbrella with rain drops:', '☔'); + Smilies::add($b, ':umbrella on ground:', '⛱'); + Smilies::add($b, ':high voltage:', '⚡'); + Smilies::add($b, ':snowflake:', '❄'); + Smilies::add($b, ':snowman:', '☃'); + Smilies::add($b, ':snowman without snow:', '⛄'); + Smilies::add($b, ':comet:', '☄'); + Smilies::add($b, ':fire:', '🔥'); + Smilies::add($b, ':droplet:', '💧'); + Smilies::add($b, ':water wave:', '🌊'); // Activities // event - Smilies::add($b, ':jack-o-lantern:', '🎃'); - Smilies::add($b, ':Christmas tree:', '🎄'); - Smilies::add($b, ':fireworks:', '🎆'); - Smilies::add($b, ':sparkler:', '🎇'); - Smilies::add($b, ':firecracker:', '🧨'); - Smilies::add($b, ':sparkles:', '✨'); - Smilies::add($b, ':balloon:', '🎈'); - Smilies::add($b, ':party popper:', '🎉'); - Smilies::add($b, ':confetti ball:', '🎊'); - Smilies::add($b, ':tanabata tree:', '🎋'); - Smilies::add($b, ':pine decoration:', '🎍'); - Smilies::add($b, ':Japanese dolls:', '🎎'); - Smilies::add($b, ':carp streamer:', '🎏'); - Smilies::add($b, ':wind chime:', '🎐'); - Smilies::add($b, ':moon viewing ceremony:', '🎑'); - Smilies::add($b, ':red envelope:', '🧧'); - Smilies::add($b, ':ribbon:', '🎀'); - Smilies::add($b, ':wrapped gift:', '🎁'); - Smilies::add($b, ':reminder ribbon:', '🎗'); - Smilies::add($b, ':admission tickets:', '🎟'); - Smilies::add($b, ':ticket:', '🎫'); + Smilies::add($b, ':jack-o-lantern:', '🎃'); + Smilies::add($b, ':Christmas tree:', '🎄'); + Smilies::add($b, ':fireworks:', '🎆'); + Smilies::add($b, ':sparkler:', '🎇'); + Smilies::add($b, ':firecracker:', '🧨'); + Smilies::add($b, ':sparkles:', '✨'); + Smilies::add($b, ':balloon:', '🎈'); + Smilies::add($b, ':party popper:', '🎉'); + Smilies::add($b, ':confetti ball:', '🎊'); + Smilies::add($b, ':tanabata tree:', '🎋'); + Smilies::add($b, ':pine decoration:', '🎍'); + Smilies::add($b, ':Japanese dolls:', '🎎'); + Smilies::add($b, ':carp streamer:', '🎏'); + Smilies::add($b, ':wind chime:', '🎐'); + Smilies::add($b, ':moon viewing ceremony:', '🎑'); + Smilies::add($b, ':red envelope:', '🧧'); + Smilies::add($b, ':ribbon:', '🎀'); + Smilies::add($b, ':wrapped gift:', '🎁'); + Smilies::add($b, ':reminder ribbon:', '🎗'); + Smilies::add($b, ':admission tickets:', '🎟'); + Smilies::add($b, ':ticket:', '🎫'); // award-medal - Smilies::add($b, ':military medal:', '🎖'); - Smilies::add($b, ':trophy:', '🏆'); - Smilies::add($b, ':sports medal:', '🏅'); - Smilies::add($b, ':1st place medal:', '🥇'); - Smilies::add($b, ':2nd place medal:', '🥈'); - Smilies::add($b, ':3rd place medal:', '🥉'); + Smilies::add($b, ':military medal:', '🎖'); + Smilies::add($b, ':trophy:', '🏆'); + Smilies::add($b, ':sports medal:', '🏅'); + Smilies::add($b, ':1st place medal:', '🥇'); + Smilies::add($b, ':2nd place medal:', '🥈'); + Smilies::add($b, ':3rd place medal:', '🥉'); // sport - Smilies::add($b, ':soccer ball:', '⚽'); - Smilies::add($b, ':baseball:', '⚾'); - Smilies::add($b, ':softball:', '🥎'); - Smilies::add($b, ':basketball:', '🏀'); - Smilies::add($b, ':volleyball:', '🏐'); - Smilies::add($b, ':american football:', '🏈'); + Smilies::add($b, ':soccer ball:', '⚽'); + Smilies::add($b, ':baseball:', '⚾'); + Smilies::add($b, ':softball:', '🥎'); + Smilies::add($b, ':basketball:', '🏀'); + Smilies::add($b, ':volleyball:', '🏐'); + Smilies::add($b, ':american football:', '🏈'); Smilies::add($b, ':football:', '🏈'); - Smilies::add($b, ':rugby football:', '🏉'); - Smilies::add($b, ':tennis:', '🎾'); - Smilies::add($b, ':flying disc:', '🥏'); - Smilies::add($b, ':bowling:', '🎳'); - Smilies::add($b, ':cricket game:', '🏏'); - Smilies::add($b, ':field hockey:', '🏑'); - Smilies::add($b, ':ice hockey:', '🏒'); - Smilies::add($b, ':lacrosse:', '🥍'); - Smilies::add($b, ':ping pong:', '🏓'); - Smilies::add($b, ':badminton:', '🏸'); - Smilies::add($b, ':boxing glove:', '🥊'); - Smilies::add($b, ':martial arts uniform:', '🥋'); - Smilies::add($b, ':goal net:', '🥅'); - Smilies::add($b, ':flag in hole:', '⛳'); - Smilies::add($b, ':ice skate:', '⛸'); - Smilies::add($b, ':fishing pole:', '🎣'); -// Smilies::add($b, ':diving mask:', '🤿'); - Smilies::add($b, ':running shirt:', '🎽'); - Smilies::add($b, ':skis:', '🎿'); - Smilies::add($b, ':sled:', '🛷'); - Smilies::add($b, ':curling stone:', '🥌'); + Smilies::add($b, ':rugby football:', '🏉'); + Smilies::add($b, ':tennis:', '🎾'); + Smilies::add($b, ':flying disc:', '🥏'); + Smilies::add($b, ':bowling:', '🎳'); + Smilies::add($b, ':cricket game:', '🏏'); + Smilies::add($b, ':field hockey:', '🏑'); + Smilies::add($b, ':ice hockey:', '🏒'); + Smilies::add($b, ':lacrosse:', '🥍'); + Smilies::add($b, ':ping pong:', '🏓'); + Smilies::add($b, ':badminton:', '🏸'); + Smilies::add($b, ':boxing glove:', '🥊'); + Smilies::add($b, ':martial arts uniform:', '🥋'); + Smilies::add($b, ':goal net:', '🥅'); + Smilies::add($b, ':flag in hole:', '⛳'); + Smilies::add($b, ':ice skate:', '⛸'); + Smilies::add($b, ':fishing pole:', '🎣'); +// Smilies::add($b, ':diving mask:', '🤿'); + Smilies::add($b, ':running shirt:', '🎽'); + Smilies::add($b, ':skis:', '🎿'); + Smilies::add($b, ':sled:', '🛷'); + Smilies::add($b, ':curling stone:', '🥌'); Smilies::add($b, ':cycling:', '🚴'); Smilies::add($b, ':darts:', '🎯'); Smilies::add($b, ':fencing:', '🤺'); Smilies::add($b, ':juggling:', '🤹'); -// Smilies::add($b, ':skipping:', '&#x;'); -// Smilies::add($b, ':archery:', '&#x;'); +// Smilies::add($b, ':skipping:', '&#x;'); +// Smilies::add($b, ':archery:', '&#x;'); Smilies::add($b, ':surfing:', '🏄'); Smilies::add($b, ':snooker:', '🎱'); Smilies::add($b, ':horseriding:', '🏇'); // game - Smilies::add($b, ':direct hit:', '🎯'); - Smilies::add($b, ':yo-yo:', '🪀'); - Smilies::add($b, ':kite:', '🪁'); - Smilies::add($b, ':pool 8 ball:', '🎱'); - Smilies::add($b, ':crystal ball:', '🔮'); - Smilies::add($b, ':nazar amulet:', '🧿'); - Smilies::add($b, ':video game:', '🎮'); - Smilies::add($b, ':joystick:', '🕹'); - Smilies::add($b, ':slot machine:', '🎰'); - Smilies::add($b, ':game die:', '🎲'); - Smilies::add($b, ':puzzle piece:', '🧩'); - Smilies::add($b, ':teddy bear:', '🧸'); - Smilies::add($b, ':spade suit:', '♠'); - Smilies::add($b, ':heart suit:', '♥'); - Smilies::add($b, ':diamond suit:', '♦'); - Smilies::add($b, ':club suit:', '♣'); - Smilies::add($b, ':chess pawn:', '♟'); - Smilies::add($b, ':joker:', '🃏'); - Smilies::add($b, ':mahjong red dragon:', '🀄'); - Smilies::add($b, ':flower playing cards:', '🎴'); + Smilies::add($b, ':direct hit:', '🎯'); + Smilies::add($b, ':yo-yo:', '🪀'); + Smilies::add($b, ':kite:', '🪁'); + Smilies::add($b, ':pool 8 ball:', '🎱'); + Smilies::add($b, ':crystal ball:', '🔮'); + Smilies::add($b, ':nazar amulet:', '🧿'); + Smilies::add($b, ':video game:', '🎮'); + Smilies::add($b, ':joystick:', '🕹'); + Smilies::add($b, ':slot machine:', '🎰'); + Smilies::add($b, ':game die:', '🎲'); + Smilies::add($b, ':puzzle piece:', '🧩'); + Smilies::add($b, ':teddy bear:', '🧸'); + Smilies::add($b, ':spade suit:', '♠'); + Smilies::add($b, ':heart suit:', '♥'); + Smilies::add($b, ':diamond suit:', '♦'); + Smilies::add($b, ':club suit:', '♣'); + Smilies::add($b, ':chess pawn:', '♟'); + Smilies::add($b, ':joker:', '🃏'); + Smilies::add($b, ':mahjong red dragon:', '🀄'); + Smilies::add($b, ':flower playing cards:', '🎴'); // arts & crafts - Smilies::add($b, ':performing arts:', '🎭'); - Smilies::add($b, ':framed picture:', '🖼'); - Smilies::add($b, ':artist palette:', '🎨'); - Smilies::add($b, ':thread:', '🧵'); - Smilies::add($b, ':yarn:', '🧶'); + Smilies::add($b, ':performing arts:', '🎭'); + Smilies::add($b, ':framed picture:', '🖼'); + Smilies::add($b, ':artist palette:', '🎨'); + Smilies::add($b, ':thread:', '🧵'); + Smilies::add($b, ':yarn:', '🧶'); // Objects // clothing - Smilies::add($b, ':glasses:', '👓'); - Smilies::add($b, ':sunglasses:', '🕶'); - Smilies::add($b, ':goggles:', '🥽'); - Smilies::add($b, ':lab coat:', '🥼'); - Smilies::add($b, ':safety vest:', '🦺'); - Smilies::add($b, ':necktie:', '👔'); - Smilies::add($b, ':t-shirt:', '👕'); - Smilies::add($b, ':jeans:', '👖'); - Smilies::add($b, ':scarf:', '🧣'); - Smilies::add($b, ':gloves:', '🧤'); - Smilies::add($b, ':coat:', '🧥'); - Smilies::add($b, ':socks:', '🧦'); - Smilies::add($b, ':dress:', '👗'); - Smilies::add($b, ':kimono:', '👘'); - Smilies::add($b, ':sari:', '🥻'); - Smilies::add($b, ':one-piece swimsuit:', '🩱'); - Smilies::add($b, ':briefs:', '🩲'); - Smilies::add($b, ':shorts:', '🩳'); - Smilies::add($b, ':bikini:', '👙'); - Smilies::add($b, ':woman’s clothes:', '👚'); - Smilies::add($b, ':purse:', '👛'); - Smilies::add($b, ':handbag:', '👜'); - Smilies::add($b, ':clutch bag:', '👝'); - Smilies::add($b, ':shopping bags:', '🛍'); - Smilies::add($b, ':backpack:', '🎒'); - Smilies::add($b, ':man’s shoe:', '👞'); - Smilies::add($b, ':running shoe:', '👟'); - Smilies::add($b, ':hiking boot:', '🥾'); - Smilies::add($b, ':flat shoe:', '🥿'); - Smilies::add($b, ':high-heeled shoe:', '👠'); - Smilies::add($b, ':woman’s sandal:', '👡'); -// Smilies::add($b, ':ballet shoes:', '🩰'); - Smilies::add($b, ':woman’s boot:', '👢'); - Smilies::add($b, ':crown:', '👑'); - Smilies::add($b, ':woman’s hat:', '👒'); - Smilies::add($b, ':top hat:', '🎩'); - Smilies::add($b, ':graduation cap:', '🎓'); - Smilies::add($b, ':billed cap:', '🧢'); - Smilies::add($b, ':rescue worker’s helmet:', '⛑'); - Smilies::add($b, ':prayer beads:', '📿'); - Smilies::add($b, ':lipstick:', '💄'); - Smilies::add($b, ':ring:', '💍'); - Smilies::add($b, ':gem stone:', '💎'); + Smilies::add($b, ':glasses:', '👓'); + Smilies::add($b, ':sunglasses:', '🕶'); + Smilies::add($b, ':goggles:', '🥽'); + Smilies::add($b, ':lab coat:', '🥼'); + Smilies::add($b, ':safety vest:', '🦺'); + Smilies::add($b, ':necktie:', '👔'); + Smilies::add($b, ':t-shirt:', '👕'); + Smilies::add($b, ':jeans:', '👖'); + Smilies::add($b, ':scarf:', '🧣'); + Smilies::add($b, ':gloves:', '🧤'); + Smilies::add($b, ':coat:', '🧥'); + Smilies::add($b, ':socks:', '🧦'); + Smilies::add($b, ':dress:', '👗'); + Smilies::add($b, ':kimono:', '👘'); + Smilies::add($b, ':sari:', '🥻'); + Smilies::add($b, ':one-piece swimsuit:', '🩱'); + Smilies::add($b, ':briefs:', '🩲'); + Smilies::add($b, ':shorts:', '🩳'); + Smilies::add($b, ':bikini:', '👙'); + Smilies::add($b, ':woman’s clothes:', '👚'); + Smilies::add($b, ':purse:', '👛'); + Smilies::add($b, ':handbag:', '👜'); + Smilies::add($b, ':clutch bag:', '👝'); + Smilies::add($b, ':shopping bags:', '🛍'); + Smilies::add($b, ':backpack:', '🎒'); + Smilies::add($b, ':man’s shoe:', '👞'); + Smilies::add($b, ':running shoe:', '👟'); + Smilies::add($b, ':hiking boot:', '🥾'); + Smilies::add($b, ':flat shoe:', '🥿'); + Smilies::add($b, ':high-heeled shoe:', '👠'); + Smilies::add($b, ':woman’s sandal:', '👡'); +// Smilies::add($b, ':ballet shoes:', '🩰'); + Smilies::add($b, ':woman’s boot:', '👢'); + Smilies::add($b, ':crown:', '👑'); + Smilies::add($b, ':woman’s hat:', '👒'); + Smilies::add($b, ':top hat:', '🎩'); + Smilies::add($b, ':graduation cap:', '🎓'); + Smilies::add($b, ':billed cap:', '🧢'); + Smilies::add($b, ':rescue worker’s helmet:', '⛑'); + Smilies::add($b, ':prayer beads:', '📿'); + Smilies::add($b, ':lipstick:', '💄'); + Smilies::add($b, ':ring:', '💍'); + Smilies::add($b, ':gem stone:', '💎'); // sound - Smilies::add($b, ':muted speaker:', '🔇'); - Smilies::add($b, ':speaker low volume:', '🔈'); - Smilies::add($b, ':speaker medium volume:', '🔉'); - Smilies::add($b, ':speaker high volume:', '🔊'); - Smilies::add($b, ':loudspeaker:', '📢'); - Smilies::add($b, ':megaphone:', '📣'); - Smilies::add($b, ':postal horn:', '📯'); - Smilies::add($b, ':bell:', '🔔'); - Smilies::add($b, ':bell with slash:', '🔕'); + Smilies::add($b, ':muted speaker:', '🔇'); + Smilies::add($b, ':speaker low volume:', '🔈'); + Smilies::add($b, ':speaker medium volume:', '🔉'); + Smilies::add($b, ':speaker high volume:', '🔊'); + Smilies::add($b, ':loudspeaker:', '📢'); + Smilies::add($b, ':megaphone:', '📣'); + Smilies::add($b, ':postal horn:', '📯'); + Smilies::add($b, ':bell:', '🔔'); + Smilies::add($b, ':bell with slash:', '🔕'); // musik - Smilies::add($b, ':musical score:', '🎼'); - Smilies::add($b, ':musical note:', '🎵'); - Smilies::add($b, ':musical notes:', '🎶'); - Smilies::add($b, ':studio microphone:', '🎙'); - Smilies::add($b, ':level slider:', '🎚'); - Smilies::add($b, ':control knobs:', '🎛'); - Smilies::add($b, ':microphone:', '🎤'); - Smilies::add($b, ':headphone:', '🎧'); - Smilies::add($b, ':radio:', '📻'); + Smilies::add($b, ':musical score:', '🎼'); + Smilies::add($b, ':musical note:', '🎵'); + Smilies::add($b, ':musical notes:', '🎶'); + Smilies::add($b, ':studio microphone:', '🎙'); + Smilies::add($b, ':level slider:', '🎚'); + Smilies::add($b, ':control knobs:', '🎛'); + Smilies::add($b, ':microphone:', '🎤'); + Smilies::add($b, ':headphone:', '🎧'); + Smilies::add($b, ':radio:', '📻'); // musical-instrument - Smilies::add($b, ':saxophone:', '🎷'); - Smilies::add($b, ':guitar:', '🎸'); - Smilies::add($b, ':musical keyboard:', '🎹'); - Smilies::add($b, ':trumpet:', '🎺'); - Smilies::add($b, ':violin:', '🎻'); -// Smilies::add($b, ':banjo:', '🪕'); - Smilies::add($b, ':drum:', '🥁'); + Smilies::add($b, ':saxophone:', '🎷'); + Smilies::add($b, ':guitar:', '🎸'); + Smilies::add($b, ':musical keyboard:', '🎹'); + Smilies::add($b, ':trumpet:', '🎺'); + Smilies::add($b, ':violin:', '🎻'); +// Smilies::add($b, ':banjo:', '🪕'); + Smilies::add($b, ':drum:', '🥁'); // phone - Smilies::add($b, ':mobile phone:', '📱'); - Smilies::add($b, ':mobile phone with arrow:', '📲'); - Smilies::add($b, ':telephone:', '☎'); - Smilies::add($b, ':telephone receiver:', '📞'); - Smilies::add($b, ':pager:', '📟'); - Smilies::add($b, ':fax machine:', '📠'); + Smilies::add($b, ':mobile phone:', '📱'); + Smilies::add($b, ':mobile phone with arrow:', '📲'); + Smilies::add($b, ':telephone:', '☎'); + Smilies::add($b, ':telephone receiver:', '📞'); + Smilies::add($b, ':pager:', '📟'); + Smilies::add($b, ':fax machine:', '📠'); // computer - Smilies::add($b, ':battery:', '🔋'); - Smilies::add($b, ':electric plug:', '🔌'); - Smilies::add($b, ':laptop:', '💻'); - Smilies::add($b, ':desktop computer:', '🖥'); - Smilies::add($b, ':printer:', '🖨'); - Smilies::add($b, ':keyboard:', '⌨'); - Smilies::add($b, ':computer mouse:', '🖱'); - Smilies::add($b, ':trackball:', '🖲'); - Smilies::add($b, ':computer disk:', '💽'); - Smilies::add($b, ':floppy disk:', '💾'); - Smilies::add($b, ':optical disk:', '💿'); - Smilies::add($b, ':dvd:', '📀'); - Smilies::add($b, ':abacus:', '🧮'); + Smilies::add($b, ':battery:', '🔋'); + Smilies::add($b, ':electric plug:', '🔌'); + Smilies::add($b, ':laptop:', '💻'); + Smilies::add($b, ':desktop computer:', '🖥'); + Smilies::add($b, ':printer:', '🖨'); + Smilies::add($b, ':keyboard:', '⌨'); + Smilies::add($b, ':computer mouse:', '🖱'); + Smilies::add($b, ':trackball:', '🖲'); + Smilies::add($b, ':computer disk:', '💽'); + Smilies::add($b, ':floppy disk:', '💾'); + Smilies::add($b, ':optical disk:', '💿'); + Smilies::add($b, ':dvd:', '📀'); + Smilies::add($b, ':abacus:', '🧮'); // light & video - Smilies::add($b, ':movie camera:', '🎥'); - Smilies::add($b, ':film frames:', '🎞'); - Smilies::add($b, ':film projector:', '📽'); - Smilies::add($b, ':clapper board:', '🎬'); - Smilies::add($b, ':television:', '📺'); - Smilies::add($b, ':camera:', '📷'); - Smilies::add($b, ':camera with flash:', '📸'); - Smilies::add($b, ':video camera:', '📹'); - Smilies::add($b, ':videocassette:', '📼'); - Smilies::add($b, ':magnifying glass tilted left:', '🔍'); - Smilies::add($b, ':magnifying glass tilted right:', '🔎'); - Smilies::add($b, ':candle:', '🕯'); - Smilies::add($b, ':light bulb:', '💡'); - Smilies::add($b, ':flashlight:', '🔦'); - Smilies::add($b, ':red paper lantern:', '🏮'); -// Smilies::add($b, ':diya lamp:', '🪔'); + Smilies::add($b, ':movie camera:', '🎥'); + Smilies::add($b, ':film frames:', '🎞'); + Smilies::add($b, ':film projector:', '📽'); + Smilies::add($b, ':clapper board:', '🎬'); + Smilies::add($b, ':television:', '📺'); + Smilies::add($b, ':camera:', '📷'); + Smilies::add($b, ':camera with flash:', '📸'); + Smilies::add($b, ':video camera:', '📹'); + Smilies::add($b, ':videocassette:', '📼'); + Smilies::add($b, ':magnifying glass tilted left:', '🔍'); + Smilies::add($b, ':magnifying glass tilted right:', '🔎'); + Smilies::add($b, ':candle:', '🕯'); + Smilies::add($b, ':light bulb:', '💡'); + Smilies::add($b, ':flashlight:', '🔦'); + Smilies::add($b, ':red paper lantern:', '🏮'); +// Smilies::add($b, ':diya lamp:', '🪔'); // book-paper - Smilies::add($b, ':notebook with decorative cover:', '📔'); - Smilies::add($b, ':closed book:', '📕'); - Smilies::add($b, ':open book:', '📖'); - Smilies::add($b, ':green book:', '📗'); - Smilies::add($b, ':blue book:', '📘'); - Smilies::add($b, ':orange book:', '📙'); - Smilies::add($b, ':books:', '📚'); - Smilies::add($b, ':notebook:', '📓'); - Smilies::add($b, ':ledger:', '📒'); - Smilies::add($b, ':page with curl:', '📃'); - Smilies::add($b, ':scroll:', '📜'); - Smilies::add($b, ':page facing up:', '📄'); - Smilies::add($b, ':newspaper:', '📰'); - Smilies::add($b, ':rolled-up newspaper:', '🗞'); - Smilies::add($b, ':bookmark tabs:', '📑'); - Smilies::add($b, ':bookmark:', '🔖'); - Smilies::add($b, ':label:', '🏷'); + Smilies::add($b, ':notebook with decorative cover:', '📔'); + Smilies::add($b, ':closed book:', '📕'); + Smilies::add($b, ':open book:', '📖'); + Smilies::add($b, ':green book:', '📗'); + Smilies::add($b, ':blue book:', '📘'); + Smilies::add($b, ':orange book:', '📙'); + Smilies::add($b, ':books:', '📚'); + Smilies::add($b, ':notebook:', '📓'); + Smilies::add($b, ':ledger:', '📒'); + Smilies::add($b, ':page with curl:', '📃'); + Smilies::add($b, ':scroll:', '📜'); + Smilies::add($b, ':page facing up:', '📄'); + Smilies::add($b, ':newspaper:', '📰'); + Smilies::add($b, ':rolled-up newspaper:', '🗞'); + Smilies::add($b, ':bookmark tabs:', '📑'); + Smilies::add($b, ':bookmark:', '🔖'); + Smilies::add($b, ':label:', '🏷'); // money - Smilies::add($b, ':money bag:', '💰'); - Smilies::add($b, ':yen banknote:', '💴'); - Smilies::add($b, ':dollar banknote:', '💵'); - Smilies::add($b, ':euro banknote:', '💶'); - Smilies::add($b, ':pound banknote:', '💷'); - Smilies::add($b, ':money with wings:', '💸'); - Smilies::add($b, ':credit card:', '💳'); - Smilies::add($b, ':receipt:', '🧾'); - Smilies::add($b, ':chart increasing with yen:', '💹'); + Smilies::add($b, ':money bag:', '💰'); + Smilies::add($b, ':yen banknote:', '💴'); + Smilies::add($b, ':dollar banknote:', '💵'); + Smilies::add($b, ':euro banknote:', '💶'); + Smilies::add($b, ':pound banknote:', '💷'); + Smilies::add($b, ':money with wings:', '💸'); + Smilies::add($b, ':credit card:', '💳'); + Smilies::add($b, ':receipt:', '🧾'); + Smilies::add($b, ':chart increasing with yen:', '💹'); // mail - Smilies::add($b, ':envelope:', '✉'); - Smilies::add($b, ':e-mail:', '📧'); - Smilies::add($b, ':incoming envelope:', '📨'); - Smilies::add($b, ':envelope with arrow:', '📩'); - Smilies::add($b, ':outbox tray:', '📤'); - Smilies::add($b, ':inbox tray:', '📥'); - Smilies::add($b, ':package:', '📦'); - Smilies::add($b, ':closed mailbox with raised flag:', '📫'); - Smilies::add($b, ':closed mailbox with lowered flag:', '📪'); - Smilies::add($b, ':open mailbox with raised flag:', '📬'); - Smilies::add($b, ':open mailbox with lowered flag:', '📭'); - Smilies::add($b, ':postbox:', '📮'); - Smilies::add($b, ':ballot box with ballot:', '🗳'); + Smilies::add($b, ':envelope:', '✉'); + Smilies::add($b, ':e-mail:', '📧'); + Smilies::add($b, ':incoming envelope:', '📨'); + Smilies::add($b, ':envelope with arrow:', '📩'); + Smilies::add($b, ':outbox tray:', '📤'); + Smilies::add($b, ':inbox tray:', '📥'); + Smilies::add($b, ':package:', '📦'); + Smilies::add($b, ':closed mailbox with raised flag:', '📫'); + Smilies::add($b, ':closed mailbox with lowered flag:', '📪'); + Smilies::add($b, ':open mailbox with raised flag:', '📬'); + Smilies::add($b, ':open mailbox with lowered flag:', '📭'); + Smilies::add($b, ':postbox:', '📮'); + Smilies::add($b, ':ballot box with ballot:', '🗳'); // writing - Smilies::add($b, ':pencil:', '✏'); - Smilies::add($b, ':black nib:', '✒'); - Smilies::add($b, ':fountain pen:', '🖋'); - Smilies::add($b, ':pen:', '🖊'); - Smilies::add($b, ':paintbrush:', '🖌'); - Smilies::add($b, ':crayon:', '🖍'); - Smilies::add($b, ':memo:', '📝'); + Smilies::add($b, ':pencil:', '✏'); + Smilies::add($b, ':black nib:', '✒'); + Smilies::add($b, ':fountain pen:', '🖋'); + Smilies::add($b, ':pen:', '🖊'); + Smilies::add($b, ':paintbrush:', '🖌'); + Smilies::add($b, ':crayon:', '🖍'); + Smilies::add($b, ':memo:', '📝'); // office - Smilies::add($b, ':briefcase:', '💼'); - Smilies::add($b, ':file folder:', '📁'); - Smilies::add($b, ':open file folder:', '📂'); - Smilies::add($b, ':card index dividers:', '🗂'); - Smilies::add($b, ':calendar:', '📅'); - Smilies::add($b, ':tear-off calendar:', '📆'); - Smilies::add($b, ':spiral notepad:', '🗒'); - Smilies::add($b, ':spiral calendar:', '🗓'); - Smilies::add($b, ':card index:', '📇'); - Smilies::add($b, ':chart increasing:', '📈'); - Smilies::add($b, ':chart decreasing:', '📉'); - Smilies::add($b, ':bar chart:', '📊'); - Smilies::add($b, ':clipboard:', '📋'); - Smilies::add($b, ':pushpin:', '📌'); - Smilies::add($b, ':round pushpin:', '📍'); - Smilies::add($b, ':paperclip:', '📎'); - Smilies::add($b, ':linked paperclips:', '🖇'); - Smilies::add($b, ':straight ruler:', '📏'); - Smilies::add($b, ':triangular ruler:', '📐'); - Smilies::add($b, ':scissors:', '✂'); - Smilies::add($b, ':card file box:', '🗃'); - Smilies::add($b, ':file cabinet:', '🗄'); - Smilies::add($b, ':wastebasket:', '🗑'); + Smilies::add($b, ':briefcase:', '💼'); + Smilies::add($b, ':file folder:', '📁'); + Smilies::add($b, ':open file folder:', '📂'); + Smilies::add($b, ':card index dividers:', '🗂'); + Smilies::add($b, ':calendar:', '📅'); + Smilies::add($b, ':tear-off calendar:', '📆'); + Smilies::add($b, ':spiral notepad:', '🗒'); + Smilies::add($b, ':spiral calendar:', '🗓'); + Smilies::add($b, ':card index:', '📇'); + Smilies::add($b, ':chart increasing:', '📈'); + Smilies::add($b, ':chart decreasing:', '📉'); + Smilies::add($b, ':bar chart:', '📊'); + Smilies::add($b, ':clipboard:', '📋'); + Smilies::add($b, ':pushpin:', '📌'); + Smilies::add($b, ':round pushpin:', '📍'); + Smilies::add($b, ':paperclip:', '📎'); + Smilies::add($b, ':linked paperclips:', '🖇'); + Smilies::add($b, ':straight ruler:', '📏'); + Smilies::add($b, ':triangular ruler:', '📐'); + Smilies::add($b, ':scissors:', '✂'); + Smilies::add($b, ':card file box:', '🗃'); + Smilies::add($b, ':file cabinet:', '🗄'); + Smilies::add($b, ':wastebasket:', '🗑'); // lock - Smilies::add($b, ':locked:', '🔒'); - Smilies::add($b, ':unlocked:', '🔓'); - Smilies::add($b, ':locked with pen:', '🔏'); - Smilies::add($b, ':locked with key:', '🔐'); - Smilies::add($b, ':key:', '🔑'); - Smilies::add($b, ':old key:', '🗝'); + Smilies::add($b, ':locked:', '🔒'); + Smilies::add($b, ':unlocked:', '🔓'); + Smilies::add($b, ':locked with pen:', '🔏'); + Smilies::add($b, ':locked with key:', '🔐'); + Smilies::add($b, ':key:', '🔑'); + Smilies::add($b, ':old key:', '🗝'); // tool - Smilies::add($b, ':hammer:', '🔨'); -// Smilies::add($b, ':axe:', '🪓'); - Smilies::add($b, ':pick:', '⛏'); - Smilies::add($b, ':hammer and pick:', '⚒'); - Smilies::add($b, ':hammer and wrench:', '🛠'); - Smilies::add($b, ':dagger:', '🗡'); + Smilies::add($b, ':hammer:', '🔨'); +// Smilies::add($b, ':axe:', '🪓'); + Smilies::add($b, ':pick:', '⛏'); + Smilies::add($b, ':hammer and pick:', '⚒'); + Smilies::add($b, ':hammer and wrench:', '🛠'); + Smilies::add($b, ':dagger:', '🗡'); Smilies::add($b, ':sabre:', '🗡'); - Smilies::add($b, ':crossed swords:', '⚔'); - Smilies::add($b, ':pistol:', '🔫'); - Smilies::add($b, ':bow and arrow:', '🏹'); - Smilies::add($b, ':shield:', '🛡'); - Smilies::add($b, ':wrench:', '🔧'); - Smilies::add($b, ':nut and bolt:', '🔩'); - Smilies::add($b, ':gear:', '⚙'); - Smilies::add($b, ':clamp:', '🗜'); - Smilies::add($b, ':balance scale:', '⚖'); - Smilies::add($b, ':white cane:', '🦯'); - Smilies::add($b, ':link:', '🔗'); - Smilies::add($b, ':chains:', '⛓'); - Smilies::add($b, ':toolbox:', '🧰'); - Smilies::add($b, ':magnet:', '🧲'); + Smilies::add($b, ':crossed swords:', '⚔'); + Smilies::add($b, ':pistol:', '🔫'); + Smilies::add($b, ':bow and arrow:', '🏹'); + Smilies::add($b, ':shield:', '🛡'); + Smilies::add($b, ':wrench:', '🔧'); + Smilies::add($b, ':nut and bolt:', '🔩'); + Smilies::add($b, ':gear:', '⚙'); + Smilies::add($b, ':clamp:', '🗜'); + Smilies::add($b, ':balance scale:', '⚖'); + Smilies::add($b, ':white cane:', '🦯'); + Smilies::add($b, ':link:', '🔗'); + Smilies::add($b, ':chains:', '⛓'); + Smilies::add($b, ':toolbox:', '🧰'); + Smilies::add($b, ':magnet:', '🧲'); // science - Smilies::add($b, ':alembic:', '⚗'); - Smilies::add($b, ':test tube:', '🧪'); - Smilies::add($b, ':petri dish:', '🧫'); - Smilies::add($b, ':dna:', '🧬'); - Smilies::add($b, ':microscope:', '🔬'); - Smilies::add($b, ':telescope:', '🔭'); - Smilies::add($b, ':satellite antenna:', '📡'); - Smilies::add($b, ':asterism:', '⁂'); - Smilies::add($b, ':outlines white star:', '⚝'); + Smilies::add($b, ':alembic:', '⚗'); + Smilies::add($b, ':test tube:', '🧪'); + Smilies::add($b, ':petri dish:', '🧫'); + Smilies::add($b, ':dna:', '🧬'); + Smilies::add($b, ':microscope:', '🔬'); + Smilies::add($b, ':telescope:', '🔭'); + Smilies::add($b, ':satellite antenna:', '📡'); + Smilies::add($b, ':asterism:', '⁂'); + Smilies::add($b, ':outlines white star:', '颅'); // medical - Smilies::add($b, ':syringe:', '💉'); - Smilies::add($b, ':drop of blood:', '🩸'); - Smilies::add($b, ':pill:', '💊'); - Smilies::add($b, ':adhesive bandage:', '🩹'); - Smilies::add($b, ':stethoscope:', '🩺'); + Smilies::add($b, ':syringe:', '💉'); + Smilies::add($b, ':drop of blood:', '🩸'); + Smilies::add($b, ':pill:', '💊'); + Smilies::add($b, ':adhesive bandage:', '🩹'); + Smilies::add($b, ':stethoscope:', '🩺'); // household - Smilies::add($b, ':door:', '🚪'); - Smilies::add($b, ':bed:', '🛏'); - Smilies::add($b, ':couch and lamp:', '🛋'); -// Smilies::add($b, ':chair:', '🪑'); - Smilies::add($b, ':toilet:', '🚽'); - Smilies::add($b, ':shower:', '🚿'); - Smilies::add($b, ':bathtub:', '🛁'); - Smilies::add($b, ':razor:', '🪒'); - Smilies::add($b, ':lotion bottle:', '🧴'); - Smilies::add($b, ':safety pin:', '🧷'); - Smilies::add($b, ':broom:', '🧹'); - Smilies::add($b, ':basket:', '🧺'); - Smilies::add($b, ':roll of paper:', '🧻'); - Smilies::add($b, ':soap:', '🧼'); - Smilies::add($b, ':sponge:', '🧽'); - Smilies::add($b, ':fire extinguisher:', '🧯'); - Smilies::add($b, ':shopping cart:', '🛒'); + Smilies::add($b, ':door:', '🚪'); + Smilies::add($b, ':bed:', '🛏'); + Smilies::add($b, ':couch and lamp:', '🛋'); +// Smilies::add($b, ':chair:', '🪑'); + Smilies::add($b, ':toilet:', '🚽'); + Smilies::add($b, ':shower:', '🚿'); + Smilies::add($b, ':bathtub:', '🛁'); + Smilies::add($b, ':razor:', '🪒'); + Smilies::add($b, ':lotion bottle:', '🧴'); + Smilies::add($b, ':safety pin:', '🧷'); + Smilies::add($b, ':broom:', '🧹'); + Smilies::add($b, ':basket:', '🧺'); + Smilies::add($b, ':roll of paper:', '🧻'); + Smilies::add($b, ':soap:', '🧼'); + Smilies::add($b, ':sponge:', '🧽'); + Smilies::add($b, ':fire extinguisher:', '🧯'); + Smilies::add($b, ':shopping cart:', '🛒'); // other-object - Smilies::add($b, ':cigarette:', '🚬'); - Smilies::add($b, ':coffin:', '⚰'); - Smilies::add($b, ':funeral urn:', '⚱'); - Smilies::add($b, ':moai:', '🗿'); + Smilies::add($b, ':cigarette:', '🚬'); + Smilies::add($b, ':coffin:', '⚰'); + Smilies::add($b, ':funeral urn:', '⚱'); + Smilies::add($b, ':moai:', '🗿'); // Symbols // transport-sign - Smilies::add($b, ':atm sign:', '🏧'); - Smilies::add($b, ':litter in bin sign:', '🚮'); - Smilies::add($b, ':potable water:', '🚰'); - Smilies::add($b, ':wheelchair symbol:', '♿'); - Smilies::add($b, ':men’s room:', '🚹'); - Smilies::add($b, ':women’s room:', '🚺'); - Smilies::add($b, ':restroom:', '🚻'); - Smilies::add($b, ':baby symbol:', '🚼'); - Smilies::add($b, ':water closet:', '🚾'); - Smilies::add($b, ':passport control:', '🛂'); - Smilies::add($b, ':customs:', '🛃'); - Smilies::add($b, ':baggage claim:', '🛄'); - Smilies::add($b, ':left luggage:', '🛅'); + Smilies::add($b, ':atm sign:', '🏧'); + Smilies::add($b, ':litter in bin sign:', '🚮'); + Smilies::add($b, ':potable water:', '🚰'); + Smilies::add($b, ':wheelchair symbol:', '♿'); + Smilies::add($b, ':men’s room:', '🚹'); + Smilies::add($b, ':women’s room:', '🚺'); + Smilies::add($b, ':restroom:', '🚻'); + Smilies::add($b, ':baby symbol:', '🚼'); + Smilies::add($b, ':water closet:', '🚾'); + Smilies::add($b, ':passport control:', '🛂'); + Smilies::add($b, ':customs:', '🛃'); + Smilies::add($b, ':baggage claim:', '🛄'); + Smilies::add($b, ':left luggage:', '🛅'); // warning - Smilies::add($b, ':warning:', '⚠'); - Smilies::add($b, ':children crossing:', '🚸'); - Smilies::add($b, ':no entry:', '⛔'); - Smilies::add($b, ':prohibited:', '🚫'); - Smilies::add($b, ':no bicycles:', '🚳'); - Smilies::add($b, ':no smoking:', '🚭'); - Smilies::add($b, ':no littering:', '🚯'); - Smilies::add($b, ':non-potable water:', '🚱'); - Smilies::add($b, ':no pedestrians:', '🚷'); - Smilies::add($b, ':no mobile phones:', '📵'); - Smilies::add($b, ':no one under eighteen:', '🔞'); - Smilies::add($b, ':radioactive:', '☢'); - Smilies::add($b, ':biohazard:', '☣'); + Smilies::add($b, ':warning:', '⚠'); + Smilies::add($b, ':children crossing:', '🚸'); + Smilies::add($b, ':no entry:', '⛔'); + Smilies::add($b, ':prohibited:', '🚫'); + Smilies::add($b, ':no bicycles:', '🚳'); + Smilies::add($b, ':no smoking:', '🚭'); + Smilies::add($b, ':no littering:', '🚯'); + Smilies::add($b, ':non-potable water:', '🚱'); + Smilies::add($b, ':no pedestrians:', '🚷'); + Smilies::add($b, ':no mobile phones:', '📵'); + Smilies::add($b, ':no one under eighteen:', '🔞'); + Smilies::add($b, ':radioactive:', '☢'); + Smilies::add($b, ':biohazard:', '☣'); Smilies::add($b, ':army:', '🪖'); // arrow - Smilies::add($b, ':up arrow:', '⬆'); - Smilies::add($b, ':up-right arrow:', '↗'); - Smilies::add($b, ':right arrow:', '➡'); - Smilies::add($b, ':down-right arrow:', '↘'); - Smilies::add($b, ':down arrow:', '⬇'); - Smilies::add($b, ':down-left arrow:', '↙'); - Smilies::add($b, ':left arrow:', '⬅'); - Smilies::add($b, ':up-left arrow:', '↖'); - Smilies::add($b, ':up-down arrow:', '↕'); - Smilies::add($b, ':left-right arrow:', '↔'); - Smilies::add($b, ':right arrow curving left:', '↩'); - Smilies::add($b, ':left arrow curving right:', '↪'); - Smilies::add($b, ':right arrow curving up:', '⤴'); - Smilies::add($b, ':right arrow curving down:', '⤵'); - Smilies::add($b, ':clockwise vertical arrows:', '🔃'); - Smilies::add($b, ':counterclockwise arrows button:', '🔄'); - Smilies::add($b, ':BACK arrow:', '🔙'); - Smilies::add($b, ':END arrow:', '🔚'); - Smilies::add($b, ':ON! arrow:', '🔛'); - Smilies::add($b, ':SOON arrow:', '🔜'); - Smilies::add($b, ':TOP arrow:', '🔝'); + Smilies::add($b, ':up arrow:', '⬆'); + Smilies::add($b, ':up-right arrow:', '↗'); + Smilies::add($b, ':right arrow:', '➡'); + Smilies::add($b, ':down-right arrow:', '↘'); + Smilies::add($b, ':down arrow:', '⬇'); + Smilies::add($b, ':down-left arrow:', '↙'); + Smilies::add($b, ':left arrow:', '⬅'); + Smilies::add($b, ':up-left arrow:', '↖'); + Smilies::add($b, ':up-down arrow:', '↕'); + Smilies::add($b, ':left-right arrow:', '↔'); + Smilies::add($b, ':right arrow curving left:', '↩'); + Smilies::add($b, ':left arrow curving right:', '↪'); + Smilies::add($b, ':right arrow curving up:', '⤴'); + Smilies::add($b, ':right arrow curving down:', '⤵'); + Smilies::add($b, ':clockwise vertical arrows:', '🔃'); + Smilies::add($b, ':counterclockwise arrows button:', '🔄'); + Smilies::add($b, ':BACK arrow:', '🔙'); + Smilies::add($b, ':END arrow:', '🔚'); + Smilies::add($b, ':ON! arrow:', '🔛'); + Smilies::add($b, ':SOON arrow:', '🔜'); + Smilies::add($b, ':TOP arrow:', '🔝'); // religion - Smilies::add($b, ':place of worship:', '🛐'); - Smilies::add($b, ':atom symbol:', '⚛'); - Smilies::add($b, ':om:', '🕉'); - Smilies::add($b, ':star of David:', '✡'); - Smilies::add($b, ':wheel of dharma:', '☸'); - Smilies::add($b, ':yin yang:', '☯'); - Smilies::add($b, ':latin cross:', '✝'); - Smilies::add($b, ':orthodox cross:', '☦'); - Smilies::add($b, ':star and crescent:', '☪'); - Smilies::add($b, ':peace symbol:', '☮'); - Smilies::add($b, ':menorah:', '🕎'); - Smilies::add($b, ':dotted six-pointed star:', '🔯'); + Smilies::add($b, ':place of worship:', '🛐'); + Smilies::add($b, ':atom symbol:', '⚛'); + Smilies::add($b, ':om:', '🕉'); + Smilies::add($b, ':star of David:', '✡'); + Smilies::add($b, ':wheel of dharma:', '☸'); + Smilies::add($b, ':yin yang:', '☯'); + Smilies::add($b, ':latin cross:', '✝'); + Smilies::add($b, ':orthodox cross:', '☦'); + Smilies::add($b, ':star and crescent:', '☪'); + Smilies::add($b, ':peace symbol:', '☮'); + Smilies::add($b, ':menorah:', '🕎'); + Smilies::add($b, ':dotted six-pointed star:', '🔯'); // zodiac - Smilies::add($b, ':Aries:', '♈'); - Smilies::add($b, ':Taurus:', '♉'); - Smilies::add($b, ':Gemini:', '♊'); - Smilies::add($b, ':Cancer:', '♋'); - Smilies::add($b, ':Leo:', '♌'); - Smilies::add($b, ':Virgo:', '♍'); - Smilies::add($b, ':Libra:', '♎'); - Smilies::add($b, ':Scorpio:', '♏'); - Smilies::add($b, ':Sagittarius:', '♐'); - Smilies::add($b, ':Capricorn:', '♑'); - Smilies::add($b, ':Aquarius:', '♒'); - Smilies::add($b, ':Pisces:', '♓'); - Smilies::add($b, ':Ophiuchus:', '⛎'); + Smilies::add($b, ':Aries:', '♈'); + Smilies::add($b, ':Taurus:', '♉'); + Smilies::add($b, ':Gemini:', '♊'); + Smilies::add($b, ':Cancer:', '♋'); + Smilies::add($b, ':Leo:', '♌'); + Smilies::add($b, ':Virgo:', '♍'); + Smilies::add($b, ':Libra:', '♎'); + Smilies::add($b, ':Scorpio:', '♏'); + Smilies::add($b, ':Sagittarius:', '♐'); + Smilies::add($b, ':Capricorn:', '♑'); + Smilies::add($b, ':Aquarius:', '♒'); + Smilies::add($b, ':Pisces:', '♓'); + Smilies::add($b, ':Ophiuchus:', '⛎'); // av-symbol - Smilies::add($b, ':shuffle tracks button:', '🔀'); - Smilies::add($b, ':repeat button:', '🔁'); - Smilies::add($b, ':repeat single button:', '🔂'); - Smilies::add($b, ':play button:', '▶'); - Smilies::add($b, ':fast-forward button:', '⏩'); - Smilies::add($b, ':next track button:', '⏭'); - Smilies::add($b, ':play or pause button:', '⏯'); - Smilies::add($b, ':reverse button:', '◀'); - Smilies::add($b, ':fast reverse button:', '⏪'); - Smilies::add($b, ':last track button:', '⏮'); - Smilies::add($b, ':upwards button:', '🔼'); - Smilies::add($b, ':fast up button:', '⏫'); - Smilies::add($b, ':downwards button:', '🔽'); - Smilies::add($b, ':fast down button:', '⏬'); - Smilies::add($b, ':pause button:', '⏸'); - Smilies::add($b, ':stop button:', '⏹'); - Smilies::add($b, ':record button:', '⏺'); - Smilies::add($b, ':eject button:', '⏏'); - Smilies::add($b, ':cinema:', '🎦'); - Smilies::add($b, ':dim button:', '🔅'); - Smilies::add($b, ':bright button:', '🔆'); - Smilies::add($b, ':antenna bars:', '📶'); - Smilies::add($b, ':vibration mode:', '📳'); - Smilies::add($b, ':mobile phone off:', '📴'); + Smilies::add($b, ':shuffle tracks button:', '🔀'); + Smilies::add($b, ':repeat button:', '🔁'); + Smilies::add($b, ':repeat single button:', '🔂'); + Smilies::add($b, ':play button:', '▶'); + Smilies::add($b, ':fast-forward button:', '⏩'); + Smilies::add($b, ':next track button:', '⏭'); + Smilies::add($b, ':play or pause button:', '⏯'); + Smilies::add($b, ':reverse button:', '◀'); + Smilies::add($b, ':fast reverse button:', '⏪'); + Smilies::add($b, ':last track button:', '⏮'); + Smilies::add($b, ':upwards button:', '🔼'); + Smilies::add($b, ':fast up button:', '⏫'); + Smilies::add($b, ':downwards button:', '🔽'); + Smilies::add($b, ':fast down button:', '⏬'); + Smilies::add($b, ':pause button:', '⏸'); + Smilies::add($b, ':stop button:', '⏹'); + Smilies::add($b, ':record button:', '⏺'); + Smilies::add($b, ':eject button:', '⏏'); + Smilies::add($b, ':cinema:', '🎦'); + Smilies::add($b, ':dim button:', '🔅'); + Smilies::add($b, ':bright button:', '🔆'); + Smilies::add($b, ':antenna bars:', '📶'); + Smilies::add($b, ':vibration mode:', '📳'); + Smilies::add($b, ':mobile phone off:', '📴'); // gender - Smilies::add($b, ':female sign:', '♀'); - Smilies::add($b, ':male sign:', '♂'); + Smilies::add($b, ':female sign:', '♀'); + Smilies::add($b, ':male sign:', '♂'); // math - Smilies::add($b, ':multiply:', '✖'); - Smilies::add($b, ':plus:', '➕'); - Smilies::add($b, ':minus:', '➖'); - Smilies::add($b, ':divide:', '➗'); - Smilies::add($b, ':infinity:', '♾'); + Smilies::add($b, ':multiply:', '✖'); + Smilies::add($b, ':plus:', '➕'); + Smilies::add($b, ':minus:', '➖'); + Smilies::add($b, ':divide:', '➗'); + Smilies::add($b, ':infinity:', '♾'); Smilies::add($b, ':kreisoperator:', '∘'); Smilies::add($b, ':leere menge:', '∅'); Smilies::add($b, ':rundung:', '≈'); @@ -1458,407 +1454,408 @@ function unicode_smilies_smilies(array &$b) Smilies::add($b, ':prozent:', '%'); // punctuation - Smilies::add($b, ':double exclamation mark:', '‼'); - Smilies::add($b, ':exclamation question mark:', '⁉'); - Smilies::add($b, ':question mark:', '❓'); - Smilies::add($b, ':white question mark:', '❔'); - Smilies::add($b, ':white exclamation mark:', '❕'); - Smilies::add($b, ':exclamation mark:', '❗'); - Smilies::add($b, ':wavy dash:', '〰'); + Smilies::add($b, ':double exclamation mark:', '‼'); + Smilies::add($b, ':exclamation question mark:', '⁉'); + Smilies::add($b, ':question mark:', '❓'); + Smilies::add($b, ':white question mark:', '❔'); + Smilies::add($b, ':white exclamation mark:', '❕'); + Smilies::add($b, ':exclamation mark:', '❗'); + Smilies::add($b, ':wavy dash:', '〰'); // currency - Smilies::add($b, ':currency exchange:', '💱'); - Smilies::add($b, ':heavy dollar sign:', '💲'); + Smilies::add($b, ':currency exchange:', '💱'); + Smilies::add($b, ':heavy dollar sign:', '💲'); // other-symbol - Smilies::add($b, ':medical symbol:', '⚕'); - Smilies::add($b, ':recycling symbol:', '♻'); - Smilies::add($b, ':fleur-de-lis:', '⚜'); - Smilies::add($b, ':trident emblem:', '🔱'); - Smilies::add($b, ':name badge:', '📛'); - Smilies::add($b, ':Japanese symbol for beginner:', '🔰'); - Smilies::add($b, ':hollow red circle:', '⭕'); - Smilies::add($b, ':check mark button:', '✅'); - Smilies::add($b, ':check box with check:', '☑'); - Smilies::add($b, ':check mark:', '✔'); - Smilies::add($b, ':cross mark:', '❌'); - Smilies::add($b, ':cross mark button:', '❎'); - Smilies::add($b, ':curly loop:', '➰'); - Smilies::add($b, ':double curly loop:', '➿'); - Smilies::add($b, ':part alternation mark:', '〽'); - Smilies::add($b, ':eight-spoked asterisk:', '✳'); - Smilies::add($b, ':eight-pointed star:', '✴'); - Smilies::add($b, ':sparkle:', '❇'); - Smilies::add($b, ':copyright:', '©'); - Smilies::add($b, ':registered:', '®'); - Smilies::add($b, ':trade mark:', '™'); + Smilies::add($b, ':medical symbol:', '⚕'); + Smilies::add($b, ':recycling symbol:', '♻'); + Smilies::add($b, ':fleur-de-lis:', '⚜'); + Smilies::add($b, ':trident emblem:', '🔱'); + Smilies::add($b, ':name badge:', '📛'); + Smilies::add($b, ':Japanese symbol for beginner:', '🔰'); + Smilies::add($b, ':hollow red circle:', '⭕'); + Smilies::add($b, ':check mark button:', '✅'); + Smilies::add($b, ':check box with check:', '☑'); + Smilies::add($b, ':check mark:', '✔'); + Smilies::add($b, ':cross mark:', '❌'); + Smilies::add($b, ':cross mark button:', '❎'); + Smilies::add($b, ':curly loop:', '➰'); + Smilies::add($b, ':double curly loop:', '➿'); + Smilies::add($b, ':part alternation mark:', '〽'); + Smilies::add($b, ':eight-spoked asterisk:', '✳'); + Smilies::add($b, ':eight-pointed star:', '✴'); + Smilies::add($b, ':sparkle:', '❇'); + Smilies::add($b, ':copyright:', '©'); + Smilies::add($b, ':registered:', '®'); + Smilies::add($b, ':trade mark:', '™'); // keycap - Smilies::add($b, ':keycap: #:', '#️⃣'); - Smilies::add($b, ':keycap: *:', '*️⃣'); - Smilies::add($b, ':keycap: 0:', '0️⃣'); - Smilies::add($b, ':keycap: 1:', '1️⃣'); - Smilies::add($b, ':keycap: 2:', '2️⃣'); - Smilies::add($b, ':keycap: 3:', '3️⃣'); - Smilies::add($b, ':keycap: 4:', '4️⃣'); - Smilies::add($b, ':keycap: 5:', '5️⃣'); - Smilies::add($b, ':keycap: 6:', '6️⃣'); - Smilies::add($b, ':keycap: 7:', '7️⃣'); - Smilies::add($b, ':keycap: 8:', '8️⃣'); - Smilies::add($b, ':keycap: 9:', '9️⃣'); - Smilies::add($b, ':keycap: 10:', '🔟'); + Smilies::add($b, ':keycap: #:', '#️⃣'); + Smilies::add($b, ':keycap: *:', '*️⃣'); + Smilies::add($b, ':keycap: 0:', '0️⃣'); + Smilies::add($b, ':keycap: 1:', '1️⃣'); + Smilies::add($b, ':keycap: 2:', '2️⃣'); + Smilies::add($b, ':keycap: 3:', '3️⃣'); + Smilies::add($b, ':keycap: 4:', '4️⃣'); + Smilies::add($b, ':keycap: 5:', '5️⃣'); + Smilies::add($b, ':keycap: 6:', '6️⃣'); + Smilies::add($b, ':keycap: 7:', '7️⃣'); + Smilies::add($b, ':keycap: 8:', '8️⃣'); + Smilies::add($b, ':keycap: 9:', '9️⃣'); + Smilies::add($b, ':keycap: 10:', '🔟'); // alphanum - Smilies::add($b, ':input latin uppercase:', '🔠'); - Smilies::add($b, ':input latin lowercase:', '🔡'); - Smilies::add($b, ':input numbers:', '🔢'); - Smilies::add($b, ':input symbols:', '🔣'); - Smilies::add($b, ':input latin letters:', '🔤'); - Smilies::add($b, ':A button (blood type):', '🅰'); - Smilies::add($b, ':AB button (blood type):', '🆎'); - Smilies::add($b, ':B button (blood type):', '🅱'); - Smilies::add($b, ':CL button:', '🆑'); - Smilies::add($b, ':COOL button:', '🆒'); + Smilies::add($b, ':input latin uppercase:', '🔠'); + Smilies::add($b, ':input latin lowercase:', '🔡'); + Smilies::add($b, ':input numbers:', '🔢'); + Smilies::add($b, ':input symbols:', '🔣'); + Smilies::add($b, ':input latin letters:', '🔤'); + Smilies::add($b, ':A button (blood type):', '🅰'); + Smilies::add($b, ':AB button (blood type):', '🆎'); + Smilies::add($b, ':B button (blood type):', '🅱'); + Smilies::add($b, ':CL button:', '🆑'); + Smilies::add($b, ':COOL button:', '🆒'); Smilies::add($b, ':cool:', '🆒'); - Smilies::add($b, ':FREE button:', '🆓'); - Smilies::add($b, ':information:', 'ℹ'); - Smilies::add($b, ':ID button:', '🆔'); - Smilies::add($b, ':circled M:', 'Ⓜ'); - Smilies::add($b, ':NEW button:', '🆕'); - Smilies::add($b, ':NG button:', '🆖'); - Smilies::add($b, ':O button (blood type):', '🅾'); - Smilies::add($b, ':OK button:', '🆗'); - Smilies::add($b, ':P button:', '🅿'); - Smilies::add($b, ':SOS button:', '🆘'); - Smilies::add($b, ':UP! button:', '🆙'); - Smilies::add($b, ':VS button:', '🆚'); - Smilies::add($b, ':Japanese “here” button:', '🈁'); - Smilies::add($b, ':Japanese “service charge” button:', '🈂'); - Smilies::add($b, ':Japanese “monthly amount” button:', '🈷'); - Smilies::add($b, ':Japanese “not free of charge” button:', '🈶'); - Smilies::add($b, ':Japanese “reserved” button:', '🈯'); - Smilies::add($b, ':Japanese “bargain” button:', '🉐'); - Smilies::add($b, ':Japanese “discount” button:', '🈹'); - Smilies::add($b, ':Japanese “free of charge” button:', '🈚'); - Smilies::add($b, ':Japanese “prohibited” button:', '🈲'); - Smilies::add($b, ':Japanese “acceptable” button:', '🉑'); - Smilies::add($b, ':Japanese “application” button:', '🈸'); - Smilies::add($b, ':Japanese “passing grade” button:', '🈴'); - Smilies::add($b, ':Japanese “vacancy” button:', '🈳'); - Smilies::add($b, ':Japanese “congratulations” button:', '㊗'); - Smilies::add($b, ':Japanese “secret” button:', '㊙'); - Smilies::add($b, ':Japanese “open for business” button:', '🈺'); - Smilies::add($b, ':Japanese “no vacancy” button:', '🈵'); + Smilies::add($b, ':FREE button:', '🆓'); + Smilies::add($b, ':information:', 'ℹ'); + Smilies::add($b, ':ID button:', '🆔'); + Smilies::add($b, ':circled M:', 'Ⓜ'); + Smilies::add($b, ':NEW button:', '🆕'); + Smilies::add($b, ':NG button:', '🆖'); + Smilies::add($b, ':O button (blood type):', '🅾'); + Smilies::add($b, ':OK button:', '🆗'); + Smilies::add($b, ':P button:', '🅿'); + Smilies::add($b, ':SOS button:', '🆘'); + Smilies::add($b, ':UP! button:', '🆙'); + Smilies::add($b, ':VS button:', '🆚'); + Smilies::add($b, ':Japanese “here” button:', '🈁'); + Smilies::add($b, ':Japanese “service charge” button:', '🈂'); + Smilies::add($b, ':Japanese “monthly amount” button:', '🈷'); + Smilies::add($b, ':Japanese “not free of charge” button:', '🈶'); + Smilies::add($b, ':Japanese “reserved” button:', '🈯'); + Smilies::add($b, ':Japanese “bargain” button:', '🉐'); + Smilies::add($b, ':Japanese “discount” button:', '🈹'); + Smilies::add($b, ':Japanese “free of charge” button:', '🈚'); + Smilies::add($b, ':Japanese “prohibited” button:', '🈲'); + Smilies::add($b, ':Japanese “acceptable” button:', '🉑'); + Smilies::add($b, ':Japanese “application” button:', '🈸'); + Smilies::add($b, ':Japanese “passing grade” button:', '🈴'); + Smilies::add($b, ':Japanese “vacancy” button:', '🈳'); + Smilies::add($b, ':Japanese “congratulations” button:', '㊗'); + Smilies::add($b, ':Japanese “secret” button:', '㊙'); + Smilies::add($b, ':Japanese “open for business” button:', '🈺'); + Smilies::add($b, ':Japanese “no vacancy” button:', '🈵'); // geometric - Smilies::add($b, ':red circle:', '🔴'); -// Smilies::add($b, ':orange circle:', '🟠'); -// Smilies::add($b, ':yellow circle:', '🟡'); -// Smilies::add($b, ':green circle:', '🟢'); - Smilies::add($b, ':blue circle:', '🔵'); -// Smilies::add($b, ':purple circle:', '🟣'); -// Smilies::add($b, ':brown circle:', '🟤'); - Smilies::add($b, ':black circle:', '⚫'); - Smilies::add($b, ':white circle:', '⚪'); -// Smilies::add($b, ':red square:', '🟥'); -// Smilies::add($b, ':orange square:', '🟧'); -// Smilies::add($b, ':yellow square:', '🟨'); -// Smilies::add($b, ':green square:', '🟩'); -// Smilies::add($b, ':blue square:', '🟦'); -// Smilies::add($b, ':purple square:', '🟪'); -// Smilies::add($b, ':brown square:', '🟫'); - Smilies::add($b, ':black large square:', '⬛'); - Smilies::add($b, ':white large square:', '⬜'); - Smilies::add($b, ':black medium square:', '◼'); - Smilies::add($b, ':white medium square:', '◻'); - Smilies::add($b, ':black medium-small square:', '◾'); - Smilies::add($b, ':white medium-small square:', '◽'); - Smilies::add($b, ':black small square:', '▪'); - Smilies::add($b, ':white small square:', '▫'); - Smilies::add($b, ':large orange diamond:', '🔶'); - Smilies::add($b, ':large blue diamond:', '🔷'); - Smilies::add($b, ':small orange diamond:', '🔸'); - Smilies::add($b, ':small blue diamond:', '🔹'); - Smilies::add($b, ':red triangle pointed up:', '🔺'); - Smilies::add($b, ':red triangle pointed down:', '🔻'); - Smilies::add($b, ':diamond with a dot:', '💠'); - Smilies::add($b, ':radio button:', '🔘'); - Smilies::add($b, ':white square button:', '🔳'); - Smilies::add($b, ':black square button:', '🔲'); + Smilies::add($b, ':red circle:', '🔴'); +// Smilies::add($b, ':orange circle:', '🟠'); +// Smilies::add($b, ':yellow circle:', '🟡'); +// Smilies::add($b, ':green circle:', '🟢'); + Smilies::add($b, ':blue circle:', '🔵'); +// Smilies::add($b, ':purple circle:', '🟣'); +// Smilies::add($b, ':brown circle:', '🟤'); + Smilies::add($b, ':black circle:', '⚫'); + Smilies::add($b, ':white circle:', '⚪'); +// Smilies::add($b, ':red square:', '🟥'); +// Smilies::add($b, ':orange square:', '🟧'); +// Smilies::add($b, ':yellow square:', '🟨'); +// Smilies::add($b, ':green square:', '🟩'); +// Smilies::add($b, ':blue square:', '🟦'); +// Smilies::add($b, ':purple square:', '🟪'); +// Smilies::add($b, ':brown square:', '🟫'); + Smilies::add($b, ':black large square:', '⬛'); + Smilies::add($b, ':white large square:', '⬜'); + Smilies::add($b, ':black medium square:', '◼'); + Smilies::add($b, ':white medium square:', '◻'); + Smilies::add($b, ':black medium-small square:', '◾'); + Smilies::add($b, ':white medium-small square:', '◽'); + Smilies::add($b, ':black small square:', '▪'); + Smilies::add($b, ':white small square:', '▫'); + Smilies::add($b, ':large orange diamond:', '🔶'); + Smilies::add($b, ':large blue diamond:', '🔷'); + Smilies::add($b, ':small orange diamond:', '🔸'); + Smilies::add($b, ':small blue diamond:', '🔹'); + Smilies::add($b, ':red triangle pointed up:', '🔺'); + Smilies::add($b, ':red triangle pointed down:', '🔻'); + Smilies::add($b, ':diamond with a dot:', '💠'); + Smilies::add($b, ':radio button:', '🔘'); + Smilies::add($b, ':white square button:', '🔳'); + Smilies::add($b, ':black square button:', '🔲'); // Flags // flag - Smilies::add($b, ':chequered flag:', '🏁'); - Smilies::add($b, ':triangular flag:', '🚩'); - Smilies::add($b, ':crossed flags:', '🎌'); - Smilies::add($b, ':black flag:', '🏴'); - Smilies::add($b, ':white flag:', '🏳'); - Smilies::add($b, ':rainbow flag:', '🏳️‍🌈'); - Smilies::add($b, ':pirate flag:', '🏴‍☠️'); + Smilies::add($b, ':chequered flag:', '🏁'); + Smilies::add($b, ':triangular flag:', '🚩'); + Smilies::add($b, ':crossed flags:', '🎌'); + Smilies::add($b, ':black flag:', '🏴'); + Smilies::add($b, ':white flag:', '🏳'); + Smilies::add($b, ':rainbow flag:', '🏳️‍🌈'); + Smilies::add($b, ':pirate flag:', '🏴‍☠️'); // country-flag - Smilies::add($b, ':ascension island:', '🇦🇨'); - Smilies::add($b, ':andorra:', '🇦🇩'); - Smilies::add($b, ':united arab emirates:', '🇦🇪'); - Smilies::add($b, ':afghanistan:', '🇦🇫'); - Smilies::add($b, ':antigua & barbuda:', '🇦🇬'); - Smilies::add($b, ':anguilla:', '🇦🇮'); - Smilies::add($b, ':albania:', '🇦🇱'); - Smilies::add($b, ':armenia:', '🇦🇲'); - Smilies::add($b, ':angola:', '🇦🇴'); - Smilies::add($b, ':antarctica:', '🇦🇶'); - Smilies::add($b, ':argentina:', '🇦🇷'); - Smilies::add($b, ':americansamoa:', '🇦🇸'); - Smilies::add($b, ':austria:', '🇦🇹'); - Smilies::add($b, ':australia:', '🇦🇺'); - Smilies::add($b, ':aruba:', '🇦🇼'); - Smilies::add($b, ':ålandislands:', '🇦🇽'); - Smilies::add($b, ':azerbaijan:', '🇦🇿'); - Smilies::add($b, ':bosnia&herzegovina:', '🇧🇦'); - Smilies::add($b, ':barbados:', '🇧🇧'); - Smilies::add($b, ':bangladesh:', '🇧🇩'); - Smilies::add($b, ':belgium:', '🇧🇪'); - Smilies::add($b, ':burkinafaso:', '🇧🇫'); - Smilies::add($b, ':bulgaria:', '🇧🇬'); - Smilies::add($b, ':bahrain:', '🇧🇭'); - Smilies::add($b, ':burundi:', '🇧🇮'); - Smilies::add($b, ':benin:', '🇧🇯'); - Smilies::add($b, ':st.barthélemy:', '🇧🇱'); - Smilies::add($b, ':bermuda:', '🇧🇲'); - Smilies::add($b, ':brunei:', '🇧🇳'); - Smilies::add($b, ':bolivia:', '🇧🇴'); - Smilies::add($b, ':caribbeannetherlands:', '🇧🇶'); - Smilies::add($b, ':brazil:', '🇧🇷'); - Smilies::add($b, ':bahamas:', '🇧🇸'); - Smilies::add($b, ':bhutan:', '🇧🇹'); - Smilies::add($b, ':bouvetisland:', '🇧🇻'); - Smilies::add($b, ':botswana:', '🇧🇼'); - Smilies::add($b, ':belarus:', '🇧🇾'); - Smilies::add($b, ':belize:', '🇧🇿'); - Smilies::add($b, ':canada:', '🇨🇦'); - Smilies::add($b, ':cocos(keeling)islands:', '🇨🇨'); - Smilies::add($b, ':congo-kinshasa:', '🇨🇩'); - Smilies::add($b, ':centralafricanrepublic:', '🇨🇫'); - Smilies::add($b, ':congo-brazzaville:', '🇨🇬'); - Smilies::add($b, ':switzerland:', '🇨🇭'); - Smilies::add($b, ':côted’ivoire:', '🇨🇮'); - Smilies::add($b, ':cookislands:', '🇨🇰'); - Smilies::add($b, ':chile:', '🇨🇱'); - Smilies::add($b, ':cameroon:', '🇨🇲'); - Smilies::add($b, ':china:', '🇨🇳'); - Smilies::add($b, ':colombia:', '🇨🇴'); - Smilies::add($b, ':clippertonisland:', '🇨🇵'); - Smilies::add($b, ':costarica:', '🇨🇷'); - Smilies::add($b, ':cuba:', '🇨🇺'); - Smilies::add($b, ':capeverde:', '🇨🇻'); - Smilies::add($b, ':curaçao:', '🇨🇼'); - Smilies::add($b, ':christmasisland:', '🇨🇽'); - Smilies::add($b, ':cyprus:', '🇨🇾'); - Smilies::add($b, ':czechia:', '🇨🇿'); - Smilies::add($b, ':germany:', '🇩🇪'); - Smilies::add($b, ':diegogarcia:', '🇩🇬'); - Smilies::add($b, ':djibouti:', '🇩🇯'); - Smilies::add($b, ':denmark:', '🇩🇰'); - Smilies::add($b, ':dominica:', '🇩🇲'); - Smilies::add($b, ':dominicanrepublic:', '🇩🇴'); - Smilies::add($b, ':algeria:', '🇩🇿'); - Smilies::add($b, ':ceuta&melilla:', '🇪🇦'); - Smilies::add($b, ':ecuador:', '🇪🇨'); - Smilies::add($b, ':estonia:', '🇪🇪'); - Smilies::add($b, ':egypt:', '🇪🇬'); - Smilies::add($b, ':westernsahara:', '🇪🇭'); - Smilies::add($b, ':eritrea:', '🇪🇷'); - Smilies::add($b, ':spain:', '🇪🇸'); - Smilies::add($b, ':ethiopia:', '🇪🇹'); - Smilies::add($b, ':europeanunion:', '🇪🇺'); - Smilies::add($b, ':finland:', '🇫🇮'); - Smilies::add($b, ':fiji:', '🇫🇯'); - Smilies::add($b, ':falklandislands:', '🇫🇰'); - Smilies::add($b, ':micronesia:', '🇫🇲'); - Smilies::add($b, ':faroeislands:', '🇫🇴'); - Smilies::add($b, ':france:', '🇫🇷'); - Smilies::add($b, ':gabon:', '🇬🇦'); - Smilies::add($b, ':unitedkingdom:', '🇬🇧'); - Smilies::add($b, ':grenada:', '🇬🇩'); - Smilies::add($b, ':georgia:', '🇬🇪'); - Smilies::add($b, ':frenchguiana:', '🇬🇫'); - Smilies::add($b, ':guernsey:', '🇬🇬'); - Smilies::add($b, ':ghana:', '🇬🇭'); - Smilies::add($b, ':gibraltar:', '🇬🇮'); - Smilies::add($b, ':greenland:', '🇬🇱'); - Smilies::add($b, ':gambia:', '🇬🇲'); - Smilies::add($b, ':guinea:', '🇬🇳'); - Smilies::add($b, ':guadeloupe:', '🇬🇵'); - Smilies::add($b, ':equatorialguinea:', '🇬🇶'); - Smilies::add($b, ':greece:', '🇬🇷'); - Smilies::add($b, ':southgeorgia&southsandwichislands:', '🇬🇸'); - Smilies::add($b, ':guatemala:', '🇬🇹'); - Smilies::add($b, ':guam:', '🇬🇺'); - Smilies::add($b, ':guinea-bissau:', '🇬🇼'); - Smilies::add($b, ':guyana:', '🇬🇾'); - Smilies::add($b, ':hongkongsarchina:', '🇭🇰'); - Smilies::add($b, ':heard&mcdonaldislands:', '🇭🇲'); - Smilies::add($b, ':honduras:', '🇭🇳'); - Smilies::add($b, ':croatia:', '🇭🇷'); - Smilies::add($b, ':haiti:', '🇭🇹'); - Smilies::add($b, ':hungary:', '🇭🇺'); - Smilies::add($b, ':canaryislands:', '🇮🇨'); - Smilies::add($b, ':indonesia:', '🇮🇩'); - Smilies::add($b, ':ireland:', '🇮🇪'); - Smilies::add($b, ':israel:', '🇮🇱'); - Smilies::add($b, ':isleofman:', '🇮🇲'); - Smilies::add($b, ':india:', '🇮🇳'); - Smilies::add($b, ':britishindianoceanterritory:', '🇮🇴'); - Smilies::add($b, ':iraq:', '🇮🇶'); - Smilies::add($b, ':iran:', '🇮🇷'); - Smilies::add($b, ':iceland:', '🇮🇸'); - Smilies::add($b, ':italy:', '🇮🇹'); - Smilies::add($b, ':jersey:', '🇯🇪'); - Smilies::add($b, ':jamaica:', '🇯🇲'); - Smilies::add($b, ':jordan:', '🇯🇴'); - Smilies::add($b, ':japan:', '🇯🇵'); - Smilies::add($b, ':kenya:', '🇰🇪'); - Smilies::add($b, ':kyrgyzstan:', '🇰🇬'); - Smilies::add($b, ':cambodia:', '🇰🇭'); - Smilies::add($b, ':kiribati:', '🇰🇮'); - Smilies::add($b, ':comoros:', '🇰🇲'); - Smilies::add($b, ':st.kitts&nevis:', '🇰🇳'); - Smilies::add($b, ':northkorea:', '🇰🇵'); - Smilies::add($b, ':southkorea:', '🇰🇷'); - Smilies::add($b, ':kuwait:', '🇰🇼'); - Smilies::add($b, ':caymanislands:', '🇰🇾'); - Smilies::add($b, ':kazakhstan:', '🇰🇿'); - Smilies::add($b, ':laos:', '🇱🇦'); - Smilies::add($b, ':lebanon:', '🇱🇧'); - Smilies::add($b, ':st.lucia:', '🇱🇨'); - Smilies::add($b, ':liechtenstein:', '🇱🇮'); - Smilies::add($b, ':srilanka:', '🇱🇰'); - Smilies::add($b, ':liberia:', '🇱🇷'); - Smilies::add($b, ':lesotho:', '🇱🇸'); - Smilies::add($b, ':lithuania:', '🇱🇹'); - Smilies::add($b, ':luxembourg:', '🇱🇺'); - Smilies::add($b, ':latvia:', '🇱🇻'); - Smilies::add($b, ':libya:', '🇱🇾'); - Smilies::add($b, ':morocco:', '🇲🇦'); - Smilies::add($b, ':monaco:', '🇲🇨'); - Smilies::add($b, ':moldova:', '🇲🇩'); - Smilies::add($b, ':montenegro:', '🇲🇪'); - Smilies::add($b, ':st.martin:', '🇲🇫'); - Smilies::add($b, ':madagascar:', '🇲🇬'); - Smilies::add($b, ':marshallislands:', '🇲🇭'); - Smilies::add($b, ':northmacedonia:', '🇲🇰'); - Smilies::add($b, ':mali:', '🇲🇱'); - Smilies::add($b, ':myanmar(burma):', '🇲🇲'); - Smilies::add($b, ':mongolia:', '🇲🇳'); - Smilies::add($b, ':macaosarchina:', '🇲🇴'); - Smilies::add($b, ':northernmarianaislands:', '🇲🇵'); - Smilies::add($b, ':martinique:', '🇲🇶'); - Smilies::add($b, ':mauritania:', '🇲🇷'); - Smilies::add($b, ':montserrat:', '🇲🇸'); - Smilies::add($b, ':malta:', '🇲🇹'); - Smilies::add($b, ':mauritius:', '🇲🇺'); - Smilies::add($b, ':maldives:', '🇲🇻'); - Smilies::add($b, ':malawi:', '🇲🇼'); - Smilies::add($b, ':mexico:', '🇲🇽'); - Smilies::add($b, ':malaysia:', '🇲🇾'); - Smilies::add($b, ':mozambique:', '🇲🇿'); - Smilies::add($b, ':namibia:', '🇳🇦'); - Smilies::add($b, ':newcaledonia:', '🇳🇨'); - Smilies::add($b, ':niger:', '🇳🇪'); - Smilies::add($b, ':norfolkisland:', '🇳🇫'); - Smilies::add($b, ':nigeria:', '🇳🇬'); - Smilies::add($b, ':nicaragua:', '🇳🇮'); - Smilies::add($b, ':netherlands:', '🇳🇱'); - Smilies::add($b, ':norway:', '🇳🇴'); - Smilies::add($b, ':nepal:', '🇳🇵'); - Smilies::add($b, ':nauru:', '🇳🇷'); - Smilies::add($b, ':niue:', '🇳🇺'); - Smilies::add($b, ':newzealand:', '🇳🇿'); - Smilies::add($b, ':oman:', '🇴🇲'); - Smilies::add($b, ':panama:', '🇵🇦'); - Smilies::add($b, ':peru:', '🇵🇪'); - Smilies::add($b, ':frenchpolynesia:', '🇵🇫'); - Smilies::add($b, ':papuanewguinea:', '🇵🇬'); - Smilies::add($b, ':philippines:', '🇵🇭'); - Smilies::add($b, ':pakistan:', '🇵🇰'); - Smilies::add($b, ':poland:', '🇵🇱'); - Smilies::add($b, ':st.pierre&miquelon:', '🇵🇲'); - Smilies::add($b, ':pitcairnislands:', '🇵🇳'); - Smilies::add($b, ':puertorico:', '🇵🇷'); - Smilies::add($b, ':palestinianterritories:', '🇵🇸'); - Smilies::add($b, ':portugal:', '🇵🇹'); - Smilies::add($b, ':palau:', '🇵🇼'); - Smilies::add($b, ':paraguay:', '🇵🇾'); - Smilies::add($b, ':qatar:', '🇶🇦'); - Smilies::add($b, ':réunion:', '🇷🇪'); - Smilies::add($b, ':romania:', '🇷🇴'); - Smilies::add($b, ':serbia:', '🇷🇸'); - Smilies::add($b, ':russia:', '🇷🇺'); - Smilies::add($b, ':rwanda:', '🇷🇼'); - Smilies::add($b, ':saudiarabia:', '🇸🇦'); - Smilies::add($b, ':solomonislands:', '🇸🇧'); - Smilies::add($b, ':seychelles:', '🇸🇨'); - Smilies::add($b, ':sudan:', '🇸🇩'); - Smilies::add($b, ':sweden:', '🇸🇪'); - Smilies::add($b, ':singapore:', '🇸🇬'); - Smilies::add($b, ':st.helena:', '🇸🇭'); - Smilies::add($b, ':slovenia:', '🇸🇮'); - Smilies::add($b, ':svalbard&janmayen:', '🇸🇯'); - Smilies::add($b, ':slovakia:', '🇸🇰'); - Smilies::add($b, ':sierraleone:', '🇸🇱'); - Smilies::add($b, ':sanmarino:', '🇸🇲'); - Smilies::add($b, ':senegal:', '🇸🇳'); - Smilies::add($b, ':somalia:', '🇸🇴'); - Smilies::add($b, ':suriname:', '🇸🇷'); - Smilies::add($b, ':southsudan:', '🇸🇸'); - Smilies::add($b, ':sãotomé&príncipe:', '🇸🇹'); - Smilies::add($b, ':elsalvador:', '🇸🇻'); - Smilies::add($b, ':sintmaarten:', '🇸🇽'); - Smilies::add($b, ':syria:', '🇸🇾'); - Smilies::add($b, ':eswatini:', '🇸🇿'); - Smilies::add($b, ':tristandacunha:', '🇹🇦'); - Smilies::add($b, ':turks&caicosislands:', '🇹🇨'); - Smilies::add($b, ':chad:', '🇹🇩'); - Smilies::add($b, ':frenchsouthernterritories:', '🇹🇫'); - Smilies::add($b, ':togo:', '🇹🇬'); - Smilies::add($b, ':thailand:', '🇹🇭'); - Smilies::add($b, ':tajikistan:', '🇹🇯'); - Smilies::add($b, ':tokelau:', '🇹🇰'); - Smilies::add($b, ':timor-leste:', '🇹🇱'); - Smilies::add($b, ':turkmenistan:', '🇹🇲'); - Smilies::add($b, ':tunisia:', '🇹🇳'); - Smilies::add($b, ':tonga:', '🇹🇴'); - Smilies::add($b, ':turkey:', '🇹🇷'); - Smilies::add($b, ':trinidad&tobago:', '🇹🇹'); - Smilies::add($b, ':tuvalu:', '🇹🇻'); - Smilies::add($b, ':taiwan:', '🇹🇼'); - Smilies::add($b, ':tanzania:', '🇹🇿'); - Smilies::add($b, ':ukraine:', '🇺🇦'); - Smilies::add($b, ':uganda:', '🇺🇬'); - Smilies::add($b, ':u.s.outlyingislands:', '🇺🇲'); - Smilies::add($b, ':unitednations:', '🇺🇳'); - Smilies::add($b, ':unitedstates:', '🇺🇸'); - Smilies::add($b, ':uruguay:', '🇺🇾'); - Smilies::add($b, ':uzbekistan:', '🇺🇿'); - Smilies::add($b, ':vaticancity:', '🇻🇦'); - Smilies::add($b, ':st.vincent&grenadines:', '🇻🇨'); - Smilies::add($b, ':venezuela:', '🇻🇪'); - Smilies::add($b, ':britishvirginislands:', '🇻🇬'); - Smilies::add($b, ':u.s.virginislands:', '🇻🇮'); - Smilies::add($b, ':vietnam:', '🇻🇳'); - Smilies::add($b, ':vanuatu:', '🇻🇺'); - Smilies::add($b, ':wallis&futuna:', '🇼🇫'); - Smilies::add($b, ':samoa:', '🇼🇸'); - Smilies::add($b, ':kosovo:', '🇽🇰'); - Smilies::add($b, ':yemen:', '🇾🇪'); - Smilies::add($b, ':mayotte:', '🇾🇹'); - Smilies::add($b, ':southafrica:', '🇿🇦'); - Smilies::add($b, ':zambia:', '🇿🇲'); - Smilies::add($b, ':zimbabwe:', '🇿🇼'); + Smilies::add($b, ':ascension island:', '🇦🇨'); + Smilies::add($b, ':andorra:', '🇦🇩'); + Smilies::add($b, ':united arab emirates:', '🇦🇪'); + Smilies::add($b, ':afghanistan:', '🇦🇫'); + Smilies::add($b, ':antigua & barbuda:', '🇦🇬'); + Smilies::add($b, ':anguilla:', '🇦🇮'); + Smilies::add($b, ':albania:', '🇦🇱'); + Smilies::add($b, ':armenia:', '🇦🇲'); + Smilies::add($b, ':angola:', '🇦🇴'); + Smilies::add($b, ':antarctica:', '🇦🇶'); + Smilies::add($b, ':argentina:', '🇦🇷'); + Smilies::add($b, ':americansamoa:', '🇦🇸'); + Smilies::add($b, ':austria:', '🇦🇹'); + Smilies::add($b, ':australia:', '🇦🇺'); + Smilies::add($b, ':aruba:', '🇦🇼'); + Smilies::add($b, ':ålandislands:', '🇦🇽'); + Smilies::add($b, ':azerbaijan:', '🇦🇿'); + Smilies::add($b, ':bosnia&herzegovina:', '🇧🇦'); + Smilies::add($b, ':barbados:', '🇧🇧'); + Smilies::add($b, ':bangladesh:', '🇧🇩'); + Smilies::add($b, ':belgium:', '🇧🇪'); + Smilies::add($b, ':burkinafaso:', '🇧🇫'); + Smilies::add($b, ':bulgaria:', '🇧🇬'); + Smilies::add($b, ':bahrain:', '🇧🇭'); + Smilies::add($b, ':burundi:', '🇧🇮'); + Smilies::add($b, ':benin:', '🇧🇯'); + Smilies::add($b, ':st.barthélemy:', '🇧🇱'); + Smilies::add($b, ':bermuda:', '🇧🇲'); + Smilies::add($b, ':brunei:', '🇧🇳'); + Smilies::add($b, ':bolivia:', '🇧🇴'); + Smilies::add($b, ':caribbeannetherlands:', '🇧🇶'); + Smilies::add($b, ':brazil:', '🇧🇷'); + Smilies::add($b, ':bahamas:', '🇧🇸'); + Smilies::add($b, ':bhutan:', '🇧🇹'); + Smilies::add($b, ':bouvetisland:', '🇧🇻'); + Smilies::add($b, ':botswana:', '🇧🇼'); + Smilies::add($b, ':belarus:', '🇧🇾'); + Smilies::add($b, ':belize:', '🇧🇿'); + Smilies::add($b, ':canada:', '🇨🇦'); + Smilies::add($b, ':cocos(keeling)islands:', '🇨🇨'); + Smilies::add($b, ':congo-kinshasa:', '🇨🇩'); + Smilies::add($b, ':centralafricanrepublic:', '🇨🇫'); + Smilies::add($b, ':congo-brazzaville:', '🇨🇬'); + Smilies::add($b, ':switzerland:', '🇨🇭'); + Smilies::add($b, ':côted’ivoire:', '🇨🇮'); + Smilies::add($b, ':cookislands:', '🇨🇰'); + Smilies::add($b, ':chile:', '🇨🇱'); + Smilies::add($b, ':cameroon:', '🇨🇲'); + Smilies::add($b, ':china:', '🇨🇳'); + Smilies::add($b, ':colombia:', '🇨🇴'); + Smilies::add($b, ':clippertonisland:', '🇨🇵'); + Smilies::add($b, ':costarica:', '🇨🇷'); + Smilies::add($b, ':cuba:', '🇨🇺'); + Smilies::add($b, ':capeverde:', '🇨🇻'); + Smilies::add($b, ':curaçao:', '🇨🇼'); + Smilies::add($b, ':christmasisland:', '🇨🇽'); + Smilies::add($b, ':cyprus:', '🇨🇾'); + Smilies::add($b, ':czechia:', '🇨🇿'); + Smilies::add($b, ':germany:', '🇩🇪'); + Smilies::add($b, ':diegogarcia:', '🇩🇬'); + Smilies::add($b, ':djibouti:', '🇩🇯'); + Smilies::add($b, ':denmark:', '🇩🇰'); + Smilies::add($b, ':dominica:', '🇩🇲'); + Smilies::add($b, ':dominicanrepublic:', '🇩🇴'); + Smilies::add($b, ':algeria:', '🇩🇿'); + Smilies::add($b, ':ceuta&melilla:', '🇪🇦'); + Smilies::add($b, ':ecuador:', '🇪🇨'); + Smilies::add($b, ':estonia:', '🇪🇪'); + Smilies::add($b, ':egypt:', '🇪🇬'); + Smilies::add($b, ':westernsahara:', '🇪🇭'); + Smilies::add($b, ':eritrea:', '🇪🇷'); + Smilies::add($b, ':spain:', '🇪🇸'); + Smilies::add($b, ':ethiopia:', '🇪🇹'); + Smilies::add($b, ':europeanunion:', '🇪🇺'); + Smilies::add($b, ':finland:', '🇫🇮'); + Smilies::add($b, ':fiji:', '🇫🇯'); + Smilies::add($b, ':falklandislands:', '🇫🇰'); + Smilies::add($b, ':micronesia:', '🇫🇲'); + Smilies::add($b, ':faroeislands:', '🇫🇴'); + Smilies::add($b, ':france:', '🇫🇷'); + Smilies::add($b, ':gabon:', '🇬🇦'); + Smilies::add($b, ':unitedkingdom:', '🇬🇧'); + Smilies::add($b, ':grenada:', '🇬🇩'); + Smilies::add($b, ':georgia:', '🇬🇪'); + Smilies::add($b, ':frenchguiana:', '🇬🇫'); + Smilies::add($b, ':guernsey:', '🇬🇬'); + Smilies::add($b, ':ghana:', '🇬🇭'); + Smilies::add($b, ':gibraltar:', '🇬🇮'); + Smilies::add($b, ':greenland:', '🇬🇱'); + Smilies::add($b, ':gambia:', '🇬🇲'); + Smilies::add($b, ':guinea:', '🇬🇳'); + Smilies::add($b, ':guadeloupe:', '🇬🇵'); + Smilies::add($b, ':equatorialguinea:', '🇬🇶'); + Smilies::add($b, ':greece:', '🇬,;🇷'); + Smilies::add($b, ':southgeorgia&southsandwichislands:', '🇬🇸'); + Smilies::add($b, ':guatemala:', '🇬🇹'); + Smilies::add($b, ':guam:', '🇬🇺'); + Smilies::add($b, ':guinea-bissau:', '🇬🇼'); + Smilies::add($b, ':guyana:', '🇬🇾'); + Smilies::add($b, ':hongkongsarchina:', '🇭🇰'); + Smilies::add($b, ':heard&mcdonaldislands:', '🇭🇲'); + Smilies::add($b, ':honduras:', '🇭🇳'); + Smilies::add($b, ':croatia:', '🇭🇷'); + Smilies::add($b, ':haiti:', '🇭🇹'); + Smilies::add($b, ':hungary:', '🇭🇺'); + Smilies::add($b, ':canaryislands:', '🇮🇨'); + Smilies::add($b, ':indonesia:', '🇮🇩'); + Smilies::add($b, ':ireland:', '🇮🇪'); + Smilies::add($b, ':israel:', '🇮🇱'); + Smilies::add($b, ':isleofman:', '🇮🇲'); + Smilies::add($b, ':india:', '🇮🇳'); + Smilies::add($b, ':britishindianoceanterritory:', '🇮🇴'); + Smilies::add($b, ':iraq:', '🇮🇶'); + Smilies::add($b, ':iran:', '🇮🇷'); + Smilies::add($b, ':iceland:', '🇮🇸'); + Smilies::add($b, ':italy:', '🇮🇹'); + Smilies::add($b, ':jersey:', '🇯🇪'); + Smilies::add($b, ':jamaica:', '🇯🇲'); + Smilies::add($b, ':jordan:', '🇯🇴'); + Smilies::add($b, ':japan:', '🇯🇵'); + Smilies::add($b, ':kenya:', '🇰🇪'); + Smilies::add($b, ':kyrgyzstan:', '🇰🇬'); + Smilies::add($b, ':cambodia:', '🇰🇭'); + Smilies::add($b, ':kiribati:', '🇰🇮'); + Smilies::add($b, ':comoros:', '🇰🇲'); + Smilies::add($b, ':st.kitts&nevis:', '🇰🇳'); + Smilies::add($b, ':northkorea:', '🇰🇵'); + Smilies::add($b, ':southkorea:', '🇰🇷'); + Smilies::add($b, ':kuwait:', '🇰🇼'); + Smilies::add($b, ':caymanislands:', '🇰🇾'); + Smilies::add($b, ':kazakhstan:', '🇰🇿'); + Smilies::add($b, ':laos:', '🇱🇦'); + Smilies::add($b, ':lebanon:', '🇱🇧'); + Smilies::add($b, ':st.lucia:', '🇱🇨'); + Smilies::add($b, ':liechtenstein:', '🇱🇮'); + Smilies::add($b, ':srilanka:', '🇱🇰'); + Smilies::add($b, ':liberia:', '🇱🇷'); + Smilies::add($b, ':lesotho:', '🇱🇸'); + Smilies::add($b, ':lithuania:', '🇱🇹'); + Smilies::add($b, ':luxembourg:', '🇱🇺'); + Smilies::add($b, ':latvia:', '🇱🇻'); + Smilies::add($b, ':libya:', '🇱🇾'); + Smilies::add($b, ':morocco:', '🇲🇦'); + Smilies::add($b, ':monaco:', '🇲🇨'); + Smilies::add($b, ':moldova:', '🇲🇩'); + Smilies::add($b, ':montenegro:', '🇲🇪'); + Smilies::add($b, ':st.martin:', '🇲🇫'); + Smilies::add($b, ':madagascar:', '🇲🇬'); + Smilies::add($b, ':marshallislands:', '🇲🇭'); + Smilies::add($b, ':northmacedonia:', '🇲🇰'); + Smilies::add($b, ':mali:', '🇲🇱'); + Smilies::add($b, ':myanmar(burma):', '🇲🇲'); + Smilies::add($b, ':mongolia:', '🇲🇳'); + Smilies::add($b, ':macaosarchina:', '🇲🇴'); + Smilies::add($b, ':northernmarianaislands:', '🇲🇵'); + Smilies::add($b, ':martinique:', '🇲🇶'); + Smilies::add($b, ':mauritania:', '🇲🇷'); + Smilies::add($b, ':montserrat:', '🇲🇸'); + Smilies::add($b, ':malta:', '🇲🇹'); + Smilies::add($b, ':mauritius:', '🇲🇺'); + Smilies::add($b, ':maldives:', '🇲🇻'); + Smilies::add($b, ':malawi:', '🇲🇼'); + Smilies::add($b, ':mexico:', '🇲🇽'); + Smilies::add($b, ':malaysia:', '🇲🇾'); + Smilies::add($b, ':mozambique:', '🇲🇿'); + Smilies::add($b, ':namibia:', '🇳🇦'); + Smilies::add($b, ':newcaledonia:', '🇳🇨'); + Smilies::add($b, ':niger:', '🇳🇪'); + Smilies::add($b, ':norfolkisland:', '🇳🇫'); + Smilies::add($b, ':nigeria:', '🇳🇬'); + Smilies::add($b, ':nicaragua:', '🇳🇮'); + Smilies::add($b, ':netherlands:', '🇳🇱'); + Smilies::add($b, ':norway:', '🇳🇴'); + Smilies::add($b, ':nepal:', '🇳🇵'); + Smilies::add($b, ':nauru:', '🇳🇷'); + Smilies::add($b, ':niue:', '🇳🇺'); + Smilies::add($b, ':newzealand:', '🇳🇿'); + Smilies::add($b, ':oman:', '🇴🇲'); + Smilies::add($b, ':panama:', '🇵🇦'); + Smilies::add($b, ':peru:', '🇵🇪'); + Smilies::add($b, ':frenchpolynesia:', '🇵🇫'); + Smilies::add($b, ':papuanewguinea:', '🇵🇬'); + Smilies::add($b, ':philippines:', '🇵🇭'); + Smilies::add($b, ':pakistan:', '🇵🇰'); + Smilies::add($b, ':poland:', '🇵🇱'); + Smilies::add($b, ':st.pierre&miquelon:', '🇵🇲'); + Smilies::add($b, ':pitcairnislands:', '🇵🇳'); + Smilies::add($b, ':puertorico:', '🇵🇷'); + Smilies::add($b, ':palestinianterritories:', '🇵🇸'); + Smilies::add($b, ':portugal:', '🇵🇹'); + Smilies::add($b, ':palau:', '🇵🇼'); + Smilies::add($b, ':paraguay:', '🇵🇾'); + Smilies::add($b, ':qatar:', '🇶🇦'); + Smilies::add($b, ':réunion:', '🇷🇪'); + Smilies::add($b, ':romania:', '🇷🇴'); + Smilies::add($b, ':serbia:', '🇷🇸'); + Smilies::add($b, ':russia:', '🇷🇺'); + Smilies::add($b, ':rwanda:', '🇷🇼'); + Smilies::add($b, ':saudiarabia:', '🇸🇦'); + Smilies::add($b, ':solomonislands:', '🇸🇧'); + Smilies::add($b, ':seychelles:', '🇸🇨'); + Smilies::add($b, ':sudan:', '🇸🇩'); + Smilies::add($b, ':sweden:', '🇸🇪'); + Smilies::add($b, ':singapore:', '🇸🇬'); + Smilies::add($b, ':st.helena:', '🇸🇭'); + Smilies::add($b, ':slovenia:', '🇸🇮'); + Smilies::add($b, ':svalbard&janmayen:', '🇸🇯'); + Smilies::add($b, ':slovakia:', '🇸🇰'); + Smilies::add($b, ':sierraleone:', '🇸🇱'); + Smilies::add($b, ':sanmarino:', '🇸🇲'); + Smilies::add($b, ':senegal:', '🇸🇳'); + Smilies::add($b, ':somalia:', '🇸🇴'); + Smilies::add($b, ':suriname:', '🇸🇷'); + Smilies::add($b, ':southsudan:', '🇸🇸'); + Smilies::add($b, ':sãotomé&príncipe:', '🇸🇹'); + Smilies::add($b, ':elsalvador:', '🇸🇻'); + Smilies::add($b, ':sintmaarten:', '🇸🇽'); + Smilies::add($b, ':syria:', '🇸🇾'); + Smilies::add($b, ':eswatini:', '🇸🇿'); + Smilies::add($b, ':tristandacunha:', '🇹🇦'); + Smilies::add($b, ':turks&caicosislands:', '🇹🇨'); + Smilies::add($b, ':chad:', '🇹🇩'); + Smilies::add($b, ':frenchsouthernterritories:', '🇹🇫'); + Smilies::add($b, ':togo:', '🇹🇬'); + Smilies::add($b, ':thailand:', '🇹🇭'); + Smilies::add($b, ':tajikistan:', '🇹🇯'); + Smilies::add($b, ':tokelau:', '🇹🇰'); + Smilies::add($b, ':timor-leste:', '🇹🇱'); + Smilies::add($b, ':turkmenistan:', '🇹🇲'); + Smilies::add($b, ':tunisia:', '🇹🇳'); + Smilies::add($b, ':tonga:', '🇹🇴'); + Smilies::add($b, ':turkey:', '🇹🇷'); + Smilies::add($b, ':trinidad&tobago:', '🇹🇹'); + Smilies::add($b, ':tuvalu:', '🇹🇻'); + Smilies::add($b, ':taiwan:', '🇹🇼'); + Smilies::add($b, ':tanzania:', '🇹🇿'); + Smilies::add($b, ':ukraine:', '🇺🇦'); + Smilies::add($b, ':uganda:', '🇺🇬'); + Smilies::add($b, ':u.s.outlyingislands:', '🇺🇲'); + Smilies::add($b, ':unitednations:', '🇺🇳'); + Smilies::add($b, ':unitedstates:', '🇺🇸'); + Smilies::add($b, ':uruguay:', '🇺🇾'); + Smilies::add($b, ':uzbekistan:', '🇺🇿'); + Smilies::add($b, ':vaticancity:', '🇻🇦'); + Smilies::add($b, ':st.vincent&grenadines:', '🇻🇨'); + Smilies::add($b, ':venezuela:', '🇻🇪'); + Smilies::add($b, ':britishvirginislands:', '🇻🇬'); + Smilies::add($b, ':u.s.virginislands:', '🇻🇮'); + Smilies::add($b, ':vietnam:', '🇻🇳'); + Smilies::add($b, ':vanuatu:', '🇻🇺'); + Smilies::add($b, ':wallis&futuna:', '🇼🇫'); + Smilies::add($b, ':samoa:', '🇼🇸'); + Smilies::add($b, ':kosovo:', '🇽🇰'); + Smilies::add($b, ':yemen:', '🇾🇪'); + Smilies::add($b, ':mayotte:', '🇾🇹'); + Smilies::add($b, ':southafrica:', '🇿🇦'); + Smilies::add($b, ':zambia:', '🇿🇲'); + Smilies::add($b, ':zimbabwe:', '🇿🇼'); // subdivision-flag - Smilies::add($b, ':england:', '🏴󠁧󠁢󠁥󠁮󠁧󠁿'); - Smilies::add($b, ':scotland:', '🏴󠁧󠁢󠁳󠁴󠁿'); - Smilies::add($b, ':wales:', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'); + Smilies::add($b, ':england:', '🏴󠁧󠁢󠁥󠁮󠁧󠁿'); + Smilies::add($b, ':scotland:', '🏴󠁧󠁢󠁳󠁴󠁿'); + Smilies::add($b, ':wales:', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'); } + From 0697f078f11af094ec8455d1ec9e59ec63cd66d0 Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 22 Dec 2024 08:38:17 +0100 Subject: [PATCH 206/294] [CI] Fix codecov --- .woodpecker/.phpunit.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 887e897e..3f713d19 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -98,9 +98,9 @@ pipeline: - friendica/friendica-addons commands: - codecov -R '.' -Z -f 'clover.xml' - secrets: - - source: codecov-token - target: codecov_token + environment: + codecov_token: + from_secret: codecov-token services: mariadb: From 5f50fd2498b58787f8671c3e6cff6658d9dd38dd Mon Sep 17 00:00:00 2001 From: Philipp Date: Sun, 22 Dec 2024 08:54:51 +0100 Subject: [PATCH 207/294] Fix codecov token env --- .woodpecker/.phpunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 3f713d19..6acbf787 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -99,7 +99,7 @@ pipeline: commands: - codecov -R '.' -Z -f 'clover.xml' environment: - codecov_token: + CODECOV_TOKEN: from_secret: codecov-token services: From 9e1f7dc468b3e615e2345b691b89ecfc80364f87 Mon Sep 17 00:00:00 2001 From: Michael Date: Fri, 27 Dec 2024 10:26:20 +0000 Subject: [PATCH 208/294] Bluesky: Preparation to be able to fetch AT links --- bluesky/bluesky.php | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index d6b7624b..1355f000 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -97,27 +97,25 @@ function bluesky_item_by_link(array &$hookData) return; } - $token = DI::atProtocol()->getUserToken($hookData['uid']); - if (empty($token)) { - return; + if (substr($hookData['uri'], 0, 5) != 'at://') { + if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { + return; + } + + $did = DI::atProtocol()->getDid($matches[1]); + if (empty($did)) { + return; + } + + Logger::debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); + + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; + } else { + $uri = $hookData['uri']; } - // @todo also support the URI format (at://did/app.bsky.feed.post/cid) - if (!preg_match('#^' . ATProtocol::WEB . '/profile/(.+)/post/(.+)#', $hookData['uri'], $matches)) { - return; - } - - $did = DI::atProtocol()->getDid($matches[1]); - if (empty($did)) { - return; - } - - Logger::debug('Found bluesky post', ['url' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - - $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; - $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); - Logger::debug('Got post', ['did' => $did, 'cid' => $matches[2], 'result' => $uri]); + Logger::debug('Got post', ['uri' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { From 995e81e951a7525f4aa9bbceb661dd0fc8e548ae Mon Sep 17 00:00:00 2001 From: Philipp Date: Wed, 1 Jan 2025 20:06:43 +0100 Subject: [PATCH 209/294] [CI] Fix releaser --- .woodpecker/.code_standards_check.yml | 2 +- .woodpecker/.continuous-deployment.yml | 2 +- .woodpecker/.messages.po_check.yml | 2 +- .woodpecker/.phpunit.yml | 2 +- .woodpecker/.releaser.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index fb5be33c..50872d4c 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.continuous-deployment.yml b/.woodpecker/.continuous-deployment.yml index 4d3bc5b7..6b41deae 100644 --- a/.woodpecker/.continuous-deployment.yml +++ b/.woodpecker/.continuous-deployment.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.messages.po_check.yml b/.woodpecker/.messages.po_check.yml index aa40ab4e..e0239dcd 100644 --- a/.woodpecker/.messages.po_check.yml +++ b/.woodpecker/.messages.po_check.yml @@ -1,6 +1,6 @@ skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.phpunit.yml b/.woodpecker/.phpunit.yml index 6acbf787..8b840f80 100644 --- a/.woodpecker/.phpunit.yml +++ b/.woodpecker/.phpunit.yml @@ -17,7 +17,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: diff --git a/.woodpecker/.releaser.yml b/.woodpecker/.releaser.yml index f12697b9..2d880a6b 100644 --- a/.woodpecker/.releaser.yml +++ b/.woodpecker/.releaser.yml @@ -5,7 +5,7 @@ labels: skip_clone: true -pipeline: +steps: clone_friendica_base: image: alpine/git commands: From d034e311cbe5c45f808baf0c88efd88c484acd76 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 5 Jan 2025 21:51:37 +0100 Subject: [PATCH 210/294] Ratioed: add help link --- ratioed/templates/ratioed.tpl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 0d81b0d7..5d92bff2 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -2,7 +2,10 @@
-

{{$title}} - {{$page}} ({{$count}})

+

+ {{$title}} - {{$page}} ({{$count}}) + +

{{$h_newuser}}

From 8e65141cb5e04be141ee0489d28aa8be62155553 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 5 Jan 2025 21:57:18 +0100 Subject: [PATCH 211/294] Ratioed: bump version number --- ratioed/ratioed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 8ae0d48c..581ef89b 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -2,7 +2,7 @@ /** * Name: Ratioed * Description: Additional moderation user table with statistics about user behaviour - * Version: 0.1 + * Version: 0.2 * Author: Matthew Exon */ From 2ef9cb8add8bc28a5d6dea9f40276abea2814d97 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:36:06 +0100 Subject: [PATCH 212/294] Ratioed: fill in zeroes for empty values --- ratioed/RatioedPanel.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index bd9b44dc..dac71752 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -175,8 +175,10 @@ class RatioedPanel extends Active $user['ratioed'] = (float)($user['ratio']) >= 2.0; } else { + $user['reactions'] = 0; if ($user['comments'] == 0) { - $user['ratio'] = '0'; + $user['comments'] = 0; + $user['ratio'] = 0; $user['ratioed'] = false; } else { From d495810b2daf9e278cf317df9a12702b136d131c Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:36:38 +0100 Subject: [PATCH 213/294] Ratioed: allow both sorting directions --- ratioed/RatioedPanel.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index dac71752..08d94167 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -70,10 +70,10 @@ class RatioedPanel extends Active $order = 'last-item'; $order_direction = '-'; - if (!empty($request['o'])) { - $new_order = $request['o']; - if ($new_order[0] === '-') { - $order_direction = '-'; + if (!empty($_REQUEST['o'])) { + $new_order = $_REQUEST['o']; + if ($new_order[0] === '+') { + $order_direction = '+'; $new_order = substr($new_order, 1); } From 81639ff61574c38769c3693bec6054b1b27bfefc Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:38:29 +0100 Subject: [PATCH 214/294] Ratioed: fix sorting by columns --- ratioed/templates/ratioed.tpl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 5d92bff2..d634993e 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -22,9 +22,9 @@
- + {{if $order_users == $th.1}} {{if $order_direction_users == "+"}} ↓ @@ -66,11 +66,7 @@ {{$u.login_date}}{{$u.lastitem_date}}
From b360b553eddf3a7ad01c06f7b050b1a69734cdc7 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 20:07:18 +0100 Subject: [PATCH 216/294] Ratioed: remove actions --- ratioed/RatioedPanel.php | 30 ++++-------------------------- ratioed/templates/ratioed.tpl | 26 ++------------------------ 2 files changed, 6 insertions(+), 50 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 08d94167..19f6dd44 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -24,7 +24,6 @@ class RatioedPanel extends Active return Renderer::replaceMacros($template, array('$config' => DI::baseUrl() . '/settings/addon')); } - $action = $this->parameters['action'] ?? ''; $uid = $this->parameters['uid'] ?? 0; $user = []; @@ -32,31 +31,10 @@ class RatioedPanel extends Active $user = User::getById($uid, ['username', 'blocked']); if (!$user) { $this->systemMessages->addNotice($this->t('User not found')); - $this->baseUrl->redirect('moderation/users'); + $this->baseUrl->redirect('ratioed'); } } - switch ($action) { - case 'delete': - if ($this->session->getLocalUserId() != $uid) { - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - // delete user - User::remove($uid); - - $this->systemMessages->addNotice($this->t('User "%s" deleted', $user['username'])); - } else { - $this->systemMessages->addNotice($this->t('You can\'t remove yourself')); - } - - $this->baseUrl->redirect('moderation/users/active'); - break; - case 'block': - self::checkFormSecurityTokenRedirectOnError('moderation/users/active', 'moderation_users_active', 't'); - User::block($uid); - $this->systemMessages->addNotice($this->t('User "%s" blocked', $user['username'])); - $this->baseUrl->redirect('moderation/users/active'); - break; - } $pager = new Pager($this->l10n, $this->args->getQueryString(), 100); $valid_orders = [ @@ -69,11 +47,11 @@ class RatioedPanel extends Active ]; $order = 'last-item'; - $order_direction = '-'; + $order_direction = '+'; if (!empty($_REQUEST['o'])) { $new_order = $_REQUEST['o']; - if ($new_order[0] === '+') { - $order_direction = '+'; + if ($new_order[0] === '-') { + $order_direction = '-'; $new_order = substr($new_order, 1); } diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index c64cb1dc..24ae20b8 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -11,12 +11,7 @@
- + {{foreach $th_users as $k=>$th}} {{if $k < 2 || $order_users == $th.1 || ($k==4 && !in_array($order_users,[$th_users.2.1, $th_users.3.1, $th_users.5.1])) }} @@ -42,16 +37,7 @@ {{foreach $users as $u}} - + @@ -151,14 +137,6 @@ {{/foreach}}
-
- - -
-
- {{if $u.is_deletable}} -
- - -
- {{else}} -   - {{/if}} -
{{$u.name}} {{$u.email}}
- {{$pager nofilter}} From 3441c9bd0e7bcf713b5358a3d316c091af1c459a Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sun, 5 Jan 2025 00:23:51 +0100 Subject: [PATCH 217/294] Ratioed: add statistics about reply likes and reply guy score --- ratioed/RatioedPanel.php | 137 ++++++++++++++++++++++++++++++++++ ratioed/templates/help.tpl | 57 +++++++++++++- ratioed/templates/ratioed.tpl | 2 +- 3 files changed, 192 insertions(+), 4 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 19f6dd44..33a009cd 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -8,7 +8,9 @@ use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\User; +use Friendica\Model\Verb; use Friendica\Module\Moderation\Users\Active; +use Friendica\Protocol\Activity; /** * This class implements the "Behaviour" panel in Moderation/Users @@ -75,6 +77,11 @@ class RatioedPanel extends Active $this->t('Comments last 24h'), $this->t('Reactions last 24h'), $this->t('Ratio last 24h'), + $this->t('Replies last month'), + $this->t('Reply likes'), + $this->t('Respondee likes'), + $this->t('OP likes'), + $this->t('Reply guy score'), ]; $field_names = [ 'name', @@ -87,6 +94,11 @@ class RatioedPanel extends Active 'comments', 'reactions', 'ratio', + 'reply_count', + 'reply_likes', + 'reply_respondee_likes', + 'reply_op_likes', + 'reply_guy_score', ]; $th_users = array_map(null, $header_titles, $valid_orders, $field_names); @@ -125,6 +137,129 @@ class RatioedPanel extends Active ]); } + protected function getReplyGuyRow($contact_uid) + { + $like_vid = Verb::getID(Activity::LIKE); + $post_vid = Verb::getID(Activity::POST); + + /* + * This is a complicated query. + * + * The innermost select retrieves a chain of four posts: an + * original post, a target comment (possibly deep down in the + * thread), a reply from our user, and a like for that reply. + * If there's no like, we still want to count the reply, so we + * use an outer join. + * + * The second select adds "points" for different kinds of + * likes. The outermost select then counts up these points, + * and the number of distinct replies. + */ + $reply_guy_result = DBA::p(' +SELECT + COUNT(distinct reply_id) AS replies_total, + SUM(like_point) AS like_total, + SUM(target_like_point) AS target_like_total, + SUM(original_like_point) AS original_like_total +FROM ( + SELECT + reply_id, + like_date, + like_date IS NOT NULL AS like_point, + like_author = target_author AS target_like_point, + like_author = original_author AS original_like_point + FROM ( + SELECT + original_post.`uri-id` AS original_id, + original_post.`author-id` AS original_author, + original_post.created AS original_date, + target_post.`uri-id` AS target_id, + target_post.`author-id` AS target_author, + target_post.created AS target_date, + reply_post.`uri-id` AS reply_id, + reply_post.`author-id` AS reply_author, + reply_post.created AS reply_date, + like_post.`uri-id` AS like_id, + like_post.`author-id` AS like_author, + like_post.created AS like_date + FROM + post AS original_post + JOIN + post AS target_post + ON + original_post.`uri-id` = target_post.`parent-uri-id` + JOIN + post AS reply_post + ON + target_post.`uri-id` = reply_post.`thr-parent-id` AND + reply_post.`author-id` = ? AND + reply_post.`author-id` != target_post.`author-id` AND + reply_post.`author-id` != original_post.`author-id` AND + reply_post.`uri-id` != reply_post.`thr-parent-id` AND + reply_post.vid = ? AND + reply_post.created > CURDATE() - INTERVAL 1 MONTH + LEFT OUTER JOIN + post AS like_post + ON + reply_post.`uri-id` = like_post.`thr-parent-id` AND + like_post.vid = ? AND + like_post.`author-id` != reply_post.`author-id` + ) AS post_meta +) AS reply_counts +', $contact_uid, $post_vid, $like_vid); + return $reply_guy_result; + } + + // https://stackoverflow.com/a/48283297/235936 + protected function sigFig($value, $digits) + { + if ($value == 0) { + $decimalPlaces = $digits - 1; + } elseif ($value < 0) { + $decimalPlaces = $digits - floor(log10($value * -1)) - 1; + } else { + $decimalPlaces = $digits - floor(log10($value)) - 1; + } + + $answer = ($decimalPlaces > 0) ? + number_format($value, $decimalPlaces) : round($value, $decimalPlaces); + return $answer; + } + + protected function fillReplyGuyData(&$user) { + $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); + if (DBA::isResult($reply_guy_result)) { + $reply_guy_result_row = DBA::fetch($reply_guy_result); + $user['reply_count'] = $reply_guy_result_row['replies_total'] ?? 0; + $user['reply_likes'] = $reply_guy_result_row['like_total'] ?? 0; + $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; + $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; + + $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + if ($user['reply_count'] == 0) { + $user['reply_guy'] = false; + $user['reply_guy_score'] = 0; + } + elseif ($denominator == 0) { + $user['reply_guy'] = true; + $user['reply_guy_score'] = '∞'; + } + else { + $reply_guy_score = $user['reply_count'] / $denominator; + $user['reply_guy'] = $reply_guy_score >= 1.0; + $user['reply_guy_score'] = $this->sigFig($reply_guy_score, 2); + } + } + else { + $user['reply_count'] = "error"; + $user['reply_likes'] = "error"; + $user['reply_respondee_likes'] = "error"; + $user['reply_op_likes'] = "error"; + $user['reply_guy'] = false; + $user['reply_guy_score'] = 0; + } + } + protected function setupUserCallback(): \Closure { Logger::debug("ratioed: setupUserCallback"); @@ -179,6 +314,8 @@ class RatioedPanel extends Active $user['ratioed'] = false; } + $this->fillReplyGuyData($user); + $user = $parentCallback($user); Logger::debug("ratioed: setupUserCallback", [ 'uid' => $user['uid'], diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl index fee47e34..db6480cf 100644 --- a/ratioed/templates/help.tpl +++ b/ratioed/templates/help.tpl @@ -2,7 +2,7 @@

Ratioed Plugin Help

- This plugin provides administrators with additional statistics about + This plugin provides moderators with additional statistics about the behaviour of users. These may be useful as early warning signs that warrant more carefully watching the behaviour of a user. They are not suitable as a trigger for instantly blocking, @@ -28,7 +28,7 @@

This plugin allows viewing of an actual ratio, calculated over the last 24 hours. This is a useful timeframe for sudden dogpiling - events that administrators might not otherwise notice. The plugin + events that moderators might not otherwise notice. The plugin also calculates other statistics.

Explanation of Statistics

@@ -68,10 +68,61 @@ 24h". It is intended to approximate the traditional ratio as understood on Twitter.

+

Replies last month

+

+ This is the number of times the user posted a reply to someone any time in the last month. +

+

Reply likes

+

+ This is the number of likes received by the user on their + replies to other people's posts in the last month. Replies that + receive likes can be assumed to be more of a valuable + contribution than replies that do not. +

+

Respondee likes

+

+ The number of times in the last month the user replied to + someone else's comment and that person then liked the reply. + Likes to replies are not necessarily a positive thing, but if + the person you're replying to approves the reply, that's a very + good sign. Of course it's also common in a debate for neither + side to like the other side's comments, but the debate still can + be valuable. +

+

OP likes

+

+ The number of times in the last month the user replied on a + thread and the original poster that started the thread liked the + reply. While there is no formal concept of "ownership" of a + thread, conventionally the original poster is assumed to have + started the thread for a reason, and making replies that do not + fulfil that purpose are bad etiquette. Getting approval from + the original poster therefore is a good sign that the user is + posting replies that are wanted. +

+

Reply guy score

+

+ A "reply + guy" is a common Internet phenomenon of people (disproportionately male) + posting unwanted comments on other (disproportionately female) + people's threads, derailing the + conversation. This score loosely approximates this phenomenon, + as the ratio betwen the number of replies and the sum of likes, + respondee likes, and OP likes. This formula gives extra weight + to particularly relevant likes: a reply to a top-level post that + is liked by the original poster scores the maximum of 3 + "points". A score above 1.0 might indicate cause for concern + for moderators. +

+

+ Since this is indicative of long-term behaviour, the score is + calculated over a month instead of 24 hours. +

+

Performance

The statistics are computed from scratch each time the page loads. - It's possible that this might put a heavy load on the database. and + It's possible that this might put a heavy load on the database, and the page may take a long time to load.

Extending

diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 24ae20b8..6ee6b1d0 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -36,7 +36,7 @@ {{foreach $users as $u}} - + {{$u.name}} From 8ba4cd5f6140a1ad64ad5404e603ed76b8d535f3 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Sat, 11 Jan 2025 19:42:03 +0100 Subject: [PATCH 218/294] Ratioed: bump version number --- ratioed/ratioed.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 581ef89b..443fdaa9 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -2,7 +2,7 @@ /** * Name: Ratioed * Description: Additional moderation user table with statistics about user behaviour - * Version: 0.2 + * Version: 0.3 * Author: Matthew Exon */ From 807598dbd03b9dca3c3ac7d890fe0cb2f8a1bb9f Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Wed, 15 Jan 2025 19:32:55 +0100 Subject: [PATCH 219/294] Ratioed: wrap long lines --- ratioed/templates/help.tpl | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ratioed/templates/help.tpl b/ratioed/templates/help.tpl index db6480cf..0d012ca7 100644 --- a/ratioed/templates/help.tpl +++ b/ratioed/templates/help.tpl @@ -70,7 +70,9 @@

Replies last month

- This is the number of times the user posted a reply to someone any time in the last month. + This is the number of times the user posted a reply to someone + else, on a thread the user did not start, any time in the last + month.

Reply likes

@@ -86,8 +88,8 @@ Likes to replies are not necessarily a positive thing, but if the person you're replying to approves the reply, that's a very good sign. Of course it's also common in a debate for neither - side to like the other side's comments, but the debate still can - be valuable. + side to like the other side's comments without that indicating + an unhealthy interaction, so interpret this statistic cautiously.

OP likes

@@ -103,10 +105,10 @@

Reply guy score

A "reply - guy" is a common Internet phenomenon of people (disproportionately male) - posting unwanted comments on other (disproportionately female) - people's threads, derailing the - conversation. This score loosely approximates this phenomenon, + guy" is a common Internet phenomenon of people + (disproportionately male) posting unwanted comments on other + (disproportionately female) people's threads, derailing the + conversation. This score loosely quantifies this phenomenon, as the ratio betwen the number of replies and the sum of likes, respondee likes, and OP likes. This formula gives extra weight to particularly relevant likes: a reply to a top-level post that From ee8c852d38cd74ca770a8d2445c4975607260bfc Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Wed, 15 Jan 2025 19:33:11 +0100 Subject: [PATCH 220/294] Ratioed: remove action buttons --- ratioed/templates/ratioed.tpl | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/ratioed/templates/ratioed.tpl b/ratioed/templates/ratioed.tpl index 6ee6b1d0..2413ed9d 100644 --- a/ratioed/templates/ratioed.tpl +++ b/ratioed/templates/ratioed.tpl @@ -121,18 +121,7 @@ {{/foreach}} - - {{if $u.is_deletable}} - - - - - - - {{else}} -   - {{/if}} - + {{/foreach}} From cb70a4eaffa1e603c5a910211118deab02e519e8 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 18 Jan 2025 15:25:50 +0000 Subject: [PATCH 221/294] Fix codestyle --- ratioed/RatioedPanel.php | 111 ++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 33a009cd..d0fac8ad 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -163,47 +163,47 @@ SELECT SUM(original_like_point) AS original_like_total FROM ( SELECT - reply_id, - like_date, - like_date IS NOT NULL AS like_point, - like_author = target_author AS target_like_point, - like_author = original_author AS original_like_point + reply_id, + like_date, + like_date IS NOT NULL AS like_point, + like_author = target_author AS target_like_point, + like_author = original_author AS original_like_point FROM ( - SELECT - original_post.`uri-id` AS original_id, - original_post.`author-id` AS original_author, - original_post.created AS original_date, - target_post.`uri-id` AS target_id, - target_post.`author-id` AS target_author, - target_post.created AS target_date, - reply_post.`uri-id` AS reply_id, - reply_post.`author-id` AS reply_author, - reply_post.created AS reply_date, - like_post.`uri-id` AS like_id, - like_post.`author-id` AS like_author, - like_post.created AS like_date - FROM - post AS original_post - JOIN - post AS target_post - ON - original_post.`uri-id` = target_post.`parent-uri-id` - JOIN - post AS reply_post - ON - target_post.`uri-id` = reply_post.`thr-parent-id` AND - reply_post.`author-id` = ? AND - reply_post.`author-id` != target_post.`author-id` AND - reply_post.`author-id` != original_post.`author-id` AND - reply_post.`uri-id` != reply_post.`thr-parent-id` AND - reply_post.vid = ? AND - reply_post.created > CURDATE() - INTERVAL 1 MONTH - LEFT OUTER JOIN - post AS like_post - ON - reply_post.`uri-id` = like_post.`thr-parent-id` AND - like_post.vid = ? AND - like_post.`author-id` != reply_post.`author-id` + SELECT + original_post.`uri-id` AS original_id, + original_post.`author-id` AS original_author, + original_post.created AS original_date, + target_post.`uri-id` AS target_id, + target_post.`author-id` AS target_author, + target_post.created AS target_date, + reply_post.`uri-id` AS reply_id, + reply_post.`author-id` AS reply_author, + reply_post.created AS reply_date, + like_post.`uri-id` AS like_id, + like_post.`author-id` AS like_author, + like_post.created AS like_date + FROM + post AS original_post + JOIN + post AS target_post + ON + original_post.`uri-id` = target_post.`parent-uri-id` + JOIN + post AS reply_post + ON + target_post.`uri-id` = reply_post.`thr-parent-id` AND + reply_post.`author-id` = ? AND + reply_post.`author-id` != target_post.`author-id` AND + reply_post.`author-id` != original_post.`author-id` AND + reply_post.`uri-id` != reply_post.`thr-parent-id` AND + reply_post.vid = ? AND + reply_post.created > CURDATE() - INTERVAL 1 MONTH + LEFT OUTER JOIN + post AS like_post + ON + reply_post.`uri-id` = like_post.`thr-parent-id` AND + like_post.vid = ? AND + like_post.`author-id` != reply_post.`author-id` ) AS post_meta ) AS reply_counts ', $contact_uid, $post_vid, $like_vid); @@ -226,7 +226,8 @@ FROM ( return $answer; } - protected function fillReplyGuyData(&$user) { + protected function fillReplyGuyData(&$user) + { $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); if (DBA::isResult($reply_guy_result)) { $reply_guy_result_row = DBA::fetch($reply_guy_result); @@ -235,22 +236,19 @@ FROM ( $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; - $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + $denominator = (int)($user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']); if ($user['reply_count'] == 0) { $user['reply_guy'] = false; $user['reply_guy_score'] = 0; - } - elseif ($denominator == 0) { + } elseif ($denominator == 0) { $user['reply_guy'] = true; $user['reply_guy_score'] = '∞'; - } - else { + } else { $reply_guy_score = $user['reply_count'] / $denominator; $user['reply_guy'] = $reply_guy_score >= 1.0; $user['reply_guy_score'] = $this->sigFig($reply_guy_score, 2); } - } - else { + } else { $user['reply_count'] = "error"; $user['reply_likes'] = "error"; $user['reply_respondee_likes'] = "error"; @@ -272,9 +270,8 @@ FROM ( if (DBA::isResult($self_contact_result)) { $self_contact_result_row = DBA::fetch($self_contact_result); $user['user_contact_uid'] = $self_contact_result_row['user_contact_uid']; - } - else { - $user['user_contact_uid'] = NULL; + } else { + $user['user_contact_uid'] = null; } if ($user['user_contact_uid']) { @@ -286,28 +283,24 @@ FROM ( if ($user['reactions'] > 0) { $user['ratio'] = number_format($user['comments'] / $user['reactions'], 1, '.', ''); $user['ratioed'] = (float)($user['ratio']) >= 2.0; - } - else { + } else { $user['reactions'] = 0; if ($user['comments'] == 0) { $user['comments'] = 0; $user['ratio'] = 0; $user['ratioed'] = false; - } - else { + } else { $user['ratio'] = '∞'; $user['ratioed'] = false; } } - } - else { + } else { $user['comments'] = 'error'; $user['reactions'] = 'error'; $user['ratio'] = 'error'; $user['ratioed'] = false; } - } - else { + } else { $user['comments'] = 'error'; $user['reactions'] = 'error'; $user['ratio'] = 'error'; From 0d0aae36cd1a5a646ddbad15e1a4f548d6f14073 Mon Sep 17 00:00:00 2001 From: Matthew Exon Date: Wed, 22 Jan 2025 08:30:30 +0100 Subject: [PATCH 222/294] Clean up phpstan warning --- ratioed/RatioedPanel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index d0fac8ad..b611b256 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -236,7 +236,7 @@ FROM ( $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; - $denominator = (int)($user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']); + $denominator = intval($user['reply_likes']) + intval($user['reply_respondee_likes']) + intval($user['reply_op_likes']); if ($user['reply_count'] == 0) { $user['reply_guy'] = false; $user['reply_guy_score'] = 0; From 2741227bfa8bb174d29a69399403f72b94e00ba2 Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 08:42:18 +0000 Subject: [PATCH 223/294] Add phpstan in woodpacker --- .woodpecker/.code_standards_check.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.woodpecker/.code_standards_check.yml b/.woodpecker/.code_standards_check.yml index 50872d4c..60a1bd2a 100644 --- a/.woodpecker/.code_standards_check.yml +++ b/.woodpecker/.code_standards_check.yml @@ -56,6 +56,10 @@ steps: - /tmp/drone-cache:/tmp/cache when: event: pull_request + phpstan: + image: friendicaci/php8.3:php8.3.3 + commands: + - ./bin/composer.phar run phpstan; check: image: friendicaci/php-cs commands: From 7a7940a8eddcd39279afc953ea136ff78f854f8a Mon Sep 17 00:00:00 2001 From: Art4 Date: Wed, 22 Jan 2025 08:46:57 +0000 Subject: [PATCH 224/294] Fix PHPStan errors --- ratioed/RatioedPanel.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index b611b256..91665640 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -231,13 +231,13 @@ FROM ( $reply_guy_result = $this->getReplyGuyRow($user['user_contact_uid']); if (DBA::isResult($reply_guy_result)) { $reply_guy_result_row = DBA::fetch($reply_guy_result); - $user['reply_count'] = $reply_guy_result_row['replies_total'] ?? 0; - $user['reply_likes'] = $reply_guy_result_row['like_total'] ?? 0; - $user['reply_respondee_likes'] = $reply_guy_result_row['target_like_total'] ?? 0; - $user['reply_op_likes'] = $reply_guy_result_row['original_like_total'] ?? 0; + $user['reply_count'] = (int) $reply_guy_result_row['replies_total'] ?? 0; + $user['reply_likes'] = (int) $reply_guy_result_row['like_total'] ?? 0; + $user['reply_respondee_likes'] = (int) $reply_guy_result_row['target_like_total'] ?? 0; + $user['reply_op_likes'] = (int) $reply_guy_result_row['original_like_total'] ?? 0; - $denominator = intval($user['reply_likes']) + intval($user['reply_respondee_likes']) + intval($user['reply_op_likes']); - if ($user['reply_count'] == 0) { + $denominator = $user['reply_likes'] + $user['reply_respondee_likes'] + $user['reply_op_likes']; + if ($user['reply_count'] === 0) { $user['reply_guy'] = false; $user['reply_guy_score'] = 0; } elseif ($denominator == 0) { From 2b5764c132bb02390d8a417bc80e0fb28f83df07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Wed, 15 Jan 2025 10:42:08 +0100 Subject: [PATCH 225/294] rework saml addon fix #1587 remove css-side hiding of elements, which was broken. remove them or make them readonly via javascript --- saml/saml.css | 1 - saml/saml.php | 9 ++++----- 2 files changed, 4 insertions(+), 6 deletions(-) delete mode 100644 saml/saml.css diff --git a/saml/saml.css b/saml/saml.css deleted file mode 100644 index 087633cd..00000000 --- a/saml/saml.css +++ /dev/null @@ -1 +0,0 @@ -#settings-form > div:first-of-type, #settings-form > h2:first-of-type, #wrapper_mpassword, #wrapper_email { display: none !important; } diff --git a/saml/saml.php b/saml/saml.php index 9f065355..f3dd1774 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -75,11 +75,6 @@ function saml_install() Hook::register('footer', __FILE__, 'saml_footer'); } -function saml_head(string &$body) -{ - DI::page()->registerStylesheet(__DIR__ . '/saml.css'); -} - function saml_footer(string &$body) { $fragment = addslashes(BBCode::convertForUriId(User::getSystemUriId(), DI::config()->get('saml', 'settings_statement'))); @@ -87,6 +82,10 @@ function saml_footer(string &$body) EOL; } From 792f50f835ebb9181f7d627282e582a153373a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Thu, 16 Jan 2025 18:53:05 +0100 Subject: [PATCH 226/294] fix view in vier and frio --- saml/saml.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index f3dd1774..7fdafc1e 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -83,9 +83,22 @@ function saml_footer(string &$body) var target=$("#settings-nickname-desc"); if (target.length) { target.append("

$fragment

"); } document.getElementById('id_email').setAttribute('readonly', 'readonly'); -document.getElementById('password-settings').remove(); -document.getElementById('password-settings-collapse').remove(); -document.getElementById('id_mpassword_wrapper').remove(); +if ( document.getElementById('password-settings') != null ) { + document.getElementById('password-settings').remove(); +} +if ( document.getElementById('password-settings-collapse') != null ) { + document.getElementById('password-settings-collapse').remove(); +} +if ( document.getElementById('id_mpassword_wrapper') != null ) { + document.getElementById('id_mpassword_wrapper').remove(); +} +if ( document.getElementById('wrapper_mpassword') != null ) { + document.getElementById('wrapper_mpassword').remove(); +} +if ( document.getElementById('wrapper_password') != null ) { + document.getElementById('wrapper_password').parentNode.parentNode.children[0].remove(); + document.getElementById('wrapper_password').parentNode.remove(); +} EOL; } From c50636727361a153b5ed5f445ab6afed9497e663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Fri, 17 Jan 2025 03:04:31 +0100 Subject: [PATCH 227/294] replace password-handling with hint also add hint to email-field --- saml/saml.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index 7fdafc1e..81a6bfcc 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -78,26 +78,32 @@ function saml_install() function saml_footer(string &$body) { $fragment = addslashes(BBCode::convertForUriId(User::getSystemUriId(), DI::config()->get('saml', 'settings_statement'))); + $samlhint = DI::l10n()->t('managed via SAML authentication'); $body .= << var target=$("#settings-nickname-desc"); if (target.length) { target.append("

$fragment

"); } document.getElementById('id_email').setAttribute('readonly', 'readonly'); -if ( document.getElementById('password-settings') != null ) { - document.getElementById('password-settings').remove(); -} +var saml_hint = document.createElement("span"); +var saml_hint_text = document.createTextNode('$samlhint'); +saml_hint.appendChild(saml_hint_text); +document.getElementById('id_email').parentNode.insertBefore(saml_hint, document.getElementById('id_email').nextSibling); +// Frio theme if ( document.getElementById('password-settings-collapse') != null ) { - document.getElementById('password-settings-collapse').remove(); + document.getElementById('password-settings-collapse').replaceChildren(saml_hint.cloneNode(true)); } if ( document.getElementById('id_mpassword_wrapper') != null ) { + document.getElementById('id_mpassword_wrapper').parentNode.appendChild(saml_hint.cloneNode(true)); document.getElementById('id_mpassword_wrapper').remove(); + document.getElementById('id_email').nextElementSibling.classList.add('help-block'); } +// Vier theme if ( document.getElementById('wrapper_mpassword') != null ) { document.getElementById('wrapper_mpassword').remove(); + document.getElementById('id_email').nextElementSibling.classList.add('field_help'); } if ( document.getElementById('wrapper_password') != null ) { - document.getElementById('wrapper_password').parentNode.parentNode.children[0].remove(); - document.getElementById('wrapper_password').parentNode.remove(); + document.getElementById('wrapper_password').parentNode.replaceChildren(saml_hint.cloneNode(true)); } EOL; From 0b4aaac9fd16bc26511f226ed470fb4e18395e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Fri, 17 Jan 2025 03:24:17 +0100 Subject: [PATCH 228/294] translation for saml-hint --- saml/lang/C/messages.po | 82 ++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/saml/lang/C/messages.po b/saml/lang/C/messages.po index 05579568..b4a4c8ce 100644 --- a/saml/lang/C/messages.po +++ b/saml/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-05-18 07:23+0200\n" +"POT-Creation-Date: 2025-01-17 03:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,82 +17,82 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: saml.php:231 +#: saml.php:81 +msgid "managed via SAML authentication" +msgstr "" + +#: saml.php:246 msgid "Settings statement" msgstr "" -#: saml.php:232 -msgid "" -"A statement on the settings page explaining where the user should go to " -"change their e-mail and password. BBCode allowed." -msgstr "" - -#: saml.php:237 -msgid "IdP ID" -msgstr "" - -#: saml.php:238 -msgid "" -"Identity provider (IdP) entity URI (e.g., https://example.com/auth/realms/" -"user)." -msgstr "" - -#: saml.php:242 -msgid "Client ID" -msgstr "" - -#: saml.php:243 -msgid "Identifier assigned to client by the identity provider (IdP)." -msgstr "" - #: saml.php:247 -msgid "IdP SSO URL" -msgstr "" - -#: saml.php:248 -msgid "The URL for your identity provider's SSO endpoint." +msgid "A statement on the settings page explaining where the user should go to change their e-mail and password. BBCode allowed." msgstr "" #: saml.php:252 -msgid "IdP SLO request URL" +msgid "IdP ID" msgstr "" #: saml.php:253 -msgid "The URL for your identity provider's SLO request endpoint." +msgid "Identity provider (IdP) entity URI (e.g., https://example.com/auth/realms/user)." msgstr "" #: saml.php:257 -msgid "IdP SLO response URL" +msgid "Client ID" msgstr "" #: saml.php:258 -msgid "The URL for your identity provider's SLO response endpoint." +msgid "Identifier assigned to client by the identity provider (IdP)." msgstr "" #: saml.php:262 -msgid "SP private key" +msgid "IdP SSO URL" msgstr "" #: saml.php:263 -msgid "The private key the addon should use to authenticate." +msgid "The URL for your identity provider's SSO endpoint." msgstr "" #: saml.php:267 -msgid "SP certificate" +msgid "IdP SLO request URL" msgstr "" #: saml.php:268 -msgid "The certficate for the addon's private key." +msgid "The URL for your identity provider's SLO request endpoint." msgstr "" #: saml.php:272 -msgid "IdP certificate" +msgid "IdP SLO response URL" msgstr "" #: saml.php:273 +msgid "The URL for your identity provider's SLO response endpoint." +msgstr "" + +#: saml.php:277 +msgid "SP private key" +msgstr "" + +#: saml.php:278 +msgid "The private key the addon should use to authenticate." +msgstr "" + +#: saml.php:282 +msgid "SP certificate" +msgstr "" + +#: saml.php:283 +msgid "The certficate for the addon's private key." +msgstr "" + +#: saml.php:287 +msgid "IdP certificate" +msgstr "" + +#: saml.php:288 msgid "The x509 certficate for your identity provider." msgstr "" -#: saml.php:276 +#: saml.php:291 msgid "Save Settings" msgstr "" From 4310c1355d42e7d0c9f071866c06624afd324f3a Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 10:53:01 +0000 Subject: [PATCH 229/294] Replace call for Logger with DI::logger() --- advancedcontentfilter/advancedcontentfilter.php | 3 +-- birdavatar/birdavatar.php | 3 +-- blackout/blackout.php | 3 +-- catavatar/catavatar.php | 3 +-- fromapp/fromapp.php | 3 +-- geonames/geonames.php | 3 +-- gnot/gnot.php | 3 +-- googlemaps/googlemaps.php | 3 +-- gravatar/gravatar.php | 3 +-- impressum/impressum.php | 3 +-- keycloakpassword/keycloakpassword.php | 3 +-- krynn/krynn.php | 3 +-- leistungsschutzrecht/leistungsschutzrecht.php | 3 +-- libravatar/libravatar.php | 3 +-- newmemberwidget/newmemberwidget.php | 3 +-- numfriends/numfriends.php | 3 +-- opmlexport/opmlexport.php | 3 +-- piwik/piwik.php | 3 +-- pumpio/pumpio_sync.php | 4 ++-- securemail/securemail.php | 3 +-- 20 files changed, 21 insertions(+), 40 deletions(-) diff --git a/advancedcontentfilter/advancedcontentfilter.php b/advancedcontentfilter/advancedcontentfilter.php index c03034cd..aeeff77c 100644 --- a/advancedcontentfilter/advancedcontentfilter.php +++ b/advancedcontentfilter/advancedcontentfilter.php @@ -36,7 +36,6 @@ use Friendica\BaseModule; use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Database\DBStructure; @@ -62,7 +61,7 @@ function advancedcontentfilter_install() Hook::add('dbstructure_definition' , __FILE__, 'advancedcontentfilter_dbstructure_definition'); DBStructure::performUpdate(); - Logger::notice('installed advancedcontentfilter'); + DI::logger()->notice('installed advancedcontentfilter'); } /* diff --git a/birdavatar/birdavatar.php b/birdavatar/birdavatar.php index 9a9dce0a..cd49b183 100644 --- a/birdavatar/birdavatar.php +++ b/birdavatar/birdavatar.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -27,7 +26,7 @@ function birdavatar_install() Hook::register('addon_settings', __FILE__, 'birdavatar_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'birdavatar_addon_settings_post'); - Logger::info('registered birdavatar'); + DI::logger()->info('registered birdavatar'); } /** diff --git a/blackout/blackout.php b/blackout/blackout.php index a3f806ff..ac1ee3e6 100644 --- a/blackout/blackout.php +++ b/blackout/blackout.php @@ -45,7 +45,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; @@ -77,7 +76,7 @@ function blackout_redirect ($b) } if (( $date1 <= $now ) && ( $now <= $date2 )) { - Logger::notice('redirecting user to blackout page'); + DI::logger()->notice('redirecting user to blackout page'); System::externalRedirect($myurl); } } diff --git a/catavatar/catavatar.php b/catavatar/catavatar.php index 2bdf0cca..7b5f05c0 100644 --- a/catavatar/catavatar.php +++ b/catavatar/catavatar.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -27,7 +26,7 @@ function catavatar_install() Hook::register('addon_settings', __FILE__, 'catavatar_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'catavatar_addon_settings_post'); - Logger::notice('registered catavatar'); + DI::logger()->notice('registered catavatar'); } /** diff --git a/fromapp/fromapp.php b/fromapp/fromapp.php index 8bd27606..bb8a4fe6 100644 --- a/fromapp/fromapp.php +++ b/fromapp/fromapp.php @@ -8,7 +8,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -17,7 +16,7 @@ function fromapp_install() Hook::register('post_local', 'addon/fromapp/fromapp.php', 'fromapp_post_hook'); Hook::register('addon_settings', 'addon/fromapp/fromapp.php', 'fromapp_settings'); Hook::register('addon_settings_post', 'addon/fromapp/fromapp.php', 'fromapp_settings_post'); - Logger::notice("installed fromapp"); + DI::logger()->notice("installed fromapp"); } function fromapp_settings_post($post) diff --git a/geonames/geonames.php b/geonames/geonames.php index d14b1e8f..4c5e54d8 100644 --- a/geonames/geonames.php +++ b/geonames/geonames.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -45,7 +44,7 @@ function geonames_post_hook(array &$item) * - The profile owner must have allowed our addon */ - Logger::notice('geonames invoked'); + DI::logger()->notice('geonames invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ return; diff --git a/gnot/gnot.php b/gnot/gnot.php index 5d0919cb..3801a210 100644 --- a/gnot/gnot.php +++ b/gnot/gnot.php @@ -9,7 +9,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Notification; @@ -20,7 +19,7 @@ function gnot_install() Hook::register('addon_settings_post', 'addon/gnot/gnot.php', 'gnot_settings_post'); Hook::register('enotify_mail', 'addon/gnot/gnot.php', 'gnot_enotify_mail'); - Logger::notice("installed gnot"); + DI::logger()->notice("installed gnot"); } /** diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index b83a9cf9..a0bba8ad 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -8,13 +8,12 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; function googlemaps_install() { Hook::register('render_location', 'addon/googlemaps/googlemaps.php', 'googlemaps_location'); - Logger::notice('installed googlemaps'); + DI::logger()->notice('installed googlemaps'); } function googlemaps_location(&$item) diff --git a/gravatar/gravatar.php b/gravatar/gravatar.php index 6007c433..7fe0d955 100644 --- a/gravatar/gravatar.php +++ b/gravatar/gravatar.php @@ -8,7 +8,6 @@ use Friendica\BaseModule; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -20,7 +19,7 @@ function gravatar_install() { Hook::register('load_config', 'addon/gravatar/gravatar.php', 'gravatar_load_config'); Hook::register('avatar_lookup', 'addon/gravatar/gravatar.php', 'gravatar_lookup'); - Logger::notice("registered gravatar in avatar_lookup hook"); + DI::logger()->notice("registered gravatar in avatar_lookup hook"); } function gravatar_load_config(ConfigFileManager $loader) diff --git a/impressum/impressum.php b/impressum/impressum.php index f61d7182..0ad34e40 100644 --- a/impressum/impressum.php +++ b/impressum/impressum.php @@ -9,7 +9,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -20,7 +19,7 @@ function impressum_install() Hook::register('load_config', 'addon/impressum/impressum.php', 'impressum_load_config'); Hook::register('about_hook', 'addon/impressum/impressum.php', 'impressum_show'); Hook::register('page_end', 'addon/impressum/impressum.php', 'impressum_footer'); - Logger::notice("installed impressum Addon"); + DI::logger()->notice("installed impressum Addon"); } /** diff --git a/keycloakpassword/keycloakpassword.php b/keycloakpassword/keycloakpassword.php index e9809f86..11034ffe 100644 --- a/keycloakpassword/keycloakpassword.php +++ b/keycloakpassword/keycloakpassword.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -37,7 +36,7 @@ function keycloakpassword_request($client_id, $secret, $url, $params = []) $res = curl_exec($ch); if (curl_errno($ch)) { - Logger::error(curl_error($ch)); + DI::logger()->error(curl_error($ch)); } curl_close($ch); diff --git a/krynn/krynn.php b/krynn/krynn.php index fa9db133..b57d827e 100644 --- a/krynn/krynn.php +++ b/krynn/krynn.php @@ -11,7 +11,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -31,7 +30,7 @@ function krynn_install() Hook::register('addon_settings', 'addon/krynn/krynn.php', 'krynn_settings'); Hook::register('addon_settings_post', 'addon/krynn/krynn.php', 'krynn_settings_post'); - Logger::notice("installed krynn"); + DI::logger()->notice("installed krynn"); } function krynn_post_hook(&$item) diff --git a/leistungsschutzrecht/leistungsschutzrecht.php b/leistungsschutzrecht/leistungsschutzrecht.php index ec8091ac..891cb6ca 100644 --- a/leistungsschutzrecht/leistungsschutzrecht.php +++ b/leistungsschutzrecht/leistungsschutzrecht.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; function leistungsschutzrecht_install() @@ -168,7 +167,7 @@ function leistungsschutzrecht_cron($b) if ($last) { $next = $last + 86400; if ($next > time()) { - Logger::notice('poll intervall not reached'); + DI::logger()->notice('poll intervall not reached'); return; } } diff --git a/libravatar/libravatar.php b/libravatar/libravatar.php index 4cd72c83..6cb35331 100644 --- a/libravatar/libravatar.php +++ b/libravatar/libravatar.php @@ -8,7 +8,6 @@ use Friendica\Core\Addon; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -20,7 +19,7 @@ function libravatar_install() { Hook::register('load_config', 'addon/libravatar/libravatar.php', 'libravatar_load_config'); Hook::register('avatar_lookup', 'addon/libravatar/libravatar.php', 'libravatar_lookup'); - Logger::notice("registered libravatar in avatar_lookup hook"); + DI::logger()->notice("registered libravatar in avatar_lookup hook"); } function libravatar_load_config(ConfigFileManager $loader) diff --git a/newmemberwidget/newmemberwidget.php b/newmemberwidget/newmemberwidget.php index d3b68807..ba7dfb39 100644 --- a/newmemberwidget/newmemberwidget.php +++ b/newmemberwidget/newmemberwidget.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\User; @@ -16,7 +15,7 @@ use Friendica\Model\User; function newmemberwidget_install() { Hook::register( 'network_mod_init', 'addon/newmemberwidget/newmemberwidget.php', 'newmemberwidget_network_mod_init'); - Logger::notice('newmemberwidget installed'); + DI::logger()->notice('newmemberwidget installed'); } function newmemberwidget_network_mod_init ($b) diff --git a/numfriends/numfriends.php b/numfriends/numfriends.php index 66c9b74a..5652c8f0 100644 --- a/numfriends/numfriends.php +++ b/numfriends/numfriends.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -16,7 +15,7 @@ function numfriends_install() { Hook::register('addon_settings', 'addon/numfriends/numfriends.php', 'numfriends_settings'); Hook::register('addon_settings_post', 'addon/numfriends/numfriends.php', 'numfriends_settings_post'); - Logger::notice("installed numfriends"); + DI::logger()->notice("installed numfriends"); } /** diff --git a/opmlexport/opmlexport.php b/opmlexport/opmlexport.php index 3df71275..be1d335c 100644 --- a/opmlexport/opmlexport.php +++ b/opmlexport/opmlexport.php @@ -9,7 +9,6 @@ use Friendica\DI; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Model\Contact; use Friendica\Model\User; @@ -18,7 +17,7 @@ function opmlexport_install() { Hook::register('addon_settings', __FILE__, 'opmlexport_addon_settings'); Hook::register('addon_settings_post', __FILE__, 'opmlexport_addon_settings_post'); - Logger::notice('installed opmlexport Addon'); + DI::logger()->notice('installed opmlexport Addon'); } diff --git a/piwik/piwik.php b/piwik/piwik.php index fc459a87..b7e9e71c 100644 --- a/piwik/piwik.php +++ b/piwik/piwik.php @@ -36,7 +36,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -45,7 +44,7 @@ function piwik_install() { Hook::register('load_config', 'addon/piwik/piwik.php', 'piwik_load_config'); Hook::register('page_end', 'addon/piwik/piwik.php', 'piwik_analytics'); - Logger::notice("installed piwik addon"); + DI::logger()->notice("installed piwik addon"); } function piwik_load_config(ConfigFileManager $loader) diff --git a/pumpio/pumpio_sync.php b/pumpio/pumpio_sync.php index beaf6e81..09548c6d 100644 --- a/pumpio/pumpio_sync.php +++ b/pumpio/pumpio_sync.php @@ -1,5 +1,5 @@ DI::config()->get('system', 'maxloadavg', 50)) { - Logger::notice('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); + DI::logger()->notice('system: load ' . $load[0] . ' too high. Pumpio sync deferred to next scheduled run.'); return; } } diff --git a/securemail/securemail.php b/securemail/securemail.php index b56c0cbc..7b412395 100644 --- a/securemail/securemail.php +++ b/securemail/securemail.php @@ -8,7 +8,6 @@ use Friendica\Addon\securemail\SecureTestEmail; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Object\EMail\IEmail; @@ -22,7 +21,7 @@ function securemail_install() Hook::register('emailer_send_prepare', 'addon/securemail/securemail.php', 'securemail_emailer_send_prepare', 10); - Logger::notice('installed securemail'); + DI::logger()->notice('installed securemail'); } /** From 41f280f0c71f214e7d2c803363e83c4d5ca7dac6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:34:33 +0000 Subject: [PATCH 230/294] Replace call for Logger with DI::logger() in blockbot addon --- blockbot/blockbot.php | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index 022f188d..163d0cbc 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -11,7 +11,6 @@ use Friendica\Core\Hook; use Friendica\DI; use Jaybizzle\CrawlerDetect\CrawlerDetect; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Network\HTTPException\ForbiddenException; @@ -70,7 +69,7 @@ function blockbot_init_1() } if (empty($parts)) { - Logger::debug('Known frontend found - accept', $logdata); + DI::logger()->debug('Known frontend found - accept', $logdata); if ($isCrawler) { blockbot_save('badly-parsed-agents', $_SERVER['HTTP_USER_AGENT']); } @@ -80,66 +79,66 @@ function blockbot_init_1() blockbot_log_activitypub($_SERVER['REQUEST_URI'], $_SERVER['HTTP_USER_AGENT']); if (blockbot_is_crawler($parts)) { - Logger::debug('Crawler found - reject', $logdata); + DI::logger()->debug('Crawler found - reject', $logdata); blockbot_reject(); } if (blockbot_is_searchbot($parts)) { - Logger::debug('Search bot found - reject', $logdata); + DI::logger()->debug('Search bot found - reject', $logdata); blockbot_reject(); } if (blockbot_is_unwanted($parts)) { - Logger::debug('Uncategorized unwanted agent found - reject', $logdata); + DI::logger()->debug('Uncategorized unwanted agent found - reject', $logdata); blockbot_reject(); } if (blockbot_is_security_checker($parts)) { if (!DI::config()->get('blockbot', 'security_checker')) { - Logger::debug('Security checker found - reject', $logdata); + DI::logger()->debug('Security checker found - reject', $logdata); blockbot_reject(); } - Logger::debug('Security checker found - accept', $logdata); + DI::logger()->debug('Security checker found - accept', $logdata); return; } if (blockbot_is_social_media($parts)) { - Logger::debug('Social media service found - accept', $logdata); + DI::logger()->debug('Social media service found - accept', $logdata); return; } if (blockbot_is_fediverse_client($parts)) { - Logger::debug('Fediverse client found - accept', $logdata); + DI::logger()->debug('Fediverse client found - accept', $logdata); return; } if (blockbot_is_feed_reader($parts)) { - Logger::debug('Feed reader found - accept', $logdata); + DI::logger()->debug('Feed reader found - accept', $logdata); return; } if (blockbot_is_fediverse_tool($parts)) { - Logger::debug('Fediverse tool found - accept', $logdata); + DI::logger()->debug('Fediverse tool found - accept', $logdata); return; } if (blockbot_is_service_agent($parts)) { - Logger::debug('Service agent found - accept', $logdata); + DI::logger()->debug('Service agent found - accept', $logdata); return; } if (blockbot_is_monitor($parts)) { - Logger::debug('Monitoring service found - accept', $logdata); + DI::logger()->debug('Monitoring service found - accept', $logdata); return; } if (blockbot_is_validator($parts)) { - Logger::debug('Validation service found - accept', $logdata); + DI::logger()->debug('Validation service found - accept', $logdata); return; } if (blockbot_is_good_tool($parts)) { - Logger::debug('Uncategorized helpful service found - accept', $logdata); + DI::logger()->debug('Uncategorized helpful service found - accept', $logdata); return; } @@ -147,10 +146,10 @@ function blockbot_init_1() if (blockbot_is_http_library($parts)) { blockbot_check_login_attempt($_SERVER['REQUEST_URI'], $logdata); if (!DI::config()->get('blockbot', 'http_libraries')) { - Logger::debug('HTTP Library found - reject', $logdata); + DI::logger()->debug('HTTP Library found - reject', $logdata); blockbot_reject(); } - Logger::debug('HTTP Library found - accept', $logdata); + DI::logger()->debug('HTTP Library found - accept', $logdata); return; } @@ -161,12 +160,12 @@ function blockbot_init_1() if (!$isCrawler) { blockbot_save('good-agents', $_SERVER['HTTP_USER_AGENT']); - Logger::debug('Non-bot user agent detected', $logdata); + DI::logger()->debug('Non-bot user agent detected', $logdata); return; } blockbot_save('bad-agents', $_SERVER['HTTP_USER_AGENT']); - Logger::notice('Possible bot found - reject', $logdata); + DI::logger()->notice('Possible bot found - reject', $logdata); blockbot_reject(); } @@ -217,7 +216,7 @@ function blockbot_log_activitypub(string $url, string $agent) function blockbot_check_login_attempt(string $url, array $logdata) { if (in_array(trim(parse_url($url, PHP_URL_PATH), '/'), ['login', 'lostpass', 'register'])) { - Logger::debug('Login attempt detected - reject', $logdata); + DI::logger()->debug('Login attempt detected - reject', $logdata); blockbot_reject(); } } @@ -443,7 +442,7 @@ function blockbot_is_monitor(array $parts): bool } /** - * Services in the centralized and decentralized social media environment + * Services in the centralized and decentralized social media environment * * @param array $parts * @return boolean From d78ea50516c67f871ddb49ca18328379a95b4d57 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:36:23 +0000 Subject: [PATCH 231/294] Replace call for Logger with DI::logger() in bluesky addon --- bluesky/bluesky.php | 95 +++++++++++++++---------------- bluesky/bluesky_feed.php | 6 +- bluesky/bluesky_notifications.php | 6 +- bluesky/bluesky_timeline.php | 6 +- 4 files changed, 56 insertions(+), 57 deletions(-) diff --git a/bluesky/bluesky.php b/bluesky/bluesky.php index 5bf07afb..7f6bb9e7 100644 --- a/bluesky/bluesky.php +++ b/bluesky/bluesky.php @@ -30,7 +30,6 @@ use Friendica\Content\Text\Plaintext; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\Worker; @@ -106,16 +105,16 @@ function bluesky_item_by_link(array &$hookData) if (empty($did)) { return; } - - Logger::debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); - + + DI::logger()->debug('Found bluesky post', ['uri' => $hookData['uri'], 'did' => $did, 'cid' => $matches[2]]); + $uri = 'at://' . $did . '/app.bsky.feed.post/' . $matches[2]; } else { $uri = $hookData['uri']; } $uri = DI::atpProcessor()->fetchMissingPost($uri, $hookData['uid'], Item::PR_FETCHED, 0, 0); - Logger::debug('Got post', ['uri' => $uri]); + DI::logger()->debug('Got post', ['uri' => $uri]); if (!empty($uri)) { $item = Post::selectFirst(['id'], ['uri' => $uri, 'uid' => $hookData['uid']]); if (!empty($item['id'])) { @@ -138,7 +137,7 @@ function bluesky_follow(array &$hook_data) return; } - Logger::debug('Check if contact is bluesky', ['data' => $hook_data]); + DI::logger()->debug('Check if contact is bluesky', ['data' => $hook_data]); $contact = DBA::selectFirst('contact', [], ['network' => Protocol::BLUESKY, 'url' => $hook_data['url'], 'uid' => [0, $hook_data['uid']]]); if (empty($contact)) { return; @@ -159,7 +158,7 @@ function bluesky_follow(array &$hook_data) $activity = DI::atProtocol()->XRPCPost($hook_data['uid'], 'com.atproto.repo.createRecord', $post); if (!empty($activity->uri)) { $hook_data['contact'] = $contact; - Logger::debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); + DI::logger()->debug('Successfully start following', ['url' => $contact['url'], 'uri' => $activity->uri]); } } @@ -213,7 +212,7 @@ function bluesky_block(array &$hook_data) if ($ucid) { Contact::remove($ucid); } - Logger::debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); + DI::logger()->debug('Successfully blocked contact', ['url' => $hook_data['contact']['url'], 'uri' => $activity->uri]); } } @@ -421,11 +420,11 @@ function bluesky_cron() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('poll interval not reached'); + DI::logger()->notice('poll interval not reached'); return; } } - Logger::notice('cron_start'); + DI::logger()->notice('cron_start'); $abandon_days = intval(DI::config()->get('system', 'account_abandon_days')); if ($abandon_days < 1) { @@ -437,19 +436,19 @@ function bluesky_cron() $pconfigs = DBA::selectToArray('pconfig', [], ["`cat` = ? AND `k` IN (?, ?) AND `v`", 'bluesky', 'import', 'import_feeds']); foreach ($pconfigs as $pconfig) { if (empty(DI::atProtocol()->getUserDid($pconfig['uid']))) { - Logger::debug('User has got no valid DID', ['uid' => $pconfig['uid']]); + DI::logger()->debug('User has got no valid DID', ['uid' => $pconfig['uid']]); continue; } if ($abandon_days != 0) { if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); + DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); continue; } } // Refresh the token now, so that it doesn't need to be refreshed in parallel by the following workers - Logger::debug('Refresh the token', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Refresh the token', ['uid' => $pconfig['uid']]); DI::atProtocol()->getUserToken($pconfig['uid']); $last_sync = DI::pConfig()->get($pconfig['uid'], 'bluesky', 'last_contact_sync'); @@ -463,32 +462,32 @@ function bluesky_cron() Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_timeline.php', $pconfig['uid']); } if (DI::pConfig()->get($pconfig['uid'], 'bluesky', 'import_feeds')) { - Logger::debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Fetch feeds for user', ['uid' => $pconfig['uid']]); $feeds = bluesky_get_feeds($pconfig['uid']); foreach ($feeds as $feed) { Worker::add(['priority' => Worker::PRIORITY_MEDIUM, 'force_priority' => true], 'addon/bluesky/bluesky_feed.php', $pconfig['uid'], $feed); } } - Logger::debug('Polling done for user', ['uid' => $pconfig['uid']]); + DI::logger()->debug('Polling done for user', ['uid' => $pconfig['uid']]); } - Logger::notice('Polling done for all users'); + DI::logger()->notice('Polling done for all users'); DI::keyValue()->set('bluesky_last_poll', time()); $last_clean = DI::keyValue()->get('bluesky_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { - Logger::notice('Start contact cleanup'); + DI::logger()->notice('Start contact cleanup'); $contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::BLUESKY, 0, Contact::NOTHING]); while ($contact = DBA::fetch($contacts)) { Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0); } DBA::close($contacts); DI::keyValue()->set('bluesky_last_clean', time()); - Logger::notice('Contact cleanup done'); + DI::logger()->notice('Contact cleanup done'); } - Logger::notice('cron_end'); + DI::logger()->notice('cron_end'); } function bluesky_hook_fork(array &$b) @@ -508,7 +507,7 @@ function bluesky_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'bluesky', 'import')) { // Don't post if it isn't a reply to a bluesky post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::BLUESKY])) { - Logger::notice('No bluesky parent found', ['item' => $post['id']]); + DI::logger()->notice('No bluesky parent found', ['item' => $post['id']]); $b['execute'] = false; return; } @@ -555,12 +554,12 @@ function bluesky_send(array &$b) } if ($b['gravity'] != Item::GRAVITY_PARENT) { - Logger::debug('Got comment', ['item' => $b]); + DI::logger()->debug('Got comment', ['item' => $b]); if ($b['deleted']) { $uri = DI::atpProcessor()->getUriClass($b['uri']); if (empty($uri)) { - Logger::debug('Not a bluesky post', ['uri' => $b['uri']]); + DI::logger()->debug('Not a bluesky post', ['uri' => $b['uri']]); return; } bluesky_delete_post($b['uri'], $b['uid']); @@ -571,12 +570,12 @@ function bluesky_send(array &$b) $parent = DI::atpProcessor()->getUriClass($b['thr-parent']); if (empty($root) || empty($parent)) { - Logger::debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); + DI::logger()->debug('No bluesky post', ['parent' => $b['parent'], 'thr-parent' => $b['thr-parent']]); return; } if ($b['gravity'] == Item::GRAVITY_COMMENT) { - Logger::debug('Posting comment', ['root' => $root, 'parent' => $parent]); + DI::logger()->debug('Posting comment', ['root' => $root, 'parent' => $parent]); bluesky_create_post($b, $root, $parent); return; } elseif (in_array($b['verb'], [Activity::LIKE, Activity::ANNOUNCE])) { @@ -635,10 +634,10 @@ function bluesky_create_activity(array $item, stdClass $parent = null) if (empty($activity->uri)) { return; } - Logger::debug('Activity done', ['return' => $activity]); + DI::logger()->debug('Activity done', ['return' => $activity]); $uri = DI::atpProcessor()->getUri($activity); Item::update(['extid' => $uri], ['guid' => $item['guid']]); - Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); + DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $activity]); } function bluesky_create_post(array $item, stdClass $root = null, stdClass $parent = null) @@ -722,14 +721,14 @@ function bluesky_create_post(array $item, stdClass $root = null, stdClass $paren } return; } - Logger::debug('Posting done', ['return' => $parent]); + DI::logger()->debug('Posting done', ['return' => $parent]); if (empty($root)) { $root = $parent; } if (($key == 0) && ($item['gravity'] != Item::GRAVITY_PARENT)) { $uri = DI::atpProcessor()->getUri($parent); Item::update(['extid' => $uri], ['guid' => $item['guid']]); - Logger::debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); + DI::logger()->debug('Set extid', ['id' => $item['id'], 'extid' => $uri]); } } } @@ -899,20 +898,20 @@ function bluesky_upload_blob(int $uid, array $photo): ?stdClass $new_size = strlen($content); if (($size != 0) && ($new_size == 0) && ($retrial == 0)) { - Logger::warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->warning('Size is empty after resize, uploading original file', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); $content = Photo::getImageForPhoto($photo); } else { - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); } $data = DI::atProtocol()->post($uid, '/xrpc/com.atproto.repo.uploadBlob', $content, ['Content-type' => $photo['type'], 'Authorization' => ['Bearer ' . DI::atProtocol()->getUserToken($uid)]]); if (empty($data) || empty($data->blob)) { - Logger::info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->info('Uploading failed', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return null; } Item::incrementOutbound(Protocol::BLUESKY); - Logger::debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); + DI::logger()->debug('Uploaded blob', ['return' => $data, 'uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size]); return $data->blob; } @@ -920,11 +919,11 @@ function bluesky_delete_post(string $uri, int $uid) { $parts = DI::atpProcessor()->getUriParts($uri); if (empty($parts)) { - Logger::debug('No uri delected', ['uri' => $uri]); + DI::logger()->debug('No uri delected', ['uri' => $uri]); return; } DI::atProtocol()->XRPCPost($uid, 'com.atproto.repo.deleteRecord', $parts); - Logger::debug('Deleted', ['parts' => $parts]); + DI::logger()->debug('Deleted', ['parts' => $parts]); } function bluesky_fetch_timeline(int $uid) @@ -1026,10 +1025,10 @@ function bluesky_fetch_notifications(int $uid) foreach ($data->notifications as $notification) { $uri = DI::atpProcessor()->getUri($notification); if (Post::exists(['uri' => $uri, 'uid' => $uid]) || Post::exists(['extid' => $uri, 'uid' => $uid])) { - Logger::debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); + DI::logger()->debug('Notification already processed', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); continue; } - Logger::debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); + DI::logger()->debug('Process notification', ['uid' => $uid, 'reason' => $notification->reason, 'uri' => $uri, 'indexedAt' => $notification->indexedAt]); switch ($notification->reason) { case 'like': $item = DI::atpProcessor()->getHeaderFromPost($notification, $uri, $uid, Conversation::PARCEL_CONNECTOR); @@ -1039,9 +1038,9 @@ function bluesky_fetch_notifications(int $uid) $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); - Logger::debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + DI::logger()->debug('Got like', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); } else { - Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); + DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } break; @@ -1053,37 +1052,37 @@ function bluesky_fetch_notifications(int $uid) $item['thr-parent'] = DI::atpProcessor()->fetchMissingPost($item['thr-parent'], $uid, Item::PR_FETCHED, $item['contact-id'], 0); if (!empty($item['thr-parent'])) { $data = Item::insert($item); - Logger::debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); + DI::logger()->debug('Got repost', ['uid' => $uid, 'result' => $data, 'uri' => $uri]); } else { - Logger::info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); + DI::logger()->info('Thread parent not found', ['uid' => $uid, 'parent' => $item['thr-parent'], 'uri' => $uri]); } break; case 'follow': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, $uid); - Logger::debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); + DI::logger()->debug('New follower', ['uid' => $uid, 'nick' => $contact['nick'], 'uri' => $uri]); break; case 'mention': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_TO, $contact['id'], 0); - Logger::debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + DI::logger()->debug('Got mention', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'reply': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_COMMENT, $contact['id'], 0); - Logger::debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + DI::logger()->debug('Got reply', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; case 'quote': $contact = DI::atpActor()->getContactByDID($notification->author->did, $uid, 0); $result = DI::atpProcessor()->fetchMissingPost($uri, $uid, Item::PR_PUSHED, $contact['id'], 0); - Logger::debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); + DI::logger()->debug('Got quote', ['uid' => $uid, 'nick' => $contact['nick'], 'result' => $result, 'uri' => $uri]); break; default: - Logger::notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]); + DI::logger()->notice('Unhandled reason', ['reason' => $notification->reason, 'uri' => $uri]); break; } } @@ -1114,16 +1113,16 @@ function bluesky_fetch_feed(int $uid, string $feed) $languages = $entry->post->record->langs ?? []; if (!Relay::isWantedLanguage($entry->post->record->text, 0, $contact['id'] ?? 0, $languages)) { - Logger::debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); + DI::logger()->debug('Unwanted language detected', ['languages' => $languages, 'text' => $entry->post->record->text]); continue; } $causer = DI::atpActor()->getContactByDID($entry->post->author->did, $uid, 0); $uri_id = bluesky_complete_post($entry->post, $uid, Item::PR_TAG, $causer['id'], Conversation::PARCEL_CONNECTOR); if (!empty($uri_id)) { $stored = Post\Category::storeFileByURIId($uri_id, $uid, Post\Category::SUBCRIPTION, $feedname, $feedurl); - Logger::debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); + DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $uri_id, 'uid' => $uid, 'name' => $feedname, 'url' => $feedurl, 'stored' => $stored]); } else { - Logger::notice('Post not found', ['entry' => $entry]); + DI::logger()->notice('Post not found', ['entry' => $entry]); } if (!empty($entry->reason)) { bluesky_process_reason($entry->reason, DI::atpProcessor()->getUri($entry->post), $uid); diff --git a/bluesky/bluesky_feed.php b/bluesky/bluesky_feed.php index a20ef1b9..e4aa3fdc 100644 --- a/bluesky/bluesky_feed.php +++ b/bluesky/bluesky_feed.php @@ -1,6 +1,6 @@ $argv[1], 'feed' => $argv[2]]); + DI::logger()->debug('Importing feed - start', ['user' => $argv[1], 'feed' => $argv[2]]); bluesky_fetch_feed($argv[1], $argv[2]); - Logger::debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); + DI::logger()->debug('Importing feed - done', ['user' => $argv[1], 'feed' => $argv[2]]); } diff --git a/bluesky/bluesky_notifications.php b/bluesky/bluesky_notifications.php index 1fbc8f67..e1bf2047 100644 --- a/bluesky/bluesky_notifications.php +++ b/bluesky/bluesky_notifications.php @@ -1,6 +1,6 @@ $argv[1]]); + DI::logger()->notice('importing notifications - start', ['user' => $argv[1]]); bluesky_fetch_notifications($argv[1]); - Logger::notice('importing notifications - done', ['user' => $argv[1]]); + DI::logger()->notice('importing notifications - done', ['user' => $argv[1]]); } diff --git a/bluesky/bluesky_timeline.php b/bluesky/bluesky_timeline.php index fda846ba..37b22d99 100644 --- a/bluesky/bluesky_timeline.php +++ b/bluesky/bluesky_timeline.php @@ -1,6 +1,6 @@ $argv[1]]); + DI::logger()->notice('importing timeline - start', ['user' => $argv[1]]); bluesky_fetch_timeline($argv[1]); - Logger::notice('importing timeline - done', ['user' => $argv[1]]); + DI::logger()->notice('importing timeline - done', ['user' => $argv[1]]); } From 77ebaca28102deb1c8ae398aeb18903c5188d0a6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:37:28 +0000 Subject: [PATCH 232/294] Replace call for Logger with DI::logger() in ratioed addon --- ratioed/RatioedPanel.php | 5 ++--- ratioed/ratioed.php | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/ratioed/RatioedPanel.php b/ratioed/RatioedPanel.php index 91665640..4cf5d7ff 100644 --- a/ratioed/RatioedPanel.php +++ b/ratioed/RatioedPanel.php @@ -3,7 +3,6 @@ namespace Friendica\Addon\ratioed; use Friendica\Content\Pager; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -260,7 +259,7 @@ FROM ( protected function setupUserCallback(): \Closure { - Logger::debug("ratioed: setupUserCallback"); + DI::logger()->debug("ratioed: setupUserCallback"); $parentCallback = parent::setupUserCallback(); return function ($user) use ($parentCallback) { $blocked_count = DBA::count('user-contact', ['uid' => $user['uid'], 'is-blocked' => 1]); @@ -310,7 +309,7 @@ FROM ( $this->fillReplyGuyData($user); $user = $parentCallback($user); - Logger::debug("ratioed: setupUserCallback", [ + DI::logger()->debug("ratioed: setupUserCallback", [ 'uid' => $user['uid'], 'blocked_by' => $user['blocked_by'], 'comments' => $user['comments'], diff --git a/ratioed/ratioed.php b/ratioed/ratioed.php index 443fdaa9..5cc6d539 100644 --- a/ratioed/ratioed.php +++ b/ratioed/ratioed.php @@ -8,7 +8,6 @@ use Friendica\Addon\ratioed\RatioedPanel; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; /** @@ -18,7 +17,7 @@ function ratioed_install() { Hook::register('moderation_users_tabs', 'addon/ratioed/ratioed.php', 'ratioed_users_tabs'); - Logger::info("ratioed: installed"); + DI::logger()->info("ratioed: installed"); } /** @@ -34,7 +33,7 @@ function ratioed_module() {} * @param array $arr Parameters, including "tabs" which is the list to modify, and "selectedTab", which is the currently selected tab ID */ function ratioed_users_tabs(array &$arr) { - Logger::debug("ratioed: users tabs"); + DI::logger()->debug("ratioed: users tabs"); array_push($arr['tabs'], [ 'label' => DI::l10n()->t('Behaviour'), @@ -50,7 +49,7 @@ function ratioed_users_tabs(array &$arr) { * @brief Displays the ratioed tab in the moderation panel */ function ratioed_content() { - Logger::debug("ratioed: content"); + DI::logger()->debug("ratioed: content"); $ratioed = DI::getDice()->create(RatioedPanel::class, [$_SERVER]); $httpException = DI::getDice()->create(Friendica\Module\Special\HTTPException::class); From 1d1a00df275d19e81fdf44580d126c2affc89f74 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:37:58 +0000 Subject: [PATCH 233/294] Replace call for Logger with DI::logger() in cld addon --- cld/cld.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/cld/cld.php b/cld/cld.php index 83361e2b..d4fef6c5 100644 --- a/cld/cld.php +++ b/cld/cld.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\DI; function cld_install() @@ -18,17 +17,17 @@ function cld_install() function cld_detect_languages(array &$data) { if (!in_array('cld2', get_loaded_extensions())) { - Logger::warning('CLD2 is not installed.'); + DI::logger()->warning('CLD2 is not installed.'); return; } if (!class_exists('CLD2Detector')) { - Logger::warning('CLD2Detector class does not exist.'); + DI::logger()->warning('CLD2Detector class does not exist.'); return; } if (!class_exists('CLD2Encoding')) { - Logger::warning('CLD2Encoding class does not exist.'); + DI::logger()->warning('CLD2Encoding class does not exist.'); return; } @@ -53,7 +52,7 @@ function cld_detect_languages(array &$data) } if (!$result['is_reliable']) { - Logger::debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Unreliable detection', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); if (($original == $detected) && ($data['detected'][$original] < $result['language_probability'] / 100)) { $data['detected'][$original] = $result['language_probability'] / 100; } @@ -63,12 +62,12 @@ function cld_detect_languages(array &$data) $available = array_keys(DI::l10n()->getLanguageCodes()); if (!in_array($detected, $available)) { - Logger::debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Unsupported language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); return; } if ($original != $detected) { - Logger::debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); + DI::logger()->debug('Detected different language', ['uri-id' => $data['uri-id'], 'original' => $original, 'detected' => $detected, 'name' => $result['language_name'], 'probability' => $result['language_probability'], 'text' => $data['text']]); } $length = count($data['detected']); From 4881e6004a9bc883714fe31eff59484a41ad8e2e Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:38:27 +0000 Subject: [PATCH 234/294] Replace call for Logger with DI::logger() in diaspora addon --- diaspora/diaspora.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/diaspora/diaspora.php b/diaspora/diaspora.php index d6c98e34..3c4b4c0e 100644 --- a/diaspora/diaspora.php +++ b/diaspora/diaspora.php @@ -11,7 +11,6 @@ require_once 'addon/diaspora/Diaspora_Connection.php'; use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\Core\Worker; @@ -186,7 +185,7 @@ function diaspora_send(array &$b) { $hostname = DI::baseUrl()->getHost(); - Logger::notice('diaspora_send: invoked'); + DI::logger()->notice('diaspora_send: invoked'); if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; @@ -210,14 +209,14 @@ function diaspora_send(array &$b) return; } - Logger::info('diaspora_send: prepare posting'); + DI::logger()->info('diaspora_send: prepare posting'); $handle = DI::pConfig()->get($b['uid'], 'diaspora', 'handle'); $password = DI::pConfig()->get($b['uid'], 'diaspora', 'password'); $aspect = DI::pConfig()->get($b['uid'], 'diaspora', 'aspect'); if ($handle && $password) { - Logger::info('diaspora_send: all values seem to be okay'); + DI::logger()->info('diaspora_send: all values seem to be okay'); $title = $b['title']; $body = $b['body']; @@ -248,20 +247,20 @@ function diaspora_send(array &$b) require_once "addon/diaspora/diasphp.php"; try { - Logger::info('diaspora_send: prepare'); + DI::logger()->info('diaspora_send: prepare'); $conn = new Diaspora_Connection($handle, $password); - Logger::info('diaspora_send: try to log in ' . $handle); + DI::logger()->info('diaspora_send: try to log in ' . $handle); $conn->logIn(); - Logger::info('diaspora_send: try to send ' . $body); + DI::logger()->info('diaspora_send: try to send ' . $body); $conn->provider = $hostname; $conn->postStatusMessage($body, $aspect); - Logger::notice('diaspora_send: success'); + DI::logger()->notice('diaspora_send: success'); } catch (Exception $e) { - Logger::notice("diaspora_send: Error submitting the post: " . $e->getMessage()); + DI::logger()->notice("diaspora_send: Error submitting the post: " . $e->getMessage()); - Logger::info('diaspora_send: requeueing ' . $b['uid']); + DI::logger()->info('diaspora_send: requeueing ' . $b['uid']); Worker::defer(); } From b38c2d18be2d0174e7e5866cdbbae8cfa75b5b88 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:38:48 +0000 Subject: [PATCH 235/294] Replace call for Logger with DI::logger() in discourse addon --- discourse/discourse.php | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/discourse/discourse.php b/discourse/discourse.php index e97a4fd8..b8d0d996 100644 --- a/discourse/discourse.php +++ b/discourse/discourse.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\Markdown; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Database\DBA; @@ -79,13 +78,13 @@ function discourse_email_getmessage(&$message) // We do assume that all Discourse servers are running with SSL if (preg_match('=topic/(.*\d)/(.*\d)@(.*)=', $message['item']['uri'], $matches) && discourse_fetch_post_from_api($message, $matches[2], $matches[3])) { - Logger::info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]); + DI::logger()->info('Fetched comment via API (message-id mode)', ['host' => $matches[3], 'topic' => $matches[1], 'post' => $matches[2]]); return; } if (preg_match('=topic/(.*\d)@(.*)=', $message['item']['uri'], $matches) && discourse_fetch_topic_from_api($message, 'https://' . $matches[2], $matches[1], 1)) { - Logger::info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]); + DI::logger()->info('Fetched starting post via API (message-id mode)', ['host' => $matches[2], 'topic' => $matches[1]]); return; } @@ -95,16 +94,16 @@ function discourse_email_getmessage(&$message) } if (empty($message['item']['plink']) || !preg_match('=(http.*)/t/.*/(.*\d)/(.*\d)=', $message['item']['plink'], $matches)) { - Logger::info('This is no Discourse post'); + DI::logger()->info('This is no Discourse post'); return; } if (discourse_fetch_topic_from_api($message, $matches[1], $matches[2], $matches[3])) { - Logger::info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]); + DI::logger()->info('Fetched post via API (plink mode)', ['host' => $matches[1], 'topic' => $matches[2], 'id' => $matches[3]]); return; } - Logger::info('Fallback mode', ['plink' => $message['item']['plink']]); + DI::logger()->info('Fallback mode', ['plink' => $message['item']['plink']]); // Search in the HTML part for the discourse entry and the author profile if (!empty($message['html'])) { $message = discourse_get_html($message); @@ -121,7 +120,7 @@ function discourse_fetch_post($host, $topic, $pid) $url = $host . '/t/' . $topic . '/' . $pid . '.json'; $curlResult = DI::httpClient()->get($url); if (!$curlResult->isSuccess()) { - Logger::info('No success', ['url' => $url]); + DI::logger()->info('No success', ['url' => $url]); return false; } @@ -133,11 +132,11 @@ function discourse_fetch_post($host, $topic, $pid) /// @todo Possibly fetch missing posts here continue; } - Logger::info('Got post data from topic', $post); + DI::logger()->info('Got post data from topic', $post); return $post; } - Logger::info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]); + DI::logger()->info('Post not found', ['host' => $host, 'topic' => $topic, 'pid' => $pid]); return false; } @@ -169,7 +168,7 @@ function discourse_fetch_post_from_api(&$message, $post, $host) $message = discourse_process_post($message, $data, $hostaddr); - Logger::info('Got API data', $message); + DI::logger()->info('Got API data', $message); return true; } @@ -202,7 +201,7 @@ function discourse_get_user($post, $hostaddr) $contact['url'] = $hostaddr . '/u/' . $contact['nick']; $contact['nurl'] = Strings::normaliseLink($contact['url']); $contact['baseurl'] = $hostaddr; - Logger::info('Contact', $contact); + DI::logger()->info('Contact', $contact); $contact['id'] = Contact::getIdForURL($contact['url'], 0, false, $contact); if (!empty($contact['id'])) { $avatar = $contact['photo']; @@ -268,11 +267,11 @@ function discourse_get_html($message) $div = $doc2->importNode($result->item(0), true); $doc2->appendChild($div); $message['html'] = $doc2->saveHTML(); - Logger::info('Found html body', ['html' => $message['html']]); + DI::logger()->info('Found html body', ['html' => $message['html']]); $profile = discourse_get_profile($xpath); if (!empty($profile['url'])) { - Logger::info('Found profile', $profile); + DI::logger()->info('Found profile', $profile); $message['item']['author-id'] = Contact::getIdForURL($profile['url'], 0, false, $profile); $message['item']['author-link'] = $profile['url']; $message['item']['author-name'] = $profile['name']; @@ -288,21 +287,21 @@ function discourse_get_text($message) $text = str_replace("\r", '', $text); $pos = strpos($text, "\n---\n"); if ($pos == 0) { - Logger::info('No separator found', ['text' => $text]); + DI::logger()->info('No separator found', ['text' => $text]); return $message; } $message['text'] = trim(substr($text, 0, $pos)); - Logger::info('Found text body', ['text' => $message['text']]); + DI::logger()->info('Found text body', ['text' => $message['text']]); $message['text'] = Markdown::toBBCode($message['text']); $text = substr($text, $pos); - Logger::info('Found footer', ['text' => $text]); + DI::logger()->info('Found footer', ['text' => $text]); if (preg_match('=\((http.*/t/.*/.*\d/.*\d)\)=', $text, $link)) { $message['item']['plink'] = $link[1]; - Logger::info('Found plink', ['plink' => $message['item']['plink']]); + DI::logger()->info('Found plink', ['plink' => $message['item']['plink']]); } return $message; } From 1db552ead93ef398b6f3fb689c95d763c4d93a72 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:39:11 +0000 Subject: [PATCH 236/294] Replace call for Logger with DI::logger() in dwpost addon --- dwpost/dwpost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dwpost/dwpost.php b/dwpost/dwpost.php index 7ce30086..7bad85dc 100644 --- a/dwpost/dwpost.php +++ b/dwpost/dwpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -185,12 +184,12 @@ function dwpost_send(array &$b) EOT; - Logger::debug('dwpost: data: ' . $xml); + DI::logger()->debug('dwpost: data: ' . $xml); if ($dw_blog !== 'test') { $x = DI::httpClient()->post($dw_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to dreamwidth: ' . ($x) ? $x : ''); + DI::logger()->info('posted to dreamwidth: ' . ($x) ? $x : ''); } } From e7755584cbbd3850389495420613ebfe2b59ddb1 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:40:12 +0000 Subject: [PATCH 237/294] Replace call for Logger with DI::logger() in geocoordinates addon --- geocoordinates/geocoordinates.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/geocoordinates/geocoordinates.php b/geocoordinates/geocoordinates.php index eb56f093..5af1defc 100644 --- a/geocoordinates/geocoordinates.php +++ b/geocoordinates/geocoordinates.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -51,25 +50,25 @@ function geocoordinates_resolve_item(array &$item) $s = DI::httpClient()->fetch('https://api.opencagedata.com/geocode/v1/json?q=' . $coords[0] . ',' . $coords[1] . '&key=' . $key . '&language=' . $language); if (!$s) { - Logger::info('API could not be queried'); + DI::logger()->info('API could not be queried'); return; } $data = json_decode($s); if ($data->status->code != '200') { - Logger::info('API returned error ' . $data->status->code . ' ' . $data->status->message); + DI::logger()->info('API returned error ' . $data->status->code . ' ' . $data->status->message); return; } if (($data->total_results == 0) || (count($data->results) == 0)) { - Logger::info('No results found for coordinates ' . $item['coord']); + DI::logger()->info('No results found for coordinates ' . $item['coord']); return; } $item['location'] = $data->results[0]->formatted; - Logger::info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']); + DI::logger()->info('Got location for coordinates ' . $coords[0] . '-' . $coords[1] . ': ' . $item['location']); if ($item['location'] != '') { DI::cache()->set('geocoordinates:' . $language.':' . $coords[0] . '-' . $coords[1], $item['location']); From 15a951235f1f2d2039315851eb0a38831b77c05a Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:40:32 +0000 Subject: [PATCH 238/294] Replace call for Logger with DI::logger() in ifttt addon --- ifttt/ifttt.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/ifttt/ifttt.php b/ifttt/ifttt.php index 51fa8db8..cb23032b 100644 --- a/ifttt/ifttt.php +++ b/ifttt/ifttt.php @@ -8,7 +8,6 @@ */ use Friendica\Content\PageInfo; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Worker; use Friendica\Database\DBA; @@ -86,16 +85,16 @@ function ifttt_post() $user = DBA::selectFirst('user', ['uid'], ['nickname' => $nickname]); if (!DBA::isResult($user)) { - Logger::info('User ' . $nickname . ' not found.'); + DI::logger()->info('User ' . $nickname . ' not found.'); return; } $uid = $user['uid']; - Logger::info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true)); + DI::logger()->info('Received a post for user ' . $uid . ' from ifttt ' . print_r($_REQUEST, true)); if (!isset($_REQUEST['key'])) { - Logger::notice('No key found.'); + DI::logger()->notice('No key found.'); return; } @@ -103,7 +102,7 @@ function ifttt_post() // Check the key if ($key != DI::pConfig()->get($uid, 'ifttt', 'key')) { - Logger::info('Invalid key for user ' . $uid); + DI::logger()->info('Invalid key for user ' . $uid); return; } @@ -114,7 +113,7 @@ function ifttt_post() } if (!in_array($item['type'], ['status', 'link', 'photo'])) { - Logger::info('Unknown item type ' . $item['type']); + DI::logger()->info('Unknown item type ' . $item['type']); return; } From 50023180895a4c1e70163762bd90d56d38d823ba Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:41:02 +0000 Subject: [PATCH 239/294] Replace call for Logger with DI::logger() in ijpost addon --- ijpost/ijpost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ijpost/ijpost.php b/ijpost/ijpost.php index 37c3cd45..9fe502af 100644 --- a/ijpost/ijpost.php +++ b/ijpost/ijpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -178,11 +177,11 @@ function ijpost_send(array &$b) EOT; - Logger::debug('ijpost: data: ' . $xml); + DI::logger()->debug('ijpost: data: ' . $xml); if ($ij_blog !== 'test') { $x = DI::httpClient()->post($ij_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to insanejournal: ' . $x ? $x : ''); + DI::logger()->info('posted to insanejournal: ' . $x ? $x : ''); } } From 5d51c5b56ecbbc220332fd5b2bea6bb34c436e5f Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:42:25 +0000 Subject: [PATCH 240/294] Replace call for Logger with DI::logger() in js_upload addon --- js_upload/js_upload.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/js_upload/js_upload.php b/js_upload/js_upload.php index f1d85aa3..c0a2467d 100644 --- a/js_upload/js_upload.php +++ b/js_upload/js_upload.php @@ -8,7 +8,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Util\Images; @@ -68,7 +67,7 @@ function js_upload_post_init(array &$b) $js_upload_jsonresponse = htmlspecialchars(json_encode($result), ENT_NOQUOTES); if (isset($result['error'])) { - Logger::info('mod/photos.php: photos_post(): error uploading photo: ' . $result['error']); + DI::logger()->info('mod/photos.php: photos_post(): error uploading photo: ' . $result['error']); echo json_encode($result); exit(); } @@ -91,7 +90,7 @@ function js_upload_post_end(int &$b) { global $js_upload_jsonresponse; - Logger::notice('upload_post_end'); + DI::logger()->notice('upload_post_end'); if (!empty($js_upload_jsonresponse)) { echo $js_upload_jsonresponse; exit(); @@ -187,6 +186,10 @@ class js_upload_qqFileUploader { private $allowedExtensions; private $sizeLimit; + + /** + * @var js_upload_qqUploadedFileXhr|js_upload_qqUploadedFileForm + */ private $file; function __construct(array $allowedExtensions = [], $sizeLimit) @@ -234,7 +237,7 @@ class js_upload_qqFileUploader $filename = $pathinfo['filename']; if (!isset($pathinfo['extension'])) { - Logger::warning('extension isn\'t set.', ['filename' => $filename]); + DI::logger()->warning('extension isn\'t set.', ['filename' => $filename]); } $ext = $pathinfo['extension'] ?? ''; From a488f2513159b44765400fa03f3351f5885e851f Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:44:48 +0000 Subject: [PATCH 241/294] Replace call for Logger with DI::logger() in ldapauth addon --- ldapauth/ldapauth.php | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/ldapauth/ldapauth.php b/ldapauth/ldapauth.php index f834b4d5..b80c5226 100644 --- a/ldapauth/ldapauth.php +++ b/ldapauth/ldapauth.php @@ -30,7 +30,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Database\DBA; use Friendica\DI; use Friendica\Model\User; @@ -69,54 +68,54 @@ function ldapauth_authenticate($username, $password) $ldap_autocreateaccount_nameattribute = DI::config()->get('ldapauth', 'ldap_autocreateaccount_nameattribute'); if (!extension_loaded('ldap') || !strlen($ldap_server)) { - Logger::error('Addon not configured or missing php-ldap extension', ['extension_loaded' => extension_loaded('ldap'), 'server' => $ldap_server]); + DI::logger()->error('Addon not configured or missing php-ldap extension', ['extension_loaded' => extension_loaded('ldap'), 'server' => $ldap_server]); return false; } if (!strlen($password)) { - Logger::error('Empty password disallowed', ['provided_password_length' => strlen($password)]); + DI::logger()->error('Empty password disallowed', ['provided_password_length' => strlen($password)]); return false; } $connect = @ldap_connect($ldap_server); if ($connect === false) { - Logger::warning('Could not connect to LDAP server', ['server' => $ldap_server]); + DI::logger()->warning('Could not connect to LDAP server', ['server' => $ldap_server]); return false; } @ldap_set_option($connect, LDAP_OPT_PROTOCOL_VERSION, 3); @ldap_set_option($connect, LDAP_OPT_REFERRALS, 0); if ((@ldap_bind($connect, $ldap_binddn, $ldap_bindpw)) === false) { - Logger::warning('Could not bind to LDAP server', ['server' => $ldap_server, 'binddn' => $ldap_binddn, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->warning('Could not bind to LDAP server', ['server' => $ldap_server, 'binddn' => $ldap_binddn, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $res = @ldap_search($connect, $ldap_searchdn, $ldap_userattr . '=' . $username); if (!$res) { - Logger::notice('LDAP user not found.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP user not found.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $id = @ldap_first_entry($connect, $res); if (!$id) { - Logger::notice('Could not retrieve first LDAP entry.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('Could not retrieve first LDAP entry.', ['searchdn' => $ldap_searchdn, 'userattr' => $ldap_userattr, 'username' => $username, 'errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } $dn = @ldap_get_dn($connect, $id); if (!@ldap_bind($connect, $dn, $password)) { - Logger::notice('Could not authenticate LDAP user with provided password', ['errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); + DI::logger()->notice('Could not authenticate LDAP user with provided password', ['errno' => ldap_errno($connect), 'error' => ldap_error($connect)]); return false; } if (strlen($ldap_group) && @ldap_compare($connect, $ldap_group, 'member', $dn) !== true) { $errno = @ldap_errno($connect); if ($errno === 32) { - Logger::notice('LDAP Access Control Group does not exist', ['errno' => $errno, 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP Access Control Group does not exist', ['errno' => $errno, 'error' => ldap_error($connect)]); } elseif ($errno === 16) { - Logger::notice('LDAP membership attribute does not exist in access control group', ['errno' => $errno, 'error' => ldap_error($connect)]); + DI::logger()->notice('LDAP membership attribute does not exist in access control group', ['errno' => $errno, 'error' => ldap_error($connect)]); } else { - Logger::notice('LDAP user isn\'t part of the authorized group', ['dn' => $dn]); + DI::logger()->notice('LDAP user isn\'t part of the authorized group', ['dn' => $dn]); } @ldap_close($connect); @@ -140,7 +139,7 @@ function ldapauth_authenticate($username, $password) $authentication = User::getAuthenticationInfo($username); return User::getById($authentication['uid']); } catch (Exception $e) { - Logger::notice('LDAP authentication error: ' . $e->getMessage()); + DI::logger()->notice('LDAP authentication error: ' . $e->getMessage()); return false; } } @@ -148,7 +147,7 @@ function ldapauth_authenticate($username, $password) function ldap_createaccount($username, $password, $email, $name) { if (!strlen($email) || !strlen($name)) { - Logger::notice('Could not create local user from LDAP data, no email or nickname provided'); + DI::logger()->notice('Could not create local user from LDAP data, no email or nickname provided'); return false; } @@ -160,10 +159,10 @@ function ldap_createaccount($username, $password, $email, $name) 'password' => $password, 'verified' => 1 ]); - Logger::info('Local user created from LDAP data', ['username' => $username, 'name' => $name]); + DI::logger()->info('Local user created from LDAP data', ['username' => $username, 'name' => $name]); return $user; } catch (Exception $ex) { - Logger::error('Could not create local user from LDAP data', ['username' => $username, 'exception' => $ex->getMessage()]); + DI::logger()->error('Could not create local user from LDAP data', ['username' => $username, 'exception' => $ex->getMessage()]); } return false; From f08750199df1a0b7833e2eaba774f41c88cfe049 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:45:25 +0000 Subject: [PATCH 242/294] Replace call for Logger with DI::logger() in libertree addon --- libertree/libertree.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libertree/libertree.php b/libertree/libertree.php index c138e597..1489a029 100644 --- a/libertree/libertree.php +++ b/libertree/libertree.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -130,7 +129,7 @@ function libertree_post_local(array &$b) function libertree_send(array &$b) { - Logger::notice('libertree_send: invoked'); + DI::logger()->notice('libertree_send: invoked'); if ($b['deleted'] || ($b['private'] == Item::PRIVATE) || ($b['created'] !== $b['edited'])) { return; @@ -196,6 +195,6 @@ function libertree_send(array &$b) ]; $result = DI::httpClient()->post($ltree_blog, $params)->getBodyString(); - Logger::notice('libertree: ' . $result); + DI::logger()->notice('libertree: ' . $result); } } From 9ed02034f1755ae5832b96d34800a7758ad37bf5 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:46:04 +0000 Subject: [PATCH 243/294] Replace call for Logger with DI::logger() in ljpost addon --- ljpost/ljpost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ljpost/ljpost.php b/ljpost/ljpost.php index b416c605..fd7d1bd8 100644 --- a/ljpost/ljpost.php +++ b/ljpost/ljpost.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Model\Item; @@ -200,7 +199,7 @@ function ljpost_send(array &$b) EOT; - Logger::debug('ljpost: data: ' . $xml); + DI::logger()->debug('ljpost: data: ' . $xml); $x = ''; @@ -208,6 +207,6 @@ EOT; $x = DI::httpClient()->post($lj_blog, $xml, ['Content-Type' => 'text/xml'])->getBodyString(); } - Logger::info('posted to livejournal: ' . $x); + DI::logger()->info('posted to livejournal: ' . $x); } } From 9a91bae363392fd1df0849afb4a21e24de994579 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:46:30 +0000 Subject: [PATCH 244/294] Replace call for Logger with DI::logger() in mailstream addon --- mailstream/mailstream.php | 45 +++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/mailstream/mailstream.php b/mailstream/mailstream.php index 9910a63d..5228b168 100644 --- a/mailstream/mailstream.php +++ b/mailstream/mailstream.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Core\Worker; @@ -32,7 +31,7 @@ function mailstream_install() Hook::register('post_remote_end', 'addon/mailstream/mailstream.php', 'mailstream_post_hook'); Hook::register('mailstream_send_hook', 'addon/mailstream/mailstream.php', 'mailstream_send_hook'); - Logger::info("installed mailstream"); + DI::logger()->info("installed mailstream"); } /** @@ -86,7 +85,7 @@ function mailstream_generate_id(string $uri): string $host = DI::baseUrl()->getHost(); $resource = hash('md5', $uri); $message_id = "<" . $resource . "@" . $host . ">"; - Logger::debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); + DI::logger()->debug('generated message ID', ['id' => $message_id, 'uri' => $uri]); return $message_id; } @@ -95,20 +94,20 @@ function mailstream_send_hook(array $data) $criteria = array('uid' => $data['uid'], 'contact-id' => $data['contact-id'], 'uri' => $data['uri']); $item = Post::selectFirst([], $criteria); if (empty($item)) { - Logger::error('could not find item'); + DI::logger()->error('could not find item'); return; } $user = User::getById($item['uid']); if (empty($user)) { - Logger::error('could not find user', ['uid' => $item['uid']]); + DI::logger()->error('could not find user', ['uid' => $item['uid']]); return; } if (!mailstream_send($data['message_id'], $item, $user)) { - Logger::debug('send failed, will retry', $data); + DI::logger()->debug('send failed, will retry', $data); if (!Worker::defer()) { - Logger::error('failed and could not defer', $data); + DI::logger()->error('failed and could not defer', $data); } } } @@ -124,32 +123,32 @@ function mailstream_send_hook(array $data) function mailstream_post_hook(array &$item) { if ($item['uid'] === 0) { - Logger::debug('mailstream: root user, skipping item ' . $item['id']); + DI::logger()->debug('mailstream: root user, skipping item ' . $item['id']); return; } if (!DI::pConfig()->get($item['uid'], 'mailstream', 'enabled')) { - Logger::debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); + DI::logger()->debug('mailstream: not enabled.', ['item' => $item['id'], ' uid ' => $item['uid']]); return; } if (!$item['contact-id']) { - Logger::debug('no contact-id', ['item' => $item['id']]); + DI::logger()->debug('no contact-id', ['item' => $item['id']]); return; } if (!$item['uri']) { - Logger::debug('no uri', ['item' => $item['id']]); + DI::logger()->debug('no uri', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::ANNOUNCE) { - Logger::debug('ignoring announce', ['item' => $item['id']]); + DI::logger()->debug('ignoring announce', ['item' => $item['id']]); return; } if (DI::pConfig()->get($item['uid'], 'mailstream', 'nolikes')) { if ($item['verb'] == Activity::LIKE) { - Logger::debug('ignoring like', ['item' => $item['id']]); + DI::logger()->debug('ignoring like', ['item' => $item['id']]); return; } if ($item['verb'] == Activity::DISLIKE) { - Logger::debug('ignoring dislike', ['item' => $item['id']]); + DI::logger()->debug('ignoring dislike', ['item' => $item['id']]); return; } } @@ -200,7 +199,7 @@ function mailstream_do_images(array &$item, array &$attachments) try { $curlResult = DI::httpClient()->get($url, HttpClientAccept::DEFAULT, [HttpClientOptions::COOKIEJAR => $cookiejar]); if (!$curlResult->isSuccess()) { - Logger::debug('mailstream: fetch image url failed', [ + DI::logger()->debug('mailstream: fetch image url failed', [ 'url' => $url, 'item_id' => $item['id'], 'return_code' => $curlResult->getReturnCode() @@ -208,7 +207,7 @@ function mailstream_do_images(array &$item, array &$attachments) continue; } } catch (InvalidArgumentException $e) { - Logger::error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); + DI::logger()->error('exception fetching url', ['url' => $url, 'item_id' => $item['id']]); continue; } $attachments[$url] = [ @@ -309,7 +308,7 @@ function mailstream_subject(array $item): string } $contact = Contact::selectFirst([], ['id' => $item['contact-id'], 'uid' => $item['uid']]); if (!DBA::isResult($contact)) { - Logger::error('no contact', [ + DI::logger()->error('no contact', [ 'item' => $item['id'], 'plink' => $item['plink'], 'contact id' => $item['contact-id'], @@ -351,16 +350,16 @@ function mailstream_subject(array $item): string function mailstream_send(string $message_id, array $item, array $user): bool { if (!is_array($item)) { - Logger::error('item is empty', ['message_id' => $message_id]); + DI::logger()->error('item is empty', ['message_id' => $message_id]); return false; } if (!$item['visible']) { - Logger::debug('item not yet visible', ['item uri' => $item['uri']]); + DI::logger()->debug('item not yet visible', ['item uri' => $item['uri']]); return false; } if (!$message_id) { - Logger::error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); + DI::logger()->error('no message ID supplied', ['item uri' => $item['uri'], 'user email' => $user['email']]); return true; } @@ -418,15 +417,15 @@ function mailstream_send(string $message_id, array $item, array $user): bool if (!$mail->Send()) { throw new Exception($mail->ErrorInfo); } - Logger::debug('sent message', [ + DI::logger()->debug('sent message', [ 'message ID' => $mail->MessageID, 'subject' => $mail->Subject, 'address' => $address ]); } catch (phpmailerException $e) { - Logger::debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); + DI::logger()->debug('PHPMailer exception sending message', ['id' => $message_id, 'error' => $e->errorMessage()]); } catch (Exception $e) { - Logger::debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); + DI::logger()->debug('exception sending message', ['id' => $message_id, 'error' => $e->getMessage()]); } return true; From 9ceff8f5929d7899b91cc8b1acc26e47cd3dfce7 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:46:58 +0000 Subject: [PATCH 245/294] Replace call for Logger with DI::logger() in nominatim addon --- nominatim/nominatim.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nominatim/nominatim.php b/nominatim/nominatim.php index a3d14af5..3a567b7b 100644 --- a/nominatim/nominatim.php +++ b/nominatim/nominatim.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -45,19 +44,19 @@ function nominatim_resolve_item(array &$item) $s = DI::httpClient()->fetch('https://nominatim.openstreetmap.org/reverse?lat=' . $coords[0] . '&lon=' . $coords[1] . '&format=json&addressdetails=0&accept-language=' . $language); if (empty($s)) { - Logger::info('API could not be queried'); + DI::logger()->info('API could not be queried'); return; } $data = json_decode($s, true); if (empty($data['display_name'])) { - Logger::info('No results found for coordinates', ['coordinates' => $item['coord'], 'data' => $data]); + DI::logger()->info('No results found for coordinates', ['coordinates' => $item['coord'], 'data' => $data]); return; } $item['location'] = $data['display_name']; - Logger::info('Got location', ['lat' => $coords[0], 'long' => $coords[1], 'location' => $item['location']]); + DI::logger()->info('Got location', ['lat' => $coords[0], 'long' => $coords[1], 'location' => $item['location']]); if (!empty($item['location'])) { DI::cache()->set('nominatim:' . $language . ':' . $coords[0] . '-' . $coords[1], $item['location']); From 757d72c360396a06a58f91c4c9d14f7726a9f644 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:47:24 +0000 Subject: [PATCH 246/294] Replace call for Logger with DI::logger() in openstreetmap addon --- openstreetmap/openstreetmap.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/openstreetmap/openstreetmap.php b/openstreetmap/openstreetmap.php index fc5ebbbe..bf0f54b6 100644 --- a/openstreetmap/openstreetmap.php +++ b/openstreetmap/openstreetmap.php @@ -11,7 +11,6 @@ use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; use Friendica\Core\Config\Util\ConfigFileManager; @@ -31,7 +30,7 @@ function openstreetmap_install() Hook::register('Map::getCoordinates', 'addon/openstreetmap/openstreetmap.php', 'openstreetmap_get_coordinates'); Hook::register('page_header', 'addon/openstreetmap/openstreetmap.php', 'openstreetmap_alterheader'); - Logger::notice("installed openstreetmap"); + DI::logger()->notice("installed openstreetmap"); } function openstreetmap_load_config(ConfigFileManager $loader) @@ -154,8 +153,8 @@ function openstreetmap_generate_map(array &$b) $lat = $b['lat']; // round($b['lat'], 5); $lon = $b['lon']; // round($b['lon'], 5); - Logger::debug('lat: ' . $lat); - Logger::debug('lon: ' . $lon); + DI::logger()->debug('lat: ' . $lat); + DI::logger()->debug('lon: ' . $lon); $cardlink = 'notice("installed planets"); } /** @@ -39,7 +38,7 @@ function planets_install() */ function planets_post_hook(&$item) { - Logger::notice('planets invoked'); + DI::logger()->notice('planets invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ From 119ba0a78e1d578d802bf87b1d39e6da35a02da6 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:48:21 +0000 Subject: [PATCH 248/294] Replace call for Logger with DI::logger() in pnut addon --- pnut/pnut.php | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/pnut/pnut.php b/pnut/pnut.php index f298997b..5460b991 100644 --- a/pnut/pnut.php +++ b/pnut/pnut.php @@ -14,7 +14,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Plaintext; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\DI; @@ -76,7 +75,7 @@ function pnut_connect() try { $token = $nut->getAccessToken($callback_url); - Logger::debug('Got Token', [$token]); + DI::logger()->debug('Got Token', [$token]); $o = DI::l10n()->t('You are now authenticated with pnut.io.'); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pnut', 'access_token', $token); } catch (phpnutException $e) { @@ -266,8 +265,8 @@ function pnut_post_hook(array &$b) return; } - Logger::notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); - Logger::debug('PNUT array', $b); + DI::logger()->notice('PNUT post invoked', ['id' => $b['id'], 'guid' => $b['guid'], 'plink' => $b['plink']]); + DI::logger()->debug('PNUT array', $b); $token = DI::pConfig()->get($b['uid'], 'pnut', 'access_token'); $nut = new phpnut\phpnut($token); @@ -276,7 +275,7 @@ function pnut_post_hook(array &$b) $text = $msgarr['text']; $raw = []; - Logger::debug('PNUT msgarr', $msgarr); + DI::logger()->debug('PNUT msgarr', $msgarr); if (count($msgarr['parts']) > 1) { $tstamp = time(); @@ -292,23 +291,23 @@ function pnut_post_hook(array &$b) if ($msgarr['type'] == 'photo') { $fileraw = ['type' => 'dev.mcmillian.friendica.image', 'kind' => 'image', 'is_public' => true]; foreach ($msgarr['images'] as $image) { - Logger::debug('PNUT image', $image); + DI::logger()->debug('PNUT image', $image); if (!empty($image['id'])) { $photo = Photo::selectFirst([], ['id' => $image['id']]); - Logger::debug('PNUT selectFirst'); + DI::logger()->debug('PNUT selectFirst'); } else { $photo = Photo::createPhotoForExternalResource($image['url']); - Logger::debug('PNUT createPhotoForExternalResource'); + DI::logger()->debug('PNUT createPhotoForExternalResource'); } $picturedata = Photo::getImageForPhoto($photo); - Logger::debug('PNUT photo', $photo); + DI::logger()->debug('PNUT photo', $photo); $picurefile = tempnam(System::getTempPath(), 'pnut'); file_put_contents($picurefile, $picturedata); - Logger::debug('PNUT got file?', ['filename' => $picurefile]); + DI::logger()->debug('PNUT got file?', ['filename' => $picurefile]); $imagefile = $nut->createFile($picurefile, $fileraw); - Logger::debug('PNUT file', ['pnutimagefile' => $imagefile]); + DI::logger()->debug('PNUT file', ['pnutimagefile' => $imagefile]); unlink($picurefile); $raw['io.pnut.core.oembed'][] = ['+io.pnut.core.file' => ['file_id' => $imagefile['id'], 'file_token' => $imagefile['file_token'], 'format' => 'oembed']]; @@ -318,5 +317,5 @@ function pnut_post_hook(array &$b) $raw['io.pnut.core.crosspost'][] = ['canonical_url' => $b['plink']]; $nut->createPost($text, ['raw' => $raw]); - Logger::debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); + DI::logger()->debug('PNUT post complete', ['id' => $b['id'], 'text' => $text, 'raw' => $raw]); } From e32ba1ce7b0a1baad29d47df9dcb6328834fbd94 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:54:34 +0000 Subject: [PATCH 249/294] Replace call for Logger with DI::logger() in public_server addon --- public_server/public_server.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/public_server/public_server.php b/public_server/public_server.php index eb7af1e7..9cd0f667 100644 --- a/public_server/public_server.php +++ b/public_server/public_server.php @@ -8,7 +8,6 @@ use Friendica\BaseModule; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -47,7 +46,7 @@ function public_server_register_account($b) function public_server_cron($b) { - Logger::notice("public_server: cron start"); + DI::logger()->notice("public_server: cron start"); $users = DBA::selectToArray('user', [], ["`account_expires_on` > ? AND `account_expires_on` < ? AND `expire_notification_sent` <= ?", DBA::NULL_DATETIME, DateTimeFormat::utc('now + 5 days'), DBA::NULL_DATETIME]); @@ -96,7 +95,7 @@ function public_server_cron($b) } } - Logger::notice("public_server: cron end"); + DI::logger()->notice("public_server: cron end"); } function public_server_enotify(array &$b) From d50650b8cfe7284ee17b482f261e0a8778ad3758 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:55:13 +0000 Subject: [PATCH 250/294] Replace call for Logger with DI::logger() in pumpio addon --- pumpio/pumpio.php | 73 +++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/pumpio/pumpio.php b/pumpio/pumpio.php index ffe5f187..c3445b48 100644 --- a/pumpio/pumpio.php +++ b/pumpio/pumpio.php @@ -10,7 +10,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Addon; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\Worker; @@ -107,7 +106,7 @@ function pumpio_registerclient($host) $params['logo_url'] = DI::baseUrl() . '/images/friendica-256.png'; $params['redirect_uris'] = DI::baseUrl() . '/pumpio/connect'; - Logger::info('pumpio_registerclient: ' . $url . ' parameters', $params); + DI::logger()->info('pumpio_registerclient: ' . $url . ' parameters', $params); // @TODO Rewrite this to our own HTTP client $ch = curl_init($url); @@ -122,10 +121,10 @@ function pumpio_registerclient($host) if ($curl_info['http_code'] == '200') { $values = json_decode($s); - Logger::info('pumpio_registerclient: success ', (array)$values); + DI::logger()->info('pumpio_registerclient: success ', (array)$values); return $values; } - Logger::info('pumpio_registerclient: failed: ', $curl_info); + DI::logger()->info('pumpio_registerclient: failed: ', $curl_info); return false; } @@ -138,7 +137,7 @@ function pumpio_connect() $hostname = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'host'); if ((($consumer_key == '') || ($consumer_secret == '')) && ($hostname != '')) { - Logger::notice('pumpio_connect: register client'); + DI::logger()->notice('pumpio_connect: register client'); $clientdata = pumpio_registerclient($hostname); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_key', $clientdata->client_id); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_secret', $clientdata->client_secret); @@ -146,11 +145,11 @@ function pumpio_connect() $consumer_key = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_key'); $consumer_secret = DI::pConfig()->get(DI::userSession()->getLocalUserId(), 'pumpio', 'consumer_secret'); - Logger::info('pumpio_connect: ckey: ' . $consumer_key . ' csecrect: ' . $consumer_secret); + DI::logger()->info('pumpio_connect: ckey: ' . $consumer_key . ' csecrect: ' . $consumer_secret); } if (($consumer_key == '') || ($consumer_secret == '')) { - Logger::notice('pumpio_connect: '.sprintf('Unable to register the client at the pump.io server "%s".', $hostname)); + DI::logger()->notice('pumpio_connect: '.sprintf('Unable to register the client at the pump.io server "%s".', $hostname)); return DI::l10n()->t("Unable to register the client at the pump.io server '%s'.", $hostname); } @@ -179,7 +178,7 @@ function pumpio_connect() if (($success = $client->Initialize())) { if (($success = $client->Process())) { if (strlen($client->access_token)) { - Logger::info('pumpio_connect: otoken: ' . $client->access_token . ', osecrect: ' . $client->access_token_secret); + DI::logger()->info('pumpio_connect: otoken: ' . $client->access_token . ', osecrect: ' . $client->access_token_secret); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'oauth_token', $client->access_token); DI::pConfig()->set(DI::userSession()->getLocalUserId(), 'pumpio', 'oauth_token_secret', $client->access_token_secret); } @@ -191,11 +190,11 @@ function pumpio_connect() } if ($success) { - Logger::notice('pumpio_connect: authenticated'); + DI::logger()->notice('pumpio_connect: authenticated'); $o = DI::l10n()->t('You are now authenticated to pumpio.'); $o .= '
' . DI::l10n()->t('return to the connector page') . ''; } else { - Logger::notice('pumpio_connect: could not connect'); + DI::logger()->notice('pumpio_connect: could not connect'); $o = 'Could not connect to pumpio. Refresh the page or try again later.'; } @@ -345,7 +344,7 @@ function pumpio_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'pumpio', 'import')) { // Don't fork if it isn't a reply to a pump.io post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::PUMPIO])) { - Logger::notice('No pump.io parent found for item ' . $post['id']); + DI::logger()->notice('No pump.io parent found for item ' . $post['id']); $b['execute'] = false; return; } @@ -389,7 +388,7 @@ function pumpio_send(array &$b) return; } - Logger::debug('pumpio_send: parameter ', $b); + DI::logger()->debug('pumpio_send: parameter ', $b); $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); @@ -399,7 +398,7 @@ function pumpio_send(array &$b) $orig_post = Post::selectFirst([], $condition); if (!DBA::isResult($orig_post)) { - Logger::notice('pumpio_send: no pumpio post ' . $b['parent']); + DI::logger()->notice('pumpio_send: no pumpio post ' . $b['parent']); return; } else { $iscomment = true; @@ -409,7 +408,7 @@ function pumpio_send(array &$b) $receiver = pumpio_getreceiver($b); - Logger::notice('pumpio_send: receiver ', $receiver); + DI::logger()->notice('pumpio_send: receiver ', $receiver); if (!count($receiver) && ($b['private'] == Item::PRIVATE) || !strstr($b['postopts'], 'pumpio')) { return; @@ -543,13 +542,13 @@ function pumpio_send(array &$b) } $post_id = $user->object->id; - Logger::notice('pumpio_send ' . $username . ': success ' . $post_id); + DI::logger()->notice('pumpio_send ' . $username . ': success ' . $post_id); if ($post_id && $iscomment) { - Logger::notice('pumpio_send ' . $username . ': Update extid ' . $post_id . ' for post id ' . $b['id']); + DI::logger()->notice('pumpio_send ' . $username . ': Update extid ' . $post_id . ' for post id ' . $b['id']); Item::update(['extid' => $post_id], ['id' => $b['id']]); } } else { - Logger::notice('pumpio_send '.$username.': '.$url.' general error: ' . print_r($user, true)); + DI::logger()->notice('pumpio_send '.$username.': '.$url.' general error: ' . print_r($user, true)); Worker::defer(); } } @@ -619,9 +618,9 @@ function pumpio_action(int $uid, string $uri, string $action, string $content = } if ($success) { - Logger::notice('pumpio_action '.$username.' '.$action.': success '.$uri); + DI::logger()->notice('pumpio_action '.$username.' '.$action.': success '.$uri); } else { - Logger::notice('pumpio_action '.$username.' '.$action.': general error: '.$uri); + DI::logger()->notice('pumpio_action '.$username.' '.$action.': general error: '.$uri); Worker::defer(); } } @@ -639,15 +638,15 @@ function pumpio_sync() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('pumpio: poll intervall not reached'); + DI::logger()->notice('pumpio: poll intervall not reached'); return; } } - Logger::notice('pumpio: cron_start'); + DI::logger()->notice('pumpio: cron_start'); $pconfigs = DBA::selectToArray('pconfig', ['uid'], ['cat' => 'pumpio', 'k' => 'mirror', 'v' => '1']); foreach ($pconfigs as $rr) { - Logger::notice('pumpio: mirroring user '.$rr['uid']); + DI::logger()->notice('pumpio: mirroring user '.$rr['uid']); pumpio_fetchtimeline($rr['uid']); } @@ -662,12 +661,12 @@ function pumpio_sync() foreach ($pconfigs as $rr) { if ($abandon_days != 0) { if (DBA::exists('user', ["uid = ? AND `login_date` >= ?", $rr['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user '.$rr['uid'].' will not be imported'); + DI::logger()->notice('abandoned account: timeline from user '.$rr['uid'].' will not be imported'); continue; } } - Logger::notice('pumpio: importing timeline from user '.$rr['uid']); + DI::logger()->notice('pumpio: importing timeline from user '.$rr['uid']); pumpio_fetchinbox($rr['uid']); // check for new contacts once a day @@ -684,7 +683,7 @@ function pumpio_sync() } } - Logger::notice('pumpio: cron_end'); + DI::logger()->notice('pumpio: cron_end'); DI::keyValue()->set('pumpio_last_poll', time()); } @@ -729,7 +728,7 @@ function pumpio_fetchtimeline(int $uid) $url = 'https://'.$hostname.'/api/user/'.$username.'/feed/major'; - Logger::notice('pumpio: fetching for user ' . $uid . ' ' . $url . ' C:' . $client->client_id . ' CS:' . $client->client_secret . ' T:' . $client->access_token . ' TS:' . $client->access_token_secret); + DI::logger()->notice('pumpio: fetching for user ' . $uid . ' ' . $url . ' C:' . $client->client_id . ' CS:' . $client->client_secret . ' T:' . $client->access_token . ' TS:' . $client->access_token_secret); $useraddr = $username.'@'.$hostname; @@ -741,7 +740,7 @@ function pumpio_fetchtimeline(int $uid) } if (!$success) { - Logger::notice('pumpio: error fetching posts for user ' . $uid . ' ' . $useraddr . ' ', $user); + DI::logger()->notice('pumpio: error fetching posts for user ' . $uid . ' ' . $useraddr . ' ', $user); return; } @@ -801,11 +800,11 @@ function pumpio_fetchtimeline(int $uid) } } - Logger::notice('pumpio: posting for user ' . $uid); + DI::logger()->notice('pumpio: posting for user ' . $uid); Item::insert($postarray, true); - Logger::notice('pumpio: posting done - user ' . $uid); + DI::logger()->notice('pumpio: posting done - user ' . $uid); } } } @@ -846,16 +845,16 @@ function pumpio_dounlike(int $uid, array $self, $post, string $own_id) Item::markForDeletion(['verb' => Activity::LIKE, 'uid' => $uid, 'contact-id' => $contactid, 'thr-parent' => $orig_post['uri']]); if (DBA::isResult($contact)) { - Logger::notice('pumpio_dounlike: unliked existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dounlike: unliked existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); } else { - Logger::notice('pumpio_dounlike: not found. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' Url ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dounlike: not found. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' Url ' . $orig_post['uri']); } } function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcompletion = true) { if (empty($post->object->id)) { - Logger::info('Got empty like: '.print_r($post, true)); + DI::logger()->info('Got empty like: '.print_r($post, true)); return; } @@ -900,7 +899,7 @@ function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcomp ]; if (Post::exists($condition)) { - Logger::notice('pumpio_dolike: found existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dolike: found existing like. User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); return; } @@ -934,7 +933,7 @@ function pumpio_dolike(int $uid, array $self, $post, string $own_id, $threadcomp $ret = Item::insert($likedata); - Logger::notice('pumpio_dolike: ' . $ret . ' User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); + DI::logger()->notice('pumpio_dolike: ' . $ret . ' User ' . $own_id . ' ' . $uid . ' Contact: ' . $contactid . ' URI ' . $orig_post['uri']); } function pumpio_get_contact($uid, $contact, $no_insert = false) @@ -1405,7 +1404,7 @@ function pumpio_fetchallcomments($uid, $id) $hostname = DI::pConfig()->get($uid, 'pumpio', 'host'); $username = DI::pConfig()->get($uid, 'pumpio', 'user'); - Logger::notice('pumpio_fetchallcomments: completing comment for user ' . $uid . ' post id ' . $id); + DI::logger()->notice('pumpio_fetchallcomments: completing comment for user ' . $uid . ' post id ' . $id); $own_id = 'https://' . $hostname . '/' . $username; @@ -1430,7 +1429,7 @@ function pumpio_fetchallcomments($uid, $id) $client->access_token = $otoken; $client->access_token_secret = $osecret; - Logger::notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); + DI::logger()->notice('pumpio_fetchallcomments: fetching comment for user ' . $uid . ', URL ' . $url); $item = new \stdClass(); @@ -1495,7 +1494,7 @@ function pumpio_fetchallcomments($uid, $id) $post->object = $item; - Logger::notice('pumpio_fetchallcomments: posting comment ' . $post->object->id . ' ', json_decode(json_encode($post), true)); + DI::logger()->notice('pumpio_fetchallcomments: posting comment ' . $post->object->id . ' ', json_decode(json_encode($post), true)); pumpio_dopost($client, $uid, $self, $post, $own_id, false); } } From 32a3160445d6a148b81daadd169705ddfe5558af Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:56:09 +0000 Subject: [PATCH 251/294] Replace call for Logger with DI::logger() in randplace addon --- randplace/randplace.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/randplace/randplace.php b/randplace/randplace.php index 5cb07597..89a75f98 100644 --- a/randplace/randplace.php +++ b/randplace/randplace.php @@ -20,7 +20,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\DI; @@ -40,7 +39,7 @@ function randplace_install() Hook::register('addon_settings', 'addon/randplace/randplace.php', 'randplace_settings'); Hook::register('addon_settings_post', 'addon/randplace/randplace.php', 'randplace_settings_post'); - Logger::notice("installed randplace"); + DI::logger()->notice("installed randplace"); } function randplace_uninstall() @@ -50,7 +49,7 @@ function randplace_uninstall() * * Except hooks, they are all unregistered automatically and don't need to be unregistered manually. */ - Logger::notice("removed randplace"); + DI::logger()->notice("removed randplace"); } function randplace_post_hook(&$item) @@ -61,7 +60,7 @@ function randplace_post_hook(&$item) * - A status post by a profile owner * - The profile owner must have allowed our addon */ - Logger::notice('randplace invoked'); + DI::logger()->notice('randplace invoked'); if (!DI::userSession()->getLocalUserId()) { /* non-zero if this is a logged in user of this system */ From ac6c1d7a49a386555c054faa6d13bb108856ebd0 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:56:29 +0000 Subject: [PATCH 252/294] Replace call for Logger with DI::logger() in saml addon --- saml/saml.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index 81a6bfcc..c8824b46 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -8,7 +8,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -63,7 +62,7 @@ function saml_metadata() ); } } catch (Exception $e) { - Logger::error($e->getMessage()); + DI::logger()->error($e->getMessage()); } } @@ -125,7 +124,7 @@ function saml_is_configured() function saml_sso_initiate(string &$body) { if (!saml_is_configured()) { - Logger::warning('SAML SSO tried to trigger, but the SAML addon is not configured yet!'); + DI::logger()->warning('SAML SSO tried to trigger, but the SAML addon is not configured yet!'); return; } @@ -154,7 +153,7 @@ function saml_sso_reply() if (!empty($errors)) { echo 'Errors encountered.'; - Logger::error(implode(', ', $errors)); + DI::logger()->error(implode(', ', $errors)); exit(); } @@ -190,7 +189,7 @@ function saml_sso_reply() function saml_slo_initiate() { if (!saml_is_configured()) { - Logger::warning('SAML SLO tried to trigger, but the SAML addon is not configured yet!'); + DI::logger()->warning('SAML SLO tried to trigger, but the SAML addon is not configured yet!'); return; } @@ -221,7 +220,7 @@ function saml_slo_reply() if (empty($errors)) { $auth->redirectTo(DI::baseUrl()); } else { - Logger::error(implode(', ', $errors)); + DI::logger()->error(implode(', ', $errors)); } } @@ -314,7 +313,7 @@ function saml_addon_admin_post() function saml_create_user($username, $email, $name) { if (!strlen($email) || !strlen($name)) { - Logger::error('Could not create user: no email or username given.'); + DI::logger()->error('Could not create user: no email or username given.'); return false; } @@ -336,7 +335,7 @@ function saml_create_user($username, $email, $name) return $user; } catch (Exception $e) { - Logger::error( + DI::logger()->error( 'Exception while creating user', [ 'username' => $username, From bfdccb451ce391361de025d01565b4a52af99d6c Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:56:45 +0000 Subject: [PATCH 253/294] Replace call for Logger with DI::logger() in statusnet addon --- statusnet/statusnet.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/statusnet/statusnet.php b/statusnet/statusnet.php index bd115115..8663aaea 100644 --- a/statusnet/statusnet.php +++ b/statusnet/statusnet.php @@ -40,7 +40,6 @@ require_once __DIR__ . DIRECTORY_SEPARATOR . 'library' . DIRECTORY_SEPARATOR . ' use CodebirdSN\CodebirdSN; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\System; use Friendica\Database\DBA; @@ -58,7 +57,7 @@ function statusnet_install() Hook::register('hook_fork', 'addon/statusnet/statusnet.php', 'statusnet_hook_fork'); Hook::register('post_local', 'addon/statusnet/statusnet.php', 'statusnet_post_local'); Hook::register('jot_networks', 'addon/statusnet/statusnet.php', 'statusnet_jot_nets'); - Logger::notice('installed GNU Social'); + DI::logger()->notice('installed GNU Social'); } function statusnet_jot_nets(array &$jotnets_fields) @@ -355,7 +354,7 @@ function statusnet_post_hook(array &$b) return; } - Logger::notice('GNU Socialpost invoked'); + DI::logger()->notice('GNU Socialpost invoked'); DI::pConfig()->load($b['uid'], 'statusnet'); @@ -407,7 +406,7 @@ function statusnet_post_hook(array &$b) $cb->setToken($otoken, $osecret); $result = $cb->statuses_update($postdata); //$result = $dent->post('statuses/update', $postdata); - Logger::info('statusnet_post send, result: ' . print_r($result, true) . + DI::logger()->info('statusnet_post send, result: ' . print_r($result, true) . "\nmessage: " . $msg . "\nOriginal post: " . print_r($b, true) . "\nPost Data: " . print_r($postdata, true)); if (!empty($result->source)) { @@ -415,9 +414,9 @@ function statusnet_post_hook(array &$b) } if (!empty($result->error)) { - Logger::notice('Send to GNU Social failed: "' . $result->error . '"'); + DI::logger()->notice('Send to GNU Social failed: "' . $result->error . '"'); } elseif ($iscomment) { - Logger::notice('statusnet_post: Update extid ' . $result->id . ' for post id ' . $b['id']); + DI::logger()->notice('statusnet_post: Update extid ' . $result->id . ' for post id ' . $b['id']); Item::update(['extid' => $hostname . '::' . $result->id, 'body' => $result->text], ['id' => $b['id']]); } } From 763c5026f237a569f9f6cc9b4b65311556ca0087 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:57:12 +0000 Subject: [PATCH 254/294] Replace call for Logger with DI::logger() in tumblr addon --- tumblr/tumblr.php | 99 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/tumblr/tumblr.php b/tumblr/tumblr.php index 12f13aa8..819c0ca5 100644 --- a/tumblr/tumblr.php +++ b/tumblr/tumblr.php @@ -14,7 +14,6 @@ use Friendica\Content\Text\NPF; use Friendica\Core\Cache\Enum\Duration; use Friendica\Core\Config\Util\ConfigFileManager; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Protocol; use Friendica\Core\Renderer; use Friendica\Core\System; @@ -60,7 +59,7 @@ function tumblr_install() Hook::register('check_item_notification', __FILE__, 'tumblr_check_item_notification'); Hook::register('probe_detect', __FILE__, 'tumblr_probe_detect'); Hook::register('item_by_link', __FILE__, 'tumblr_item_by_link'); - Logger::info('installed tumblr'); + DI::logger()->info('installed tumblr'); } function tumblr_load_config(ConfigFileManager $loader) @@ -121,16 +120,16 @@ function tumblr_item_by_link(array &$hookData) return; } - Logger::debug('Found tumblr post', ['url' => $hookData['uri'], 'blog' => $matches[1], 'id' => $matches[2]]); + DI::logger()->debug('Found tumblr post', ['url' => $hookData['uri'], 'blog' => $matches[1], 'id' => $matches[2]]); $parameters = ['id' => $matches[2], 'reblog_info' => false, 'notes_info' => false, 'npf' => false]; $result = tumblr_get($hookData['uid'], 'blog/' . $matches[1] . '/posts', $parameters); if ($result->meta->status > 399) { - Logger::notice('Error fetching status', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'blog' => $matches[1], 'id' => $matches[2]]); + DI::logger()->notice('Error fetching status', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'blog' => $matches[1], 'id' => $matches[2]]); return []; } - Logger::debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); + DI::logger()->debug('Got post', ['blog' => $matches[1], 'id' => $matches[2], 'result' => $result->response->posts]); if (!empty($result->response->posts)) { $hookData['item_id'] = tumblr_process_post($result->response->posts[0], $hookData['uid'], Item::PR_FETCHED); Item::incrementInbound(Protocol::TUMBLR); @@ -159,20 +158,20 @@ function tumblr_follow(array &$hook_data) return; } - Logger::debug('Check if contact is Tumblr', ['url' => $hook_data['url']]); + DI::logger()->debug('Check if contact is Tumblr', ['url' => $hook_data['url']]); $fields = tumblr_get_contact_by_url($hook_data['url'], $uid); if (empty($fields)) { - Logger::debug('Contact is not a Tumblr contact', ['url' => $hook_data['url']]); + DI::logger()->debug('Contact is not a Tumblr contact', ['url' => $hook_data['url']]); return; } $result = tumblr_post($uid, 'user/follow', ['url' => $fields['url']]); if ($result->meta->status <= 399) { $hook_data['contact'] = $fields; - Logger::debug('Successfully start following', ['url' => $fields['url']]); + DI::logger()->debug('Successfully start following', ['url' => $fields['url']]); } else { - Logger::notice('Following failed', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'url' => $fields['url']]); + DI::logger()->notice('Following failed', ['meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'url' => $fields['url']]); } } @@ -415,11 +414,11 @@ function tumblr_cron() if ($last) { $next = $last + ($poll_interval * 60); if ($next > time()) { - Logger::notice('poll interval not reached'); + DI::logger()->notice('poll interval not reached'); return; } } - Logger::notice('cron_start'); + DI::logger()->notice('cron_start'); $abandon_days = intval(DI::config()->get('system', 'account_abandon_days')); if ($abandon_days < 1) { @@ -432,30 +431,30 @@ function tumblr_cron() foreach ($pconfigs as $pconfig) { if ($abandon_days != 0) { if (!DBA::exists('user', ["`uid` = ? AND `login_date` >= ?", $pconfig['uid'], $abandon_limit])) { - Logger::notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); + DI::logger()->notice('abandoned account: timeline from user will not be imported', ['user' => $pconfig['uid']]); continue; } } - Logger::notice('importing timeline - start', ['user' => $pconfig['uid']]); + DI::logger()->notice('importing timeline - start', ['user' => $pconfig['uid']]); tumblr_fetch_dashboard($pconfig['uid'], $last); tumblr_fetch_tags($pconfig['uid'], $last); - Logger::notice('importing timeline - done', ['user' => $pconfig['uid']]); + DI::logger()->notice('importing timeline - done', ['user' => $pconfig['uid']]); } $last_clean = DI::keyValue()->get('tumblr_last_clean'); if (empty($last_clean) || ($last_clean + 86400 < time())) { - Logger::notice('Start contact cleanup'); + DI::logger()->notice('Start contact cleanup'); $contacts = DBA::select('account-user-view', ['id', 'pid'], ["`network` = ? AND `uid` != ? AND `rel` = ?", Protocol::TUMBLR, 0, Contact::NOTHING]); while ($contact = DBA::fetch($contacts)) { Worker::add(Worker::PRIORITY_LOW, 'MergeContact', $contact['pid'], $contact['id'], 0); } DBA::close($contacts); DI::keyValue()->set('tumblr_last_clean', time()); - Logger::notice('Contact cleanup done'); + DI::logger()->notice('Contact cleanup done'); } - Logger::notice('cron_end'); + DI::logger()->notice('cron_end'); DI::keyValue()->set('tumblr_last_poll', time()); } @@ -478,7 +477,7 @@ function tumblr_hook_fork(array &$b) if (DI::pConfig()->get($post['uid'], 'tumblr', 'import')) { // Don't post if it isn't a reply to a tumblr post if (($post['gravity'] != Item::GRAVITY_PARENT) && !Post::exists(['id' => $post['parent'], 'network' => Protocol::TUMBLR])) { - Logger::notice('No tumblr parent found', ['item' => $post['id']]); + DI::logger()->notice('No tumblr parent found', ['item' => $post['id']]); $b['execute'] = false; return; } @@ -525,20 +524,20 @@ function tumblr_send(array &$b) } if ($b['gravity'] != Item::GRAVITY_PARENT) { - Logger::debug('Got comment', ['item' => $b]); + DI::logger()->debug('Got comment', ['item' => $b]); $parent = tumblr_get_post_from_uri($b['thr-parent']); if (empty($parent)) { - Logger::notice('No tumblr post', ['thr-parent' => $b['thr-parent']]); + DI::logger()->notice('No tumblr post', ['thr-parent' => $b['thr-parent']]); return; } - Logger::debug('Parent found', ['parent' => $parent]); + DI::logger()->debug('Parent found', ['parent' => $parent]); $page = tumblr_get_page($b['uid']); if ($b['gravity'] == Item::GRAVITY_COMMENT) { - Logger::notice('Commenting is not supported (yet)'); + DI::logger()->notice('Commenting is not supported (yet)'); } else { if (($b['verb'] == Activity::LIKE) && !$b['deleted']) { $params = ['id' => $parent['id'], 'reblog_key' => $parent['reblog_key']]; @@ -562,12 +561,12 @@ function tumblr_send(array &$b) } if ($result->meta->status < 400) { - Logger::info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Successfully performed activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response]); if (!$b['deleted'] && !empty($result->response->id_string)) { Item::update(['extid' => 'tumblr::' . $result->response->id_string], ['guid' => $b['guid']]); } } else { - Logger::notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error while performing activity', ['verb' => $b['verb'], 'deleted' => $b['deleted'], 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); } } return; @@ -665,9 +664,9 @@ function tumblr_send_legacy(array $b) $result = tumblr_post($b['uid'], 'blog/' . $page . '/post', $params); if ($result->meta->status < 400) { - Logger::info('Success (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Success (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); } else { - Logger::notice('Error posting blog (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error posting blog (legacy)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); } } @@ -676,7 +675,7 @@ function tumblr_send_npf(array $post): bool $page = tumblr_get_page($post['uid']); if (empty($page)) { - Logger::notice('Missing page, post will not be send to Tumblr.', ['uid' => $post['uid'], 'page' => $page, 'id' => $post['id']]); + DI::logger()->notice('Missing page, post will not be send to Tumblr.', ['uid' => $post['uid'], 'page' => $page, 'id' => $post['id']]); // "true" is returned, since the legacy function will fail as well. return true; } @@ -707,10 +706,10 @@ function tumblr_send_npf(array $post): bool $result = tumblr_post($post['uid'], 'blog/' . $page . '/posts', $params); if ($result->meta->status < 400) { - Logger::info('Success (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); + DI::logger()->info('Success (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response]); return true; } else { - Logger::notice('Error posting blog (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); + DI::logger()->notice('Error posting blog (NPF)', ['blog' => $page, 'meta' => $result->meta, 'response' => $result->response, 'errors' => $result->errors, 'params' => $params]); return false; } } @@ -747,10 +746,10 @@ function tumblr_fetch_tags(int $uid, int $last_poll) foreach (array_reverse($data->response) as $post) { $id = tumblr_process_post($post, $uid, Item::PR_TAG, $last_poll); if (!empty($id)) { - Logger::debug('Tag post imported', ['tag' => $tag, 'id' => $id]); + DI::logger()->debug('Tag post imported', ['tag' => $tag, 'id' => $id]); $post = Post::selectFirst(['uri-id'], ['id' => $id]); $stored = Post\Category::storeFileByURIId($post['uri-id'], $uid, Post\Category::SUBCRIPTION, $tag); - Logger::debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); + DI::logger()->debug('Stored tag subscription for user', ['uri-id' => $post['uri-id'], 'uid' => $uid, 'tag' => $tag, 'stored' => $stored]); Item::incrementInbound(Protocol::TUMBLR); } } @@ -775,7 +774,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) $dashboard = tumblr_get($uid, 'user/dashboard', $parameters); if ($dashboard->meta->status > 399) { - Logger::notice('Error fetching dashboard', ['meta' => $dashboard->meta, 'response' => $dashboard->response, 'errors' => $dashboard->errors]); + DI::logger()->notice('Error fetching dashboard', ['meta' => $dashboard->meta, 'response' => $dashboard->response, 'errors' => $dashboard->errors]); return []; } @@ -788,7 +787,7 @@ function tumblr_fetch_dashboard(int $uid, int $last_poll) $last = $post->id; } - Logger::debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); + DI::logger()->debug('Importing post', ['uid' => $uid, 'created' => date(DateTimeFormat::MYSQL, $post->timestamp), 'id' => $post->id_string]); tumblr_process_post($post, $uid, Item::PR_NONE, $last_poll); Item::incrementInbound(Protocol::TUMBLR); @@ -1063,7 +1062,7 @@ function tumblr_get_type_replacement(array $data, string $plink): string } default: - Logger::notice('Unknown type', ['type' => $data['type'], 'data' => $data, 'plink' => $plink]); + DI::logger()->notice('Unknown type', ['type' => $data['type'], 'data' => $data, 'plink' => $plink]); $body = ''; } @@ -1118,9 +1117,9 @@ function tumblr_get_contact(stdClass $blog, int $uid): array $cid = $contact['id']; Contact::update($fields, ['id' => $cid], true); } - Logger::debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); + DI::logger()->debug('Get user contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); } else { - Logger::debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); + DI::logger()->debug('Get public contact', ['id' => $cid, 'uid' => $uid, 'update' => $update]); } if (!empty($avatar)) { @@ -1156,13 +1155,13 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra ]; if (!$update) { - Logger::debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url']]); + DI::logger()->debug('Got contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; } $info = tumblr_get($uid, 'blog/' . $blog->uuid . '/info'); if ($info->meta->status > 399) { - Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); + DI::logger()->notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors]); return $fields; } Item::incrementInbound(Protocol::TUMBLR); @@ -1184,7 +1183,7 @@ function tumblr_get_contact_fields(stdClass $blog, int $uid, bool $update): arra $fields['header'] = $info->response->blog->theme->header_image_focused; - Logger::debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); + DI::logger()->debug('Got updated contact fields', ['uid' => $uid, 'url' => $fields['url']]); return $fields; } @@ -1226,7 +1225,7 @@ function tumblr_get_blogs(int $uid): array { $userinfo = tumblr_get($uid, 'user/info'); if ($userinfo->meta->status > 399) { - Logger::notice('Error fetching blogs', ['meta' => $userinfo->meta, 'response' => $userinfo->response, 'errors' => $userinfo->errors]); + DI::logger()->notice('Error fetching blogs', ['meta' => $userinfo->meta, 'response' => $userinfo->response, 'errors' => $userinfo->errors]); return []; } @@ -1282,15 +1281,15 @@ function tumblr_get_contact_by_url(string $url, int $uid): ?array return null; } - Logger::debug('Update Tumblr blog data', ['url' => $url, 'blog' => $blog, 'uid' => $uid]); + DI::logger()->debug('Update Tumblr blog data', ['url' => $url, 'blog' => $blog, 'uid' => $uid]); $info = tumblr_get($uid, 'blog/' . $blog . '/info'); if ($info->meta->status > 399) { - Logger::notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); + DI::logger()->notice('Error fetching blog info', ['meta' => $info->meta, 'response' => $info->response, 'errors' => $info->errors, 'blog' => $blog, 'uid' => $uid]); return null; } - Logger::debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); + DI::logger()->debug('Got data', ['blog' => $blog, 'meta' => $info->meta]); Item::incrementInbound(Protocol::TUMBLR); $baseurl = 'https://tumblr.com'; @@ -1419,7 +1418,7 @@ function tumblr_get_token(int $uid, string $code = ''): string $refresh_token = DI::pConfig()->get($uid, 'tumblr', 'refresh_token'); if (empty($code) && !empty($access_token) && ($expires_at > (time()))) { - Logger::debug('Got token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Got token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); return $access_token; } @@ -1431,11 +1430,11 @@ function tumblr_get_token(int $uid, string $code = ''): string if (empty($refresh_token) && empty($code)) { $result = tumblr_exchange_token($uid); if (empty($result->refresh_token)) { - Logger::info('Invalid result while exchanging token', ['uid' => $uid]); + DI::logger()->info('Invalid result while exchanging token', ['uid' => $uid]); return ''; } $expires_at = time() + $result->expires_in; - Logger::debug('Updated token from OAuth1 to OAuth2', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Updated token from OAuth1 to OAuth2', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); } else { if (!empty($code)) { $parameters['code'] = $code; @@ -1447,18 +1446,18 @@ function tumblr_get_token(int $uid, string $code = ''): string $curlResult = DI::httpClient()->post('https://api.tumblr.com/v2/oauth2/token', $parameters); if (!$curlResult->isSuccess()) { - Logger::info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); + DI::logger()->info('Error fetching token', ['uid' => $uid, 'code' => $code, 'result' => $curlResult->getBodyString(), 'parameters' => $parameters]); return ''; } $result = json_decode($curlResult->getBodyString()); if (empty($result)) { - Logger::info('Invalid result when updating token', ['uid' => $uid]); + DI::logger()->info('Invalid result when updating token', ['uid' => $uid]); return ''; } $expires_at = time() + $result->expires_in; - Logger::debug('Renewed token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); + DI::logger()->debug('Renewed token', ['uid' => $uid, 'expires_at' => date('c', $expires_at)]); } DI::pConfig()->set($uid, 'tumblr', 'access_token', $result->access_token); @@ -1502,7 +1501,7 @@ function tumblr_exchange_token(int $uid): stdClass $response = $client->post('oauth2/exchange', ['auth' => 'oauth']); return json_decode($response->getBody()->getContents()); } catch (RequestException $exception) { - Logger::notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->notice('Exchange failed', ['code' => $exception->getCode(), 'message' => $exception->getMessage()]); return new stdClass; } } From a7b26f64538159e72799fae87679d1d10e0b1bb3 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:57:34 +0000 Subject: [PATCH 255/294] Replace call for Logger with DI::logger() in tesseract addon --- tesseract/tesseract.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php index 4c630dbb..ea048032 100644 --- a/tesseract/tesseract.php +++ b/tesseract/tesseract.php @@ -7,7 +7,6 @@ */ use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\System; use thiagoalessio\TesseractOCR\TesseractOCR; @@ -17,7 +16,7 @@ function tesseract_install() { Hook::register('ocr-detection', __FILE__, 'tesseract_ocr_detection'); - Logger::notice('installed tesseract'); + DI::logger()->notice('installed tesseract'); } function tesseract_ocr_detection(&$media) @@ -33,6 +32,6 @@ function tesseract_ocr_detection(&$media) $ocr->imageData($media['img_str'], strlen($media['img_str'])); $media['description'] = $ocr->run(); } catch (\Throwable $th) { - Logger::info('Error calling TesseractOCR', ['message' => $th->getMessage()]); + DI::logger()->info('Error calling TesseractOCR', ['message' => $th->getMessage()]); } } From e4d14cab62755aa91d986584b4898d75054b3471 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:58:10 +0000 Subject: [PATCH 256/294] Replace call for Logger with DI::logger() in twitter addon --- tesseract/tesseract.php | 1 + twitter/twitter.php | 31 +++++++++++++++---------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tesseract/tesseract.php b/tesseract/tesseract.php index ea048032..a07c690c 100644 --- a/tesseract/tesseract.php +++ b/tesseract/tesseract.php @@ -8,6 +8,7 @@ use Friendica\Core\Hook; use Friendica\Core\System; +use Friendica\DI; use thiagoalessio\TesseractOCR\TesseractOCR; require_once __DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'; diff --git a/twitter/twitter.php b/twitter/twitter.php index ea4ae356..a9654405 100644 --- a/twitter/twitter.php +++ b/twitter/twitter.php @@ -38,7 +38,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\Plaintext; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Core\Worker; use Friendica\DI; @@ -217,7 +216,7 @@ function twitter_post_hook(array &$b) $b['body'] = Post\Media::addAttachmentsToBody($b['uri-id'], DI::contentItem()->addSharedPost($b)); - Logger::notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]); + DI::logger()->notice('twitter post invoked', ['id' => $b['id'], 'guid' => $b['guid']]); DI::pConfig()->load($b['uid'], 'twitter'); @@ -227,17 +226,17 @@ function twitter_post_hook(array &$b) $access_secret = DI::pConfig()->get($b['uid'], 'twitter', 'access_secret'); if (empty($api_key) || empty($api_secret) || empty($access_token) || empty($access_secret)) { - Logger::info('Missing keys, secrets or tokens.'); + DI::logger()->info('Missing keys, secrets or tokens.'); return; } $msgarr = Plaintext::getPost($b, 280, true, BBCode::TWITTER); - Logger::debug('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]); + DI::logger()->debug('Got plaintext', ['id' => $b['id'], 'message' => $msgarr]); $media_ids = []; if (!empty($msgarr['images']) || !empty($msgarr['remote_images'])) { - Logger::info('Got images', ['id' => $b['id'], 'images' => $msgarr['images'] ?? []]); + DI::logger()->info('Got images', ['id' => $b['id'], 'images' => $msgarr['images'] ?? []]); $retrial = Worker::getRetrial(); if ($retrial > 4) { @@ -250,7 +249,7 @@ function twitter_post_hook(array &$b) try { $media_ids[] = twitter_upload_image($b['uid'], $image, $retrial); } catch (RequestException $exception) { - Logger::warning('Error while uploading image', ['image' => $image, 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->warning('Error while uploading image', ['image' => $image, 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); Worker::defer(); return; } @@ -259,13 +258,13 @@ function twitter_post_hook(array &$b) $in_reply_to_tweet_id = 0; - Logger::debug('Post message', ['id' => $b['id'], 'parts' => count($msgarr['parts'])]); + DI::logger()->debug('Post message', ['id' => $b['id'], 'parts' => count($msgarr['parts'])]); foreach ($msgarr['parts'] as $key => $part) { try { $id = twitter_post_status($b['uid'], $part, $media_ids, $in_reply_to_tweet_id); - Logger::info('twitter_post send', ['part' => $key, 'id' => $b['id'], 'result' => $id]); + DI::logger()->info('twitter_post send', ['part' => $key, 'id' => $b['id'], 'result' => $id]); } catch (RequestException $exception) { - Logger::warning('Error while posting message', ['part' => $key, 'id' => $b['id'], 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); + DI::logger()->warning('Error while posting message', ['part' => $key, 'id' => $b['id'], 'code' => $exception->getCode(), 'message' => $exception->getMessage()]); $status = [ 'code' => $exception->getCode(), 'reason' => $exception->getResponse()->getReasonPhrase(), @@ -319,9 +318,9 @@ function twitter_upload_image(int $uid, array $image, int $retrial) $picturedata = $picture->asString(); $new_size = strlen($picturedata); - Logger::info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); + DI::logger()->info('Uploading', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); $media = twitter_post($uid, 'https://upload.twitter.com/1.1/media/upload.json', 'form_params', ['media' => base64_encode($picturedata)]); - Logger::info('Uploading done', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); + DI::logger()->info('Uploading done', ['uid' => $uid, 'retrial' => $retrial, 'height' => $new_height, 'width' => $new_width, 'size' => $new_size, 'orig-height' => $height, 'orig-width' => $width, 'orig-size' => $size, 'image' => $image]); if (isset($media->media_id_string)) { $media_id = $media->media_id_string; @@ -334,10 +333,10 @@ function twitter_upload_image(int $uid, array $image, int $retrial) ] ]; $ret = twitter_post($uid, 'https://upload.twitter.com/1.1/media/metadata/create.json', 'json', $data); - Logger::info('Metadata create', ['uid' => $uid, 'data' => $data, 'return' => $ret]); + DI::logger()->info('Metadata create', ['uid' => $uid, 'data' => $data, 'return' => $ret]); } } else { - Logger::error('Failed upload', ['uid' => $uid, 'size' => strlen($picturedata), 'image' => $image['url'], 'return' => $media]); + DI::logger()->error('Failed upload', ['uid' => $uid, 'size' => strlen($picturedata), 'image' => $image['url'], 'return' => $media]); throw new Exception('Failed upload of ' . $image['url']); } @@ -373,7 +372,7 @@ function twitter_post(int $uid, string $url, string $type, array $data): stdClas DI::pConfig()->set($uid, 'twitter', 'last_status', $status); $content = json_decode($body) ?? new stdClass; - Logger::debug('Success', ['content' => $content]); + DI::logger()->debug('Success', ['content' => $content]); return $content; } @@ -402,7 +401,7 @@ function twitter_test_connection(int $uid) 'content' => $response->getBody()->getContents() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); - Logger::info('Test successful', ['uid' => $uid]); + DI::logger()->info('Test successful', ['uid' => $uid]); } catch (RequestException $exception) { $status = [ 'code' => $exception->getCode(), @@ -410,6 +409,6 @@ function twitter_test_connection(int $uid) 'content' => $exception->getMessage() ]; DI::pConfig()->set(1, 'twitter', 'last_status', $status); - Logger::info('Test failed', ['uid' => $uid]); + DI::logger()->info('Test failed', ['uid' => $uid]); } } From dd775645d48b0309e08f604500e2baf85171800f Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 11:58:32 +0000 Subject: [PATCH 257/294] Replace call for Logger with DI::logger() in wppost addon --- wppost/wppost.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wppost/wppost.php b/wppost/wppost.php index f2ee5d21..de216806 100644 --- a/wppost/wppost.php +++ b/wppost/wppost.php @@ -9,7 +9,6 @@ use Friendica\Content\Text\BBCode; use Friendica\Content\Text\HTML; use Friendica\Core\Hook; -use Friendica\Core\Logger; use Friendica\Core\Renderer; use Friendica\Database\DBA; use Friendica\DI; @@ -257,13 +256,13 @@ function wppost_send(array &$b) EOT; - Logger::debug('wppost: data: ' . $xml); + DI::logger()->debug('wppost: data: ' . $xml); $x = ''; if ($wp_blog !== 'test') { $x = DI::httpClient()->post($wp_blog, $xml)->getBodyString(); } - Logger::info('posted to wordpress: ' . $x); + DI::logger()->info('posted to wordpress: ' . $x); } } From 4c8c262b07f61d08a6f9a67c325a54dcb95b4c75 Mon Sep 17 00:00:00 2001 From: Art4 Date: Fri, 24 Jan 2025 12:10:58 +0000 Subject: [PATCH 258/294] fix in googlemaps addon --- googlemaps/googlemaps.php | 1 + 1 file changed, 1 insertion(+) diff --git a/googlemaps/googlemaps.php b/googlemaps/googlemaps.php index a0bba8ad..94a3a96b 100644 --- a/googlemaps/googlemaps.php +++ b/googlemaps/googlemaps.php @@ -8,6 +8,7 @@ */ use Friendica\Core\Hook; +use Friendica\DI; function googlemaps_install() { From cbfcfb33494d1662de1a5f5689caa23d723d6bca Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 25 Jan 2025 02:44:54 +0000 Subject: [PATCH 259/294] Issue 14692: Avoid loop situation --- blockbot/blockbot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/blockbot/blockbot.php b/blockbot/blockbot.php index 163d0cbc..71e35c93 100644 --- a/blockbot/blockbot.php +++ b/blockbot/blockbot.php @@ -208,7 +208,7 @@ function blockbot_log_activitypub(string $url, string $agent) blockbot_save('activitypub-inbox-agents', $agent); } - if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER))) { + if (!empty($_SERVER['HTTP_SIGNATURE']) && !empty(HTTPSignature::getSigner('', $_SERVER, false))) { blockbot_save('activitypub-signature-agents', $agent); } } From 8384b74696b54c126a2b2c835a010403b6413b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakobus=20Sch=C3=BCrz?= Date: Thu, 23 Jan 2025 16:32:22 +0100 Subject: [PATCH 260/294] add condition for selected theme --- saml/saml.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/saml/saml.php b/saml/saml.php index c8824b46..83e4d3fd 100755 --- a/saml/saml.php +++ b/saml/saml.php @@ -82,11 +82,13 @@ function saml_footer(string &$body)