├── .gitignore
├── README.md
├── composer.json
├── composer.lock
├── configure.phtml
├── extension.php
├── metadata.json
├── static
└── style.css
└── vendor
├── autoload.php
├── composer
├── ClassLoader.php
├── InstalledVersions.php
├── LICENSE
├── autoload_classmap.php
├── autoload_namespaces.php
├── autoload_psr4.php
├── autoload_real.php
├── autoload_static.php
├── installed.json
├── installed.php
└── platform_check.php
├── fivefilters
└── readability.php
│ ├── .editorconfig
│ ├── .gitattributes
│ ├── .github
│ └── workflows
│ │ └── main.yml
│ ├── .gitignore
│ ├── AUTHORS.md
│ ├── CHANGELOG.md
│ ├── CONTRIBUTING.md
│ ├── LICENSE
│ ├── README.md
│ ├── composer.json
│ └── src
│ ├── Configuration.php
│ ├── Nodes
│ ├── DOM
│ │ ├── DOMAttr.php
│ │ ├── DOMCdataSection.php
│ │ ├── DOMCharacterData.php
│ │ ├── DOMComment.php
│ │ ├── DOMDocument.php
│ │ ├── DOMDocumentFragment.php
│ │ ├── DOMDocumentType.php
│ │ ├── DOMElement.php
│ │ ├── DOMEntity.php
│ │ ├── DOMEntityReference.php
│ │ ├── DOMNode.php
│ │ ├── DOMNodeList.php
│ │ ├── DOMNotation.php
│ │ ├── DOMProcessingInstruction.php
│ │ └── DOMText.php
│ ├── NodeTrait.php
│ └── NodeUtility.php
│ ├── ParseException.php
│ └── Readability.php
├── league
├── uri-interfaces
│ ├── Contracts
│ │ ├── AuthorityInterface.php
│ │ ├── DataPathInterface.php
│ │ ├── DomainHostInterface.php
│ │ ├── FragmentInterface.php
│ │ ├── HostInterface.php
│ │ ├── IpHostInterface.php
│ │ ├── PathInterface.php
│ │ ├── PortInterface.php
│ │ ├── QueryInterface.php
│ │ ├── SegmentedPathInterface.php
│ │ ├── UriAccess.php
│ │ ├── UriComponentInterface.php
│ │ ├── UriException.php
│ │ ├── UriInterface.php
│ │ └── UserInfoInterface.php
│ ├── Encoder.php
│ ├── Exceptions
│ │ ├── ConversionFailed.php
│ │ ├── MissingFeature.php
│ │ ├── OffsetOutOfBounds.php
│ │ └── SyntaxError.php
│ ├── FeatureDetection.php
│ ├── IPv4
│ │ ├── BCMathCalculator.php
│ │ ├── Calculator.php
│ │ ├── Converter.php
│ │ ├── GMPCalculator.php
│ │ └── NativeCalculator.php
│ ├── IPv6
│ │ └── Converter.php
│ ├── Idna
│ │ ├── Converter.php
│ │ ├── Error.php
│ │ ├── Option.php
│ │ └── Result.php
│ ├── KeyValuePair
│ │ └── Converter.php
│ ├── LICENSE
│ ├── QueryString.php
│ ├── UriString.php
│ └── composer.json
└── uri
│ ├── BaseUri.php
│ ├── Http.php
│ ├── HttpFactory.php
│ ├── LICENSE
│ ├── Uri.php
│ ├── UriInfo.php
│ ├── UriResolver.php
│ ├── UriTemplate.php
│ ├── UriTemplate
│ ├── Expression.php
│ ├── Operator.php
│ ├── Template.php
│ ├── TemplateCanNotBeExpanded.php
│ ├── VarSpecifier.php
│ └── VariableBag.php
│ └── composer.json
├── masterminds
└── html5
│ ├── CREDITS
│ ├── LICENSE.txt
│ ├── README.md
│ ├── RELEASE.md
│ ├── UPGRADING.md
│ ├── bin
│ └── entities.php
│ ├── composer.json
│ └── src
│ ├── HTML5.php
│ └── HTML5
│ ├── Elements.php
│ ├── Entities.php
│ ├── Exception.php
│ ├── InstructionProcessor.php
│ ├── Parser
│ ├── CharacterReference.php
│ ├── DOMTreeBuilder.php
│ ├── EventHandler.php
│ ├── FileInputStream.php
│ ├── InputStream.php
│ ├── ParseError.php
│ ├── README.md
│ ├── Scanner.php
│ ├── StringInputStream.php
│ ├── Tokenizer.php
│ ├── TreeBuildingRules.php
│ └── UTF8Utils.php
│ └── Serializer
│ ├── HTML5Entities.php
│ ├── OutputRules.php
│ ├── README.md
│ ├── RulesInterface.php
│ └── Traverser.php
└── psr
├── http-factory
├── .gitignore
├── .pullapprove.yml
├── LICENSE
├── README.md
├── composer.json
└── src
│ ├── RequestFactoryInterface.php
│ ├── ResponseFactoryInterface.php
│ ├── ServerRequestFactoryInterface.php
│ ├── StreamFactoryInterface.php
│ ├── UploadedFileFactoryInterface.php
│ └── UriFactoryInterface.php
├── http-message
├── CHANGELOG.md
├── LICENSE
├── README.md
├── composer.json
├── docs
│ ├── PSR7-Interfaces.md
│ └── PSR7-Usage.md
└── src
│ ├── MessageInterface.php
│ ├── RequestInterface.php
│ ├── ResponseInterface.php
│ ├── ServerRequestInterface.php
│ ├── StreamInterface.php
│ ├── UploadedFileInterface.php
│ └── UriInterface.php
└── log
├── LICENSE
├── README.md
├── composer.json
└── src
├── AbstractLogger.php
├── InvalidArgumentException.php
├── LogLevel.php
├── LoggerAwareInterface.php
├── LoggerAwareTrait.php
├── LoggerInterface.php
├── LoggerTrait.php
└── NullLogger.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/fivefilters/readability.php/test
2 | vendor/masterminds/html5/test
3 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Article Full Text FreshRSS Extension
2 |
3 | This FreshRSS extension uses the [Fivefilters Readability.php library](https://github.com/fivefilters/readability.php) to extract the full text of an article. Most importantly, it does **not** require any docker containers or external services to work.
4 |
5 | ## Features
6 | - Extracts full article content using [Readability.php library by Fivefilters](https://github.com/fivefilters/readability.php)
7 | - Works entirely client-side (no external services required)
8 | - Preserves original formatting when possible
9 |
10 | ## Requirements
11 | - PHP 8.1+, ext-dom, ext-xml, and ext-mbstring
12 |
13 | ## Installation
14 |
15 | ### Step-by-Step Installation Guide
16 |
17 | 1. **Download the extension**:
18 | - Clone this repository or download the ZIP file and extract it
19 | - The extension folder should be named `af_readability`
20 |
21 | 2. **Copy to FreshRSS extensions folder**:
22 | - Place the `af_readability` folder in your FreshRSS `extensions` directory
23 | - Typical paths:
24 | - Docker: `/usr/share/freshrss/extensions/`
25 | - Manual install: `/path/to/FreshRSS/extensions/`
26 |
27 | 3. **Set proper permissions**:
28 | - Ensure the web server has read access to the extension files
29 | - Example: `chown -R www-data:www-data /path/to/extensions/af_readability`
30 |
31 | ## Activation
32 |
33 | 1. **Log in** to your FreshRSS instance as an administrator
34 | 2. **Navigate** to the "System configuration" section in the admin panel
35 | 3. **Click** on the "Extensions" tab
36 | 4. **Find** "Af_Readability" in the list of available extensions
37 | 5. **Click** the toggle switch to enable the extension
38 | 6. **Click** "Save" to apply changes
39 |
40 | ## Configuration
41 |
42 | ### Enabling the plugin for a feed
43 |
44 | 1. After activation, go back to the "Extensions" tab in System configuration
45 | 2. Find "Af_Readability" in the list of active extensions
46 | 3. Click the gear/settings icon next to the extension name
47 | 4. Activate the checkbox for the feeds for which you want the plugin to fetch full article contents
48 | 5. Click "Save" to apply your settings
49 |
50 | ## Usage Notes
51 |
52 | - The extension processes **NEW** articles when they are first fetched
53 | - Existing articles won't be automatically reprocessed
54 |
55 | To reprocess existing articles:
56 | 1. Go to "Manage" → "Archiving" → "Delete all articles" (consider this step carefully)
57 | 2. Refresh your feeds to fetch articles again
58 | - "Clear cache" won't reprocess existing articles
59 |
60 | ## Troubleshooting
61 |
62 | - If articles aren't showing full text:
63 | - Ensure the extension is properly activated
64 | - Try deleting and refetching articles as described above
65 | - Check FreshRSS protocol for error messages related to the plugin
66 |
67 | ## Based on:
68 | - [ttrss-af_readability](https://gitlab.tt-rss.org/tt-rss/plugins/ttrss-af-readability) for Tiny Tiny RSS by Andrew Dolgov
69 | - [xExtension-Readable](https://github.com/printfuck/xExtension-Readable) for FreshRSS by printfuck
70 |
71 | [Official FreshRSS documentation](https://freshrss.github.io/FreshRSS/en/developers/03_Backend/05_Extensions.html) on writing extensions.
72 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "minimum-stability": "dev",
3 | "prefer-stable": true,
4 | "repositories": [
5 | {
6 | "name": "fivefilters/readability.php",
7 | "type": "vcs",
8 | "url": "https://github.com/fivefilters/readability.php.git"
9 | },
10 | {
11 | "name": "masterminds/html5",
12 | "type": "vcs",
13 | "url": "https://github.com/Masterminds/html5-php.git"
14 | }
15 | ],
16 | "config": {
17 | "platform": {
18 | "php": "8.1.0"
19 | }
20 | },
21 | "require": {
22 | "fivefilters/readability.php": "*",
23 | "psr/http-factory": "1.0.1"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/configure.phtml:
--------------------------------------------------------------------------------
1 |
5 |
70 |
--------------------------------------------------------------------------------
/metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Af_Readability",
3 | "author": "niehztog",
4 | "description": "Try to inline article content using Readability",
5 | "version": "0.1",
6 | "entrypoint": "Af_Readability",
7 | "type": "user"
8 | }
9 |
--------------------------------------------------------------------------------
/static/style.css:
--------------------------------------------------------------------------------
1 | td.rotate {
2 | /* Something you can count on */
3 | /*height: 60px; */
4 | white-space: nowrap;
5 | padding-bottom: 63px;
6 | border-width: 0px;
7 | padding-top: 0px;
8 | }
9 |
10 | td.rotate > div {
11 | transform:
12 | /* Magic Numbers */
13 | translate(25px, 51px)
14 | /* 45 is really 360 - 45 */
15 | rotate(315deg);
16 | width: 33px;
17 | margin-left: -8px;
18 | margin-bottom: 4px;
19 | }
20 | td.rotate > div > span {
21 | #padding: 20px 26px;
22 | border-top: 1px solid;
23 | margin: 0px -33px;
24 | margin-top: 6px;
25 | #padding-top: 8px;
26 | padding-left: 38px;
27 | }
28 | td.rotatelast {
29 | /* Something you can count on */
30 | /* height: 60px; */
31 | white-space: nowrap;
32 | padding-bottom: 63px;
33 | border-width: 0px;
34 | padding-top: 0px;
35 | }
36 | td.rotatelast > div {
37 | transform:
38 | /* Magic Numbers */
39 | translate(25px, 51px)
40 | /* 45 is really 360 - 45 */
41 | rotate(315deg);
42 | width: 33px;
43 | margin-left: -8px;
44 | margin-bottom: 4px;
45 | }
46 | td.rotatelast > div > span {
47 | #padding: 20px 26px;
48 | border-top: 1px solid;
49 | margin: 0px -33px;
50 | margin-top: 6px;
51 | #padding-top: 8px;
52 | padding-left: 34px;
53 | padding-right: 29px;
54 | }
55 |
56 | .form-group.form-fix {
57 | display: grid;
58 | }
59 |
60 | .boldtd {
61 | font-size: larger;
62 | font-weight: bold;
63 | }
64 |
--------------------------------------------------------------------------------
/vendor/autoload.php:
--------------------------------------------------------------------------------
1 | $vendorDir . '/composer/InstalledVersions.php',
10 | );
11 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_namespaces.php:
--------------------------------------------------------------------------------
1 | array($vendorDir . '/fivefilters/readability.php/src'),
10 | 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'),
11 | 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'),
12 | 'Masterminds\\' => array($vendorDir . '/masterminds/html5/src'),
13 | 'League\\Uri\\' => array($vendorDir . '/league/uri', $vendorDir . '/league/uri-interfaces'),
14 | );
15 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | register(true);
35 |
36 | return $loader;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/vendor/composer/autoload_static.php:
--------------------------------------------------------------------------------
1 |
11 | array (
12 | 'fivefilters\\Readability\\' => 24,
13 | ),
14 | 'P' =>
15 | array (
16 | 'Psr\\Log\\' => 8,
17 | 'Psr\\Http\\Message\\' => 17,
18 | ),
19 | 'M' =>
20 | array (
21 | 'Masterminds\\' => 12,
22 | ),
23 | 'L' =>
24 | array (
25 | 'League\\Uri\\' => 11,
26 | ),
27 | );
28 |
29 | public static $prefixDirsPsr4 = array (
30 | 'fivefilters\\Readability\\' =>
31 | array (
32 | 0 => __DIR__ . '/..' . '/fivefilters/readability.php/src',
33 | ),
34 | 'Psr\\Log\\' =>
35 | array (
36 | 0 => __DIR__ . '/..' . '/psr/log/src',
37 | ),
38 | 'Psr\\Http\\Message\\' =>
39 | array (
40 | 0 => __DIR__ . '/..' . '/psr/http-factory/src',
41 | 1 => __DIR__ . '/..' . '/psr/http-message/src',
42 | ),
43 | 'Masterminds\\' =>
44 | array (
45 | 0 => __DIR__ . '/..' . '/masterminds/html5/src',
46 | ),
47 | 'League\\Uri\\' =>
48 | array (
49 | 0 => __DIR__ . '/..' . '/league/uri',
50 | 1 => __DIR__ . '/..' . '/league/uri-interfaces',
51 | ),
52 | );
53 |
54 | public static $classMap = array (
55 | 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
56 | );
57 |
58 | public static function getInitializer(ClassLoader $loader)
59 | {
60 | return \Closure::bind(function () use ($loader) {
61 | $loader->prefixLengthsPsr4 = ComposerStaticInitb44cc79a0eaef9cd9c2f2ac697cbe9c0::$prefixLengthsPsr4;
62 | $loader->prefixDirsPsr4 = ComposerStaticInitb44cc79a0eaef9cd9c2f2ac697cbe9c0::$prefixDirsPsr4;
63 | $loader->classMap = ComposerStaticInitb44cc79a0eaef9cd9c2f2ac697cbe9c0::$classMap;
64 |
65 | }, null, ClassLoader::class);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/vendor/composer/installed.php:
--------------------------------------------------------------------------------
1 | array(
3 | 'name' => '__root__',
4 | 'pretty_version' => 'dev-master',
5 | 'version' => 'dev-master',
6 | 'reference' => 'ecc96987909acb2ed49fd750cdac5921ae04b8c6',
7 | 'type' => 'library',
8 | 'install_path' => __DIR__ . '/../../',
9 | 'aliases' => array(),
10 | 'dev' => true,
11 | ),
12 | 'versions' => array(
13 | '__root__' => array(
14 | 'pretty_version' => 'dev-master',
15 | 'version' => 'dev-master',
16 | 'reference' => 'ecc96987909acb2ed49fd750cdac5921ae04b8c6',
17 | 'type' => 'library',
18 | 'install_path' => __DIR__ . '/../../',
19 | 'aliases' => array(),
20 | 'dev_requirement' => false,
21 | ),
22 | 'fivefilters/readability.php' => array(
23 | 'pretty_version' => 'v3.3.3',
24 | 'version' => '3.3.3.0',
25 | 'reference' => 'e2ee7b9e49eae89ac7ed2c74b15718100a73b4c8',
26 | 'type' => 'library',
27 | 'install_path' => __DIR__ . '/../fivefilters/readability.php',
28 | 'aliases' => array(),
29 | 'dev_requirement' => false,
30 | ),
31 | 'league/uri' => array(
32 | 'pretty_version' => '7.5.1',
33 | 'version' => '7.5.1.0',
34 | 'reference' => '81fb5145d2644324614cc532b28efd0215bda430',
35 | 'type' => 'library',
36 | 'install_path' => __DIR__ . '/../league/uri',
37 | 'aliases' => array(),
38 | 'dev_requirement' => false,
39 | ),
40 | 'league/uri-interfaces' => array(
41 | 'pretty_version' => '7.5.0',
42 | 'version' => '7.5.0.0',
43 | 'reference' => '08cfc6c4f3d811584fb09c37e2849e6a7f9b0742',
44 | 'type' => 'library',
45 | 'install_path' => __DIR__ . '/../league/uri-interfaces',
46 | 'aliases' => array(),
47 | 'dev_requirement' => false,
48 | ),
49 | 'masterminds/html5' => array(
50 | 'pretty_version' => '2.9.0',
51 | 'version' => '2.9.0.0',
52 | 'reference' => 'f5ac2c0b0a2eefca70b2ce32a5809992227e75a6',
53 | 'type' => 'library',
54 | 'install_path' => __DIR__ . '/../masterminds/html5',
55 | 'aliases' => array(),
56 | 'dev_requirement' => false,
57 | ),
58 | 'psr/http-factory' => array(
59 | 'pretty_version' => '1.0.1',
60 | 'version' => '1.0.1.0',
61 | 'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
62 | 'type' => 'library',
63 | 'install_path' => __DIR__ . '/../psr/http-factory',
64 | 'aliases' => array(),
65 | 'dev_requirement' => false,
66 | ),
67 | 'psr/http-message' => array(
68 | 'pretty_version' => '1.1',
69 | 'version' => '1.1.0.0',
70 | 'reference' => 'cb6ce4845ce34a8ad9e68117c10ee90a29919eba',
71 | 'type' => 'library',
72 | 'install_path' => __DIR__ . '/../psr/http-message',
73 | 'aliases' => array(),
74 | 'dev_requirement' => false,
75 | ),
76 | 'psr/log' => array(
77 | 'pretty_version' => '3.0.2',
78 | 'version' => '3.0.2.0',
79 | 'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
80 | 'type' => 'library',
81 | 'install_path' => __DIR__ . '/../psr/log',
82 | 'aliases' => array(),
83 | 'dev_requirement' => false,
84 | ),
85 | ),
86 | );
87 |
--------------------------------------------------------------------------------
/vendor/composer/platform_check.php:
--------------------------------------------------------------------------------
1 | = 80100)) {
8 | $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
9 | }
10 |
11 | if ($issues) {
12 | if (!headers_sent()) {
13 | header('HTTP/1.1 500 Internal Server Error');
14 | }
15 | if (!ini_get('display_errors')) {
16 | if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
17 | fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
18 | } elseif (!headers_sent()) {
19 | 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;
20 | }
21 | }
22 | trigger_error(
23 | 'Composer detected issues in your platform: ' . implode(' ', $issues),
24 | E_USER_ERROR
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = false
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/.gitattributes:
--------------------------------------------------------------------------------
1 | # Ignore test-related files
2 | /test/ export-ignore
3 | /phpunit.xml export-ignore
4 | /Makefile export-ignore
5 | /docker export-ignore
6 | /docker-compose.yml export-ignore
7 |
8 | test/* linguist-language=PHP
9 | * text=auto eol=lf
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: CI
4 |
5 | # Controls when the workflow will run
6 | on:
7 | # Triggers the workflow on push or pull request events but only for the master branch
8 | push:
9 | branches: [master]
10 | pull_request:
11 | branches: [master]
12 |
13 | # Allows you to run this workflow manually from the Actions tab
14 | workflow_dispatch:
15 |
16 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
17 | jobs:
18 | # This workflow contains a single job called "build"
19 | build:
20 | # The type of runner that the job will run on
21 | runs-on: ubuntu-latest
22 |
23 | strategy:
24 | matrix:
25 | php: ['8.1', '8.2', '8.3', '8.4']
26 | libxml: ['2.9.14']
27 |
28 | # Steps represent a sequence of tasks that will be executed as part of the job
29 | steps:
30 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
31 | - uses: actions/checkout@v3
32 |
33 | - name: Set up PHP
34 | uses: shivammathur/setup-php@v2
35 | with:
36 | php-version: ${{matrix.php}}
37 | tools: composer:v2
38 |
39 | - name: Install dependencies
40 | run: composer install
41 |
42 | # Runs a set of commands using the runners shell
43 | - name: Run tests
44 | run: |
45 | docker build --build-arg PHP_VERSION=${{matrix.php}} --build-arg LIBXML_VERSION=${{matrix.libxml}} -t gh-action - < ./docker/php/Dockerfile
46 | docker run --volume $PWD:/app --workdir="/app" --env XDEBUG_MODE=coverage gh-action php ./vendor/bin/phpunit --coverage-clover /app/test/clover.xml
47 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | vendor
3 | composer.lock
4 | /test.*
5 | /test/changed/
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/AUTHORS.md:
--------------------------------------------------------------------------------
1 | # Authors
2 |
3 | Readability.php developed by **Andres Rey**.
4 |
5 | Based on Arc90's readability.js (1.7.1) script available at: http://code.google.com/p/arc90labs-readability.
6 | Copyright (c) 2010 Arc90 Inc
7 |
8 | The AUTHORS/Contributors are (and/or have been):
9 |
10 | * Andres Rey
11 | * Sergiy Lavryk
12 | * Pedro Amorim
13 | * Malu Decks
14 | * Keyvan Minoukadeh
15 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are **welcome** and will be fully **credited**.
4 |
5 | When it comes to the core article-extraction functionality, please contribute to [Mozilla's Readability](https://github.com/mozilla/readability/) repository, as we're trying to mirror that here.
6 |
7 | For anything else, we accept contributions via Pull Requests on [Github](https://github.com/fivefilters/readability.php/).
8 |
9 | ## Pull Requests
10 |
11 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date.
12 |
13 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests.
14 |
15 | - **Create feature branches** - Don't ask us to pull from your master branch.
16 |
17 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests.
18 |
19 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting.
20 |
21 | - **Don't forget to add yourself to AUTHORS.md** - If you want to be credited, make sure you add your information (whatever you want to include) in `AUTHORS.md`.
22 |
23 |
24 | ## Running Tests
25 |
26 | ``` bash
27 | $ make test-all #requires docker and docker-compose
28 | ```
29 |
30 |
31 | **Happy coding**!
32 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fivefilters/readability.php",
3 | "type": "library",
4 | "description": "A PHP port of Readability.js",
5 | "keywords": ["readability", "html"],
6 | "homepage": "https://github.com/fivefilters/readability.php",
7 | "license": "Apache-2.0",
8 | "authors": [
9 | {
10 | "name": "Andres Rey",
11 | "email": "andreskrey@gmail.com",
12 | "role": "Original Developer"
13 | },
14 | {
15 | "name": "Keyvan Minoukadeh",
16 | "email": "keyvan@fivefilters.org",
17 | "homepage": "https://www.fivefilters.org",
18 | "role": "Developer/Maintainer"
19 | }
20 | ],
21 | "autoload": {
22 | "psr-4": {
23 | "fivefilters\\Readability\\": "src/"
24 | }
25 | },
26 | "autoload-dev": {
27 | "psr-4": {"fivefilters\\Readability\\Test\\": "test"}
28 | },
29 | "require": {
30 | "php": ">=8.1",
31 | "ext-dom": "*",
32 | "ext-xml": "*",
33 | "ext-mbstring": "*",
34 | "psr/log": "^1.0 || ^2.0 || ^3.0",
35 | "masterminds/html5": "^2.0",
36 | "league/uri": "^7.0"
37 | },
38 | "require-dev": {
39 | "phpunit/phpunit": "^10.0 || ^11.0",
40 | "monolog/monolog": "^3.0"
41 | },
42 | "suggest": {
43 | "monolog/monolog": "Allow logging debug information"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/src/Nodes/DOM/DOMAttr.php:
--------------------------------------------------------------------------------
1 | registerNodeClass('DOMAttr', DOMAttr::class);
16 | $this->registerNodeClass('DOMCdataSection', DOMCdataSection::class);
17 | $this->registerNodeClass('DOMCharacterData', DOMCharacterData::class);
18 | $this->registerNodeClass('DOMComment', DOMComment::class);
19 | $this->registerNodeClass('DOMDocument', self::class);
20 | $this->registerNodeClass('DOMDocumentFragment', DOMDocumentFragment::class);
21 | $this->registerNodeClass('DOMDocumentType', DOMDocumentType::class);
22 | $this->registerNodeClass('DOMElement', DOMElement::class);
23 | $this->registerNodeClass('DOMEntity', DOMEntity::class);
24 | $this->registerNodeClass('DOMEntityReference', DOMEntityReference::class);
25 | $this->registerNodeClass('DOMNode', DOMNode::class);
26 | $this->registerNodeClass('DOMNotation', DOMNotation::class);
27 | $this->registerNodeClass('DOMProcessingInstruction', DOMProcessingInstruction::class);
28 | $this->registerNodeClass('DOMText', DOMText::class);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/src/Nodes/DOM/DOMDocumentFragment.php:
--------------------------------------------------------------------------------
1 | childNodes as $node) {
20 | if ($node->nodeType === XML_ELEMENT_NODE) {
21 | $newList->add($node);
22 | }
23 | }
24 | return $newList;
25 | }
26 |
27 | /**
28 | * Returns the Element immediately prior to the specified one in its parent's children list, or null if the specified element is the first one in the list.
29 | *
30 | * @deprecated Use previousElementSibling instead - introduced in PHP 8.0.
31 | */
32 | public function previousElementSibling(): ?DOMElement
33 | {
34 | return $this->previousElementSibling;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/src/Nodes/DOM/DOMEntity.php:
--------------------------------------------------------------------------------
1 | length is hidden
13 | * from the user and cannot be extended, changed, or tweaked.
14 | */
15 | class DOMNodeList implements \Countable, \IteratorAggregate
16 | {
17 | /**
18 | * @var array
19 | */
20 | protected $items = [];
21 |
22 | /**
23 | * @var int
24 | */
25 | protected $length = 0;
26 |
27 | /**
28 | * To allow access to length in the same way that DOMNodeList allows.
29 | *
30 | * {@inheritdoc}
31 | */
32 | public function __get($name)
33 | {
34 | switch ($name) {
35 | case 'length':
36 | return $this->length;
37 | default:
38 | trigger_error(sprintf('Undefined property: %s::%s', static::class, $name));
39 | }
40 | }
41 |
42 | /**
43 | * Add node to the list.
44 | */
45 | public function add(DOMNode|DOMElement|DOMText|DOMComment|DOMProcessingInstruction|DOMCdataSection $node): DOMNodeList
46 | {
47 | $this->items[] = $node;
48 | $this->length++;
49 |
50 | return $this;
51 | }
52 |
53 | /**
54 | * Get node.
55 | */
56 | public function item(int $offset): DOMNode|DOMElement|DOMText|DOMComment|DOMProcessingInstruction|DOMCdataSection
57 | {
58 | return $this->items[$offset];
59 | }
60 |
61 | /**
62 | * Number of items.
63 | */
64 | public function count(): int
65 | {
66 | return $this->length;
67 | }
68 |
69 | /**
70 | * To make it compatible with iterator_to_array() function.
71 | *
72 | * {@inheritdoc}
73 | */
74 | public function getIterator(): \ArrayIterator
75 | {
76 | return new \ArrayIterator($this->items);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/vendor/fivefilters/readability.php/src/Nodes/DOM/DOMNotation.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use League\Uri\Exceptions\MissingFeature;
17 | use League\Uri\Exceptions\SyntaxError;
18 | use Stringable;
19 |
20 | interface AuthorityInterface extends UriComponentInterface
21 | {
22 | /**
23 | * Returns the host component of the authority.
24 | */
25 | public function getHost(): ?string;
26 |
27 | /**
28 | * Returns the port component of the authority.
29 | */
30 | public function getPort(): ?int;
31 |
32 | /**
33 | * Returns the user information component of the authority.
34 | */
35 | public function getUserInfo(): ?string;
36 |
37 | /**
38 | * Returns an associative array containing all the Authority components.
39 | *
40 | * The returned a hashmap similar to PHP's parse_url return value
41 | *
42 | * @link https://tools.ietf.org/html/rfc3986
43 | *
44 | * @return array{user: ?string, pass : ?string, host: ?string, port: ?int}
45 | */
46 | public function components(): array;
47 |
48 | /**
49 | * Return an instance with the specified host.
50 | *
51 | * This method MUST retain the state of the current instance, and return
52 | * an instance that contains the specified host.
53 | *
54 | * A null value provided for the host is equivalent to removing the host
55 | * information.
56 | *
57 | * @throws SyntaxError for invalid component or transformations
58 | * that would result in an object in invalid state.
59 | * @throws MissingFeature for component or transformations
60 | * requiring IDN support when IDN support is not present
61 | * or misconfigured.
62 | */
63 | public function withHost(Stringable|string|null $host): self;
64 |
65 | /**
66 | * Return an instance with the specified port.
67 | *
68 | * This method MUST retain the state of the current instance, and return
69 | * an instance that contains the specified port.
70 | *
71 | * A null value provided for the port is equivalent to removing the port
72 | * information.
73 | *
74 | * @throws SyntaxError for invalid component or transformations
75 | * that would result in an object in invalid state.
76 | */
77 | public function withPort(?int $port): self;
78 |
79 | /**
80 | * Return an instance with the specified user information.
81 | *
82 | * This method MUST retain the state of the current instance, and return
83 | * an instance that contains the specified user information.
84 | *
85 | * Password is optional, but the user information MUST include the
86 | * user; a null value for the user is equivalent to removing user
87 | * information.
88 | *
89 | * @throws SyntaxError for invalid component or transformations
90 | * that would result in an object in invalid state.
91 | */
92 | public function withUserInfo(Stringable|string|null $user, Stringable|string|null $password = null): self;
93 | }
94 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/DataPathInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use SplFileObject;
17 | use Stringable;
18 |
19 | interface DataPathInterface extends PathInterface
20 | {
21 | /**
22 | * Retrieve the data mime type associated to the URI.
23 | *
24 | * If no mimetype is present, this method MUST return the default mimetype 'text/plain'.
25 | *
26 | * @see http://tools.ietf.org/html/rfc2397#section-2
27 | */
28 | public function getMimeType(): string;
29 |
30 | /**
31 | * Retrieve the parameters associated with the Mime Type of the URI.
32 | *
33 | * If no parameters is present, this method MUST return the default parameter 'charset=US-ASCII'.
34 | *
35 | * @see http://tools.ietf.org/html/rfc2397#section-2
36 | */
37 | public function getParameters(): string;
38 |
39 | /**
40 | * Retrieve the mediatype associated with the URI.
41 | *
42 | * If no mediatype is present, this method MUST return the default parameter 'text/plain;charset=US-ASCII'.
43 | *
44 | * @see http://tools.ietf.org/html/rfc2397#section-3
45 | *
46 | * @return string The URI scheme.
47 | */
48 | public function getMediaType(): string;
49 |
50 | /**
51 | * Retrieves the data string.
52 | *
53 | * Retrieves the data part of the path. If no data part is provided return
54 | * an empty string
55 | */
56 | public function getData(): string;
57 |
58 | /**
59 | * Tells whether the data is binary safe encoded.
60 | */
61 | public function isBinaryData(): bool;
62 |
63 | /**
64 | * Save the data to a specific file.
65 | */
66 | public function save(string $path, string $mode = 'w'): SplFileObject;
67 |
68 | /**
69 | * Returns an instance where the data part is base64 encoded.
70 | *
71 | * This method MUST retain the state of the current instance, and return
72 | * an instance where the data part is base64 encoded
73 | */
74 | public function toBinary(): self;
75 |
76 | /**
77 | * Returns an instance where the data part is url encoded following RFC3986 rules.
78 | *
79 | * This method MUST retain the state of the current instance, and return
80 | * an instance where the data part is url encoded
81 | */
82 | public function toAscii(): self;
83 |
84 | /**
85 | * Return an instance with the specified mediatype parameters.
86 | *
87 | * This method MUST retain the state of the current instance, and return
88 | * an instance that contains the specified mediatype parameters.
89 | *
90 | * Users must provide encoded characters.
91 | *
92 | * An empty parameters value is equivalent to removing the parameter.
93 | */
94 | public function withParameters(Stringable|string $parameters): self;
95 | }
96 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use Countable;
17 | use Iterator;
18 | use IteratorAggregate;
19 | use League\Uri\Exceptions\SyntaxError;
20 | use Stringable;
21 |
22 | /**
23 | * @extends IteratorAggregate
24 | */
25 | interface DomainHostInterface extends Countable, HostInterface, IteratorAggregate
26 | {
27 | /**
28 | * Returns the labels total number.
29 | */
30 | public function count(): int;
31 |
32 | /**
33 | * Iterate over the Domain labels.
34 | *
35 | * @return Iterator
36 | */
37 | public function getIterator(): Iterator;
38 |
39 | /**
40 | * Retrieves a single host label.
41 | *
42 | * If the label offset has not been set, returns the null value.
43 | */
44 | public function get(int $offset): ?string;
45 |
46 | /**
47 | * Returns the associated key for a specific label or all the keys.
48 | *
49 | * @return int[]
50 | */
51 | public function keys(?string $label = null): array;
52 |
53 | /**
54 | * Tells whether the domain is absolute.
55 | */
56 | public function isAbsolute(): bool;
57 |
58 | /**
59 | * Prepends a label to the host.
60 | */
61 | public function prepend(Stringable|string $label): self;
62 |
63 | /**
64 | * Appends a label to the host.
65 | */
66 | public function append(Stringable|string $label): self;
67 |
68 | /**
69 | * Extracts a slice of $length elements starting at position $offset from the host.
70 | *
71 | * This method MUST retain the state of the current instance, and return
72 | * an instance that contains the selected slice.
73 | *
74 | * If $length is null it returns all elements from $offset to the end of the Domain.
75 | */
76 | public function slice(int $offset, ?int $length = null): self;
77 |
78 | /**
79 | * Returns an instance with its Root label.
80 | *
81 | * @see https://tools.ietf.org/html/rfc3986#section-3.2.2
82 | */
83 | public function withRootLabel(): self;
84 |
85 | /**
86 | * Returns an instance without its Root label.
87 | *
88 | * @see https://tools.ietf.org/html/rfc3986#section-3.2.2
89 | */
90 | public function withoutRootLabel(): self;
91 |
92 | /**
93 | * Returns an instance with the modified label.
94 | *
95 | * This method MUST retain the state of the current instance, and return
96 | * an instance that contains the new label
97 | *
98 | * If $key is non-negative, the added label will be the label at $key position from the start.
99 | * If $key is negative, the added label will be the label at $key position from the end.
100 | *
101 | * @throws SyntaxError If the key is invalid
102 | */
103 | public function withLabel(int $key, Stringable|string $label): self;
104 |
105 | /**
106 | * Returns an instance without the specified label.
107 | *
108 | * This method MUST retain the state of the current instance, and return
109 | * an instance that contains the modified component
110 | *
111 | * If $key is non-negative, the removed label will be the label at $key position from the start.
112 | * If $key is negative, the removed label will be the label at $key position from the end.
113 | *
114 | * @throws SyntaxError If the key is invalid
115 | */
116 | public function withoutLabel(int ...$keys): self;
117 | }
118 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/FragmentInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | interface FragmentInterface extends UriComponentInterface
17 | {
18 | /**
19 | * Returns the decoded fragment.
20 | */
21 | public function decoded(): ?string;
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/HostInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | interface HostInterface extends UriComponentInterface
17 | {
18 | /**
19 | * Returns the ascii representation.
20 | */
21 | public function toAscii(): ?string;
22 |
23 | /**
24 | * Returns the unicode representation.
25 | */
26 | public function toUnicode(): ?string;
27 |
28 | /**
29 | * Returns the IP version.
30 | *
31 | * If the host is a not an IP this method will return null
32 | */
33 | public function getIpVersion(): ?string;
34 |
35 | /**
36 | * Returns the IP component If the Host is an IP address.
37 | *
38 | * If the host is a not an IP this method will return null
39 | */
40 | public function getIp(): ?string;
41 |
42 | /**
43 | * Tells whether the host is a domain name.
44 | */
45 | public function isDomain(): bool;
46 |
47 | /**
48 | * Tells whether the host is an IP Address.
49 | */
50 | public function isIp(): bool;
51 |
52 | /**
53 | * Tells whether the host is a registered name.
54 | */
55 | public function isRegisteredName(): bool;
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/IpHostInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | interface IpHostInterface extends HostInterface
17 | {
18 | /**
19 | * Tells whether the host is an IPv4 address.
20 | */
21 | public function isIpv4(): bool;
22 |
23 | /**
24 | * Tells whether the host is an IPv6 address.
25 | */
26 | public function isIpv6(): bool;
27 |
28 | /**
29 | * Tells whether the host is an IPv6 address.
30 | */
31 | public function isIpFuture(): bool;
32 |
33 | /**
34 | * Tells whether the host has a ZoneIdentifier.
35 | *
36 | * @see http://tools.ietf.org/html/rfc6874#section-4
37 | */
38 | public function hasZoneIdentifier(): bool;
39 |
40 | /**
41 | * Returns a host without its zone identifier according to RFC6874.
42 | *
43 | * This method MUST retain the state of the current instance, and return
44 | * an instance without the host zone identifier according to RFC6874
45 | *
46 | * @see http://tools.ietf.org/html/rfc6874#section-4
47 | */
48 | public function withoutZoneIdentifier(): self;
49 | }
50 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/PathInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use League\Uri\Exceptions\SyntaxError;
17 |
18 | interface PathInterface extends UriComponentInterface
19 | {
20 | /**
21 | * Returns the decoded path.
22 | */
23 | public function decoded(): string;
24 |
25 | /**
26 | * Tells whether the path is absolute or relative.
27 | */
28 | public function isAbsolute(): bool;
29 |
30 | /**
31 | * Tells whether the path has a trailing slash.
32 | */
33 | public function hasTrailingSlash(): bool;
34 |
35 | /**
36 | * Returns an instance without dot segments.
37 | *
38 | * This method MUST retain the state of the current instance, and return
39 | * an instance that contains the path component normalized by removing
40 | * the dot segment.
41 | *
42 | * @throws SyntaxError for invalid component or transformations
43 | * that would result in a object in invalid state.
44 | */
45 | public function withoutDotSegments(): self;
46 |
47 | /**
48 | * Returns an instance with a leading slash.
49 | *
50 | * This method MUST retain the state of the current instance, and return
51 | * an instance that contains the path component with a leading slash
52 | *
53 | * @throws SyntaxError for invalid component or transformations
54 | * that would result in a object in invalid state.
55 | */
56 | public function withLeadingSlash(): self;
57 |
58 | /**
59 | * Returns an instance without a leading slash.
60 | *
61 | * This method MUST retain the state of the current instance, and return
62 | * an instance that contains the path component without a leading slash
63 | *
64 | * @throws SyntaxError for invalid component or transformations
65 | * that would result in a object in invalid state.
66 | */
67 | public function withoutLeadingSlash(): self;
68 |
69 | /**
70 | * Returns an instance with a trailing slash.
71 | *
72 | * This method MUST retain the state of the current instance, and return
73 | * an instance that contains the path component with a trailing slash
74 | *
75 | * @throws SyntaxError for invalid component or transformations
76 | * that would result in a object in invalid state.
77 | */
78 | public function withTrailingSlash(): self;
79 |
80 | /**
81 | * Returns an instance without a trailing slash.
82 | *
83 | * This method MUST retain the state of the current instance, and return
84 | * an instance that contains the path component without a trailing slash
85 | *
86 | * @throws SyntaxError for invalid component or transformations
87 | * that would result in a object in invalid state.
88 | */
89 | public function withoutTrailingSlash(): self;
90 | }
91 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/PortInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | interface PortInterface extends UriComponentInterface
17 | {
18 | /**
19 | * Returns the integer representation of the Port.
20 | */
21 | public function toInt(): ?int;
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use Countable;
17 | use Iterator;
18 | use IteratorAggregate;
19 | use League\Uri\Exceptions\SyntaxError;
20 | use Stringable;
21 |
22 | /**
23 | * @extends IteratorAggregate
24 | */
25 | interface SegmentedPathInterface extends Countable, IteratorAggregate, PathInterface
26 | {
27 | /**
28 | * Returns the total number of segments in the path.
29 | */
30 | public function count(): int;
31 |
32 | /**
33 | * Iterate over the path segment.
34 | *
35 | * @return Iterator
36 | */
37 | public function getIterator(): Iterator;
38 |
39 | /**
40 | * Returns parent directory's path.
41 | */
42 | public function getDirname(): string;
43 |
44 | /**
45 | * Returns the path basename.
46 | */
47 | public function getBasename(): string;
48 |
49 | /**
50 | * Returns the basename extension.
51 | */
52 | public function getExtension(): string;
53 |
54 | /**
55 | * Retrieves a single path segment.
56 | *
57 | * If the segment offset has not been set, returns null.
58 | */
59 | public function get(int $offset): ?string;
60 |
61 | /**
62 | * Returns the associated key for a specific segment.
63 | *
64 | * If a value is specified only the keys associated with
65 | * the given value will be returned
66 | *
67 | * @return array
68 | */
69 | public function keys(Stringable|string|null $segment = null): array;
70 |
71 | /**
72 | * Appends a segment to the path.
73 | */
74 | public function append(Stringable|string $segment): self;
75 |
76 | /**
77 | * Extracts a slice of $length elements starting at position $offset from the host.
78 | *
79 | * This method MUST retain the state of the current instance, and return
80 | * an instance that contains the selected slice.
81 | *
82 | * If $length is null it returns all elements from $offset to the end of the Path.
83 | */
84 | public function slice(int $offset, ?int $length = null): self;
85 |
86 | /**
87 | * Prepends a segment to the path.
88 | */
89 | public function prepend(Stringable|string $segment): self;
90 |
91 | /**
92 | * Returns an instance with the modified segment.
93 | *
94 | * This method MUST retain the state of the current instance, and return
95 | * an instance that contains the new segment
96 | *
97 | * If $key is non-negative, the added segment will be the segment at $key position from the start.
98 | * If $key is negative, the added segment will be the segment at $key position from the end.
99 | *
100 | * @throws SyntaxError If the key is invalid
101 | */
102 | public function withSegment(int $key, Stringable|string $segment): self;
103 |
104 | /**
105 | * Returns an instance without the specified segment.
106 | *
107 | * This method MUST retain the state of the current instance, and return
108 | * an instance that contains the modified component
109 | *
110 | * If $key is non-negative, the removed segment will be the segment at $key position from the start.
111 | * If $key is negative, the removed segment will be the segment at $key position from the end.
112 | *
113 | * @throws SyntaxError If the key is invalid
114 | */
115 | public function withoutSegment(int ...$keys): self;
116 |
117 | /**
118 | * Returns an instance without duplicate delimiters.
119 | *
120 | * This method MUST retain the state of the current instance, and return
121 | * an instance that contains the path component normalized by removing
122 | * multiple consecutive empty segment
123 | */
124 | public function withoutEmptySegments(): self;
125 |
126 | /**
127 | * Returns an instance with the specified parent directory's path.
128 | *
129 | * This method MUST retain the state of the current instance, and return
130 | * an instance that contains the extension basename modified.
131 | */
132 | public function withDirname(Stringable|string $path): self;
133 |
134 | /**
135 | * Returns an instance with the specified basename.
136 | *
137 | * This method MUST retain the state of the current instance, and return
138 | * an instance that contains the extension basename modified.
139 | */
140 | public function withBasename(Stringable|string $basename): self;
141 |
142 | /**
143 | * Returns an instance with the specified basename extension.
144 | *
145 | * This method MUST retain the state of the current instance, and return
146 | * an instance that contains the extension basename modified.
147 | */
148 | public function withExtension(Stringable|string $extension): self;
149 | }
150 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/UriAccess.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use Psr\Http\Message\UriInterface as Psr7UriInterface;
17 |
18 | interface UriAccess
19 | {
20 | public function getUri(): UriInterface|Psr7UriInterface;
21 |
22 | /**
23 | * Returns the RFC3986 string representation of the complete URI.
24 | */
25 | public function getUriString(): string;
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use JsonSerializable;
17 | use Stringable;
18 |
19 | interface UriComponentInterface extends JsonSerializable, Stringable
20 | {
21 | /**
22 | * Returns the instance string representation.
23 | *
24 | * If the instance is defined, the value returned MUST be percent-encoded,
25 | * but MUST NOT double-encode any characters. To determine what characters
26 | * to encode, please refer to RFC 3986, Sections 2 and 3.
27 | *
28 | * If the instance is not defined null is returned
29 | */
30 | public function value(): ?string;
31 |
32 | /**
33 | * Returns the instance string representation.
34 | *
35 | * If the instance is defined, the value returned MUST be percent-encoded,
36 | * but MUST NOT double-encode any characters. To determine what characters
37 | * to encode, please refer to RFC 3986, Sections 2 and 3.
38 | *
39 | * If the instance is not defined an empty string is returned
40 | */
41 | public function toString(): string;
42 |
43 | /**
44 | * Returns the instance string representation.
45 | *
46 | * If the instance is defined, the value returned MUST be percent-encoded,
47 | * but MUST NOT double-encode any characters. To determine what characters
48 | * to encode, please refer to RFC 3986, Sections 2 and 3.
49 | *
50 | * If the instance is not defined an empty string is returned
51 | */
52 | public function __toString(): string;
53 |
54 | /**
55 | * Returns the instance json representation.
56 | *
57 | * If the instance is defined, the value returned MUST be percent-encoded,
58 | * but MUST NOT double-encode any characters. To determine what characters
59 | * to encode, please refer to RFC 3986 or RFC 1738.
60 | *
61 | * If the instance is not defined null is returned
62 | */
63 | public function jsonSerialize(): ?string;
64 |
65 | /**
66 | * Returns the instance string representation with its optional URI delimiters.
67 | *
68 | * The value returned MUST be percent-encoded, but MUST NOT double-encode any
69 | * characters. To determine what characters to encode, please refer to RFC 3986,
70 | * Sections 2 and 3.
71 | *
72 | * If the instance is not defined an empty string is returned
73 | */
74 | public function getUriComponent(): string;
75 | }
76 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/UriException.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use Throwable;
17 |
18 | interface UriException extends Throwable
19 | {
20 | }
21 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Contracts/UserInfoInterface.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Contracts;
15 |
16 | use Stringable;
17 |
18 | interface UserInfoInterface extends UriComponentInterface
19 | {
20 | /**
21 | * Returns the user component part.
22 | */
23 | public function getUser(): ?string;
24 |
25 | /**
26 | * Returns the pass component part.
27 | */
28 | public function getPass(): ?string;
29 |
30 | /**
31 | * Returns an associative array containing all the User Info components.
32 | *
33 | * The returned a hashmap similar to PHP's parse_url return value
34 | *
35 | * @link https://tools.ietf.org/html/rfc3986
36 | *
37 | * @return array{user: ?string, pass : ?string}
38 | */
39 | public function components(): array;
40 |
41 | /**
42 | * Returns an instance with the specified user and/or pass.
43 | *
44 | * This method MUST retain the state of the current instance, and return
45 | * an instance that contains the specified new username
46 | * otherwise it returns the same instance unchanged.
47 | *
48 | * A variable equal to null is equivalent to removing the complete user information.
49 | */
50 | public function withUser(Stringable|string|null $username): self;
51 |
52 | /**
53 | * Returns an instance with the specified user and/or pass.
54 | *
55 | * This method MUST retain the state of the current instance, and return
56 | * an instance that contains the specified password if the user is specified
57 | * otherwise it returns the same instance unchanged.
58 | *
59 | * An empty user is equivalent to removing the user information.
60 | */
61 | public function withPass(Stringable|string|null $password): self;
62 | }
63 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Exceptions;
15 |
16 | use League\Uri\Idna\Error;
17 | use League\Uri\Idna\Result;
18 | use Stringable;
19 |
20 | final class ConversionFailed extends SyntaxError
21 | {
22 | private function __construct(
23 | string $message,
24 | private readonly string $host,
25 | private readonly Result $result
26 | ) {
27 | parent::__construct($message);
28 | }
29 |
30 | public static function dueToIdnError(Stringable|string $host, Result $result): self
31 | {
32 | $reasons = array_map(fn (Error $error): string => $error->description(), $result->errors());
33 |
34 | return new self('Host `'.$host.'` is invalid: '.implode('; ', $reasons).'.', (string) $host, $result);
35 | }
36 |
37 | public function getHost(): string
38 | {
39 | return $this->host;
40 | }
41 |
42 | public function getResult(): Result
43 | {
44 | return $this->result;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Exceptions/MissingFeature.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Exceptions;
15 |
16 | use League\Uri\Contracts\UriException;
17 | use RuntimeException;
18 |
19 | class MissingFeature extends RuntimeException implements UriException
20 | {
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Exceptions/OffsetOutOfBounds.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Exceptions;
15 |
16 | class OffsetOutOfBounds extends SyntaxError
17 | {
18 | }
19 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Exceptions/SyntaxError.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Exceptions;
15 |
16 | use InvalidArgumentException;
17 | use League\Uri\Contracts\UriException;
18 |
19 | class SyntaxError extends InvalidArgumentException implements UriException
20 | {
21 | }
22 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/FeatureDetection.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri;
15 |
16 | use finfo;
17 | use League\Uri\Exceptions\MissingFeature;
18 | use League\Uri\IPv4\Calculator;
19 |
20 | use const PHP_INT_SIZE;
21 |
22 | /**
23 | * Allow detecting features needed to make the packages work.
24 | */
25 | final class FeatureDetection
26 | {
27 | public static function supportsFileDetection(): void
28 | {
29 | static $isSupported = null;
30 | $isSupported = $isSupported ?? class_exists(finfo::class);
31 |
32 | if (!$isSupported) {
33 | throw new MissingFeature('Support for file type detection requires the `fileinfo` extension.');
34 | }
35 | }
36 |
37 | public static function supportsIdn(): void
38 | {
39 | static $isSupported = null;
40 | $isSupported = $isSupported ?? (function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46'));
41 |
42 | if (!$isSupported) {
43 | throw new MissingFeature('Support for IDN host requires the `intl` extension for best performance or run "composer require symfony/polyfill-intl-idn" to install a polyfill.');
44 | }
45 | }
46 |
47 | public static function supportsIPv4Conversion(): void
48 | {
49 | static $isSupported = null;
50 | $isSupported = $isSupported ?? (extension_loaded('gmp') || extension_loaded('bcmath') || (4 < PHP_INT_SIZE));
51 |
52 | if (!$isSupported) {
53 | throw new MissingFeature('A '.Calculator::class.' implementation could not be automatically loaded. To perform IPv4 conversion use a x.64 PHP build or install one of the following extension GMP or BCMath. You can also ship your own implmentation.');
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/IPv4/BCMathCalculator.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\IPv4;
15 |
16 | use function bcadd;
17 | use function bccomp;
18 | use function bcdiv;
19 | use function bcmod;
20 | use function bcmul;
21 | use function bcpow;
22 | use function bcsub;
23 | use function str_split;
24 |
25 | final class BCMathCalculator implements Calculator
26 | {
27 | private const SCALE = 0;
28 | private const CONVERSION_TABLE = [
29 | '0' => '0', '1' => '1', '2' => '2', '3' => '3',
30 | '4' => '4', '5' => '5', '6' => '6', '7' => '7',
31 | '8' => '8', '9' => '9', 'a' => '10', 'b' => '11',
32 | 'c' => '12', 'd' => '13', 'e' => '14', 'f' => '15',
33 | ];
34 |
35 | public function baseConvert(mixed $value, int $base): string
36 | {
37 | $value = (string) $value;
38 | if (10 === $base) {
39 | return $value;
40 | }
41 |
42 | $base = (string) $base;
43 | $decimal = '0';
44 | foreach (str_split($value) as $char) {
45 | $decimal = bcadd($this->multiply($decimal, $base), self::CONVERSION_TABLE[$char], self::SCALE);
46 | }
47 |
48 | return $decimal;
49 | }
50 |
51 | public function pow(mixed $value, int $exponent): string
52 | {
53 | return bcpow((string) $value, (string) $exponent, self::SCALE);
54 | }
55 |
56 | public function compare(mixed $value1, $value2): int
57 | {
58 | return bccomp((string) $value1, (string) $value2, self::SCALE);
59 | }
60 |
61 | public function multiply(mixed $value1, $value2): string
62 | {
63 | return bcmul((string) $value1, (string) $value2, self::SCALE);
64 | }
65 |
66 | public function div(mixed $value, mixed $base): string
67 | {
68 | return bcdiv((string) $value, (string) $base, self::SCALE);
69 | }
70 |
71 | public function mod(mixed $value, mixed $base): string
72 | {
73 | return bcmod((string) $value, (string) $base, self::SCALE);
74 | }
75 |
76 | public function add(mixed $value1, mixed $value2): string
77 | {
78 | return bcadd((string) $value1, (string) $value2, self::SCALE);
79 | }
80 |
81 | public function sub(mixed $value1, mixed $value2): string
82 | {
83 | return bcsub((string) $value1, (string) $value2, self::SCALE);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/IPv4/Calculator.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\IPv4;
15 |
16 | interface Calculator
17 | {
18 | /**
19 | * Add numbers.
20 | *
21 | * @param mixed $value1 a number that will be added to $value2
22 | * @param mixed $value2 a number that will be added to $value1
23 | *
24 | * @return mixed the addition result
25 | */
26 | public function add(mixed $value1, mixed $value2);
27 |
28 | /**
29 | * Subtract one number from another.
30 | *
31 | * @param mixed $value1 a number that will be subtracted of $value2
32 | * @param mixed $value2 a number that will be subtracted to $value1
33 | *
34 | * @return mixed the subtraction result
35 | */
36 | public function sub(mixed $value1, mixed $value2);
37 |
38 | /**
39 | * Multiply numbers.
40 | *
41 | * @param mixed $value1 a number that will be multiplied by $value2
42 | * @param mixed $value2 a number that will be multiplied by $value1
43 | *
44 | * @return mixed the multiplication result
45 | */
46 | public function multiply(mixed $value1, mixed $value2);
47 |
48 | /**
49 | * Divide numbers.
50 | *
51 | * @param mixed $value The number being divided.
52 | * @param mixed $base The number that $value is being divided by.
53 | *
54 | * @return mixed the result of the division
55 | */
56 | public function div(mixed $value, mixed $base);
57 |
58 | /**
59 | * Raise an number to the power of exponent.
60 | *
61 | * @param mixed $value scalar, the base to use
62 | *
63 | * @return mixed the value raised to the power of exp.
64 | */
65 | public function pow(mixed $value, int $exponent);
66 |
67 | /**
68 | * Returns the int point remainder (modulo) of the division of the arguments.
69 | *
70 | * @param mixed $value The dividend
71 | * @param mixed $base The divisor
72 | *
73 | * @return mixed the remainder
74 | */
75 | public function mod(mixed $value, mixed $base);
76 |
77 | /**
78 | * Number comparison.
79 | *
80 | * @param mixed $value1 the first value
81 | * @param mixed $value2 the second value
82 | *
83 | * @return int Returns < 0 if value1 is less than value2; > 0 if value1 is greater than value2, and 0 if they are equal.
84 | */
85 | public function compare(mixed $value1, mixed $value2): int;
86 |
87 | /**
88 | * Get the decimal integer value of a variable.
89 | *
90 | * @param mixed $value The scalar value being converted to an integer
91 | *
92 | * @return mixed the integer value
93 | */
94 | public function baseConvert(mixed $value, int $base);
95 | }
96 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/IPv4/GMPCalculator.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\IPv4;
15 |
16 | use GMP;
17 |
18 | use function gmp_add;
19 | use function gmp_cmp;
20 | use function gmp_div_q;
21 | use function gmp_init;
22 | use function gmp_mod;
23 | use function gmp_mul;
24 | use function gmp_pow;
25 | use function gmp_sub;
26 |
27 | use const GMP_ROUND_MINUSINF;
28 |
29 | final class GMPCalculator implements Calculator
30 | {
31 | public function baseConvert(mixed $value, int $base): GMP
32 | {
33 | return gmp_init($value, $base);
34 | }
35 |
36 | public function pow(mixed $value, int $exponent): GMP
37 | {
38 | return gmp_pow($value, $exponent);
39 | }
40 |
41 | public function compare(mixed $value1, mixed $value2): int
42 | {
43 | return gmp_cmp($value1, $value2);
44 | }
45 |
46 | public function multiply(mixed $value1, mixed $value2): GMP
47 | {
48 | return gmp_mul($value1, $value2);
49 | }
50 |
51 | public function div(mixed $value, mixed $base): GMP
52 | {
53 | return gmp_div_q($value, $base, GMP_ROUND_MINUSINF);
54 | }
55 |
56 | public function mod(mixed $value, mixed $base): GMP
57 | {
58 | return gmp_mod($value, $base);
59 | }
60 |
61 | public function add(mixed $value1, mixed $value2): GMP
62 | {
63 | return gmp_add($value1, $value2);
64 | }
65 |
66 | public function sub(mixed $value1, mixed $value2): GMP
67 | {
68 | return gmp_sub($value1, $value2);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/IPv4/NativeCalculator.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\IPv4;
15 |
16 | use function floor;
17 | use function intval;
18 |
19 | final class NativeCalculator implements Calculator
20 | {
21 | public function baseConvert(mixed $value, int $base): int
22 | {
23 | return intval((string) $value, $base);
24 | }
25 |
26 | public function pow(mixed $value, int $exponent)
27 | {
28 | return $value ** $exponent;
29 | }
30 |
31 | public function compare(mixed $value1, mixed $value2): int
32 | {
33 | return $value1 <=> $value2;
34 | }
35 |
36 | public function multiply(mixed $value1, mixed $value2): int
37 | {
38 | return $value1 * $value2;
39 | }
40 |
41 | public function div(mixed $value, mixed $base): int
42 | {
43 | return (int) floor($value / $base);
44 | }
45 |
46 | public function mod(mixed $value, mixed $base): int
47 | {
48 | return $value % $base;
49 | }
50 |
51 | public function add(mixed $value1, mixed $value2): int
52 | {
53 | return $value1 + $value2;
54 | }
55 |
56 | public function sub(mixed $value1, mixed $value2): int
57 | {
58 | return $value1 - $value2;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/IPv6/Converter.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\IPv6;
15 |
16 | use Stringable;
17 | use ValueError;
18 |
19 | use function filter_var;
20 | use function implode;
21 | use function inet_pton;
22 | use function str_split;
23 | use function strtolower;
24 | use function unpack;
25 |
26 | use const FILTER_FLAG_IPV6;
27 | use const FILTER_VALIDATE_IP;
28 |
29 | final class Converter
30 | {
31 | /**
32 | * Significant 10 bits of IP to detect Zone ID regular expression pattern.
33 | *
34 | * @var string
35 | */
36 | private const HOST_ADDRESS_BLOCK = "\xfe\x80";
37 |
38 | public static function compressIp(string $ipAddress): string
39 | {
40 | return match (filter_var($ipAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
41 | false => throw new ValueError('The submitted IP is not a valid IPv6 address.'),
42 | default => strtolower((string) inet_ntop((string) inet_pton($ipAddress))),
43 | };
44 | }
45 |
46 | public static function expandIp(string $ipAddress): string
47 | {
48 | if (false === filter_var($ipAddress, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
49 | throw new ValueError('The submitted IP is not a valid IPv6 address.');
50 | }
51 |
52 | $hex = (array) unpack('H*hex', (string) inet_pton($ipAddress));
53 |
54 | return implode(':', str_split(strtolower($hex['hex'] ?? ''), 4));
55 | }
56 |
57 | public static function compress(Stringable|string|null $host): ?string
58 | {
59 | $components = self::parse($host);
60 | if (null === $components['ipAddress']) {
61 | return match ($host) {
62 | null => $host,
63 | default => (string) $host,
64 | };
65 | }
66 |
67 | $components['ipAddress'] = self::compressIp($components['ipAddress']);
68 |
69 | return self::build($components);
70 | }
71 |
72 | public static function expand(Stringable|string|null $host): ?string
73 | {
74 | $components = self::parse($host);
75 | if (null === $components['ipAddress']) {
76 | return match ($host) {
77 | null => $host,
78 | default => (string) $host,
79 | };
80 | }
81 |
82 | $components['ipAddress'] = self::expandIp($components['ipAddress']);
83 |
84 | return self::build($components);
85 | }
86 |
87 | private static function build(array $components): string
88 | {
89 | $components['ipAddress'] ??= null;
90 | $components['zoneIdentifier'] ??= null;
91 |
92 | if (null === $components['ipAddress']) {
93 | return '';
94 | }
95 |
96 | return '['.$components['ipAddress'].match ($components['zoneIdentifier']) {
97 | null => '',
98 | default => '%'.$components['zoneIdentifier'],
99 | }.']';
100 | }
101 |
102 | /**]
103 | * @param Stringable|string|null $host
104 | *
105 | * @return array{ipAddress:string|null, zoneIdentifier:string|null}
106 | */
107 | private static function parse(Stringable|string|null $host): array
108 | {
109 | if (null === $host) {
110 | return ['ipAddress' => null, 'zoneIdentifier' => null];
111 | }
112 |
113 | $host = (string) $host;
114 | if ('' === $host) {
115 | return ['ipAddress' => null, 'zoneIdentifier' => null];
116 | }
117 |
118 | if (!str_starts_with($host, '[')) {
119 | return ['ipAddress' => null, 'zoneIdentifier' => null];
120 | }
121 |
122 | if (!str_ends_with($host, ']')) {
123 | return ['ipAddress' => null, 'zoneIdentifier' => null];
124 | }
125 |
126 | [$ipv6, $zoneIdentifier] = explode('%', substr($host, 1, -1), 2) + [1 => null];
127 | if (false === filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
128 | return ['ipAddress' => null, 'zoneIdentifier' => null];
129 | }
130 |
131 | return match (true) {
132 | null === $zoneIdentifier,
133 | is_string($ipv6) && str_starts_with((string)inet_pton($ipv6), self::HOST_ADDRESS_BLOCK) => ['ipAddress' => $ipv6, 'zoneIdentifier' => $zoneIdentifier],
134 | default => ['ipAddress' => null, 'zoneIdentifier' => null],
135 | };
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Idna/Error.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | namespace League\Uri\Idna;
13 |
14 | enum Error: int
15 | {
16 | case NONE = 0;
17 | case EMPTY_LABEL = 1;
18 | case LABEL_TOO_LONG = 2;
19 | case DOMAIN_NAME_TOO_LONG = 4;
20 | case LEADING_HYPHEN = 8;
21 | case TRAILING_HYPHEN = 0x10;
22 | case HYPHEN_3_4 = 0x20;
23 | case LEADING_COMBINING_MARK = 0x40;
24 | case DISALLOWED = 0x80;
25 | case PUNYCODE = 0x100;
26 | case LABEL_HAS_DOT = 0x200;
27 | case INVALID_ACE_LABEL = 0x400;
28 | case BIDI = 0x800;
29 | case CONTEXTJ = 0x1000;
30 | case CONTEXTO_PUNCTUATION = 0x2000;
31 | case CONTEXTO_DIGITS = 0x4000;
32 |
33 | public function description(): string
34 | {
35 | return match ($this) {
36 | self::NONE => 'No error has occurred',
37 | self::EMPTY_LABEL => 'a non-final domain name label (or the whole domain name) is empty',
38 | self::LABEL_TOO_LONG => 'a domain name label is longer than 63 bytes',
39 | self::DOMAIN_NAME_TOO_LONG => 'a domain name is longer than 255 bytes in its storage form',
40 | self::LEADING_HYPHEN => 'a label starts with a hyphen-minus ("-")',
41 | self::TRAILING_HYPHEN => 'a label ends with a hyphen-minus ("-")',
42 | self::HYPHEN_3_4 => 'a label contains hyphen-minus ("-") in the third and fourth positions',
43 | self::LEADING_COMBINING_MARK => 'a label starts with a combining mark',
44 | self::DISALLOWED => 'a label or domain name contains disallowed characters',
45 | self::PUNYCODE => 'a label starts with "xn--" but does not contain valid Punycode',
46 | self::LABEL_HAS_DOT => 'a label contains a dot=full stop',
47 | self::INVALID_ACE_LABEL => 'An ACE label does not contain a valid label string',
48 | self::BIDI => 'a label does not meet the IDNA BiDi requirements (for right-to-left characters)',
49 | self::CONTEXTJ => 'a label does not meet the IDNA CONTEXTJ requirements',
50 | self::CONTEXTO_DIGITS => 'a label does not meet the IDNA CONTEXTO requirements for digits',
51 | self::CONTEXTO_PUNCTUATION => 'a label does not meet the IDNA CONTEXTO requirements for punctuation characters. Some punctuation characters "Would otherwise have been DISALLOWED" but are allowed in certain contexts',
52 | };
53 | }
54 |
55 | public static function filterByErrorBytes(int $errors): array
56 | {
57 | return array_values(
58 | array_filter(
59 | self::cases(),
60 | fn (self $error): bool => 0 !== ($error->value & $errors)
61 | )
62 | );
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Idna/Option.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Idna;
15 |
16 | use ReflectionClass;
17 | use ReflectionClassConstant;
18 |
19 | /**
20 | * @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html
21 | */
22 | final class Option
23 | {
24 | private const DEFAULT = 0;
25 | private const ALLOW_UNASSIGNED = 1;
26 | private const USE_STD3_RULES = 2;
27 | private const CHECK_BIDI = 4;
28 | private const CHECK_CONTEXTJ = 8;
29 | private const NONTRANSITIONAL_TO_ASCII = 0x10;
30 | private const NONTRANSITIONAL_TO_UNICODE = 0x20;
31 | private const CHECK_CONTEXTO = 0x40;
32 |
33 | private function __construct(private readonly int $value)
34 | {
35 | }
36 |
37 | private static function cases(): array
38 | {
39 | static $assoc;
40 | if (null === $assoc) {
41 | $assoc = [];
42 | $fooClass = new ReflectionClass(self::class);
43 | foreach ($fooClass->getConstants(ReflectionClassConstant::IS_PRIVATE) as $name => $value) {
44 | $assoc[$name] = $value;
45 | }
46 | }
47 |
48 | return $assoc;
49 | }
50 |
51 | public static function new(int $bytes = self::DEFAULT): self
52 | {
53 | return new self(array_reduce(
54 | self::cases(),
55 | fn (int $value, int $option) => 0 !== ($option & $bytes) ? ($value | $option) : $value,
56 | self::DEFAULT
57 | ));
58 | }
59 |
60 | public static function forIDNA2008Ascii(): self
61 | {
62 | return self::new()
63 | ->nonTransitionalToAscii()
64 | ->checkBidi()
65 | ->useSTD3Rules()
66 | ->checkContextJ();
67 | }
68 |
69 | public static function forIDNA2008Unicode(): self
70 | {
71 | return self::new()
72 | ->nonTransitionalToUnicode()
73 | ->checkBidi()
74 | ->useSTD3Rules()
75 | ->checkContextJ();
76 | }
77 |
78 | public function toBytes(): int
79 | {
80 | return $this->value;
81 | }
82 |
83 | /** array */
84 | public function list(): array
85 | {
86 | return array_keys(array_filter(
87 | self::cases(),
88 | fn (int $value) => 0 !== ($value & $this->value)
89 | ));
90 | }
91 |
92 | public function allowUnassigned(): self
93 | {
94 | return $this->add(self::ALLOW_UNASSIGNED);
95 | }
96 |
97 | public function disallowUnassigned(): self
98 | {
99 | return $this->remove(self::ALLOW_UNASSIGNED);
100 | }
101 |
102 | public function useSTD3Rules(): self
103 | {
104 | return $this->add(self::USE_STD3_RULES);
105 | }
106 |
107 | public function prohibitSTD3Rules(): self
108 | {
109 | return $this->remove(self::USE_STD3_RULES);
110 | }
111 |
112 | public function checkBidi(): self
113 | {
114 | return $this->add(self::CHECK_BIDI);
115 | }
116 |
117 | public function ignoreBidi(): self
118 | {
119 | return $this->remove(self::CHECK_BIDI);
120 | }
121 |
122 | public function checkContextJ(): self
123 | {
124 | return $this->add(self::CHECK_CONTEXTJ);
125 | }
126 |
127 | public function ignoreContextJ(): self
128 | {
129 | return $this->remove(self::CHECK_CONTEXTJ);
130 | }
131 |
132 | public function checkContextO(): self
133 | {
134 | return $this->add(self::CHECK_CONTEXTO);
135 | }
136 |
137 | public function ignoreContextO(): self
138 | {
139 | return $this->remove(self::CHECK_CONTEXTO);
140 | }
141 |
142 | public function nonTransitionalToAscii(): self
143 | {
144 | return $this->add(self::NONTRANSITIONAL_TO_ASCII);
145 | }
146 |
147 | public function transitionalToAscii(): self
148 | {
149 | return $this->remove(self::NONTRANSITIONAL_TO_ASCII);
150 | }
151 |
152 | public function nonTransitionalToUnicode(): self
153 | {
154 | return $this->add(self::NONTRANSITIONAL_TO_UNICODE);
155 | }
156 |
157 | public function transitionalToUnicode(): self
158 | {
159 | return $this->remove(self::NONTRANSITIONAL_TO_UNICODE);
160 | }
161 |
162 | public function add(Option|int|null $option = null): self
163 | {
164 | return match (true) {
165 | null === $option => $this,
166 | $option instanceof self => self::new($this->value | $option->value),
167 | default => self::new($this->value | $option),
168 | };
169 | }
170 |
171 | public function remove(Option|int|null $option = null): self
172 | {
173 | return match (true) {
174 | null === $option => $this,
175 | $option instanceof self => self::new($this->value & ~$option->value),
176 | default => self::new($this->value & ~$option),
177 | };
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/Idna/Result.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\Idna;
15 |
16 | /**
17 | * @see https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/uidna_8h.html
18 | */
19 | final class Result
20 | {
21 | private function __construct(
22 | private readonly string $domain,
23 | private readonly bool $isTransitionalDifferent,
24 | /** @var array */
25 | private readonly array $errors
26 | ) {
27 | }
28 |
29 | /**
30 | * @param array{result:string, isTransitionalDifferent:bool, errors:int} $infos
31 | */
32 | public static function fromIntl(array $infos): self
33 | {
34 | return new self($infos['result'], $infos['isTransitionalDifferent'], Error::filterByErrorBytes($infos['errors']));
35 | }
36 |
37 | public function domain(): string
38 | {
39 | return $this->domain;
40 | }
41 |
42 | public function isTransitionalDifferent(): bool
43 | {
44 | return $this->isTransitionalDifferent;
45 | }
46 |
47 | /**
48 | * @return array
49 | */
50 | public function errors(): array
51 | {
52 | return $this->errors;
53 | }
54 |
55 | public function hasErrors(): bool
56 | {
57 | return [] !== $this->errors;
58 | }
59 |
60 | public function hasError(Error $error): bool
61 | {
62 | return in_array($error, $this->errors, true);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 ignace nyamagana butera
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/vendor/league/uri-interfaces/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "league/uri-interfaces",
3 | "type": "library",
4 | "description" : "Common interfaces and classes for URI representation and interaction",
5 | "keywords": [
6 | "url",
7 | "uri",
8 | "rfc3986",
9 | "rfc3987",
10 | "rfc6570",
11 | "psr-7",
12 | "parse_url",
13 | "http",
14 | "https",
15 | "ws",
16 | "ftp",
17 | "data-uri",
18 | "file-uri",
19 | "parse_str",
20 | "query-string",
21 | "querystring",
22 | "hostname"
23 | ],
24 | "license": "MIT",
25 | "homepage": "https://uri.thephpleague.com",
26 | "authors": [
27 | {
28 | "name" : "Ignace Nyamagana Butera",
29 | "email" : "nyamsprod@gmail.com",
30 | "homepage" : "https://nyamsprod.com"
31 | }
32 | ],
33 | "funding": [
34 | {
35 | "type": "github",
36 | "url": "https://github.com/sponsors/nyamsprod"
37 | }
38 | ],
39 | "require": {
40 | "php" : "^8.1",
41 | "ext-filter": "*",
42 | "psr/http-message": "^1.1 || ^2.0",
43 | "psr/http-factory": "^1"
44 | },
45 | "autoload": {
46 | "psr-4": {
47 | "League\\Uri\\": ""
48 | }
49 | },
50 | "suggest": {
51 | "ext-bcmath": "to improve IPV4 host parsing",
52 | "ext-gmp": "to improve IPV4 host parsing",
53 | "ext-intl": "to handle IDN host with the best performance",
54 | "php-64bit": "to improve IPV4 host parsing",
55 | "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
56 | },
57 | "extra": {
58 | "branch-alias": {
59 | "dev-master": "7.x-dev"
60 | }
61 | },
62 | "support": {
63 | "forum": "https://thephpleague.slack.com",
64 | "docs": "https://uri.thephpleague.com",
65 | "issues": "https://github.com/thephpleague/uri-src/issues"
66 | },
67 | "config": {
68 | "sort-packages": true
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/vendor/league/uri/HttpFactory.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri;
15 |
16 | use Psr\Http\Message\UriFactoryInterface;
17 | use Psr\Http\Message\UriInterface;
18 |
19 | final class HttpFactory implements UriFactoryInterface
20 | {
21 | public function createUri(string $uri = ''): UriInterface
22 | {
23 | return Http::new($uri);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/vendor/league/uri/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 ignace nyamagana butera
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriInfo.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri;
15 |
16 | use Deprecated;
17 | use League\Uri\Contracts\UriInterface;
18 | use Psr\Http\Message\UriInterface as Psr7UriInterface;
19 |
20 | /**
21 | * @deprecated since version 7.0.0
22 | * @codeCoverageIgnore
23 | * @see BaseUri
24 | */
25 | final class UriInfo
26 | {
27 | /**
28 | * @codeCoverageIgnore
29 | */
30 | private function __construct()
31 | {
32 | }
33 |
34 | /**
35 | * Tells whether the URI represents an absolute URI.
36 | */
37 | #[Deprecated(message:'use League\Uri\BaseUri::isAbsolute() instead', since:'league/uri:7.0.0')]
38 | public static function isAbsolute(Psr7UriInterface|UriInterface $uri): bool
39 | {
40 | return BaseUri::from($uri)->isAbsolute();
41 | }
42 |
43 | /**
44 | * Tell whether the URI represents a network path.
45 | */
46 | #[Deprecated(message:'use League\Uri\BaseUri::isNetworkPath() instead', since:'league/uri:7.0.0')]
47 | public static function isNetworkPath(Psr7UriInterface|UriInterface $uri): bool
48 | {
49 | return BaseUri::from($uri)->isNetworkPath();
50 | }
51 |
52 | /**
53 | * Tells whether the URI represents an absolute path.
54 | */
55 | #[Deprecated(message:'use League\Uri\BaseUri::isAbsolutePath() instead', since:'league/uri:7.0.0')]
56 | public static function isAbsolutePath(Psr7UriInterface|UriInterface $uri): bool
57 | {
58 | return BaseUri::from($uri)->isAbsolutePath();
59 | }
60 |
61 | /**
62 | * Tell whether the URI represents a relative path.
63 | *
64 | */
65 | #[Deprecated(message:'use League\Uri\BaseUri::isRelativePath() instead', since:'league/uri:7.0.0')]
66 | public static function isRelativePath(Psr7UriInterface|UriInterface $uri): bool
67 | {
68 | return BaseUri::from($uri)->isRelativePath();
69 | }
70 |
71 | /**
72 | * Tells whether both URI refers to the same document.
73 | */
74 | #[Deprecated(message:'use League\Uri\BaseUri::isSameDocument() instead', since:'league/uri:7.0.0')]
75 | public static function isSameDocument(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $baseUri): bool
76 | {
77 | return BaseUri::from($baseUri)->isSameDocument($uri);
78 | }
79 |
80 | /**
81 | * Returns the URI origin property as defined by WHATWG URL living standard.
82 | *
83 | * {@see https://url.spec.whatwg.org/#origin}
84 | *
85 | * For URI without a special scheme the method returns null
86 | * For URI with the file scheme the method will return null (as this is left to the implementation decision)
87 | * For URI with a special scheme the method returns the scheme followed by its authority (without the userinfo part)
88 | */
89 | #[Deprecated(message:'use League\Uri\BaseUri::origin() instead', since:'league/uri:7.0.0')]
90 | public static function getOrigin(Psr7UriInterface|UriInterface $uri): ?string
91 | {
92 | return BaseUri::from($uri)->origin()?->__toString();
93 | }
94 |
95 | /**
96 | * Tells whether two URI do not share the same origin.
97 | *
98 | * @see UriInfo::getOrigin()
99 | */
100 | #[Deprecated(message:'use League\Uri\BaseUri::isCrossOrigin() instead', since:'league/uri:7.0.0')]
101 | public static function isCrossOrigin(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $baseUri): bool
102 | {
103 | return BaseUri::from($baseUri)->isCrossOrigin($uri);
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriResolver.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri;
15 |
16 | use Deprecated;
17 | use League\Uri\Contracts\UriInterface;
18 | use Psr\Http\Message\UriInterface as Psr7UriInterface;
19 |
20 | /**
21 | * @deprecated since version 7.0.0
22 | * @codeCoverageIgnore
23 | * @see BaseUri
24 | */
25 | final class UriResolver
26 | {
27 | /**
28 | * Resolves a URI against a base URI using RFC3986 rules.
29 | *
30 | * This method MUST retain the state of the submitted URI instance, and return
31 | * a URI instance of the same type that contains the applied modifications.
32 | *
33 | * This method MUST be transparent when dealing with error and exceptions.
34 | * It MUST not alter or silence them apart from validating its own parameters.
35 | */
36 | #[Deprecated(message:'use League\Uri\BaseUri::resolve() instead', since:'league/uri:7.0.0')]
37 | public static function resolve(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $baseUri): Psr7UriInterface|UriInterface
38 | {
39 | return BaseUri::from($baseUri)->resolve($uri)->getUri();
40 | }
41 |
42 | /**
43 | * Relativizes a URI according to a base URI.
44 | *
45 | * This method MUST retain the state of the submitted URI instance, and return
46 | * a URI instance of the same type that contains the applied modifications.
47 | *
48 | * This method MUST be transparent when dealing with error and exceptions.
49 | * It MUST not alter or silence them apart from validating its own parameters.
50 | */
51 | #[Deprecated(message:'use League\Uri\BaseUri::relativize() instead', since:'league/uri:7.0.0')]
52 | public static function relativize(Psr7UriInterface|UriInterface $uri, Psr7UriInterface|UriInterface $baseUri): Psr7UriInterface|UriInterface
53 | {
54 | return BaseUri::from($baseUri)->relativize($uri)->getUri();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriTemplate.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri;
15 |
16 | use League\Uri\Contracts\UriException;
17 | use League\Uri\Contracts\UriInterface;
18 | use League\Uri\Exceptions\SyntaxError;
19 | use League\Uri\UriTemplate\Template;
20 | use League\Uri\UriTemplate\TemplateCanNotBeExpanded;
21 | use League\Uri\UriTemplate\VariableBag;
22 | use Stringable;
23 |
24 | use function array_fill_keys;
25 | use function array_key_exists;
26 |
27 | /**
28 | * Defines the URI Template syntax and the process for expanding a URI Template into a URI reference.
29 | *
30 | * @link https://tools.ietf.org/html/rfc6570
31 | * @package League\Uri
32 | * @author Ignace Nyamagana Butera
33 | * @since 6.1.0
34 | */
35 | final class UriTemplate
36 | {
37 | private readonly Template $template;
38 | private readonly VariableBag $defaultVariables;
39 |
40 | /**
41 | * @throws SyntaxError if the template syntax is invalid
42 | * @throws TemplateCanNotBeExpanded if the template or the variables are invalid
43 | */
44 | public function __construct(Stringable|string $template, iterable $defaultVariables = [])
45 | {
46 | $this->template = $template instanceof Template ? $template : Template::new($template);
47 | $this->defaultVariables = $this->filterVariables($defaultVariables);
48 | }
49 |
50 | private function filterVariables(iterable $variables): VariableBag
51 | {
52 | if (!$variables instanceof VariableBag) {
53 | $variables = new VariableBag($variables);
54 | }
55 |
56 | return $variables
57 | ->filter(fn ($value, string|int $name) => array_key_exists(
58 | $name,
59 | array_fill_keys($this->template->variableNames, 1)
60 | ));
61 | }
62 |
63 | public function getTemplate(): string
64 | {
65 | return $this->template->value;
66 | }
67 |
68 | /**
69 | * @return array
70 | */
71 | public function getVariableNames(): array
72 | {
73 | return $this->template->variableNames;
74 | }
75 |
76 | public function getDefaultVariables(): array
77 | {
78 | return iterator_to_array($this->defaultVariables);
79 | }
80 |
81 | /**
82 | * Returns a new instance with the updated default variables.
83 | *
84 | * This method MUST retain the state of the current instance, and return
85 | * an instance that contains the modified default variables.
86 | *
87 | * If present, variables whose name is not part of the current template
88 | * possible variable names are removed.
89 | *
90 | * @throws TemplateCanNotBeExpanded if the variables are invalid
91 | */
92 | public function withDefaultVariables(iterable $defaultVariables): self
93 | {
94 | $defaultVariables = $this->filterVariables($defaultVariables);
95 | if ($defaultVariables == $this->defaultVariables) {
96 | return $this;
97 | }
98 |
99 | return new self($this->template, $defaultVariables);
100 | }
101 |
102 | /**
103 | * @throws TemplateCanNotBeExpanded if the variables are invalid
104 | * @throws UriException if the resulting expansion cannot be converted to a UriInterface instance
105 | */
106 | public function expand(iterable $variables = []): UriInterface
107 | {
108 | return Uri::new($this->template->expand(
109 | $this->filterVariables($variables)->replace($this->defaultVariables)
110 | ));
111 | }
112 |
113 | /**
114 | * @throws TemplateCanNotBeExpanded if the variables are invalid or missing
115 | * @throws UriException if the resulting expansion cannot be converted to a UriInterface instance
116 | */
117 | public function expandOrFail(iterable $variables = []): UriInterface
118 | {
119 | return Uri::new($this->template->expandOrFail(
120 | $this->filterVariables($variables)->replace($this->defaultVariables)
121 | ));
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriTemplate/Expression.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\UriTemplate;
15 |
16 | use Deprecated;
17 | use League\Uri\Exceptions\SyntaxError;
18 | use Stringable;
19 |
20 | use function array_filter;
21 | use function array_map;
22 | use function array_unique;
23 | use function explode;
24 | use function implode;
25 |
26 | /**
27 | * @internal The class exposes the internal representation of an Expression and its usage
28 | * @link https://www.rfc-editor.org/rfc/rfc6570#section-2.2
29 | */
30 | final class Expression
31 | {
32 | /** @var array */
33 | private readonly array $varSpecifiers;
34 | /** @var array */
35 | public readonly array $variableNames;
36 | public readonly string $value;
37 |
38 | private function __construct(public readonly Operator $operator, VarSpecifier ...$varSpecifiers)
39 | {
40 | $this->varSpecifiers = $varSpecifiers;
41 | $this->variableNames = array_unique(
42 | array_map(
43 | static fn (VarSpecifier $varSpecifier): string => $varSpecifier->name,
44 | $varSpecifiers
45 | )
46 | );
47 | $this->value = '{'.$operator->value.implode(',', array_map(
48 | static fn (VarSpecifier $varSpecifier): string => $varSpecifier->toString(),
49 | $varSpecifiers
50 | )).'}';
51 | }
52 |
53 | /**
54 | * @throws SyntaxError if the expression is invalid
55 | */
56 | public static function new(Stringable|string $expression): self
57 | {
58 | $parts = Operator::parseExpression($expression);
59 |
60 | return new Expression($parts['operator'], ...array_map(
61 | static fn (string $varSpec): VarSpecifier => VarSpecifier::new($varSpec),
62 | explode(',', $parts['variables'])
63 | ));
64 | }
65 |
66 | /**
67 | * DEPRECATION WARNING! This method will be removed in the next major point release.
68 | *
69 | * @throws SyntaxError if the expression is invalid
70 | * @see Expression::new()
71 | *
72 | * @deprecated Since version 7.0.0
73 | * @codeCoverageIgnore
74 | */
75 | #[Deprecated(message:'use League\Uri\UriTemplate\Exppression::new() instead', since:'league/uri:7.0.0')]
76 | public static function createFromString(Stringable|string $expression): self
77 | {
78 | return self::new($expression);
79 | }
80 |
81 | public function expand(VariableBag $variables): string
82 | {
83 | $expanded = implode(
84 | $this->operator->separator(),
85 | array_filter(
86 | array_map(
87 | fn (VarSpecifier $varSpecifier): string => $this->operator->expand($varSpecifier, $variables),
88 | $this->varSpecifiers
89 | ),
90 | static fn ($value): bool => '' !== $value
91 | )
92 | );
93 |
94 | return match ('') {
95 | $expanded => '',
96 | default => $this->operator->first().$expanded,
97 | };
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriTemplate/Template.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\UriTemplate;
15 |
16 | use Deprecated;
17 | use League\Uri\Exceptions\SyntaxError;
18 | use Stringable;
19 |
20 | use function array_filter;
21 | use function array_map;
22 | use function array_reduce;
23 | use function array_unique;
24 | use function preg_match_all;
25 | use function preg_replace;
26 | use function str_contains;
27 | use function str_replace;
28 |
29 | use const PREG_SET_ORDER;
30 |
31 | /**
32 | * @internal The class exposes the internal representation of a Template and its usage
33 | */
34 | final class Template implements Stringable
35 | {
36 | /**
37 | * Expression regular expression pattern.
38 | */
39 | private const REGEXP_EXPRESSION_DETECTOR = '/(?\{[^}]*})/x';
40 |
41 | /** @var array */
42 | private readonly array $expressions;
43 | /** @var array */
44 | public readonly array $variableNames;
45 |
46 | private function __construct(public readonly string $value, Expression ...$expressions)
47 | {
48 | $this->expressions = $expressions;
49 | $this->variableNames = array_unique(
50 | array_merge(
51 | ...array_map(
52 | static fn (Expression $expression): array => $expression->variableNames,
53 | $expressions
54 | )
55 | )
56 | );
57 | }
58 |
59 | /**
60 | * @throws SyntaxError if the template contains invalid expressions
61 | * @throws SyntaxError if the template contains invalid variable specification
62 | */
63 | public static function new(Stringable|string $template): self
64 | {
65 | $template = (string) $template;
66 | /** @var string $remainder */
67 | $remainder = preg_replace(self::REGEXP_EXPRESSION_DETECTOR, '', $template);
68 | if (str_contains($remainder, '{') || str_contains($remainder, '}')) {
69 | throw new SyntaxError('The template "'.$template.'" contains invalid expressions.');
70 | }
71 |
72 | preg_match_all(self::REGEXP_EXPRESSION_DETECTOR, $template, $founds, PREG_SET_ORDER);
73 |
74 | return new self($template, ...array_values(
75 | array_reduce($founds, function (array $carry, array $found): array {
76 | if (!isset($carry[$found['expression']])) {
77 | $carry[$found['expression']] = Expression::new($found['expression']);
78 | }
79 |
80 | return $carry;
81 | }, [])
82 | ));
83 | }
84 |
85 | /**
86 | * @throws TemplateCanNotBeExpanded if the variables are invalid
87 | */
88 | public function expand(iterable $variables = []): string
89 | {
90 | if (!$variables instanceof VariableBag) {
91 | $variables = new VariableBag($variables);
92 | }
93 |
94 | return $this->expandAll($variables);
95 | }
96 |
97 | /**
98 | * @throws TemplateCanNotBeExpanded if the variables are invalid or missing
99 | */
100 | public function expandOrFail(iterable $variables = []): string
101 | {
102 | if (!$variables instanceof VariableBag) {
103 | $variables = new VariableBag($variables);
104 | }
105 |
106 | $missing = array_filter($this->variableNames, fn (string $name): bool => !isset($variables[$name]));
107 | if ([] !== $missing) {
108 | throw TemplateCanNotBeExpanded::dueToMissingVariables(...$missing);
109 | }
110 |
111 | return $this->expandAll($variables);
112 | }
113 |
114 | private function expandAll(VariableBag $variables): string
115 | {
116 | return array_reduce(
117 | $this->expressions,
118 | fn (string $uri, Expression $expr): string => str_replace($expr->value, $expr->expand($variables), $uri),
119 | $this->value
120 | );
121 | }
122 |
123 | public function __toString(): string
124 | {
125 | return $this->value;
126 | }
127 |
128 | /**
129 | * DEPRECATION WARNING! This method will be removed in the next major point release.
130 | *
131 | * @throws SyntaxError if the template contains invalid expressions
132 | * @throws SyntaxError if the template contains invalid variable specification
133 | * @deprecated Since version 7.0.0
134 | * @codeCoverageIgnore
135 | * @see Template::new()
136 | *
137 | * Create a new instance from a string.
138 | *
139 | */
140 | #[Deprecated(message:'use League\Uri\UriTemplate\Template::new() instead', since:'league/uri:7.0.0')]
141 | public static function createFromString(Stringable|string $template): self
142 | {
143 | return self::new($template);
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriTemplate/TemplateCanNotBeExpanded.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\UriTemplate;
15 |
16 | use InvalidArgumentException;
17 | use League\Uri\Contracts\UriException;
18 |
19 | class TemplateCanNotBeExpanded extends InvalidArgumentException implements UriException
20 | {
21 | public readonly array $variablesNames;
22 |
23 | public function __construct(string $message = '', string ...$variableNames)
24 | {
25 | parent::__construct($message, 0, null);
26 |
27 | $this->variablesNames = $variableNames;
28 | }
29 |
30 | public static function dueToUnableToProcessValueListWithPrefix(string $variableName): self
31 | {
32 | return new self('The ":" modifier cannot be applied on "'.$variableName.'" since it is a list of values.', $variableName);
33 | }
34 |
35 | public static function dueToNestedListOfValue(string $variableName): self
36 | {
37 | return new self('The "'.$variableName.'" cannot be a nested list.', $variableName);
38 | }
39 |
40 | public static function dueToMissingVariables(string ...$variableNames): self
41 | {
42 | return new self('The following required variables are missing: `'.implode('`, `', $variableNames).'`.', ...$variableNames);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriTemplate/VarSpecifier.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\UriTemplate;
15 |
16 | use League\Uri\Exceptions\SyntaxError;
17 |
18 | use function preg_match;
19 |
20 | /**
21 | * @internal The class exposes the internal representation of a Var Specifier
22 | * @link https://www.rfc-editor.org/rfc/rfc6570#section-2.3
23 | */
24 | final class VarSpecifier
25 | {
26 | /**
27 | * Variables specification regular expression pattern.
28 | *
29 | * @link https://tools.ietf.org/html/rfc6570#section-2.3
30 | */
31 | private const REGEXP_VARSPEC = '/^(?(?:[A-z0-9_\.]|%[0-9a-fA-F]{2})+)(?\:(?\d+)|\*)?$/';
32 |
33 | private const MODIFIER_POSITION_MAX_POSITION = 10_000;
34 |
35 | private function __construct(
36 | public readonly string $name,
37 | public readonly string $modifier,
38 | public readonly int $position
39 | ) {
40 | }
41 |
42 | public static function new(string $specification): self
43 | {
44 | if (1 !== preg_match(self::REGEXP_VARSPEC, $specification, $parsed)) {
45 | throw new SyntaxError('The variable specification "'.$specification.'" is invalid.');
46 | }
47 |
48 | $properties = ['name' => $parsed['name'], 'modifier' => $parsed['modifier'] ?? '', 'position' => $parsed['position'] ?? ''];
49 |
50 | if ('' !== $properties['position']) {
51 | $properties['position'] = (int) $properties['position'];
52 | $properties['modifier'] = ':';
53 | }
54 |
55 | if ('' === $properties['position']) {
56 | $properties['position'] = 0;
57 | }
58 |
59 | if (self::MODIFIER_POSITION_MAX_POSITION <= $properties['position']) {
60 | throw new SyntaxError('The variable specification "'.$specification.'" is invalid the position modifier must be lower than 10000.');
61 | }
62 |
63 | return new self($properties['name'], $properties['modifier'], $properties['position']);
64 | }
65 |
66 | public function toString(): string
67 | {
68 | return $this->name.$this->modifier.match (true) {
69 | 0 < $this->position => $this->position,
70 | default => '',
71 | };
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/vendor/league/uri/UriTemplate/VariableBag.php:
--------------------------------------------------------------------------------
1 |
7 | *
8 | * For the full copyright and license information, please view the LICENSE
9 | * file that was distributed with this source code.
10 | */
11 |
12 | declare(strict_types=1);
13 |
14 | namespace League\Uri\UriTemplate;
15 |
16 | use ArrayAccess;
17 | use Closure;
18 | use Countable;
19 | use IteratorAggregate;
20 | use Stringable;
21 | use Traversable;
22 |
23 | use function array_filter;
24 | use function is_bool;
25 | use function is_scalar;
26 |
27 | use const ARRAY_FILTER_USE_BOTH;
28 |
29 | /**
30 | * @internal The class exposes the internal representation of variable bags
31 | *
32 | * @phpstan-type InputValue string|bool|int|float|array
33 | *
34 | * @implements ArrayAccess
35 | * @implements IteratorAggregate
36 | */
37 | final class VariableBag implements ArrayAccess, Countable, IteratorAggregate
38 | {
39 | /**
40 | * @var array>
41 | */
42 | private array $variables = [];
43 |
44 | /**
45 | * @param iterable $variables
46 | */
47 | public function __construct(iterable $variables = [])
48 | {
49 | foreach ($variables as $name => $value) {
50 | $this->assign((string) $name, $value);
51 | }
52 | }
53 |
54 | public function count(): int
55 | {
56 | return count($this->variables);
57 | }
58 |
59 | public function getIterator(): Traversable
60 | {
61 | yield from $this->variables;
62 | }
63 |
64 | public function offsetExists(mixed $offset): bool
65 | {
66 | return array_key_exists($offset, $this->variables);
67 | }
68 |
69 | public function offsetUnset(mixed $offset): void
70 | {
71 | unset($this->variables[$offset]);
72 | }
73 |
74 | public function offsetSet(mixed $offset, mixed $value): void
75 | {
76 | $this->assign($offset, $value); /* @phpstan-ignore-line */
77 | }
78 |
79 | public function offsetGet(mixed $offset): mixed
80 | {
81 | return $this->fetch($offset);
82 | }
83 |
84 | /**
85 | * Tells whether the bag is empty or not.
86 | */
87 | public function isEmpty(): bool
88 | {
89 | return [] === $this->variables;
90 | }
91 |
92 | /**
93 | * Tells whether the bag is empty or not.
94 | */
95 | public function isNotEmpty(): bool
96 | {
97 | return [] !== $this->variables;
98 | }
99 |
100 | /**
101 | * Fetches the variable value if none found returns null.
102 | *
103 | * @return null|string|array
104 | */
105 | public function fetch(string $name): null|string|array
106 | {
107 | return $this->variables[$name] ?? null;
108 | }
109 |
110 | /**
111 | * @param Stringable|InputValue $value
112 | */
113 | public function assign(string $name, Stringable|string|bool|int|float|array|null $value): void
114 | {
115 | $this->variables[$name] = $this->normalizeValue($value, $name, true);
116 | }
117 |
118 | /**
119 | * @param Stringable|InputValue $value
120 | *
121 | * @throws TemplateCanNotBeExpanded if the value contains nested list
122 | */
123 | private function normalizeValue(
124 | Stringable|string|float|int|bool|array|null $value,
125 | string $name,
126 | bool $isNestedListAllowed
127 | ): array|string {
128 | return match (true) {
129 | is_bool($value) => true === $value ? '1' : '0',
130 | (null === $value || is_scalar($value) || $value instanceof Stringable) => (string) $value,
131 | !$isNestedListAllowed => throw TemplateCanNotBeExpanded::dueToNestedListOfValue($name),
132 | default => array_map(fn ($var): array|string => self::normalizeValue($var, $name, false), $value),
133 | };
134 | }
135 |
136 | /**
137 | * Replaces elements from passed variables into the current instance.
138 | */
139 | public function replace(VariableBag $variables): self
140 | {
141 | return new self($this->variables + $variables->variables);
142 | }
143 |
144 | /**
145 | * Filters elements using the closure.
146 | */
147 | public function filter(Closure $fn): self
148 | {
149 | return new self(array_filter($this->variables, $fn, ARRAY_FILTER_USE_BOTH));
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/vendor/league/uri/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "league/uri",
3 | "type": "library",
4 | "description" : "URI manipulation library",
5 | "keywords": [
6 | "url",
7 | "uri",
8 | "rfc3986",
9 | "rfc3987",
10 | "rfc6570",
11 | "psr-7",
12 | "parse_url",
13 | "http",
14 | "https",
15 | "ws",
16 | "ftp",
17 | "data-uri",
18 | "file-uri",
19 | "middleware",
20 | "parse_str",
21 | "query-string",
22 | "querystring",
23 | "hostname",
24 | "uri-template"
25 | ],
26 | "license": "MIT",
27 | "homepage": "https://uri.thephpleague.com",
28 | "authors": [
29 | {
30 | "name" : "Ignace Nyamagana Butera",
31 | "email" : "nyamsprod@gmail.com",
32 | "homepage" : "https://nyamsprod.com"
33 | }
34 | ],
35 | "support": {
36 | "forum": "https://thephpleague.slack.com",
37 | "docs": "https://uri.thephpleague.com",
38 | "issues": "https://github.com/thephpleague/uri-src/issues"
39 | },
40 | "funding": [
41 | {
42 | "type": "github",
43 | "url": "https://github.com/sponsors/nyamsprod"
44 | }
45 | ],
46 | "require": {
47 | "php": "^8.1",
48 | "league/uri-interfaces": "^7.5"
49 | },
50 | "autoload": {
51 | "psr-4": {
52 | "League\\Uri\\": ""
53 | }
54 | },
55 | "conflict": {
56 | "league/uri-schemes": "^1.0"
57 | },
58 | "suggest": {
59 | "ext-bcmath": "to improve IPV4 host parsing",
60 | "ext-fileinfo": "to create Data URI from file contennts",
61 | "ext-gmp": "to improve IPV4 host parsing",
62 | "ext-intl": "to handle IDN host with the best performance",
63 | "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain",
64 | "league/uri-components" : "Needed to easily manipulate URI objects components",
65 | "php-64bit": "to improve IPV4 host parsing",
66 | "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present"
67 | },
68 | "extra": {
69 | "branch-alias": {
70 | "dev-master": "7.x-dev"
71 | }
72 | },
73 | "config": {
74 | "sort-packages": true
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/CREDITS:
--------------------------------------------------------------------------------
1 | Matt Butcher [technosophos] (lead)
2 | Matt Farina [mattfarina] (lead)
3 | Asmir Mustafic [goetas] (contributor)
4 | Edward Z. Yang [ezyang] (contributor)
5 | Geoffrey Sneddon [gsnedders] (contributor)
6 | Kukhar Vasily [ngreduce] (contributor)
7 | Rune Christensen [MrElectronic] (contributor)
8 | Mišo Belica [miso-belica] (contributor)
9 | Asmir Mustafic [goetas] (contributor)
10 | KITAITI Makoto [KitaitiMakoto] (contributor)
11 | Jacob Floyd [cognifloyd] (contributor)
12 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/LICENSE.txt:
--------------------------------------------------------------------------------
1 | ## HTML5-PHP License
2 |
3 | Copyright (c) 2013 The Authors of HTML5-PHP
4 |
5 | Matt Butcher - mattbutcher@google.com
6 | Matt Farina - matt@mattfarina.com
7 | Asmir Mustafic - goetas@gmail.com
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy of
10 | this software and associated documentation files (the "Software"), to deal in
11 | the Software without restriction, including without limitation the rights to
12 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
13 | the Software, and to permit persons to whom the Software is furnished to do so,
14 | subject to the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included in all
17 | copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 |
26 | ## HTML5Lib License
27 |
28 | Portions of this are based on html5lib's PHP version, which was a
29 | sub-project of html5lib. The following is the list of contributors from
30 | html5lib:
31 |
32 | html5lib:
33 |
34 | Copyright (c) 2006-2009 The Authors
35 |
36 | Contributors:
37 | James Graham - jg307@cam.ac.uk
38 | Anne van Kesteren - annevankesteren@gmail.com
39 | Lachlan Hunt - lachlan.hunt@lachy.id.au
40 | Matt McDonald - kanashii@kanashii.ca
41 | Sam Ruby - rubys@intertwingly.net
42 | Ian Hickson (Google) - ian@hixie.ch
43 | Thomas Broyer - t.broyer@ltgt.net
44 | Jacques Distler - distler@golem.ph.utexas.edu
45 | Henri Sivonen - hsivonen@iki.fi
46 | Adam Barth - abarth@webkit.org
47 | Eric Seidel - eric@webkit.org
48 | The Mozilla Foundation (contributions from Henri Sivonen since 2008)
49 | David Flanagan (Mozilla) - dflanagan@mozilla.com
50 |
51 | Permission is hereby granted, free of charge, to any person obtaining a copy of
52 | this software and associated documentation files (the "Software"), to deal in
53 | the Software without restriction, including without limitation the rights to
54 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
55 | the Software, and to permit persons to whom the Software is furnished to do so,
56 | subject to the following conditions:
57 |
58 | The above copyright notice and this permission notice shall be included in all
59 | copies or substantial portions of the Software.
60 |
61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
63 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
64 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
65 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
66 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
67 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/RELEASE.md:
--------------------------------------------------------------------------------
1 | # Release Notes
2 |
3 | 2.7.6 (2021-08-18)
4 |
5 | - #218: Address comment handling issues
6 |
7 | 2.7.5 (2021-07-01)
8 |
9 | - #204: Travis: Enable tests on PHP 8.0
10 | - #207: Fix PHP 8.1 deprecations
11 |
12 | 2.7.4 (2020-10-01)
13 |
14 | - #191: Fix travisci build
15 | - #195: Add .gitattributes file with export-ignore rules
16 | - #194: Fix query parameter parsed as character entity
17 |
18 | 2.7.3 (2020-07-05)
19 |
20 | - #190: mitigate cyclic reference between output rules and the traverser objects
21 |
22 | 2.7.2 (2020-07-01)
23 |
24 | - #187: Fixed memory leak in HTML5::saveHTML()
25 | - #186: Add special case for end tag
26 |
27 | 2.7.1 (2020-06-14)
28 |
29 | - #171: add PHP 7.4 job
30 | - #178: Prevent infinite loop on un-terminated entity declaration at EOF
31 |
32 | 2.7.0 (2019-07-25)
33 |
34 | - #164: Drop HHVM support
35 | - #168: Set default encoding in the DOMDocument object
36 |
37 | 2.6.0 (2019-03-10)
38 |
39 | - #163: Allow to pass a charset to the Scanner
40 |
41 | 2.5.0 (2018-12-27)
42 |
43 | - #162, #161, #155, #154, #153, #151: big performance improvements
44 | - #156: fixed typos
45 | - #160: adopt and enforce code style
46 | - #159: remove deprecated php unit base test case
47 | - #150: backport changes from old master branch
48 |
49 | 2.4.0 (2018-11-17)
50 |
51 | - #148: Improve performance by moving sequence matching
52 | - #147: Improve the Tokenizer performance
53 | - #146: Improve performance by relying on a native string instead of InputStream
54 | - #144: Add DOM extension in composer.json
55 | - #145: Add more extensions on composer.json, improve phpdocs and remove dead code
56 | - #143: Remove experimental comment
57 |
58 | 2.3.1 (2018-10-18)
59 |
60 | - #121: Audio is not a block tag (fixed by #141)
61 | - #136: Handle illegal self-closing according to spec (fixed by #137)
62 | - #141: Minor fixes in the README
63 |
64 | 2.3.0 (2017-09-04)
65 |
66 | - #129: image within inline svg breaks system (fixed by #133)
67 | - #131: ² does not work (fixed by #132)
68 | - #134: Improve tokenizer performance by 20% (alternative version of #130 thanks to @MichaelHeerklotz)
69 | - #135: Raw & in attributes
70 |
71 | 2.2.2 (2016-09-22)
72 |
73 | - #116: In XML mode, tags are case sensitive
74 | - #115: Fix PHP Notice in OutputRules
75 | - #112: fix parsing of options of an optgroup
76 | - #111: Adding test for the address tag
77 |
78 | 2.2.1 (2016-05-10)
79 |
80 | - #109: Fixed issue where address tag could be written without closing tag (thanks sylus)
81 |
82 | 2.2.0 (2016-04-11)
83 |
84 | - #105: Enable composer cache (for CI/CD)
85 | - #100: Use mb_substitute_character inset of ini_set for environments where ini_set is disable (e.g., shared hosting)
86 | - #98: Allow link, meta, style tags in noscript tags
87 | - #96: Fixed xml:href on svgs that use the "use" breaking
88 | - #94: Counting UTF8 characters performance improvement
89 | - #93: Use newer version of coveralls package
90 | - #90: Remove duplicate test
91 | - #87: Allow multiple root nodes
92 |
93 | 2.1.2 (2015-06-07)
94 | - #82: Support for PHP7
95 | - #84: Improved boolean attribute handling
96 |
97 | 2.1.1 (2015-03-23)
98 | - #78: Fixes bug where unmatched entity like string drops everything after &.
99 |
100 | 2.1.0 (2015-02-01)
101 | - #74: Added `disable_html_ns` and `target_doc` dom parsing options
102 | - Unified option names
103 | - #73: Fixed alphabet, ß now can be detected
104 | - #75 and #76: Allow whitespace in RCDATA tags
105 | - #77: Fixed parsing blunder for json embeds
106 | - #72: Add options to HTML methods
107 |
108 | 2.0.2 (2014-12-17)
109 | - #50: empty document handling
110 | - #63: tags with strange capitalization
111 | - #65: dashes and underscores as allowed characters in tag names
112 | - #68: Fixed issue with non-inline elements inside inline containers
113 |
114 | 2.0.1 (2014-09-23)
115 | - #59: Fixed issue parsing some fragments.
116 | - #56: Incorrectly saw 0 as empty string
117 | - Sami as new documentation generator
118 |
119 | 2.0.0 (2014-07-28)
120 | - #53: Improved boolean attributes handling
121 | - #52: Facebook HHVM compatibility
122 | - #48: Adopted PSR-2 as coding standard
123 | - #47: Moved everything to Masterminds namespace
124 | - #45: Added custom namespaces
125 | - #44: Added support to XML-style namespaces
126 | - #37: Refactored HTML5 class removing static methods
127 |
128 | 1.0.5 (2014-06-10)
129 | - #38: Set the dev-master branch as the 1.0.x branch for composer (goetas)
130 | - #34: Tests use PSR-4 for autoloading. (goetas)
131 | - #40, #41: Fix entity handling in RCDATA sections. (KitaitiMakoto)
132 | - #32: Fixed issue where wharacter references were being incorrectly encoded in style tags.
133 |
134 | 1.0.4 (2014-04-29)
135 | - #30/#31 Don't throw an exception for invalid tag names.
136 |
137 | 1.0.3 (2014-02-28)
138 | - #23 and #29: Ignore attributes with illegal chars in name for the PHP DOM.
139 |
140 | 1.0.2 (2014-02-12)
141 | - #23: Handle missing tag close in attribute list.
142 | - #25: Fixed text escaping in the serializer (HTML% 8.3).
143 | - #27: Fixed tests on Windows: changed "\n" -> PHP_EOL.
144 | - #28: Fixed infinite loop for char "&" in unquoted attribute in parser.
145 | - #26: Updated tag name case handling to deal with uppercase usage.
146 | - #24: Newlines and tabs are allowed inside quoted attributes (HTML5 8.2.4).
147 | - Fixed Travis CI testing.
148 |
149 | 1.0.1 (2013-11-07)
150 | - CDATA encoding is improved. (Non-standard; Issue #19)
151 | - Some parser rules were not returning the new current element. (Issue #20)
152 | - Added, to the README, details on code test coverage and to packagist version.
153 | - Fixed processor instructions.
154 | - Improved test coverage and documentation coverage.
155 |
156 | 1.0.0 (2013-10-02)
157 | - Initial release.
158 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/UPGRADING.md:
--------------------------------------------------------------------------------
1 | From 1.x to 2.x
2 | =================
3 |
4 | - All classes uses `Masterminds` namespace.
5 | - All public static methods has been removed from `HTML5` class and the general API to access the HTML5 functionalities has changed.
6 |
7 | Before:
8 |
9 | $dom = \HTML5::loadHTML('....');
10 | \HTML5::saveHTML($dom);
11 |
12 | After:
13 |
14 | use Masterminds\HTML5;
15 |
16 | $html5 = new HTML5();
17 |
18 | $dom = $html5->loadHTML('....');
19 | echo $html5->saveHTML($dom);
20 |
21 |
22 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/bin/entities.php:
--------------------------------------------------------------------------------
1 | $obj) {
14 | $sname = substr($name, 1, -1);
15 | $table[$sname] = $obj->characters;
16 | }
17 |
18 | echo '=5.3.0"
25 | },
26 | "require-dev": {
27 | "phpunit/phpunit" : "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
28 | },
29 | "autoload": {
30 | "psr-4": {"Masterminds\\": "src"}
31 | },
32 | "autoload-dev": {
33 | "psr-4": {"Masterminds\\HTML5\\Tests\\": "test/HTML5"}
34 | },
35 | "extra": {
36 | "branch-alias": {
37 | "dev-master": "2.7-dev"
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/src/HTML5/Exception.php:
--------------------------------------------------------------------------------
1 | ).
65 | *
66 | * @return int one of the Tokenizer::TEXTMODE_* constants
67 | */
68 | public function startTag($name, $attributes = array(), $selfClosing = false);
69 |
70 | /**
71 | * An end-tag.
72 | */
73 | public function endTag($name);
74 |
75 | /**
76 | * A comment section (unparsed character data).
77 | */
78 | public function comment($cdata);
79 |
80 | /**
81 | * A unit of parsed character data.
82 | *
83 | * Entities in this text are *already decoded*.
84 | */
85 | public function text($cdata);
86 |
87 | /**
88 | * Indicates that the document has been entirely processed.
89 | */
90 | public function eof();
91 |
92 | /**
93 | * Emitted when the parser encounters an error condition.
94 | */
95 | public function parseError($msg, $line, $col);
96 |
97 | /**
98 | * A CDATA section.
99 | *
100 | * @param string $data
101 | * The unparsed character data
102 | */
103 | public function cdata($data);
104 |
105 | /**
106 | * This is a holdover from the XML spec.
107 | *
108 | * While user agents don't get PIs, server-side does.
109 | *
110 | * @param string $name The name of the processor (e.g. 'php').
111 | * @param string $data The unparsed data.
112 | */
113 | public function processingInstruction($name, $data = null);
114 | }
115 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/src/HTML5/Parser/FileInputStream.php:
--------------------------------------------------------------------------------
1 | 1,
20 | 'dd' => 1,
21 | 'dt' => 1,
22 | 'rt' => 1,
23 | 'rp' => 1,
24 | 'tr' => 1,
25 | 'th' => 1,
26 | 'td' => 1,
27 | 'thead' => 1,
28 | 'tfoot' => 1,
29 | 'tbody' => 1,
30 | 'table' => 1,
31 | 'optgroup' => 1,
32 | 'option' => 1,
33 | );
34 |
35 | /**
36 | * Returns true if the given tagname has special processing rules.
37 | */
38 | public function hasRules($tagname)
39 | {
40 | return isset(static::$tags[$tagname]);
41 | }
42 |
43 | /**
44 | * Evaluate the rule for the current tag name.
45 | *
46 | * This may modify the existing DOM.
47 | *
48 | * @return \DOMElement The new Current DOM element.
49 | */
50 | public function evaluate($new, $current)
51 | {
52 | switch ($new->tagName) {
53 | case 'li':
54 | return $this->handleLI($new, $current);
55 | case 'dt':
56 | case 'dd':
57 | return $this->handleDT($new, $current);
58 | case 'rt':
59 | case 'rp':
60 | return $this->handleRT($new, $current);
61 | case 'optgroup':
62 | return $this->closeIfCurrentMatches($new, $current, array(
63 | 'optgroup',
64 | ));
65 | case 'option':
66 | return $this->closeIfCurrentMatches($new, $current, array(
67 | 'option',
68 | ));
69 | case 'tr':
70 | return $this->closeIfCurrentMatches($new, $current, array(
71 | 'tr',
72 | ));
73 | case 'td':
74 | case 'th':
75 | return $this->closeIfCurrentMatches($new, $current, array(
76 | 'th',
77 | 'td',
78 | ));
79 | case 'tbody':
80 | case 'thead':
81 | case 'tfoot':
82 | case 'table': // Spec isn't explicit about this, but it's necessary.
83 |
84 | return $this->closeIfCurrentMatches($new, $current, array(
85 | 'thead',
86 | 'tfoot',
87 | 'tbody',
88 | ));
89 | }
90 |
91 | return $current;
92 | }
93 |
94 | protected function handleLI($ele, $current)
95 | {
96 | return $this->closeIfCurrentMatches($ele, $current, array(
97 | 'li',
98 | ));
99 | }
100 |
101 | protected function handleDT($ele, $current)
102 | {
103 | return $this->closeIfCurrentMatches($ele, $current, array(
104 | 'dt',
105 | 'dd',
106 | ));
107 | }
108 |
109 | protected function handleRT($ele, $current)
110 | {
111 | return $this->closeIfCurrentMatches($ele, $current, array(
112 | 'rt',
113 | 'rp',
114 | ));
115 | }
116 |
117 | protected function closeIfCurrentMatches($ele, $current, $match)
118 | {
119 | if (in_array($current->tagName, $match, true)) {
120 | $current->parentNode->appendChild($ele);
121 | } else {
122 | $current->appendChild($ele);
123 | }
124 |
125 | return $ele;
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/vendor/masterminds/html5/src/HTML5/Serializer/README.md:
--------------------------------------------------------------------------------
1 | # The Serializer (Writer) Model
2 |
3 | The serializer roughly follows sections _8.1 Writing HTML documents_ and section
4 | _8.3 Serializing HTML fragments_ by converting DOMDocument, DOMDocumentFragment,
5 | and DOMNodeList into HTML5.
6 |
7 | [ HTML5 ] // Interface for saving.
8 | ||
9 | [ Traverser ] // Walk the DOM
10 | ||
11 | [ Rules ] // Convert DOM elements into strings.
12 | ||
13 | [ HTML5 ] // HTML5 document or fragment in text.
14 |
15 |
16 | ## HTML5 Class
17 |
18 | Provides the top level interface for saving.
19 |
20 | ## The Traverser
21 |
22 | Walks the DOM finding each element and passing it off to the output rules to
23 | convert to HTML5.
24 |
25 | ## Output Rules
26 |
27 | The output rules are defined in the RulesInterface which can have multiple
28 | implementations. Currently, the OutputRules is the default implementation that
29 | converts a DOM as is into HTML5.
30 |
31 | ## HTML5 String
32 |
33 | The output of the process it HTML5 as a string or saved to a file.
--------------------------------------------------------------------------------
/vendor/masterminds/html5/src/HTML5/Serializer/RulesInterface.php:
--------------------------------------------------------------------------------
1 | 'html',
21 | 'http://www.w3.org/1998/Math/MathML' => 'math',
22 | 'http://www.w3.org/2000/svg' => 'svg',
23 | );
24 |
25 | protected $dom;
26 |
27 | protected $options;
28 |
29 | protected $encode = false;
30 |
31 | protected $rules;
32 |
33 | protected $out;
34 |
35 | /**
36 | * Create a traverser.
37 | *
38 | * @param \DOMNode|\DOMNodeList $dom The document or node to traverse.
39 | * @param resource $out A stream that allows writing. The traverser will output into this
40 | * stream.
41 | * @param array $options An array of options for the traverser as key/value pairs. These include:
42 | * - encode_entities: A bool to specify if full encding should happen for all named
43 | * charachter references. Defaults to false which escapes &'<>".
44 | * - output_rules: The path to the class handling the output rules.
45 | */
46 | public function __construct($dom, $out, RulesInterface $rules, $options = array())
47 | {
48 | $this->dom = $dom;
49 | $this->out = $out;
50 | $this->rules = $rules;
51 | $this->options = $options;
52 |
53 | $this->rules->setTraverser($this);
54 | }
55 |
56 | /**
57 | * Tell the traverser to walk the DOM.
58 | *
59 | * @return resource $out Returns the output stream.
60 | */
61 | public function walk()
62 | {
63 | if ($this->dom instanceof \DOMDocument) {
64 | $this->rules->document($this->dom);
65 | } elseif ($this->dom instanceof \DOMDocumentFragment) {
66 | // Document fragments are a special case. Only the children need to
67 | // be serialized.
68 | if ($this->dom->hasChildNodes()) {
69 | $this->children($this->dom->childNodes);
70 | }
71 | } // If NodeList, loop
72 | elseif ($this->dom instanceof \DOMNodeList) {
73 | // If this is a NodeList of DOMDocuments this will not work.
74 | $this->children($this->dom);
75 | } // Else assume this is a DOMNode-like datastructure.
76 | else {
77 | $this->node($this->dom);
78 | }
79 |
80 | return $this->out;
81 | }
82 |
83 | /**
84 | * Process a node in the DOM.
85 | *
86 | * @param mixed $node A node implementing \DOMNode.
87 | */
88 | public function node($node)
89 | {
90 | // A listing of types is at http://php.net/manual/en/dom.constants.php
91 | switch ($node->nodeType) {
92 | case XML_ELEMENT_NODE:
93 | $this->rules->element($node);
94 | break;
95 | case XML_TEXT_NODE:
96 | $this->rules->text($node);
97 | break;
98 | case XML_CDATA_SECTION_NODE:
99 | $this->rules->cdata($node);
100 | break;
101 | case XML_PI_NODE:
102 | $this->rules->processorInstruction($node);
103 | break;
104 | case XML_COMMENT_NODE:
105 | $this->rules->comment($node);
106 | break;
107 | // Currently we don't support embedding DTDs.
108 | default:
109 | //print '';
110 | break;
111 | }
112 | }
113 |
114 | /**
115 | * Walk through all the nodes on a node list.
116 | *
117 | * @param \DOMNodeList $nl A list of child elements to walk through.
118 | */
119 | public function children($nl)
120 | {
121 | foreach ($nl as $node) {
122 | $this->node($node);
123 | }
124 | }
125 |
126 | /**
127 | * Is an element local?
128 | *
129 | * @param mixed $ele An element that implement \DOMNode.
130 | *
131 | * @return bool true if local and false otherwise.
132 | */
133 | public function isLocalElement($ele)
134 | {
135 | $uri = $ele->namespaceURI;
136 | if (empty($uri)) {
137 | return false;
138 | }
139 |
140 | return isset(static::$local_ns[$uri]);
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/vendor/psr/http-factory/.gitignore:
--------------------------------------------------------------------------------
1 | composer.lock
2 | vendor/
3 |
--------------------------------------------------------------------------------
/vendor/psr/http-factory/.pullapprove.yml:
--------------------------------------------------------------------------------
1 | extends: default
2 | reviewers:
3 | -
4 | name: contributors
5 | required: 1
6 | teams:
7 | - http-factory-contributors
8 |
--------------------------------------------------------------------------------
/vendor/psr/http-factory/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 PHP-FIG
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/vendor/psr/http-factory/README.md:
--------------------------------------------------------------------------------
1 | HTTP Factories
2 | ==============
3 |
4 | This repository holds all interfaces related to [PSR-17 (HTTP Message Factories)][psr-17].
5 | Please refer to the specification for a description.
6 |
7 | You can find implementations of the specification by looking for packages providing the
8 | [psr/http-factory-implementation](https://packagist.org/providers/psr/http-factory-implementation) virtual package.
9 |
10 | [psr-17]: https://www.php-fig.org/psr/psr-17/
11 |
--------------------------------------------------------------------------------
/vendor/psr/http-factory/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "psr/http-factory",
3 | "description": "Common interfaces for PSR-7 HTTP message factories",
4 | "keywords": [
5 | "psr",
6 | "psr-7",
7 | "psr-17",
8 | "http",
9 | "factory",
10 | "message",
11 | "request",
12 | "response"
13 | ],
14 | "license": "MIT",
15 | "authors": [
16 | {
17 | "name": "PHP-FIG",
18 | "homepage": "http://www.php-fig.org/"
19 | }
20 | ],
21 | "require": {
22 | "php": ">=7.0.0",
23 | "psr/http-message": "^1.0"
24 | },
25 | "autoload": {
26 | "psr-4": {
27 | "Psr\\Http\\Message\\": "src/"
28 | }
29 | },
30 | "extra": {
31 | "branch-alias": {
32 | "dev-master": "1.0.x-dev"
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/vendor/psr/http-factory/src/RequestFactoryInterface.php:
--------------------------------------------------------------------------------
1 | `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`.
7 | > When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered.
8 |
9 |
10 | The following examples will illustrate how basic operations are done in PSR-7.
11 |
12 | ##### Examples
13 |
14 |
15 | For this examples to work (at least) a PSR-7 implementation package is required. (eg: zendframework/zend-diactoros, guzzlehttp/psr7, slim/slim, etc)
16 | All PSR-7 implementations should have the same behaviour.
17 |
18 | The following will be assumed:
19 | `$request` is an object of `Psr\Http\Message\RequestInterface` and
20 |
21 | `$response` is an object implementing `Psr\Http\Message\RequestInterface`
22 |
23 |
24 | ### Working with HTTP Headers
25 |
26 | #### Adding headers to response:
27 |
28 | ```php
29 | $response->withHeader('My-Custom-Header', 'My Custom Message');
30 | ```
31 |
32 | #### Appending values to headers
33 |
34 | ```php
35 | $response->withAddedHeader('My-Custom-Header', 'The second message');
36 | ```
37 |
38 | #### Checking if header exists:
39 |
40 | ```php
41 | $request->hasHeader('My-Custom-Header'); // will return false
42 | $response->hasHeader('My-Custom-Header'); // will return true
43 | ```
44 |
45 | > Note: My-Custom-Header was only added in the Response
46 |
47 | #### Getting comma-separated values from a header (also applies to request)
48 |
49 | ```php
50 | // getting value from request headers
51 | $request->getHeaderLine('Content-Type'); // will return: "text/html; charset=UTF-8"
52 | // getting value from response headers
53 | $response->getHeaderLine('My-Custom-Header'); // will return: "My Custom Message; The second message"
54 | ```
55 |
56 | #### Getting array of value from a header (also applies to request)
57 | ```php
58 | // getting value from request headers
59 | $request->getHeader('Content-Type'); // will return: ["text/html", "charset=UTF-8"]
60 | // getting value from response headers
61 | $response->getHeader('My-Custom-Header'); // will return: ["My Custom Message", "The second message"]
62 | ```
63 |
64 | #### Removing headers from HTTP Messages
65 | ```php
66 | // removing a header from Request, removing deprecated "Content-MD5" header
67 | $request->withoutHeader('Content-MD5');
68 |
69 | // removing a header from Response
70 | // effect: the browser won't know the size of the stream
71 | // the browser will download the stream till it ends
72 | $response->withoutHeader('Content-Length');
73 | ```
74 |
75 | ### Working with HTTP Message Body
76 |
77 | When working with the PSR-7 there are two methods of implementation:
78 | #### 1. Getting the body separately
79 |
80 | > 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.
81 |
82 | ```php
83 | $body = $response->getBody();
84 | // operations on body, eg. read, write, seek
85 | // ...
86 | // replacing the old body
87 | $response->withBody($body);
88 | // this last statement is optional as we working with objects
89 | // in this case the "new" body is same with the "old" one
90 | // the $body variable has the same value as the one in $request, only the reference is passed
91 | ```
92 |
93 | #### 2. Working directly on response
94 |
95 | > This method is useful when only performing few operations as the `$request->getBody()` statement fragment is required
96 |
97 | ```php
98 | $response->getBody()->write('hello');
99 | ```
100 |
101 | ### Getting the body contents
102 |
103 | The following snippet gets the contents of a stream contents.
104 | > 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.
105 | ```php
106 | $body = $response->getBody();
107 | $body->rewind(); // or $body->seek(0);
108 | $bodyText = $body->getContents();
109 | ```
110 | > 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.
111 |
112 | ### Append to body
113 |
114 | ```php
115 | $response->getBody()->write('Hello'); // writing directly
116 | $body = $request->getBody(); // which is a `StreamInterface`
117 | $body->write('xxxxx');
118 | ```
119 |
120 | ### Prepend to body
121 | Prepending is different when it comes to streams. The content must be copied before writing the content to be prepended.
122 | The following example will explain the behaviour of streams.
123 |
124 | ```php
125 | // assuming our response is initially empty
126 | $body = $repsonse->getBody();
127 | // writing the string "abcd"
128 | $body->write('abcd');
129 |
130 | // seeking to start of stream
131 | $body->seek(0);
132 | // writing 'ef'
133 | $body->write('ef'); // at this point the stream contains "efcd"
134 | ```
135 |
136 | #### Prepending by rewriting separately
137 |
138 | ```php
139 | // assuming our response body stream only contains: "abcd"
140 | $body = $response->getBody();
141 | $body->rewind();
142 | $contents = $body->getContents(); // abcd
143 | // seeking the stream to beginning
144 | $body->rewind();
145 | $body->write('ef'); // stream contains "efcd"
146 | $body->write($contents); // stream contains "efabcd"
147 | ```
148 |
149 | > 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)`.
150 |
151 | #### Prepending by using contents as a string
152 | ```php
153 | $body = $response->getBody();
154 | $body->rewind();
155 | $contents = $body->getContents(); // efabcd
156 | $contents = 'ef'.$contents;
157 | $body->rewind();
158 | $body->write($contents);
159 | ```
160 |
--------------------------------------------------------------------------------
/vendor/psr/http-message/src/RequestInterface.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
34 | }
35 |
36 | public function doSomething()
37 | {
38 | if ($this->logger) {
39 | $this->logger->info('Doing work');
40 | }
41 |
42 | try {
43 | $this->doSomethingElse();
44 | } catch (Exception $exception) {
45 | $this->logger->error('Oh no!', array('exception' => $exception));
46 | }
47 |
48 | // do something useful
49 | }
50 | }
51 | ```
52 |
53 | You can then pick one of the implementations of the interface to get a logger.
54 |
55 | If you want to implement the interface, you can require this package and
56 | implement `Psr\Log\LoggerInterface` in your code. Please read the
57 | [specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md)
58 | for details.
59 |
--------------------------------------------------------------------------------
/vendor/psr/log/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "psr/log",
3 | "description": "Common interface for logging libraries",
4 | "keywords": ["psr", "psr-3", "log"],
5 | "homepage": "https://github.com/php-fig/log",
6 | "license": "MIT",
7 | "authors": [
8 | {
9 | "name": "PHP-FIG",
10 | "homepage": "https://www.php-fig.org/"
11 | }
12 | ],
13 | "require": {
14 | "php": ">=8.0.0"
15 | },
16 | "autoload": {
17 | "psr-4": {
18 | "Psr\\Log\\": "src"
19 | }
20 | },
21 | "extra": {
22 | "branch-alias": {
23 | "dev-master": "3.x-dev"
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/vendor/psr/log/src/AbstractLogger.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/vendor/psr/log/src/LoggerInterface.php:
--------------------------------------------------------------------------------
1 | log(LogLevel::EMERGENCY, $message, $context);
21 | }
22 |
23 | /**
24 | * Action must be taken immediately.
25 | *
26 | * Example: Entire website down, database unavailable, etc. This should
27 | * trigger the SMS alerts and wake you up.
28 | */
29 | public function alert(string|\Stringable $message, array $context = []): void
30 | {
31 | $this->log(LogLevel::ALERT, $message, $context);
32 | }
33 |
34 | /**
35 | * Critical conditions.
36 | *
37 | * Example: Application component unavailable, unexpected exception.
38 | */
39 | public function critical(string|\Stringable $message, array $context = []): void
40 | {
41 | $this->log(LogLevel::CRITICAL, $message, $context);
42 | }
43 |
44 | /**
45 | * Runtime errors that do not require immediate action but should typically
46 | * be logged and monitored.
47 | */
48 | public function error(string|\Stringable $message, array $context = []): void
49 | {
50 | $this->log(LogLevel::ERROR, $message, $context);
51 | }
52 |
53 | /**
54 | * Exceptional occurrences that are not errors.
55 | *
56 | * Example: Use of deprecated APIs, poor use of an API, undesirable things
57 | * that are not necessarily wrong.
58 | */
59 | public function warning(string|\Stringable $message, array $context = []): void
60 | {
61 | $this->log(LogLevel::WARNING, $message, $context);
62 | }
63 |
64 | /**
65 | * Normal but significant events.
66 | */
67 | public function notice(string|\Stringable $message, array $context = []): void
68 | {
69 | $this->log(LogLevel::NOTICE, $message, $context);
70 | }
71 |
72 | /**
73 | * Interesting events.
74 | *
75 | * Example: User logs in, SQL logs.
76 | */
77 | public function info(string|\Stringable $message, array $context = []): void
78 | {
79 | $this->log(LogLevel::INFO, $message, $context);
80 | }
81 |
82 | /**
83 | * Detailed debug information.
84 | */
85 | public function debug(string|\Stringable $message, array $context = []): void
86 | {
87 | $this->log(LogLevel::DEBUG, $message, $context);
88 | }
89 |
90 | /**
91 | * Logs with an arbitrary level.
92 | *
93 | * @param mixed $level
94 | *
95 | * @throws \Psr\Log\InvalidArgumentException
96 | */
97 | abstract public function log($level, string|\Stringable $message, array $context = []): void;
98 | }
99 |
--------------------------------------------------------------------------------
/vendor/psr/log/src/NullLogger.php:
--------------------------------------------------------------------------------
1 | logger) { }`
11 | * blocks.
12 | */
13 | class NullLogger extends AbstractLogger
14 | {
15 | /**
16 | * Logs with an arbitrary level.
17 | *
18 | * @param mixed[] $context
19 | *
20 | * @throws \Psr\Log\InvalidArgumentException
21 | */
22 | public function log($level, string|\Stringable $message, array $context = []): void
23 | {
24 | // noop
25 | }
26 | }
27 |
--------------------------------------------------------------------------------