mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 01:39:24 +02:00
Update composer
This commit is contained in:
parent
f0314f6e4e
commit
a6ee5ff144
1265 changed files with 321871 additions and 1038 deletions
100
composer.json
100
composer.json
|
@ -1,50 +1,50 @@
|
|||
{
|
||||
"name": "wwbn/avideo",
|
||||
"description": "Audio Video Platform",
|
||||
"type": "project",
|
||||
"config": {
|
||||
"platform-check": false,
|
||||
"vendor-dir": "vendor",
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"chrisjean/php-ico": "^1.0",
|
||||
"ezyang/htmlpurifier": "^4.13",
|
||||
"google/apiclient": "^2.11",
|
||||
"google/apiclient-services": "*",
|
||||
"google/auth": "^1.14.3",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"guzzlehttp/psr7": "^2.2",
|
||||
"hybridauth/hybridauth": "^3.3",
|
||||
"james-heinrich/getid3": "^1.9",
|
||||
"monolog/monolog": "^2.6",
|
||||
"phpmailer/phpmailer": "^6.2",
|
||||
"psr/cache": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"cboden/ratchet": "^0.4.3",
|
||||
"ratchet/pawl": "^0.4.1",
|
||||
"singpolyma/openpgp-php": "^0.6.0",
|
||||
"aws/aws-sdk-php": "^3.180",
|
||||
"gliterd/backblaze-b2": "^1.1",
|
||||
"paypal/rest-api-sdk-php": "*",
|
||||
"paypal/paypal-payouts-sdk": "^1.0",
|
||||
"paypal/paypal-checkout-sdk": "^1.0",
|
||||
"emojione/assets": "^4.5",
|
||||
"mervick/emojionearea": "^3.4",
|
||||
"emojione/emojione": "^4.5",
|
||||
"abraham/twitteroauth": "^3.1",
|
||||
"symfony/http-client": "^5.3",
|
||||
"nyholm/psr7": "^1.4",
|
||||
"norkunas/onesignal-php-api": "^2.7",
|
||||
"stripe/stripe-php": "^10.0",
|
||||
"symfony/translation": "^5.3",
|
||||
"amphp/amp": "^2.6",
|
||||
"scssphp/scssphp": "^1.11",
|
||||
"vimeo/vimeo-api": "^3.0"
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "wwbn/avideo",
|
||||
"description": "Audio Video Platform",
|
||||
"type": "project",
|
||||
"config": {
|
||||
"platform-check": false,
|
||||
"vendor-dir": "vendor",
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8",
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"chrisjean/php-ico": "^1.0",
|
||||
"ezyang/htmlpurifier": "^4.13",
|
||||
"google/apiclient": "^2.11",
|
||||
"google/apiclient-services": "*",
|
||||
"google/auth": "^1.14.3",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"guzzlehttp/psr7": "^2.2",
|
||||
"hybridauth/hybridauth": "^3.3",
|
||||
"james-heinrich/getid3": "^1.9",
|
||||
"monolog/monolog": "^2.6",
|
||||
"phpmailer/phpmailer": "^6.2",
|
||||
"psr/cache": "^1.0",
|
||||
"psr/http-message": "^1.0",
|
||||
"cboden/ratchet": "^0.4.3",
|
||||
"ratchet/pawl": "^0.4.1",
|
||||
"singpolyma/openpgp-php": "^0.6.0",
|
||||
"aws/aws-sdk-php": "^3.180",
|
||||
"gliterd/backblaze-b2": "^1.1",
|
||||
"paypal/rest-api-sdk-php": "*",
|
||||
"paypal/paypal-payouts-sdk": "^1.0",
|
||||
"paypal/paypal-checkout-sdk": "^1.0",
|
||||
"emojione/assets": "^4.5",
|
||||
"mervick/emojionearea": "^3.4",
|
||||
"emojione/emojione": "^4.5",
|
||||
"abraham/twitteroauth": "^3.1",
|
||||
"symfony/http-client": "^5.3",
|
||||
"nyholm/psr7": "^1.4",
|
||||
"norkunas/onesignal-php-api": "^2.7",
|
||||
"stripe/stripe-php": "^10.6",
|
||||
"symfony/translation": "^5.3",
|
||||
"amphp/amp": "^2.6",
|
||||
"scssphp/scssphp": "^1.11",
|
||||
"vimeo/vimeo-api": "^3.0"
|
||||
}
|
||||
}
|
||||
|
|
26
composer.lock
generated
26
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "114c59776b73e93dcdda84656374bcb5",
|
||||
"content-hash": "d187492ec3ae5da5d4905596c18f60a0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "abraham/twitteroauth",
|
||||
|
@ -277,16 +277,16 @@
|
|||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.258.10",
|
||||
"version": "3.258.12",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337"
|
||||
"reference": "43ee875456822ee7772cfc51da57bfa558ccb30c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337",
|
||||
"reference": "e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/43ee875456822ee7772cfc51da57bfa558ccb30c",
|
||||
"reference": "43ee875456822ee7772cfc51da57bfa558ccb30c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -365,9 +365,9 @@
|
|||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.258.10"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.258.12"
|
||||
},
|
||||
"time": "2023-02-14T19:21:16+00:00"
|
||||
"time": "2023-02-16T19:21:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
@ -4046,16 +4046,16 @@
|
|||
},
|
||||
{
|
||||
"name": "stripe/stripe-php",
|
||||
"version": "v10.5.0",
|
||||
"version": "v10.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/stripe/stripe-php.git",
|
||||
"reference": "331415b232d60d7c0449de7bde4cb7d4fedf982e"
|
||||
"reference": "5fc46f43c743c715cb5edeb7be3383efb7b4bb2e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/331415b232d60d7c0449de7bde4cb7d4fedf982e",
|
||||
"reference": "331415b232d60d7c0449de7bde4cb7d4fedf982e",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/5fc46f43c743c715cb5edeb7be3383efb7b4bb2e",
|
||||
"reference": "5fc46f43c743c715cb5edeb7be3383efb7b4bb2e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4101,9 +4101,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/stripe/stripe-php/issues",
|
||||
"source": "https://github.com/stripe/stripe-php/tree/v10.5.0"
|
||||
"source": "https://github.com/stripe/stripe-php/tree/v10.6.0"
|
||||
},
|
||||
"time": "2023-02-02T21:02:09+00:00"
|
||||
"time": "2023-02-16T23:01:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
|
17
vendor/autoload.php
vendored
17
vendor/autoload.php
vendored
|
@ -3,21 +3,8 @@
|
|||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
if (!headers_sent()) {
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
}
|
||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
if (!ini_get('display_errors')) {
|
||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||
fwrite(STDERR, $err);
|
||||
} elseif (!headers_sent()) {
|
||||
echo $err;
|
||||
}
|
||||
}
|
||||
trigger_error(
|
||||
$err,
|
||||
E_USER_ERROR
|
||||
);
|
||||
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
|
|
@ -19,6 +19,8 @@ use Aws\AwsClient;
|
|||
* @method \GuzzleHttp\Promise\Promise createBatchPredictionJobAsync(array $args = [])
|
||||
* @method \Aws\Result createDetectorVersion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createDetectorVersionAsync(array $args = [])
|
||||
* @method \Aws\Result createList(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createListAsync(array $args = [])
|
||||
* @method \Aws\Result createModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise createModelAsync(array $args = [])
|
||||
* @method \Aws\Result createModelVersion(array $args = [])
|
||||
|
@ -47,6 +49,8 @@ use Aws\AwsClient;
|
|||
* @method \GuzzleHttp\Promise\Promise deleteExternalModelAsync(array $args = [])
|
||||
* @method \Aws\Result deleteLabel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteLabelAsync(array $args = [])
|
||||
* @method \Aws\Result deleteList(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteListAsync(array $args = [])
|
||||
* @method \Aws\Result deleteModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise deleteModelAsync(array $args = [])
|
||||
* @method \Aws\Result deleteModelVersion(array $args = [])
|
||||
|
@ -87,6 +91,10 @@ use Aws\AwsClient;
|
|||
* @method \GuzzleHttp\Promise\Promise getKMSEncryptionKeyAsync(array $args = [])
|
||||
* @method \Aws\Result getLabels(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getLabelsAsync(array $args = [])
|
||||
* @method \Aws\Result getListElements(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getListElementsAsync(array $args = [])
|
||||
* @method \Aws\Result getListsMetadata(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getListsMetadataAsync(array $args = [])
|
||||
* @method \Aws\Result getModelVersion(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise getModelVersionAsync(array $args = [])
|
||||
* @method \Aws\Result getModels(array $args = [])
|
||||
|
@ -129,6 +137,8 @@ use Aws\AwsClient;
|
|||
* @method \GuzzleHttp\Promise\Promise updateDetectorVersionStatusAsync(array $args = [])
|
||||
* @method \Aws\Result updateEventLabel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateEventLabelAsync(array $args = [])
|
||||
* @method \Aws\Result updateList(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateListAsync(array $args = [])
|
||||
* @method \Aws\Result updateModel(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise updateModelAsync(array $args = [])
|
||||
* @method \Aws\Result updateModelVersion(array $args = [])
|
||||
|
|
|
@ -47,6 +47,8 @@ use Aws\AwsClient;
|
|||
* @method \GuzzleHttp\Promise\Promise listTagsForResourceAsync(array $args = [])
|
||||
* @method \Aws\Result ping(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise pingAsync(array $args = [])
|
||||
* @method \Aws\Result startNetworkResourceUpdate(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise startNetworkResourceUpdateAsync(array $args = [])
|
||||
* @method \Aws\Result tagResource(array $args = [])
|
||||
* @method \GuzzleHttp\Promise\Promise tagResourceAsync(array $args = [])
|
||||
* @method \Aws\Result untagResource(array $args = [])
|
||||
|
|
2
vendor/aws/aws-sdk-php/src/Sdk.php
vendored
2
vendor/aws/aws-sdk-php/src/Sdk.php
vendored
|
@ -683,7 +683,7 @@ namespace Aws;
|
|||
*/
|
||||
class Sdk
|
||||
{
|
||||
const VERSION = '3.258.10';
|
||||
const VERSION = '3.258.12';
|
||||
|
||||
/** @var array Arguments for creating clients */
|
||||
private $args;
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/elasticfilesystem/2015-02-01/endpoint-rule-set-1.json
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => true, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ],];
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => false, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Region', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://elasticfilesystem.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ], ], [ 'conditions' => [], 'error' => 'Invalid Configuration: Missing Region', 'type' => 'error', ], ], ], ],];
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/frauddetector/2019-11-15/endpoint-rule-set-1.json
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => true, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ],];
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => false, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Region', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://frauddetector.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ], ], [ 'conditions' => [], 'error' => 'Invalid Configuration: Missing Region', 'type' => 'error', ], ], ], ],];
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/frauddetector/2019-11-15/paginators-1.json
|
||||
return [ 'pagination' => [ 'DescribeModelVersions' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetBatchImportJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetBatchPredictionJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetDetectors' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetEntityTypes' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetEventTypes' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetExternalModels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetLabels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetModels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetOutcomes' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetRules' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetVariables' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'ListEventPredictions' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'ListTagsForResource' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], ],];
|
||||
return [ 'pagination' => [ 'DescribeModelVersions' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetBatchImportJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetBatchPredictionJobs' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetDetectors' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetEntityTypes' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetEventTypes' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetExternalModels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetLabels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetListElements' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetListsMetadata' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetModels' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetOutcomes' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetRules' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'GetVariables' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'ListEventPredictions' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], 'ListTagsForResource' => [ 'input_token' => 'nextToken', 'output_token' => 'nextToken', 'limit_key' => 'maxResults', ], ],];
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/glue/2017-03-31/endpoint-rule-set-1.json
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => true, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ],];
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => false, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Region', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://glue.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ], ], [ 'conditions' => [], 'error' => 'Invalid Configuration: Missing Region', 'type' => 'error', ], ], ], ],];
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/ivs/2020-07-14/endpoint-rule-set-1.json
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => true, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ],];
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => false, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Region', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://ivs.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ], ], [ 'conditions' => [], 'error' => 'Invalid Configuration: Missing Region', 'type' => 'error', ], ], ], ],];
|
||||
|
|
File diff suppressed because one or more lines are too long
3
vendor/aws/aws-sdk-php/src/data/privatenetworks/2021-12-03/defaults-1.json.php
vendored
Normal file
3
vendor/aws/aws-sdk-php/src/data/privatenetworks/2021-12-03/defaults-1.json.php
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/privatenetworks/2021-12-03/defaults-1.json
|
||||
return [ 'added' => [],];
|
|
@ -1,3 +1,3 @@
|
|||
<?php
|
||||
// This file was auto-generated from sdk-root/src/data/privatenetworks/2021-12-03/endpoint-rule-set-1.json
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => false, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], [ 'fn' => 'parseURL', 'argv' => [ [ 'ref' => 'Endpoint', ], ], 'assign' => 'url', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ],];
|
||||
return [ 'version' => '1.0', 'parameters' => [ 'Region' => [ 'builtIn' => 'AWS::Region', 'required' => false, 'documentation' => 'The AWS region used to dispatch the request.', 'type' => 'String', ], 'UseDualStack' => [ 'builtIn' => 'AWS::UseDualStack', 'required' => true, 'default' => false, 'documentation' => 'When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.', 'type' => 'Boolean', ], 'UseFIPS' => [ 'builtIn' => 'AWS::UseFIPS', 'required' => true, 'default' => false, 'documentation' => 'When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.', 'type' => 'Boolean', ], 'Endpoint' => [ 'builtIn' => 'SDK::Endpoint', 'required' => false, 'documentation' => 'Override the endpoint used to send this request', 'type' => 'String', ], ], 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Endpoint', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'error' => 'Invalid Configuration: FIPS and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'error' => 'Invalid Configuration: Dualstack and custom endpoint are not supported', 'type' => 'error', ], [ 'conditions' => [], 'endpoint' => [ 'url' => [ 'ref' => 'Endpoint', ], 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'isSet', 'argv' => [ [ 'ref' => 'Region', ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'aws.partition', 'argv' => [ [ 'ref' => 'Region', ], ], 'assign' => 'PartitionResult', ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks-fips.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS and DualStack are enabled, but this partition does not support one or both', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseFIPS', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsFIPS', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks-fips.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'FIPS is enabled but this partition does not support FIPS', 'type' => 'error', ], ], ], [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ [ 'ref' => 'UseDualStack', ], true, ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [ [ 'fn' => 'booleanEquals', 'argv' => [ true, [ 'fn' => 'getAttr', 'argv' => [ [ 'ref' => 'PartitionResult', ], 'supportsDualStack', ], ], ], ], ], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks.{Region}.{PartitionResult#dualStackDnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], [ 'conditions' => [], 'error' => 'DualStack is enabled but this partition does not support DualStack', 'type' => 'error', ], ], ], [ 'conditions' => [], 'type' => 'tree', 'rules' => [ [ 'conditions' => [], 'endpoint' => [ 'url' => 'https://private-networks.{Region}.{PartitionResult#dnsSuffix}', 'properties' => [], 'headers' => [], ], 'type' => 'endpoint', ], ], ], ], ], ], ], [ 'conditions' => [], 'error' => 'Invalid Configuration: Missing Region', 'type' => 'error', ], ], ], ],];
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
117
vendor/bin/php-parse
vendored
Normal file
117
vendor/bin/php-parse
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../nikic/php-parser/bin/php-parse)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
|
||||
include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse');
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse';
|
5
vendor/bin/php-parse.bat
vendored
Normal file
5
vendor/bin/php-parse.bat
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/php-parse
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
117
vendor/bin/yaml-lint
vendored
Normal file
117
vendor/bin/yaml-lint
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Proxy PHP file generated by Composer
|
||||
*
|
||||
* This file includes the referenced bin path (../symfony/yaml/Resources/bin/yaml-lint)
|
||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
||||
*
|
||||
* @generated
|
||||
*/
|
||||
|
||||
namespace Composer;
|
||||
|
||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
||||
|
||||
if (PHP_VERSION_ID < 80000) {
|
||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class BinProxyWrapper
|
||||
{
|
||||
private $handle;
|
||||
private $position;
|
||||
private $realpath;
|
||||
|
||||
public function stream_open($path, $mode, $options, &$opened_path)
|
||||
{
|
||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
||||
$opened_path = substr($path, 17);
|
||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
||||
$opened_path = $this->realpath;
|
||||
$this->handle = fopen($this->realpath, $mode);
|
||||
$this->position = 0;
|
||||
|
||||
return (bool) $this->handle;
|
||||
}
|
||||
|
||||
public function stream_read($count)
|
||||
{
|
||||
$data = fread($this->handle, $count);
|
||||
|
||||
if ($this->position === 0) {
|
||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
||||
}
|
||||
|
||||
$this->position += strlen($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function stream_cast($castAs)
|
||||
{
|
||||
return $this->handle;
|
||||
}
|
||||
|
||||
public function stream_close()
|
||||
{
|
||||
fclose($this->handle);
|
||||
}
|
||||
|
||||
public function stream_lock($operation)
|
||||
{
|
||||
return $operation ? flock($this->handle, $operation) : true;
|
||||
}
|
||||
|
||||
public function stream_seek($offset, $whence)
|
||||
{
|
||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
||||
$this->position = ftell($this->handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function stream_tell()
|
||||
{
|
||||
return $this->position;
|
||||
}
|
||||
|
||||
public function stream_eof()
|
||||
{
|
||||
return feof($this->handle);
|
||||
}
|
||||
|
||||
public function stream_stat()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
public function stream_set_option($option, $arg1, $arg2)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function url_stat($path, $flags)
|
||||
{
|
||||
$path = substr($path, 17);
|
||||
if (file_exists($path)) {
|
||||
return stat($path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
|
||||
include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint');
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
include __DIR__ . '/..'.'/symfony/yaml/Resources/bin/yaml-lint';
|
5
vendor/bin/yaml-lint.bat
vendored
Normal file
5
vendor/bin/yaml-lint.bat
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
@ECHO OFF
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
SET BIN_TARGET=%~dp0/yaml-lint
|
||||
SET COMPOSER_RUNTIME_BIN_DIR=%~dp0
|
||||
php "%BIN_TARGET%" %*
|
2
vendor/clue/graph/.github/FUNDING.yml
vendored
Normal file
2
vendor/clue/graph/.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
github: clue
|
||||
custom: https://clue.engineering/support
|
376
vendor/clue/graph/CHANGELOG.md
vendored
Normal file
376
vendor/clue/graph/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,376 @@
|
|||
# Changelog
|
||||
|
||||
## 0.9.3 (2021-12-30)
|
||||
|
||||
* Feature: Support PHP 8.1 release.
|
||||
(#208 by @clue)
|
||||
|
||||
* Fix: Fix automatic vertex ID generation when using vertex IDs with strings.
|
||||
(#204 by @viktorprogger)
|
||||
|
||||
* Improve test suite and use GitHub Actions for continuous integration (CI).
|
||||
(#207 by @clue)
|
||||
|
||||
## 0.9.2 (2020-12-03)
|
||||
|
||||
* Feature: Support PHP 8 and PHPUnit 9.3.
|
||||
(#200 by @SimonFrings)
|
||||
|
||||
## 0.9.1 (2019-10-02)
|
||||
|
||||
* Fix: Deleting vertex with loop edge no longer fails.
|
||||
(#149 by @tomzx)
|
||||
|
||||
* Fix: Fix returning directed loop edges and adjacent vertices from vertex twice.
|
||||
(#170 by @clue)
|
||||
|
||||
* Minor documentation updates and fixes.
|
||||
(#153 by @marclaporte and #163, #164 and #172 by @clue)
|
||||
|
||||
* Improve test suite to move tests to `Fhaculty\Graph\Tests` namespace,
|
||||
update test suite to support PHPUnit 6 and PHPUnit 5 and
|
||||
support running on legacy PHP 5.3 through PHP 7.2 and HHVM.
|
||||
(#148 by @tomzx and #150 and #162 by @clue)
|
||||
|
||||
* Originally planned to add a new `AttributeAware::removeAttribute()` method,
|
||||
but reverted due to BC break. Change will be reconsidered for next major release.
|
||||
(#138 and #171 by @johnathanmdell and @clue)
|
||||
|
||||
## 0.9.0 (2015-03-07)
|
||||
|
||||
* BC break: Split off individual components in order to stabilize core graph lib.
|
||||
([#120](https://github.com/clue/graph/issues/120))
|
||||
|
||||
* Split off `Algorithm` namespace into separate [graphp/algorithms](https://github.com/graphp/algorithms) package.
|
||||
([#119](https://github.com/clue/graph/issues/119))
|
||||
|
||||
* Split off `Exporter\TrivialGraphFormat` into separate [graphp/trivial-graph-format](https://github.com/graphp/trivial-graph-format) package.
|
||||
([#121](https://github.com/clue/graph/issues/121))
|
||||
|
||||
* Split off `Loader` namespace into separate [graphp/plaintext](https://github.com/graphp/plaintext) package.
|
||||
([#117](https://github.com/clue/graph/issues/117))
|
||||
|
||||
* BC break: Remove Exporter from `Graph` and `Graph::__toString()` (trivial graph format exporter has been split off).
|
||||
([#122](https://github.com/clue/graph/pull/122))
|
||||
|
||||
* BC break: Vertices can no longer be sorted by (in/out)degree (degree algorithm has been split off).
|
||||
([#128](https://github.com/clue/graph/pull/128))
|
||||
|
||||
* Apply PSR-4 layout under `src/` and add tests to achieve 100% test coverage.
|
||||
([#127](https://github.com/clue/graph/issues/127) & [#129](https://github.com/clue/graph/issues/129))
|
||||
|
||||
## 0.8.0 (2014-12-31)
|
||||
|
||||
* Feature: Add general purpose Attributes.
|
||||
([#103](https://github.com/clue/graph/pull/103))
|
||||
|
||||
* BC break: Split off all GraphViz-related classes to a separate
|
||||
[graphp/graphviz](https://github.com/graphp/graphviz) package.
|
||||
([#115](https://github.com/clue/graph/pull/115))
|
||||
|
||||
* Feature: The base `Graph`, `Vertex` and `EdgeBase` classes can now be
|
||||
extended in order to implement a custom behavior. As such, one can now also
|
||||
instantiate them using the normal `new` operator instead of having to use
|
||||
`Graph::createVertex()` family of methods.
|
||||
([#82](https://github.com/clue/graph/issues/82))
|
||||
|
||||
* BC break: Rename `Algorithm\Directed::isDirected()` to remove its ambiguity
|
||||
in regards to mixed and/or empty graphs
|
||||
([#80](https://github.com/clue/graph/issues/80))
|
||||
|
||||
| Old name | New name |
|
||||
|---|---|
|
||||
| `Algorithm\Directed::isDirected()` | `Algorithm\Directed::hasDirected()` |
|
||||
|
||||
* Feature: Add new `Algorithm\Directed::hasUndirected()` and
|
||||
`Algorithm\Directed::isMixed()` in order to complement the renamed
|
||||
`Algorithm\Directed::hasDirected()`
|
||||
([#80](https://github.com/clue/graph/issues/80))
|
||||
|
||||
* BC break: `Walk::factoryCycleFromVertices()` no longer tries to auto-complete
|
||||
a cycle if the first vertex does not match the last one, but now throws an
|
||||
`InvalidArgumentException` instead ([#87](https://github.com/clue/graph/issues/87))
|
||||
|
||||
* Feature: Support loop `Walk`s, i.e. a walk with only a single edge from
|
||||
vertex A back to A ([#87](https://github.com/clue/graph/issues/87))
|
||||
|
||||
* Fix: Stricter checks for invalid cycles, such as one with an invalid
|
||||
predecessor-map or no edges at all ([#87](https://github.com/clue/graph/issues/87))
|
||||
|
||||
* Fix: The `Algorithm\ShortestPath\MooreBellmanFord` now also works for unweighted
|
||||
edges. This also fixes an issue where `Algorithm\DetectNegativeCycle` didn't work
|
||||
for unweighted edges. ([#81](https://github.com/clue/graph/issues/81))
|
||||
|
||||
* Fix: The `Algorithm\MinimumCostFlow` algorithms now work again. The reference
|
||||
to a non-existant class has been updated. Also fixed several issues with
|
||||
regards to special cases such as disconnected or undirected graphs.
|
||||
([#74](https://github.com/clue/graph/issues/74))
|
||||
|
||||
* BC break: Remove unneeded alias definitions of `getVertexFirst()`,
|
||||
`getVertexSource()` and `getVertexTarget()`
|
||||
([#76](https://github.com/clue/graph/issues/76)):
|
||||
|
||||
| Old name | New name |
|
||||
|---|---|
|
||||
| `Graph::getVertexFirst()` | `Graph::getVertices()->getVertexFirst()` |
|
||||
| `Walk::getVertexSource()` | `Walk::getVertices()->getVertexFirst()` |
|
||||
| `Walk::getVertexTarget()` | `Walk::getVertices()->getVertexLast()` |
|
||||
|
||||
## 0.7.1 (2014-03-12)
|
||||
|
||||
* Fix: Throwing an `UnexpectedValueException` if writing GraphViz Dot script
|
||||
to a temporary file fails and remove its debugging output
|
||||
([#77](https://github.com/clue/graph/issues/77) and [#78](https://github.com/clue/graph/issues/78) @Metabor)
|
||||
|
||||
* Fix: Improved GraphViz support for MS Windows
|
||||
([#99](https://github.com/clue/graph/issues/99))
|
||||
|
||||
## 0.7.0 (2013-09-11)
|
||||
|
||||
* Feature: Add new `Set\Vertices` and `Set\Edges` classes that handle common
|
||||
operations on a Set of multiple `Vertex` and `Edge` instances respectively.
|
||||
([#48](https://github.com/clue/graph/issues/48))
|
||||
|
||||
* BC break: Move operations and their corresponding constants concerning Sets
|
||||
to their corresponding Sets:
|
||||
|
||||
| Old name | New name |
|
||||
|---|---|
|
||||
| `Edge\Base::getFirst()` | `Set\Edges::getEdgeOrder()` |
|
||||
| `Edge\Base::getAll()` | `Set\Edges::getEdgesOrder()` |
|
||||
| `Edge\Base::ORDER_*` | `Set\Edges::ORDER_*` |
|
||||
|---|---|
|
||||
| `Vertex::getFirst()` | `Set\Vertices::getVertexOrder()` |
|
||||
| `Vertex::getAll()` | `Set\Vertices::getVerticesOrder()` |
|
||||
| `Vertex::ORDER_` | `Set\Vertices::ORDER_*` |
|
||||
|
||||
* BC break: Each `getVertices*()` and `getEdges*()` method now returns a `Set`
|
||||
instead of a primitive array of instances. *Most* of the time this should
|
||||
work without changing your code, because each `Set` implements an `Iterator`
|
||||
interface and can easily be iterated using `foreach`. However, using a `Set`
|
||||
instead of a plain array differs when checking its boolean value or
|
||||
comparing two Sets. I.e. if you happen to want to check if an `Set` is empty,
|
||||
you now have to use the more explicit syntax `$set->isEmpty()`.
|
||||
|
||||
* BC break: `Vertex::getVertices()`, `Vertex::getVerticesEdgeTo()` and
|
||||
`Vertex::getVerticesEdgeFrom()` now return a `Set\Vertices` instance that
|
||||
may contain duplicate vertices if parallel (multiple) edges exist. Previously
|
||||
there was no easy way to detect this situation - this is now the default. If
|
||||
you also want to get unique / distinct `Vertex` instances, use
|
||||
`Vertex::getVertices()->getVerticesDistinct()` where applicable.
|
||||
|
||||
* BC break: Remove all occurances of `getVerticesId()`, use
|
||||
`getVertices()->getIds()` instead.
|
||||
|
||||
* BC break: Merge `Cycle` into `Walk` ([#61](https://github.com/clue/graph/issues/61)).
|
||||
As such, its static factory methods had to be renamed. Update your references if applicable:
|
||||
|
||||
| Old name | New name |
|
||||
|---|---|
|
||||
| `Cycle::factoryFromPredecessorMap()` | `Walk::factoryCycleFromPredecessorMap()` |
|
||||
| `Cycle::factoryFromVertices()` | `Walk::factoryCycleFromVertices()` |
|
||||
| `Cycle::factoryFromEdges()` | `Walk::factoryCycleFromEdges()` |
|
||||
|
||||
* BC break: Remove `Graph::isEmpty()` because it's not well-defined and might
|
||||
be confusing. Most literature suggests it should check for existing edges,
|
||||
whereas the old behavior was to check for existing vertices instead. Use either
|
||||
of the new and more transparent methods
|
||||
`Algorithm\Property\GraphProperty::isNull()` (old behavior) or (where applicable)
|
||||
`Algorithm\Property\GraphProperty::isEdgeless()` ([#63](https://github.com/clue/graph/issues/63)).
|
||||
|
||||
* BC break: Each of the above methods (`Walk::factoryCycleFromPredecessorMap()`,
|
||||
`Walk::factoryCycleFromVertices()`, `Walk::factoryCycleFromEdges()`) now
|
||||
actually makes sure the returned `Walk` instance is actually a valid Cycle,
|
||||
i.e. the start `Vertex` is the same as the end `Vertex` ([#61](https://github.com/clue/graph/issues/61))
|
||||
|
||||
* BC break: Each `Algorithm\ShortestPath` algorithm now consistenly does not
|
||||
return a zero weight for the root Vertex and now supports loop edges on the root
|
||||
Vertex ([#62](https://github.com/clue/graph/issues/62))
|
||||
|
||||
* BC break: Each `Algorithm\ShortestPath` algorithm now consistently throws an
|
||||
`OutOfBoundsException` for unreachable vertices
|
||||
([#62](https://github.com/clue/graph/issues/62))
|
||||
|
||||
* BC break: A null Graph (a Graph with no Vertices and thus no Edges) is not a
|
||||
valid tree (because it is not connected), adjust `Algorithm\Tree\Base::isTree()`
|
||||
accordingly.
|
||||
([#72](https://github.com/clue/graph/issues/72))
|
||||
|
||||
* BC break: Remove all occurances of `getNumberOfVertices()` and
|
||||
`getNumberOfEdges()` ([#75](https://github.com/clue/graph/issues/75) and
|
||||
[#48](https://github.com/clue/graph/issues/48)):
|
||||
|
||||
| Old name | New name |
|
||||
|---|---|
|
||||
| `$set->getNumberOfVertices()` | `count($set->getVertices())` |
|
||||
| `$set->getNumberOfEdges()` | `count($set->getEdges())` |
|
||||
|
||||
* BC break: Replace base `Set` class with `Set\DualAggregate` interface. This
|
||||
is unlikely to affect you, but might potentially break your custom
|
||||
inheritance or polymorphism for algorithms.
|
||||
([#75](https://github.com/clue/graph/issues/75))
|
||||
|
||||
* Feature: Add `Algorithm\ShortestPath\Base::hasVertex(Vertex $vertex)` to check whether
|
||||
a path to the given Vertex exists ([#62](https://github.com/clue/graph/issues/62)).
|
||||
|
||||
* Feature: Support opening GraphViz images on Mac OS X in default image viewer
|
||||
([#67](https://github.com/clue/graph/issues/67) @onigoetz)
|
||||
|
||||
* Feature: Add `Algorithm\MinimumSpanningTree\Base::getWeight()` to get total
|
||||
weight of resulting minimum spanning tree (MST).
|
||||
([#73](https://github.com/clue/graph/issues/73))
|
||||
|
||||
* Feature: Each `Algorithm\MinimumSpanningTree` algorithm now supports
|
||||
undirected and mixed Graphs, as well as null weights for Edges.
|
||||
([#73](https://github.com/clue/graph/issues/73))
|
||||
|
||||
* BC break: Each `Algorithm\MinimumSpanningTree` algorithm now throws an
|
||||
`UnexpectedValueException` for unconnected Graphs (and thus also null Graphs).
|
||||
([#73](https://github.com/clue/graph/issues/73))
|
||||
|
||||
* Feature: Add `Walk::factoryFromVertices()`
|
||||
([#64](https://github.com/clue/graph/issues/64)).
|
||||
|
||||
* Fix: Checking `Walk::isValid()`
|
||||
([#61](https://github.com/clue/graph/issues/61))
|
||||
|
||||
* Fix: Missing import prevented
|
||||
`Algorithm\ShortestPath\MooreBellmanFord::getCycleNegative()` from actually
|
||||
throwing the right `UnderflowException` if no cycle was found
|
||||
([#62](https://github.com/clue/graph/issues/62))
|
||||
|
||||
* Fix: Calling `Exporter\Image::setFormat()` had no effect due to misassignment
|
||||
([#70](https://github.com/clue/graph/issues/70) @FGM)
|
||||
|
||||
## 0.6.0 (2013-07-11)
|
||||
|
||||
* BC break: Move algorithm definitions in base classes to separate algorithm classes ([#27](https://github.com/clue/graph/issues/27)).
|
||||
The following methods containing algorithms were now moved to separate algorithm classes. This
|
||||
change encourages code-reuse, simplifies spotting algorithms, helps reducing complexity,
|
||||
improves testablity and avoids tight coupling. Update your references if applicable:
|
||||
|
||||
| Old name | New name | Related ticket |
|
||||
|---|---|---|
|
||||
| `Set::getWeight()` | `Algorithm\Weight::getWeight()` | [#33](https://github.com/clue/graph/issues/33) |
|
||||
| `Set::getWeightFlow()` | `Algorithm\Weight::getWeightFlow()` | [#33](https://github.com/clue/graph/issues/33) |
|
||||
| `Set::getWeightMin()` | `Algorithm\Weight::getWeightMin()` | [#33](https://github.com/clue/graph/issues/33) |
|
||||
| `Set::isWeighted()` | `Algorithm\Weight::isWeighted()` | [#33](https://github.com/clue/graph/issues/33) |
|
||||
|-|-|-|
|
||||
| `Graph::getDegree()` | `Algorithm\Degree::getDegree()` | [#29](https://github.com/clue/graph/issues/29) |
|
||||
| `Graph::getDegreeMin()` | `Algorithm\Degree::getDegreeMin()` | [#29](https://github.com/clue/graph/issues/29) |
|
||||
| `Graph::getDegreeMax()` | `Algorithm\Degree::getDegreeMax()` | [#29](https://github.com/clue/graph/issues/29) |
|
||||
| `Graph::isRegular()` | `Algorithm\Degree::isRegular()` | [#29](https://github.com/clue/graph/issues/29) |
|
||||
| `Graph::isBalanced()` | `Algorithm\Degree::isBalanced()` | [#29](https://github.com/clue/graph/issues/29) |
|
||||
| `Vertex::getDegree()` | `Algorithm\Degree:getDegreeVertex()` | [#49](https://github.com/clue/graph/issues/49) |
|
||||
| `Vertex::getDegreeIn()` | `Algorithm\Degree:getDegreeInVertex()` | [#49](https://github.com/clue/graph/issues/49) |
|
||||
| `Vertex::getDegreeOut()` | `Algorithm\Degree:getDegreeOutVertex()` | [#49](https://github.com/clue/graph/issues/49) |
|
||||
| `Vertex::isSink()` | `Algorithm\Degree:isVertexSink()` | [#49](https://github.com/clue/graph/issues/49) |
|
||||
| `Vertex::isSource()` | `Algorithm\Degree:isVertexSource()` | [#49](https://github.com/clue/graph/issues/49) |
|
||||
| `Vertex::isIsolated()` | `Algorithm\Degree::isVertexIsolated()` | [#49](https://github.com/clue/graph/issues/49) |
|
||||
|-|-|-|
|
||||
| `Set::isDirected()` | `Algorithm\Directed::isDirected()` | [#34](https://github.com/clue/graph/issues/34) |
|
||||
|-|-|-|
|
||||
| `Graph::isSymmetric()` | `Algorithm\Symmetric::isSymmetric()` | [#41](https://github.com/clue/graph/issues/41) |
|
||||
|-|-|-|
|
||||
| `Graph::isComplete()` | `Algorithm\Complete::isComplete()` | [#43](https://github.com/clue/graph/issues/43) |
|
||||
|-|-|-|
|
||||
| `Set::hasFlow()` | `Algorithm\Flow::hasFlow()` | [#47](https://github.com/clue/graph/issues/47) |
|
||||
| `Graph::getBalance()` | `Algorithm\Flow::getBalance()` | [#30](https://github.com/clue/graph/issues/30), [#47](https://github.com/clue/graph/issues/47) |
|
||||
| `Graph::isBalancedFlow()` | `Algorithm\Flow::isBalancedFlow()` | [#30](https://github.com/clue/graph/issues/39), [#47](https://github.com/clue/graph/issues/47) |
|
||||
| `Vertex::getFlow()` | `Algorithm\Flow::getFlowVertex()` | [#47](https://github.com/clue/graph/issues/47) |
|
||||
|-|-|-|
|
||||
| `Vertex::isLeaf()` | `Algorithm\Tree\Undirected::isVertexLeaf()` | [#44](https://github.com/clue/graph/issues/44) |
|
||||
|-|-|-|
|
||||
| `Set::hasLoop()` | `Algorithm\Loop::hasLoop()` | [#51](https://github.com/clue/graph/issues/51) |
|
||||
| `Vertex::hasLoop()` | `Algorithm\Loop::hasLoopVertex()` | [#51](https://github.com/clue/graph/issues/51) |
|
||||
|-|-|-|
|
||||
| `Set::hasEdgeParallel()` | `Algorithm\Parallel::hasEdgeParallel()` | [#52](https://github.com/clue/graph/issues/52) |
|
||||
| `Edge\Base::hasEdgeParallel()` | `Algorithm\Parallel::hasEdgeParallelEdge()` | [#52](https://github.com/clue/graph/issues/52) |
|
||||
| `Edge\Base::getEdgesParallel()` | `Algorithm\Parallel::getEdgeParallelEdge()` | [#52](https://github.com/clue/graph/issues/52) |
|
||||
|-|-|-|
|
||||
| `Graph::isEdgeless()` | `Algorithm\Property\GraphProperty::isEdgeless()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Graph::isTrivial()` | `Algorithm\Property\GraphProperty::isTrivial()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isCycle()` | `Algorithm\Property\WalkProperty::isCycle()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isPath()` | `Algorithm\Property\WalkProperty::isPath()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::hasCycle()` | `Algorithm\Property\WalkProperty::hasCycle()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isLoop()` | `Algorithm\Property\WalkProperty::isLoop()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isDigon()` | `Algorithm\Property\WalkProperty::isDigon()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isTriangle()` | `Algorithm\Property\WalkProperty::isTriangle()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isSimple()` | `Algorithm\Property\WalkProperty::isSimple()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isHamiltonian()` | `Algorithm\Property\WalkProperty::isHamiltonian()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
| `Walk::isEulerian()` | `Algorithm\Property\WalkProperty::isEulerian()` | [#54](https://github.com/clue/graph/issues/54) |
|
||||
|
||||
* BC break: Remove unneeded algorithm alias definitions ([#31](https://github.com/clue/graph/issues/31), [#50](https://github.com/clue/graph/issues/50)). The following *alias definitions*
|
||||
have been removed, their original/actual name has already existed before and continues to work
|
||||
unchanged. Update your references if applicable:
|
||||
|
||||
| Old/removed alias definition | Actual name |
|
||||
|---|---|
|
||||
| `Graph::isConnected()` | `Algorithm\ConnectedComponents::isSingle()` |
|
||||
| `Graph::hasEulerianCycle()` | `Algorithm\Eulerian::hasCycle()` |
|
||||
| `Graph::getNumberOfComponents()` | `Algorithm\ConnectedComponents::getNumberOfComponents()` |
|
||||
| `Graph::getNumberOfGroups()` | `Algorithm\Groups::getNumberOfGroups()` |
|
||||
| `Graph::isBipartit()` | `Algorithm\Bipartit::isBipartit()` |
|
||||
| `Vertex::hasPathTo()` | `Algorithm\ShortestPath\BreadthFirst::hasVertex()` |
|
||||
| `Vertex::hasPathFrom()` | `Algorithm\ShortestPath\BreadthFirst::hasVertex()` |
|
||||
| `Vertex::getVerticesPathTo()` | `Algorithm\ShortestPath\BreadthFirst::getVertices()` |
|
||||
| `Vertex::getVerticesPathFrom()` | `Algorithm\ShortestPath\BreadthFirst::getVertices()` |
|
||||
|
||||
* BC break: `Graph::createVertices()` now returns an array of vertices instead of the
|
||||
chainable `Graph` ([#19](https://github.com/clue/graph/issues/19))
|
||||
|
||||
* BC break: Move `Loader\UmlClassDiagram` to separate [fhaculty/graph-uml](https://github.com/fhaculty/graph-uml)
|
||||
repo ([#38](https://github.com/clue/graph/issues/38))
|
||||
|
||||
* BC break: Remove needless `Algorithm\MinimumSpanningTree\PrimWithIf`
|
||||
(use `Algorithm\MinimumSpanningTree\Prim` instead)
|
||||
([#45](https://github.com/clue/graph/issues/45))
|
||||
|
||||
* BC break: `Vertex::createEdgeTo()` now returns an instance of type
|
||||
`Edge\Undirected` instead of `Edge\UndirectedId`
|
||||
([#46](https://github.com/clue/graph/issues/46))
|
||||
|
||||
* BC break: `Edge\Base::setCapacity()` now consistently throws an `RangeException`
|
||||
instead of `InvalidArgumentException` if the current flow exceeds the new maximum
|
||||
capacity ([#53](https://github.com/clue/graph/issues/53))
|
||||
|
||||
* Feature: New `Algorithm\Tree` namespace with algorithms for undirected and directed,
|
||||
rooted trees ([#44](https://github.com/clue/graph/issues/44))
|
||||
|
||||
* Feature: According to be above list of moved algorithm methods, the following algorithm
|
||||
classes have been added ([#27](https://github.com/clue/graph/issues/27)):
|
||||
* New `Algorithm\Weight` ([#33](https://github.com/clue/graph/issues/33))
|
||||
* New `Algorithm\Degree` ([#29](https://github.com/clue/graph/issues/29), [#49](https://github.com/clue/graph/issues/49))
|
||||
* New `Algorithm\Directed` ([#34](https://github.com/clue/graph/issues/34))
|
||||
* New `Algorithm\Symmetric` ([#41](https://github.com/clue/graph/issues/41))
|
||||
* New `Algorithm\Complete` ([#43](https://github.com/clue/graph/issues/43))
|
||||
* New `Algorithm\Flow` ([#30](https://github.com/clue/graph/issues/30), [#47](https://github.com/clue/graph/issues/47))
|
||||
* New `Algorithm\Tree` ([#44](https://github.com/clue/graph/issues/44))
|
||||
* New `Algorithm\Loop` ([#51](https://github.com/clue/graph/issues/51))
|
||||
* New `Algorithm\Parallel` ([#52](https://github.com/clue/graph/issues/52))
|
||||
* New `Algorithm\Property` ([#54](https://github.com/clue/graph/issues/54))
|
||||
|
||||
* Feature: `Graph::createVertices()` now also accepts an array of vertex IDs
|
||||
([#19](https://github.com/clue/graph/issues/19))
|
||||
|
||||
* Feature: Add `Algorithm\Property\WalkProperty::hasLoop()` alias definition for
|
||||
completeness ([#54](https://github.com/clue/graph/issues/54))
|
||||
|
||||
* Feature: Add `Algorithm\Property\WalkProperty::isCircuit()` definition to distinguish
|
||||
circuits from cycles ([#54](https://github.com/clue/graph/issues/54))
|
||||
|
||||
* Fix: Checking hamiltonian cycles always returned false
|
||||
([#54](https://github.com/clue/graph/issues/54))
|
||||
|
||||
* Fix: A Walk with no edges is no longer considered a valid cycle
|
||||
([#54](https://github.com/clue/graph/issues/54))
|
||||
|
||||
* Fix: Various issues with `Vertex`/`Edge` layout attributes
|
||||
([#32](https://github.com/clue/graph/issues/32))
|
||||
|
||||
* Fix: Getting multiple parallel edges for undirected edges
|
||||
([#52](https://github.com/clue/graph/issues/52))
|
||||
|
||||
## 0.5.0 (2013-05-07)
|
||||
|
||||
* First tagged release (See issue [#20](https://github.com/clue/graph/issues/20) for more info on why it starts as v0.5.0)
|
22
vendor/clue/graph/LICENSE
vendored
Normal file
22
vendor/clue/graph/LICENSE
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012+ Christian Lück (Maintainer)
|
||||
Copyright (c) 2012+ Fhaculty Core Team and our awesome contributors <https://github.com/clue/graph/graphs/contributors>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
160
vendor/clue/graph/README.md
vendored
Normal file
160
vendor/clue/graph/README.md
vendored
Normal file
|
@ -0,0 +1,160 @@
|
|||
# graphp/graph
|
||||
|
||||
[](https://github.com/graphp/graph/actions)
|
||||
|
||||
GraPHP is the mathematical graph/network library written in PHP.
|
||||
|
||||
> You're viewing the contents of the `v0.9.x` release branch, note that active
|
||||
development continues on another branch, see `master` branch for more details.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
* [Quickstart examples](#quickstart-examples)
|
||||
* [Features](#features)
|
||||
* [Components](#components)
|
||||
* [Graph drawing](#graph-drawing)
|
||||
* [Common algorithms](#common-algorithms)
|
||||
* [Install](#install)
|
||||
* [Tests](#tests)
|
||||
* [Contributing](#contributing)
|
||||
* [License](#license)
|
||||
|
||||
## Quickstart examples
|
||||
|
||||
Once [installed](#install), let's initialize a sample graph:
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
// create some cities
|
||||
$rome = $graph->createVertex('Rome');
|
||||
$madrid = $graph->createVertex('Madrid');
|
||||
$cologne = $graph->createVertex('Cologne');
|
||||
|
||||
// build some roads
|
||||
$cologne->createEdgeTo($madrid);
|
||||
$madrid->createEdgeTo($rome);
|
||||
// create loop
|
||||
$rome->createEdgeTo($rome);
|
||||
```
|
||||
|
||||
Let's see which city (Vertex) has a road (i.e. an edge pointing) to Rome:
|
||||
|
||||
```php
|
||||
foreach ($rome->getVerticesEdgeFrom() as $vertex) {
|
||||
echo $vertex->getId().' leads to rome'.PHP_EOL;
|
||||
// result: Madrid and Rome itself
|
||||
}
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
This library is built around the concept of [mathematical graph theory](https://en.wikipedia.org/wiki/Graph_theory) (i.e. it is **not** a [charting](https://en.wikipedia.org/wiki/Chart) library for drawing a [graph of a function](https://en.wikipedia.org/wiki/Graph_of_a_function)). In essence, a graph is a set of *nodes* with any number of *connections* in between. In graph theory, [vertices](https://en.wikipedia.org/wiki/Vertex_%28graph_theory%29) (plural of vertex) are an abstract representation of these *nodes*, while *connections* are represented as *edges*. Edges may be either undirected ("two-way") or directed ("one-way", aka di-edges, arcs).
|
||||
|
||||
Depending on how the edges are constructed, the whole graph can either be undirected, can be a [directed graph](https://en.wikipedia.org/wiki/Directed_graph) (aka digraph) or be a [mixed graph](https://en.wikipedia.org/wiki/Mixed_graph). Edges are also allowed to form [loops](https://en.wikipedia.org/wiki/Loop_%28graph_theory%29) (i.e. an edge from vertex A pointing to vertex A again). Also, [multiple edges](https://en.wikipedia.org/wiki/Multiple_edges) from vertex A to vertex B are supported as well (aka parallel edges), effectively forming a [multigraph](https://en.wikipedia.org/wiki/Multigraph) (aka pseudograph). And of course, any combination thereof is supported as well. While many authors try to differentiate between these core concepts, this library tries hard to not impose any artificial limitations or assumptions on your graphs.
|
||||
|
||||
## Components
|
||||
|
||||
This library provides the core data structures for working with graphs, its vertices, edges and attributes.
|
||||
|
||||
There are several official components built on top of these structures to provide commonly needed functionality.
|
||||
This architecture allows these components to be used independently and on demand only.
|
||||
|
||||
Following is a list of some highlighted components. A list of all official components can be found in the [graphp project](https://github.com/graphp).
|
||||
|
||||
### Graph drawing
|
||||
|
||||
This library is built to support visualizing graph images, including them into webpages, opening up images from within CLI applications and exporting them as PNG, JPEG or SVG file formats (among many others). Because [graph drawing](https://en.wikipedia.org/wiki/Graph_drawing) is a complex area on its own, the actual layouting of the graph is left up to the excellent [GraphViz](https://www.graphviz.org/) "Graph Visualization Software" and we merely provide some convenient APIs to interface with GraphViz.
|
||||
|
||||
See [graphp/graphviz](https://github.com/graphp/graphviz) for more details.
|
||||
|
||||
### Common algorithms
|
||||
|
||||
Besides graph drawing, one of the most common things to do with graphs is running algorithms to solve common graph problems.
|
||||
Therefore this library is being used as the basis for implementations for a number of commonly used graph algorithms:
|
||||
|
||||
* Search
|
||||
* Deep first (DFS)
|
||||
* Breadth first search (BFS)
|
||||
* Shortest path
|
||||
* [Dijkstra](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm)
|
||||
* Moore-Bellman-Ford (MBF)
|
||||
* Counting number of hops (simple BFS)
|
||||
* [Minimum spanning tree (MST)](https://en.wikipedia.org/wiki/Minimum_spanning_tree)
|
||||
* Kruskal
|
||||
* Prim
|
||||
* [Traveling salesman problem (TSP)](https://en.wikipedia.org/wiki/Travelling_salesman_problem)
|
||||
* Bruteforce algorithm
|
||||
* Minimum spanning tree heuristic (TSP MST heuristic)
|
||||
* Nearest neighbor heuristic (NN heuristic)
|
||||
* Maximum flow
|
||||
* [Edmonds-Karp](https://en.wikipedia.org/wiki/Edmonds%E2%80%93Karp_algorithm)
|
||||
* Minimum cost flow (MCF)
|
||||
* Cycle canceling
|
||||
* Successive shortest path
|
||||
* Maximum matching
|
||||
* Flow algorithm
|
||||
|
||||
See [graphp/algorithms](https://github.com/graphp/algorithms) for more details.
|
||||
|
||||
## Install
|
||||
|
||||
The recommended way to install this library is [through Composer](https://getcomposer.org/).
|
||||
[New to Composer?](https://getcomposer.org/doc/00-intro.md)
|
||||
|
||||
This will install the latest supported version:
|
||||
|
||||
```bash
|
||||
$ composer require clue/graph:^0.9.3
|
||||
```
|
||||
|
||||
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
|
||||
|
||||
This project aims to run on any platform and thus does not require any PHP
|
||||
extensions and supports running on legacy PHP 5.3 through current PHP 8+ and
|
||||
HHVM.
|
||||
It's *highly recommended to use the latest supported PHP version* for this project.
|
||||
|
||||
You may also want to install some of the [additional components](#components).
|
||||
A list of all official components can be found in the [graphp project](https://github.com/graphp).
|
||||
|
||||
## Tests
|
||||
|
||||
This library uses PHPUnit for its extensive test suite.
|
||||
To run the test suite, you first need to clone this repo and then install all
|
||||
dependencies [through Composer](https://getcomposer.org/):
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
```
|
||||
|
||||
To run the test suite, go to the project root and run:
|
||||
|
||||
```bash
|
||||
$ vendor/bin/phpunit
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
This library comes with an extensive test suite and is regularly tested and used in the *real world*.
|
||||
Despite this, this library is still considered beta software and its API is subject to change.
|
||||
The [changelog](CHANGELOG.md) lists all relevant information for updates between releases.
|
||||
|
||||
If you encounter any issues, please don't hesitate to drop us a line, file a bug report or even best provide us with a patch / pull request and/or unit test to reproduce your problem.
|
||||
|
||||
Besides directly working with the code, any additional documentation, additions to our readme or even fixing simple typos are appreciated just as well.
|
||||
|
||||
Any feedback and/or contribution is welcome!
|
||||
|
||||
Check out #graphp on irc.freenode.net.
|
||||
|
||||
## License
|
||||
|
||||
This project is released under the permissive [MIT license](LICENSE).
|
||||
|
||||
> Did you know that I offer custom development services and issuing invoices for
|
||||
sponsorships of releases and for contributions? Contact me (@clue) for details.
|
40
vendor/clue/graph/composer.json
vendored
Normal file
40
vendor/clue/graph/composer.json
vendored
Normal file
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "clue/graph",
|
||||
"type": "library",
|
||||
"description": "GraPHP is the mathematical graph/network library written in PHP.",
|
||||
"keywords": [
|
||||
"graph",
|
||||
"network",
|
||||
"mathematical",
|
||||
"vertex",
|
||||
"edge"
|
||||
],
|
||||
"homepage": "https://github.com/graphp/graph",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Lück",
|
||||
"email": "christian@clue.engineering"
|
||||
}
|
||||
],
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Fhaculty\\Graph\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Fhaculty\\Graph\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35"
|
||||
},
|
||||
"suggest": {
|
||||
"graphp/graphviz": "GraphViz graph drawing / DOT output",
|
||||
"graphp/algorithms": "Common graph algorithms, such as Dijkstra and Moore-Bellman-Ford (shortest path), minimum spanning tree (MST), Kruskal, Prim and many more.."
|
||||
}
|
||||
}
|
35
vendor/clue/graph/src/Attribute/AttributeAware.php
vendored
Normal file
35
vendor/clue/graph/src/Attribute/AttributeAware.php
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Attribute;
|
||||
|
||||
/**
|
||||
* Implemented by any entity that is aware of additional attributes
|
||||
*
|
||||
* Each attribute consists of a name (string) and an arbitrary value.
|
||||
*/
|
||||
interface AttributeAware
|
||||
{
|
||||
/**
|
||||
* get a single attribute with the given $name (or return $default if attribute was not found)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default to return if attribute was not found
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null);
|
||||
|
||||
/**
|
||||
* set a single attribute with the given $name to given $value
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function setAttribute($name, $value);
|
||||
|
||||
/**
|
||||
* get a container for all attributes
|
||||
*
|
||||
* @return AttributeBag
|
||||
*/
|
||||
public function getAttributeBag();
|
||||
}
|
27
vendor/clue/graph/src/Attribute/AttributeBag.php
vendored
Normal file
27
vendor/clue/graph/src/Attribute/AttributeBag.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Attribute;
|
||||
|
||||
/**
|
||||
* Interface to container that represents multiple attributes
|
||||
*/
|
||||
interface AttributeBag extends AttributeAware
|
||||
{
|
||||
// public function getAttribute($name, $default);
|
||||
// public function setAttribute($name, $value);
|
||||
// public function getAttributeBag();
|
||||
|
||||
/**
|
||||
* set an array of additional attributes
|
||||
*
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function setAttributes(array $attributes);
|
||||
|
||||
/**
|
||||
* get an array of all attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes();
|
||||
}
|
76
vendor/clue/graph/src/Attribute/AttributeBagContainer.php
vendored
Normal file
76
vendor/clue/graph/src/Attribute/AttributeBagContainer.php
vendored
Normal file
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Attribute;
|
||||
|
||||
/**
|
||||
* A fairly standard AttributeBag container.
|
||||
*
|
||||
* This container passes and returns attributes by value. It is mutable,
|
||||
* however, so multiple references to the container will update in kind.
|
||||
*/
|
||||
class AttributeBagContainer implements AttributeBag
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $attributes = array();
|
||||
|
||||
/**
|
||||
* get a single attribute with the given $name (or return $default if attribute was not found)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default to return if attribute was not found
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* set a single attribute with the given $name to given $value
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return self For a fluid interface.
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an array of all attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* set an array of additional attributes
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return self For a fluid interface.
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = $attributes + $this->attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a container for all attributes
|
||||
*
|
||||
* @return AttributeBag
|
||||
*/
|
||||
public function getAttributeBag()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
116
vendor/clue/graph/src/Attribute/AttributeBagNamespaced.php
vendored
Normal file
116
vendor/clue/graph/src/Attribute/AttributeBagNamespaced.php
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Attribute;
|
||||
|
||||
/**
|
||||
* An attribute bag that automatically prefixes a given namespace.
|
||||
*
|
||||
* For example, you can use this class to prefix the attributes using a vendor
|
||||
* name, like "myvendor.item.". If another vendor shares the base attribute
|
||||
* bag, it can use a different prefix, like "otherProduct.item.". This allows
|
||||
* both libraries to have attributes with the same name without having them
|
||||
* conflict. For example, the attribute "id" would be stored separately as
|
||||
* "myvendor.item.id" and "otherProduct.item.id".
|
||||
*/
|
||||
class AttributeBagNamespaced implements AttributeBag
|
||||
{
|
||||
/**
|
||||
* @var AttributeBag
|
||||
*/
|
||||
private $bag;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $prefix;
|
||||
|
||||
/**
|
||||
* Initialize the attribute bag with a prefix to use as a namespace for the attributes.
|
||||
*
|
||||
* @param AttributeAware $bag The bag to store the prefixed attributes in.
|
||||
* @param string $prefix The prefix to prepend to all attributes before
|
||||
* storage. This prefix acts as a namespace to separate attributes.
|
||||
*/
|
||||
public function __construct(AttributeAware $bag, $prefix)
|
||||
{
|
||||
if (!($bag instanceof AttributeBag)) {
|
||||
$bag = $bag->getAttributeBag();
|
||||
}
|
||||
$this->bag = $bag;
|
||||
$this->prefix = $prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a single attribute with the given $name (or return $default if attribute was not found)
|
||||
*
|
||||
* This prefixes the attribute name before requesting from the base bag.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default to return if attribute was not found
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return $this->bag->getAttribute($this->prefix . $name, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* set a single attribute with the given $name to given $value
|
||||
*
|
||||
* This prefixes the attribute name before setting in the base bag.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->bag->setAttribute($this->prefix . $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* get an array of all attributes
|
||||
*
|
||||
* The prefix will not be included in the returned attribute keys.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
$attributes = array();
|
||||
$len = strlen($this->prefix);
|
||||
|
||||
foreach ($this->bag->getAttributes() as $name => $value) {
|
||||
if (strpos($name, $this->prefix) === 0) {
|
||||
$attributes[substr($name, $len)] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* set an array of additional attributes
|
||||
*
|
||||
* Each attribute is prefixed before setting in the base bag.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return void
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
foreach ($attributes as $name => $value) {
|
||||
$this->bag->setAttribute($this->prefix . $name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get a container for all attributes
|
||||
*
|
||||
* @return AttributeBag
|
||||
*/
|
||||
public function getAttributeBag()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
90
vendor/clue/graph/src/Attribute/AttributeBagReference.php
vendored
Normal file
90
vendor/clue/graph/src/Attribute/AttributeBagReference.php
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Attribute;
|
||||
|
||||
/**
|
||||
* The basic attribute bag, but using a reference to the base attribute array.
|
||||
*
|
||||
* This container passes and returns attributes by value, but stores them in a
|
||||
* pass-by-reference array. It is mutable, however, so multiple references to
|
||||
* the container will update in kind.
|
||||
*/
|
||||
class AttributeBagReference implements AttributeBag
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $attributes;
|
||||
|
||||
/**
|
||||
* Initialize the attribute bag with the base attribute array.
|
||||
*
|
||||
* The given array is pass-by-reference, so updates to the array here or in
|
||||
* calling code will be reflected everywhere.
|
||||
*
|
||||
* @param array $attributes The pass-by-reference attributes.
|
||||
*/
|
||||
public function __construct(array &$attributes)
|
||||
{
|
||||
$this->attributes =& $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a single attribute with the given $name (or return $default if attribute was not found)
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default to return if attribute was not found
|
||||
* @return mixed
|
||||
*/
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* set a single attribute with the given $name to given $value
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
* @return self For a fluid interface.
|
||||
*/
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an array of all attributes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAttributes()
|
||||
{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* set an array of additional attributes
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return self For a fluid interface.
|
||||
*/
|
||||
public function setAttributes(array $attributes)
|
||||
{
|
||||
$this->attributes = $attributes + $this->attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a container for all attributes
|
||||
*
|
||||
* @return AttributeBag
|
||||
*/
|
||||
public function getAttributeBag()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
308
vendor/clue/graph/src/Edge/Base.php
vendored
Normal file
308
vendor/clue/graph/src/Edge/Base.php
vendored
Normal file
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Edge;
|
||||
|
||||
use Fhaculty\Graph\Attribute\AttributeAware;
|
||||
use Fhaculty\Graph\Attribute\AttributeBagReference;
|
||||
use Fhaculty\Graph\Exception\BadMethodCallException;
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Exception\LogicException;
|
||||
use Fhaculty\Graph\Exception\RangeException;
|
||||
use Fhaculty\Graph\Graph;
|
||||
use Fhaculty\Graph\Set\Vertices;
|
||||
use Fhaculty\Graph\Set\VerticesAggregate;
|
||||
use Fhaculty\Graph\Vertex;
|
||||
|
||||
abstract class Base implements VerticesAggregate, AttributeAware
|
||||
{
|
||||
/**
|
||||
* weight of this edge
|
||||
*
|
||||
* @var float|int|NULL
|
||||
* @see self::getWeight()
|
||||
*/
|
||||
protected $weight = NULL;
|
||||
|
||||
/**
|
||||
* maximum capacity (maximum flow)
|
||||
*
|
||||
* @var float|int|NULL
|
||||
* @see self::getCapacity()
|
||||
*/
|
||||
protected $capacity = NULL;
|
||||
|
||||
/**
|
||||
* flow (capacity currently in use)
|
||||
*
|
||||
* @var float|int|NULL
|
||||
* @see self::getFlow()
|
||||
*/
|
||||
protected $flow = NULL;
|
||||
|
||||
protected $attributes = array();
|
||||
|
||||
/**
|
||||
* get Vertices that are a target of this edge
|
||||
*
|
||||
* @return Vertices
|
||||
*/
|
||||
abstract public function getVerticesTarget();
|
||||
|
||||
/**
|
||||
* get Vertices that are the start of this edge
|
||||
*
|
||||
* @return Vertices
|
||||
*/
|
||||
abstract public function getVerticesStart();
|
||||
|
||||
/**
|
||||
* return true if this edge is an outgoing edge of the given vertex (i.e. the given vertex is a valid start vertex of this edge)
|
||||
*
|
||||
* @param Vertex $startVertex
|
||||
* @return bool
|
||||
* @uses Vertex::getVertexToFrom()
|
||||
*/
|
||||
abstract public function hasVertexStart(Vertex $startVertex);
|
||||
|
||||
/**
|
||||
* return true if this edge is an ingoing edge of the given vertex (i . e. the given vertex is a valid end vertex of this edge)
|
||||
*
|
||||
* @param Vertex $targetVertex
|
||||
* @return bool
|
||||
* @uses Vertex::getVertexFromTo()
|
||||
*/
|
||||
abstract function hasVertexTarget(Vertex $targetVertex);
|
||||
|
||||
abstract public function isConnection(Vertex $from, Vertex $to);
|
||||
|
||||
/**
|
||||
* returns whether this edge is actually a loop
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
abstract public function isLoop();
|
||||
|
||||
/**
|
||||
* get target vertex we can reach with this edge from the given start vertex
|
||||
*
|
||||
* @param Vertex $startVertex
|
||||
* @return Vertex
|
||||
* @throws InvalidArgumentException if given $startVertex is not a valid start
|
||||
* @see self::hasEdgeFrom() to check if given start is valid
|
||||
*/
|
||||
abstract public function getVertexToFrom(Vertex $startVertex);
|
||||
|
||||
/**
|
||||
* get start vertex which can reach us(the given end vertex) with this edge
|
||||
*
|
||||
* @param Vertex $endVertex
|
||||
* @return Vertex
|
||||
* @throws InvalidArgumentException if given $startVertex is not a valid end
|
||||
* @see self::hasEdgeFrom() to check if given start is valid
|
||||
*/
|
||||
abstract public function getVertexFromTo(Vertex $endVertex);
|
||||
|
||||
/**
|
||||
* return weight of edge
|
||||
*
|
||||
* @return float|int|NULL numeric weight of edge or NULL=not set
|
||||
*/
|
||||
public function getWeight()
|
||||
{
|
||||
return $this->weight;
|
||||
}
|
||||
|
||||
/**
|
||||
* set new weight for edge
|
||||
*
|
||||
* @param float|int|NULL $weight new numeric weight of edge or NULL=unset weight
|
||||
* @return self $this (chainable)
|
||||
* @throws InvalidArgumentException if given weight is not numeric
|
||||
*/
|
||||
public function setWeight($weight)
|
||||
{
|
||||
if ($weight !== NULL && !is_float($weight) && !is_int($weight)) {
|
||||
throw new InvalidArgumentException('Invalid weight given - must be numeric or NULL');
|
||||
}
|
||||
$this->weight = $weight;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get total capacity of this edge
|
||||
*
|
||||
* @return float|int|NULL numeric capacity or NULL=not set
|
||||
*/
|
||||
public function getCapacity()
|
||||
{
|
||||
return $this->capacity;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the capacity remaining (total capacity - current flow)
|
||||
*
|
||||
* @return float|int|NULL numeric capacity remaining or NULL=no upper capacity set
|
||||
*/
|
||||
public function getCapacityRemaining()
|
||||
{
|
||||
if ($this->capacity === NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return $this->capacity - $this->flow;
|
||||
}
|
||||
|
||||
/**
|
||||
* set new total capacity of this edge
|
||||
*
|
||||
* @param float|int|NULL $capacity
|
||||
* @return self $this (chainable)
|
||||
* @throws InvalidArgumentException if $capacity is invalid (not numeric or negative)
|
||||
* @throws RangeException if current flow exceeds new capacity
|
||||
*/
|
||||
public function setCapacity($capacity)
|
||||
{
|
||||
if ($capacity !== NULL) {
|
||||
if (!is_float($capacity) && !is_int($capacity)) {
|
||||
throw new InvalidArgumentException('Invalid capacity given - must be numeric');
|
||||
}
|
||||
if ($capacity < 0) {
|
||||
throw new InvalidArgumentException('Capacity must not be negative');
|
||||
}
|
||||
if ($this->flow !== NULL && $this->flow > $capacity) {
|
||||
throw new RangeException('Current flow of ' . $this->flow . ' exceeds new capacity');
|
||||
}
|
||||
}
|
||||
$this->capacity = $capacity;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get current flow (capacity currently in use)
|
||||
*
|
||||
* @return float|int|NULL numeric flow or NULL=not set
|
||||
*/
|
||||
public function getFlow()
|
||||
{
|
||||
return $this->flow;
|
||||
}
|
||||
|
||||
/**
|
||||
* set new total flow (capacity currently in use)
|
||||
*
|
||||
* @param float|int|NULL $flow
|
||||
* @return self $this (chainable)
|
||||
* @throws InvalidArgumentException if $flow is invalid (not numeric or negative)
|
||||
* @throws RangeException if flow exceeds current maximum capacity
|
||||
*/
|
||||
public function setFlow($flow)
|
||||
{
|
||||
if ($flow !== NULL) {
|
||||
if (!is_float($flow) && !is_int($flow)) {
|
||||
throw new InvalidArgumentException('Invalid flow given - must be numeric');
|
||||
}
|
||||
if ($flow < 0) {
|
||||
throw new InvalidArgumentException('Flow must not be negative');
|
||||
}
|
||||
if ($this->capacity !== NULL && $flow > $this->capacity) {
|
||||
throw new RangeException('New flow exceeds maximum capacity');
|
||||
}
|
||||
}
|
||||
$this->flow = $flow;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of all Vertices this edge connects
|
||||
*
|
||||
* @return Vertices
|
||||
*/
|
||||
//abstract public function getVertices();
|
||||
|
||||
/**
|
||||
* get graph instance this edge is attached to
|
||||
*
|
||||
* @return Graph
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function getGraph()
|
||||
{
|
||||
foreach ($this->getVertices() as $vertex) {
|
||||
return $vertex->getGraph();
|
||||
|
||||
// the following code can only be reached if this edge does not
|
||||
// contain any vertices (invalid state), so ignore its coverage
|
||||
// @codeCoverageIgnoreStart
|
||||
}
|
||||
|
||||
throw new LogicException('Internal error: should not be reached');
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy edge and remove reference from vertices and graph
|
||||
*
|
||||
* @uses Graph::removeEdge()
|
||||
* @uses Vertex::removeEdge()
|
||||
* @return void
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
$this->getGraph()->removeEdge($this);
|
||||
foreach ($this->getVertices() as $vertex) {
|
||||
$vertex->removeEdge($this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone of this edge between adjacent vertices
|
||||
*
|
||||
* @return self new edge
|
||||
* @uses Graph::createEdgeClone()
|
||||
*/
|
||||
public function createEdgeClone()
|
||||
{
|
||||
return $this->getGraph()->createEdgeClone($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone of this edge inverted (in opposite direction) between adjacent vertices
|
||||
*
|
||||
* @return self new edge
|
||||
* @uses Graph::createEdgeCloneInverted()
|
||||
*/
|
||||
public function createEdgeCloneInverted()
|
||||
{
|
||||
return $this->getGraph()->createEdgeCloneInverted($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* do NOT allow cloning of objects
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new BadMethodCallException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
}
|
||||
|
||||
public function getAttributeBag()
|
||||
{
|
||||
return new AttributeBagReference($this->attributes);
|
||||
}
|
||||
}
|
119
vendor/clue/graph/src/Edge/Directed.php
vendored
Normal file
119
vendor/clue/graph/src/Edge/Directed.php
vendored
Normal file
|
@ -0,0 +1,119 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Edge;
|
||||
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Set\Vertices;
|
||||
use Fhaculty\Graph\Vertex;
|
||||
|
||||
class Directed extends Base
|
||||
{
|
||||
/**
|
||||
* source/start vertex
|
||||
*
|
||||
* @var Vertex
|
||||
*/
|
||||
private $from;
|
||||
|
||||
/**
|
||||
* target/end vertex
|
||||
*
|
||||
* @var Vertex
|
||||
*/
|
||||
private $to;
|
||||
|
||||
/**
|
||||
* create a new directed Edge from Vertex $from to Vertex $to
|
||||
*
|
||||
* @param Vertex $from start/source Vertex
|
||||
* @param Vertex $to end/target Vertex
|
||||
* @see Vertex::createEdgeTo() to create directed edges
|
||||
* @see Vertex::createEdge() to create undirected edges
|
||||
*/
|
||||
public function __construct(Vertex $from, Vertex $to)
|
||||
{
|
||||
if ($from->getGraph() !== $to->getGraph()) {
|
||||
throw new InvalidArgumentException('Vertices have to be within the same graph');
|
||||
}
|
||||
|
||||
$this->from = $from;
|
||||
$this->to = $to;
|
||||
|
||||
$from->getGraph()->addEdge($this);
|
||||
$from->addEdge($this);
|
||||
$to->addEdge($this);
|
||||
}
|
||||
|
||||
public function getVerticesTarget()
|
||||
{
|
||||
return new Vertices(array($this->to));
|
||||
}
|
||||
|
||||
public function getVerticesStart()
|
||||
{
|
||||
return new Vertices(array($this->from));
|
||||
}
|
||||
|
||||
public function getVertices()
|
||||
{
|
||||
return new Vertices(array($this->from, $this->to));
|
||||
}
|
||||
|
||||
/**
|
||||
* get end/target vertex
|
||||
*
|
||||
* @return Vertex
|
||||
*/
|
||||
public function getVertexEnd()
|
||||
{
|
||||
return $this->to;
|
||||
}
|
||||
|
||||
/**
|
||||
* get start vertex
|
||||
*
|
||||
* @return Vertex
|
||||
*/
|
||||
public function getVertexStart()
|
||||
{
|
||||
return $this->from;
|
||||
}
|
||||
|
||||
public function isConnection(Vertex $from, Vertex $to)
|
||||
{
|
||||
return ($this->to === $to && $this->from === $from);
|
||||
}
|
||||
|
||||
public function isLoop()
|
||||
{
|
||||
return ($this->to === $this->from);
|
||||
}
|
||||
|
||||
public function getVertexToFrom(Vertex $startVertex)
|
||||
{
|
||||
if ($this->from !== $startVertex) {
|
||||
throw new InvalidArgumentException('Invalid start vertex');
|
||||
}
|
||||
|
||||
return $this->to;
|
||||
}
|
||||
|
||||
public function getVertexFromTo(Vertex $endVertex)
|
||||
{
|
||||
if ($this->to !== $endVertex) {
|
||||
throw new InvalidArgumentException('Invalid end vertex');
|
||||
}
|
||||
|
||||
return $this->from;
|
||||
}
|
||||
|
||||
public function hasVertexStart(Vertex $startVertex)
|
||||
{
|
||||
return ($this->from === $startVertex);
|
||||
}
|
||||
|
||||
public function hasVertexTarget(Vertex $targetVertex)
|
||||
{
|
||||
return ($this->to === $targetVertex);
|
||||
}
|
||||
}
|
104
vendor/clue/graph/src/Edge/Undirected.php
vendored
Normal file
104
vendor/clue/graph/src/Edge/Undirected.php
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Edge;
|
||||
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Vertex;
|
||||
use Fhaculty\Graph\Set\Vertices;
|
||||
|
||||
class Undirected extends Base
|
||||
{
|
||||
/**
|
||||
* vertex a
|
||||
*
|
||||
* @var Vertex
|
||||
*/
|
||||
private $a;
|
||||
|
||||
/**
|
||||
* vertex b
|
||||
*
|
||||
* @var Vertex
|
||||
*/
|
||||
private $b;
|
||||
|
||||
/**
|
||||
* create a new undirected edge between given vertices
|
||||
*
|
||||
* @param Vertex $a
|
||||
* @param Vertex $b
|
||||
* @see Vertex::createEdge() instead
|
||||
*/
|
||||
public function __construct(Vertex $a, Vertex $b)
|
||||
{
|
||||
if ($a->getGraph() !== $b->getGraph()) {
|
||||
throw new InvalidArgumentException('Vertices have to be within the same graph');
|
||||
}
|
||||
|
||||
$this->a = $a;
|
||||
$this->b = $b;
|
||||
|
||||
$a->getGraph()->addEdge($this);
|
||||
$a->addEdge($this);
|
||||
$b->addEdge($this);
|
||||
}
|
||||
|
||||
public function getVerticesTarget()
|
||||
{
|
||||
return new Vertices(array($this->b, $this->a));
|
||||
}
|
||||
|
||||
public function getVerticesStart()
|
||||
{
|
||||
return new Vertices(array($this->a, $this->b));
|
||||
}
|
||||
|
||||
public function getVertices()
|
||||
{
|
||||
return new Vertices(array($this->a, $this->b));
|
||||
}
|
||||
|
||||
public function isConnection(Vertex $from, Vertex $to)
|
||||
{
|
||||
// one way or other way
|
||||
return (($this->a === $from && $this->b === $to) || ($this->b === $from && $this->a === $to));
|
||||
}
|
||||
|
||||
public function isLoop()
|
||||
{
|
||||
return ($this->a === $this->b);
|
||||
}
|
||||
|
||||
public function getVertexToFrom(Vertex $startVertex)
|
||||
{
|
||||
if ($this->a === $startVertex) {
|
||||
return $this->b;
|
||||
} elseif ($this->b === $startVertex) {
|
||||
return $this->a;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid start vertex');
|
||||
}
|
||||
}
|
||||
|
||||
public function getVertexFromTo(Vertex $endVertex)
|
||||
{
|
||||
if ($this->a === $endVertex) {
|
||||
return $this->b;
|
||||
} elseif ($this->b === $endVertex) {
|
||||
return $this->a;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid end vertex');
|
||||
}
|
||||
}
|
||||
|
||||
public function hasVertexStart(Vertex $startVertex)
|
||||
{
|
||||
return ($this->a === $startVertex || $this->b === $startVertex);
|
||||
}
|
||||
|
||||
public function hasVertexTarget(Vertex $targetVertex)
|
||||
{
|
||||
// same implementation as direction does not matter
|
||||
return $this->hasVertexStart($targetVertex);
|
||||
}
|
||||
}
|
7
vendor/clue/graph/src/Exception.php
vendored
Normal file
7
vendor/clue/graph/src/Exception.php
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph;
|
||||
|
||||
interface Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/BadMethodCallException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/BadMethodCallException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class BadMethodCallException extends \BadMethodCallException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/DomainException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/DomainException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class DomainException extends \DomainException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/InvalidArgumentException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/InvalidArgumentException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class InvalidArgumentException extends \InvalidArgumentException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/LogicException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/LogicException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class LogicException extends \LogicException implements Graph\Exception
|
||||
{
|
||||
}
|
36
vendor/clue/graph/src/Exception/NegativeCycleException.php
vendored
Normal file
36
vendor/clue/graph/src/Exception/NegativeCycleException.php
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph\Walk;
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class NegativeCycleException extends UnexpectedValueException implements Graph\Exception
|
||||
{
|
||||
/**
|
||||
* instance of the cycle
|
||||
*
|
||||
* @var Walk
|
||||
*/
|
||||
private $cycle;
|
||||
|
||||
public function __construct($message, $code = NULL, $previous = NULL, Walk $cycle = null)
|
||||
{
|
||||
// $cycle is required, but required argument may not appear after option arguments as of PHP 8
|
||||
if ($cycle === null) {
|
||||
throw new \InvalidArgumentException('Missing required cycle');
|
||||
}
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
$this->cycle = $cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Walk
|
||||
*/
|
||||
public function getCycle()
|
||||
{
|
||||
return $this->cycle;
|
||||
}
|
||||
}
|
9
vendor/clue/graph/src/Exception/OutOfBoundsException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/OutOfBoundsException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class OutOfBoundsException extends \OutOfBoundsException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/OverflowException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/OverflowException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class OverflowException extends \OverflowException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/RangeException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/RangeException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class RangeException extends \RangeException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/RuntimeException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/RuntimeException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class RuntimeException extends \RuntimeException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/UnderflowException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/UnderflowException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class UnderflowException extends \UnderflowException implements Graph\Exception
|
||||
{
|
||||
}
|
9
vendor/clue/graph/src/Exception/UnexpectedValueException.php
vendored
Normal file
9
vendor/clue/graph/src/Exception/UnexpectedValueException.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exception;
|
||||
|
||||
use Fhaculty\Graph;
|
||||
|
||||
class UnexpectedValueException extends \UnexpectedValueException implements Graph\Exception
|
||||
{
|
||||
}
|
10
vendor/clue/graph/src/Exporter/ExporterInterface.php
vendored
Normal file
10
vendor/clue/graph/src/Exporter/ExporterInterface.php
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Exporter;
|
||||
|
||||
use Fhaculty\Graph\Graph;
|
||||
|
||||
interface ExporterInterface
|
||||
{
|
||||
public function getOutput(Graph $graph);
|
||||
}
|
464
vendor/clue/graph/src/Graph.php
vendored
Normal file
464
vendor/clue/graph/src/Graph.php
vendored
Normal file
|
@ -0,0 +1,464 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph;
|
||||
|
||||
use Fhaculty\Graph\Attribute\AttributeAware;
|
||||
use Fhaculty\Graph\Attribute\AttributeBagReference;
|
||||
use Fhaculty\Graph\Edge\Base as Edge;
|
||||
use Fhaculty\Graph\Edge\Directed as EdgeDirected;
|
||||
use Fhaculty\Graph\Exception\BadMethodCallException;
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Exception\OutOfBoundsException;
|
||||
use Fhaculty\Graph\Exception\OverflowException;
|
||||
use Fhaculty\Graph\Exception\RuntimeException;
|
||||
use Fhaculty\Graph\Exception\UnderflowException;
|
||||
use Fhaculty\Graph\Set\DualAggregate;
|
||||
use Fhaculty\Graph\Set\Edges;
|
||||
use Fhaculty\Graph\Set\Vertices;
|
||||
use Fhaculty\Graph\Set\VerticesMap;
|
||||
|
||||
class Graph implements DualAggregate, AttributeAware
|
||||
{
|
||||
protected $verticesStorage = array();
|
||||
protected $vertices;
|
||||
|
||||
protected $edgesStorage = array();
|
||||
protected $edges;
|
||||
|
||||
protected $attributes = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->vertices = VerticesMap::factoryArrayReference($this->verticesStorage);
|
||||
$this->edges = Edges::factoryArrayReference($this->edgesStorage);
|
||||
}
|
||||
|
||||
/**
|
||||
* return set of Vertices added to this graph
|
||||
*
|
||||
* @return Vertices
|
||||
*/
|
||||
public function getVertices()
|
||||
{
|
||||
return $this->vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* return set of ALL Edges added to this graph
|
||||
*
|
||||
* @return Edges
|
||||
*/
|
||||
public function getEdges()
|
||||
{
|
||||
return $this->edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new Vertex in the Graph
|
||||
*
|
||||
* @param int|NULL $id new vertex ID to use (defaults to NULL: use next free numeric ID)
|
||||
* @param bool $returnDuplicate normal operation is to throw an exception if given id already exists. pass true to return original vertex instead
|
||||
* @return Vertex (chainable)
|
||||
* @throws InvalidArgumentException if given vertex $id is invalid
|
||||
* @throws OverflowException if given vertex $id already exists and $returnDuplicate is not set
|
||||
* @uses Vertex::getId()
|
||||
*/
|
||||
public function createVertex($id = NULL, $returnDuplicate = false)
|
||||
{
|
||||
// no ID given
|
||||
if ($id === NULL) {
|
||||
$id = $this->getNextId();
|
||||
}
|
||||
if ($returnDuplicate && $this->vertices->hasVertexId($id)) {
|
||||
return $this->vertices->getVertexId($id);
|
||||
}
|
||||
|
||||
return new Vertex($this, $id);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new Vertex in this Graph from the given input Vertex of another graph
|
||||
*
|
||||
* @param Vertex $originalVertex
|
||||
* @return Vertex new vertex in this graph
|
||||
* @throws RuntimeException if vertex with this ID already exists
|
||||
*/
|
||||
public function createVertexClone(Vertex $originalVertex)
|
||||
{
|
||||
$id = $originalVertex->getId();
|
||||
if ($this->vertices->hasVertexId($id)) {
|
||||
throw new RuntimeException('Id of cloned vertex already exists');
|
||||
}
|
||||
$newVertex = new Vertex($this, $id);
|
||||
// TODO: properly set attributes of vertex
|
||||
$newVertex->getAttributeBag()->setAttributes($originalVertex->getAttributeBag()->getAttributes());
|
||||
$newVertex->setBalance($originalVertex->getBalance());
|
||||
$newVertex->setGroup($originalVertex->getGroup());
|
||||
|
||||
return $newVertex;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone/copy of this graph - copy all attributes and vertices, but do NOT copy edges
|
||||
*
|
||||
* using this method is faster than creating a new graph and calling createEdgeClone() yourself
|
||||
*
|
||||
* @return Graph
|
||||
*/
|
||||
public function createGraphCloneEdgeless()
|
||||
{
|
||||
$graph = new Graph();
|
||||
$graph->getAttributeBag()->setAttributes($this->getAttributeBag()->getAttributes());
|
||||
// TODO: set additional graph attributes
|
||||
foreach ($this->getVertices() as $originalVertex) {
|
||||
$vertex = $graph->createVertexClone($originalVertex);
|
||||
// $graph->vertices[$vid] = $vertex;
|
||||
}
|
||||
|
||||
return $graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone/copy of this graph - copy all attributes and vertices. but only copy all given edges
|
||||
*
|
||||
* @param Edges|Edge[] $edges set or array of edges to be cloned
|
||||
* @return Graph
|
||||
* @uses Graph::createGraphCloneEdgeless()
|
||||
* @uses Graph::createEdgeClone() for each edge to be cloned
|
||||
*/
|
||||
public function createGraphCloneEdges($edges)
|
||||
{
|
||||
$graph = $this->createGraphCloneEdgeless();
|
||||
foreach ($edges as $edge) {
|
||||
$graph->createEdgeClone($edge);
|
||||
}
|
||||
|
||||
return $graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone/copy of this graph - copy all attributes, vertices and edges
|
||||
*
|
||||
* @return Graph
|
||||
* @uses Graph::createGraphCloneEdges() to clone graph with current edges
|
||||
*/
|
||||
public function createGraphClone()
|
||||
{
|
||||
return $this->createGraphCloneEdges($this->edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new clone/copy of this graph - copy all attributes and given vertices and its edges
|
||||
*
|
||||
* @param Vertices $vertices set of vertices to keep
|
||||
* @return Graph
|
||||
* @uses Graph::createGraphClone() to create a complete clone
|
||||
* @uses Vertex::destroy() to remove unneeded vertices again
|
||||
*/
|
||||
public function createGraphCloneVertices($vertices)
|
||||
{
|
||||
$verticesKeep = Vertices::factory($vertices);
|
||||
|
||||
$graph = $this->createGraphClone();
|
||||
foreach ($graph->getVertices()->getMap() as $vid => $vertex) {
|
||||
if (!$verticesKeep->hasVertexId($vid)) {
|
||||
$vertex->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
return $graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone of the given edge between adjacent vertices
|
||||
*
|
||||
* @param Edge $originalEdge original edge (not neccessarily from this graph)
|
||||
* @return Edge new edge in this graph
|
||||
* @uses Graph::createEdgeCloneInternal()
|
||||
*/
|
||||
public function createEdgeClone(Edge $originalEdge)
|
||||
{
|
||||
return $this->createEdgeCloneInternal($originalEdge, 0, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone of the given edge inverted (in opposite direction) between adjacent vertices
|
||||
*
|
||||
* @param Edge $originalEdge original edge (not neccessarily from this graph)
|
||||
* @return Edge new edge in this graph
|
||||
* @uses Graph::createEdgeCloneInternal()
|
||||
*/
|
||||
public function createEdgeCloneInverted(Edge $originalEdge)
|
||||
{
|
||||
return $this->createEdgeCloneInternal($originalEdge, 1, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new clone of the given edge between adjacent vertices
|
||||
*
|
||||
* @param Edge $originalEdge original edge from old graph
|
||||
* @param int $ia index of start vertex
|
||||
* @param int $ib index of end vertex
|
||||
* @return Edge new edge in this graph
|
||||
* @uses Edge::getVertices()
|
||||
* @uses Graph::getVertex()
|
||||
* @uses Vertex::createEdge() to create a new undirected edge if given edge was undrected
|
||||
* @uses Vertex::createEdgeTo() to create a new directed edge if given edge was directed
|
||||
* @uses Edge::getWeight()
|
||||
* @uses Edge::setWeight()
|
||||
* @uses Edge::getFlow()
|
||||
* @uses Edge::setFlow()
|
||||
* @uses Edge::getCapacity()
|
||||
* @uses Edge::setCapacity()
|
||||
*/
|
||||
private function createEdgeCloneInternal(Edge $originalEdge, $ia, $ib)
|
||||
{
|
||||
$ends = $originalEdge->getVertices()->getIds();
|
||||
|
||||
// get start vertex from old start vertex id
|
||||
$a = $this->getVertex($ends[$ia]);
|
||||
// get target vertex from old target vertex id
|
||||
$b = $this->getVertex($ends[$ib]);
|
||||
|
||||
if ($originalEdge instanceof EdgeDirected) {
|
||||
$newEdge = $a->createEdgeTo($b);
|
||||
} else {
|
||||
// create new edge between new a and b
|
||||
$newEdge = $a->createEdge($b);
|
||||
}
|
||||
// TODO: copy edge attributes
|
||||
$newEdge->getAttributeBag()->setAttributes($originalEdge->getAttributeBag()->getAttributes());
|
||||
$newEdge->setWeight($originalEdge->getWeight());
|
||||
$newEdge->setFlow($originalEdge->getFlow());
|
||||
$newEdge->setCapacity($originalEdge->getCapacity());
|
||||
|
||||
return $newEdge;
|
||||
}
|
||||
|
||||
/**
|
||||
* create the given number of vertices or given array of Vertex IDs
|
||||
*
|
||||
* @param int|array $n number of vertices to create or array of Vertex IDs to create
|
||||
* @return Vertices set of Vertices created
|
||||
* @uses Graph::getNextId()
|
||||
*/
|
||||
public function createVertices($n)
|
||||
{
|
||||
$vertices = array();
|
||||
if (is_int($n) && $n >= 0) {
|
||||
for ($id = $this->getNextId(), $n += $id; $id < $n; ++$id) {
|
||||
$vertices[$id] = new Vertex($this, $id);
|
||||
}
|
||||
} elseif (is_array($n)) {
|
||||
// array given => check to make sure all given IDs are available (atomic operation)
|
||||
foreach ($n as $id) {
|
||||
if (!is_int($id) && !is_string($id)) {
|
||||
throw new InvalidArgumentException('All Vertex IDs have to be of type integer or string');
|
||||
} elseif ($this->vertices->hasVertexId($id)) {
|
||||
throw new OverflowException('Given array of Vertex IDs contains an ID that already exists. Given IDs must be unique');
|
||||
} elseif (isset($vertices[$id])) {
|
||||
throw new InvalidArgumentException('Given array of Vertex IDs contain duplicate IDs. Given IDs must be unique');
|
||||
}
|
||||
|
||||
// temporary marker to check for duplicate IDs in the array
|
||||
$vertices[$id] = false;
|
||||
}
|
||||
|
||||
// actually create all requested vertices
|
||||
foreach ($n as $id) {
|
||||
$vertices[$id] = new Vertex($this, $id);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid number of vertices given. Must be non-negative integer or an array of Vertex IDs');
|
||||
}
|
||||
|
||||
return new Vertices($vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* get next free/unused/available vertex ID
|
||||
*
|
||||
* its guaranteed there's NO other vertex with a greater ID
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function getNextId()
|
||||
{
|
||||
if (!$this->verticesStorage) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// auto ID
|
||||
return max(array_map('intval', array_keys($this->verticesStorage)))+1;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the Vertex with identifier $id
|
||||
*
|
||||
* @param int|string $id identifier of Vertex
|
||||
* @return Vertex
|
||||
* @throws OutOfBoundsException if given vertex ID does not exist
|
||||
*/
|
||||
public function getVertex($id)
|
||||
{
|
||||
return $this->vertices->getVertexId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether given vertex ID exists in this graph
|
||||
*
|
||||
* @param int|string $id identifier of Vertex
|
||||
* @return bool
|
||||
*/
|
||||
public function hasVertex($id)
|
||||
{
|
||||
return $this->vertices->hasVertexId($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a new Vertex to the Graph (MUST NOT be called manually!)
|
||||
*
|
||||
* @param Vertex $vertex instance of the new Vertex
|
||||
* @return void
|
||||
* @internal
|
||||
* @see self::createVertex() instead!
|
||||
*/
|
||||
public function addVertex(Vertex $vertex)
|
||||
{
|
||||
if (isset($this->verticesStorage[$vertex->getId()])) {
|
||||
throw new OverflowException('ID must be unique');
|
||||
}
|
||||
$this->verticesStorage[$vertex->getId()] = $vertex;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a new Edge to the Graph (MUST NOT be called manually!)
|
||||
*
|
||||
* @param Edge $edge instance of the new Edge
|
||||
* @return void
|
||||
* @internal
|
||||
* @see Vertex::createEdge() instead!
|
||||
*/
|
||||
public function addEdge(Edge $edge)
|
||||
{
|
||||
$this->edgesStorage []= $edge;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove the given edge from list of connected edges (MUST NOT be called manually!)
|
||||
*
|
||||
* @param Edge $edge
|
||||
* @return void
|
||||
* @throws InvalidArgumentException if given edge does not exist (should not ever happen)
|
||||
* @internal
|
||||
* @see Edge::destroy() instead!
|
||||
*/
|
||||
public function removeEdge(Edge $edge)
|
||||
{
|
||||
try {
|
||||
unset($this->edgesStorage[$this->edges->getIndexEdge($edge)]);
|
||||
}
|
||||
catch (OutOfBoundsException $e) {
|
||||
throw new InvalidArgumentException('Invalid Edge does not exist in this Graph');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove the given vertex from list of known vertices (MUST NOT be called manually!)
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @return void
|
||||
* @throws InvalidArgumentException if given vertex does not exist (should not ever happen)
|
||||
* @internal
|
||||
* @see Vertex::destroy() instead!
|
||||
*/
|
||||
public function removeVertex(Vertex $vertex)
|
||||
{
|
||||
try {
|
||||
unset($this->verticesStorage[$this->vertices->getIndexVertex($vertex)]);
|
||||
}
|
||||
catch (OutOfBoundsException $e) {
|
||||
throw new InvalidArgumentException('Invalid Vertex does not exist in this Graph');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts edge from this graph
|
||||
*
|
||||
* @param Edge $edge
|
||||
* @return Edge
|
||||
* @throws UnderflowException if no edge was found
|
||||
* @throws OverflowException if multiple edges match
|
||||
*/
|
||||
public function getEdgeClone(Edge $edge)
|
||||
{
|
||||
// Extract endpoints from edge
|
||||
$vertices = $edge->getVertices()->getVector();
|
||||
|
||||
return $this->getEdgeCloneInternal($edge, $vertices[0], $vertices[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts inverted edge from this graph
|
||||
*
|
||||
* @param Edge $edge
|
||||
* @return Edge
|
||||
* @throws UnderflowException if no edge was found
|
||||
* @throws OverflowException if multiple edges match
|
||||
*/
|
||||
public function getEdgeCloneInverted(Edge $edge)
|
||||
{
|
||||
// Extract endpoints from edge
|
||||
$vertices = $edge->getVertices()->getVector();
|
||||
|
||||
return $this->getEdgeCloneInternal($edge, $vertices[1], $vertices[0]);
|
||||
}
|
||||
|
||||
private function getEdgeCloneInternal(Edge $edge, Vertex $startVertex, Vertex $targetVertex)
|
||||
{
|
||||
// Get original vertices from resultgraph
|
||||
$residualGraphEdgeStartVertex = $this->getVertex($startVertex->getId());
|
||||
$residualGraphEdgeTargetVertex = $this->getVertex($targetVertex->getId());
|
||||
|
||||
// Now get the edge
|
||||
$residualEdgeArray = $residualGraphEdgeStartVertex->getEdgesTo($residualGraphEdgeTargetVertex);
|
||||
$residualEdgeArray = Edges::factory($residualEdgeArray)->getVector();
|
||||
|
||||
// Check for parallel edges
|
||||
if (!$residualEdgeArray) {
|
||||
throw new UnderflowException('No original edges for given cloned edge found');
|
||||
} elseif (count($residualEdgeArray) !== 1) {
|
||||
throw new OverflowException('More than one cloned edge? Parallel edges (multigraph) not supported');
|
||||
}
|
||||
|
||||
return $residualEdgeArray[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* do NOT allow cloning of objects (MUST NOT be called!)
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
* @see Graph::createGraphClone() instead
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new BadMethodCallException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
}
|
||||
|
||||
public function getAttributeBag()
|
||||
{
|
||||
return new AttributeBagReference($this->attributes);
|
||||
}
|
||||
}
|
27
vendor/clue/graph/src/Set/DualAggregate.php
vendored
Normal file
27
vendor/clue/graph/src/Set/DualAggregate.php
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Set;
|
||||
|
||||
/**
|
||||
* A DualAggregate provides access to both its Vertices and its Edges
|
||||
*
|
||||
* This is the simple base interface for any Graph-like structure / data type
|
||||
* which contains a Set of Edges and a Set of Vertices, such as the Graph class
|
||||
* itself and the Walk class.
|
||||
*/
|
||||
interface DualAggregate extends VerticesAggregate, EdgesAggregate
|
||||
{
|
||||
/**
|
||||
* returns a set of ALL Edges in this graph
|
||||
*
|
||||
* @return Edges
|
||||
*/
|
||||
// abstract public function getEdges();
|
||||
|
||||
/**
|
||||
* returns a set of all Vertices
|
||||
*
|
||||
* @return Vertices
|
||||
*/
|
||||
// abstract public function getVertices();
|
||||
}
|
487
vendor/clue/graph/src/Set/Edges.php
vendored
Normal file
487
vendor/clue/graph/src/Set/Edges.php
vendored
Normal file
|
@ -0,0 +1,487 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Set;
|
||||
|
||||
use Fhaculty\Graph\Edge\Base as Edge;
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Exception\OutOfBoundsException;
|
||||
use Fhaculty\Graph\Exception\UnderflowException;
|
||||
|
||||
/**
|
||||
* A Set of Edges
|
||||
*
|
||||
* Contains any number of Edge (directed and/or undirected) instances.
|
||||
*
|
||||
* The Set is a readonly instance and it provides methods to get single Edge
|
||||
* instances or to get a new Set of Edges. This way it's safe to pass around
|
||||
* the original Set of Edges, because it will never be modified.
|
||||
*/
|
||||
class Edges implements \Countable, \IteratorAggregate, EdgesAggregate
|
||||
{
|
||||
/**
|
||||
* order by edge weight
|
||||
*
|
||||
* @var int
|
||||
* @see Edge::getWeight()
|
||||
*/
|
||||
const ORDER_WEIGHT = 1;
|
||||
|
||||
/**
|
||||
* order by edge capacity
|
||||
*
|
||||
* @var int
|
||||
* @see Edge::getCapacity()
|
||||
*/
|
||||
const ORDER_CAPACITY = 2;
|
||||
|
||||
/**
|
||||
* order by remaining capacity on edge (maximum capacity - current flow)
|
||||
*
|
||||
* @var int
|
||||
* @see Edge::getCapacityRemaining()
|
||||
*/
|
||||
const ORDER_CAPACITY_REMAINING = 3;
|
||||
|
||||
/**
|
||||
* order by edge flow
|
||||
*
|
||||
* @var int
|
||||
* @see Edge::getFlow()
|
||||
*/
|
||||
const ORDER_FLOW = 4;
|
||||
|
||||
/**
|
||||
* random/shuffled order
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const ORDER_RANDOM = 5;
|
||||
|
||||
protected $edges = array();
|
||||
|
||||
/**
|
||||
* create new Edges instance
|
||||
*
|
||||
* You can pass in just about anything that can be expressed as a Set of
|
||||
* Edges, such as:
|
||||
* - an array of Edge instances
|
||||
* - any Algorithm that implements the EdgesAggregate interface
|
||||
* - a Graph instance or
|
||||
* - an existing Set of Edges which will be returned as-is
|
||||
*
|
||||
* @param array|Edges|EdgesAggregate $edges
|
||||
* @return Edges
|
||||
*/
|
||||
public static function factory($edges)
|
||||
{
|
||||
if ($edges instanceof EdgesAggregate) {
|
||||
return $edges->getEdges();
|
||||
}
|
||||
return new self($edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new Edges instance that references the given source array of Edge instances
|
||||
*
|
||||
* Any changes in the referenced source array will automatically be
|
||||
* reflected in this Set of Edges, e.g. if you add an Edge instance to the
|
||||
* array, it will automatically be included in this Set.
|
||||
*
|
||||
* @param array $edgesArray
|
||||
* @return Edges
|
||||
*/
|
||||
public static function factoryArrayReference(array &$edgesArray)
|
||||
{
|
||||
$edges = new static();
|
||||
$edges->edges =& $edgesArray;
|
||||
return $edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* instantiate new Set of Edges
|
||||
*
|
||||
* @param array $edges
|
||||
*/
|
||||
public function __construct(array $edges = array())
|
||||
{
|
||||
$this->edges = $edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* get array index for given Edge
|
||||
*
|
||||
* @param Edge $edge
|
||||
* @throws OutOfBoundsException
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIndexEdge(Edge $edge)
|
||||
{
|
||||
$id = array_search($edge, $this->edges, true);
|
||||
if ($id === false) {
|
||||
throw new OutOfBoundsException('Given edge does NOT exist');
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* return first Edge in this set of Edges
|
||||
*
|
||||
* some algorithms do not need a particular edge, but merely a (random)
|
||||
* starting point. this is a convenience function to just pick the first
|
||||
* edge from the list of known edges.
|
||||
*
|
||||
* @return Edge first Edge in this set of Edges
|
||||
* @throws UnderflowException if set is empty
|
||||
* @see self::getEdgeOrder() if you need to apply ordering first
|
||||
*/
|
||||
public function getEdgeFirst()
|
||||
{
|
||||
if (!$this->edges) {
|
||||
throw new UnderflowException('Does not contain any edges');
|
||||
}
|
||||
reset($this->edges);
|
||||
|
||||
return current($this->edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* return last Edge in this set of Edges
|
||||
*
|
||||
* @return Edge last Edge in this set of Edges
|
||||
* @throws UnderflowException if set is empty
|
||||
*/
|
||||
public function getEdgeLast()
|
||||
{
|
||||
if (!$this->edges) {
|
||||
throw new UnderflowException('Does not contain any edges');
|
||||
}
|
||||
end($this->edges);
|
||||
|
||||
return current($this->edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* return Edge at given array index
|
||||
*
|
||||
* @param mixed $index
|
||||
* @throws OutOfBoundsException if the given index does not exist
|
||||
* @return Edge
|
||||
*/
|
||||
public function getEdgeIndex($index)
|
||||
{
|
||||
if (!isset($this->edges[$index])) {
|
||||
throw new OutOfBoundsException('Invalid edge index');
|
||||
}
|
||||
return $this->edges[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* return first Edge that matches the given callback filter function
|
||||
*
|
||||
* @param callable $callbackCheck
|
||||
* @return Edge
|
||||
* @throws UnderflowException if no Edge matches the given callback filter function
|
||||
* @uses self::getEdgeMatchOrNull()
|
||||
* @see self::getEdgesMatch() if you want to return *all* Edges that match
|
||||
*/
|
||||
public function getEdgeMatch($callbackCheck)
|
||||
{
|
||||
$ret = $this->getEdgeMatchOrNull($callbackCheck);
|
||||
if ($ret === null) {
|
||||
throw new UnderflowException('No edge found');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whethere there's an Edge that matches the given callback filter function
|
||||
*
|
||||
* @param callable $callbackCheck
|
||||
* @return bool
|
||||
* @see self::getEdgeMatch() to return the Edge instance that matches the given callback filter function
|
||||
* @uses self::getEdgeMatchOrNull()
|
||||
*/
|
||||
public function hasEdgeMatch($callbackCheck)
|
||||
{
|
||||
return ($this->getEdgeMatchOrNull($callbackCheck) !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a new set of Edges that match the given callback filter function
|
||||
*
|
||||
* This only keeps Edge elements if the $callbackCheck returns a bool
|
||||
* true and filters out everything else.
|
||||
*
|
||||
* Edge index positions will be left unchanged.
|
||||
*
|
||||
* @param callable $callbackCheck
|
||||
* @return Edges a new Edges instance
|
||||
* @see self::getEdgeMatch()
|
||||
*/
|
||||
public function getEdgesMatch($callbackCheck)
|
||||
{
|
||||
return new static(array_filter($this->edges, $callbackCheck));
|
||||
}
|
||||
|
||||
/**
|
||||
* get new set of Edges ordered by given criterium $orderBy
|
||||
*
|
||||
* Edge index positions will be left unchanged.
|
||||
*
|
||||
* @param int $orderBy criterium to sort by. see self::ORDER_WEIGHT, etc.
|
||||
* @param bool $desc whether to return biggest first (true) instead of smallest first (default:false)
|
||||
* @return Edges a new Edges set ordered by the given $orderBy criterium
|
||||
* @throws InvalidArgumentException if criterium is unknown
|
||||
*/
|
||||
public function getEdgesOrder($orderBy, $desc = false)
|
||||
{
|
||||
if ($orderBy === self::ORDER_RANDOM) {
|
||||
// shuffle the edge positions
|
||||
$keys = array_keys($this->edges);
|
||||
shuffle($keys);
|
||||
|
||||
// re-order according to shuffled edge positions
|
||||
$edges = array();
|
||||
foreach ($keys as $key) {
|
||||
$edges[$key] = $this->edges[$key];
|
||||
}
|
||||
|
||||
// create iterator for shuffled array (no need to check DESC flag)
|
||||
return new static($edges);
|
||||
}
|
||||
|
||||
$callback = $this->getCallback($orderBy);
|
||||
$array = $this->edges;
|
||||
|
||||
uasort($array, function (Edge $va, Edge $vb) use ($callback, $desc) {
|
||||
$ra = $callback($desc ? $vb : $va);
|
||||
$rb = $callback($desc ? $va : $vb);
|
||||
|
||||
if ($ra < $rb) {
|
||||
return -1;
|
||||
} elseif ($ra > $rb) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
return new static($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* get first edge ordered by given criterium $orderBy
|
||||
*
|
||||
* @param int $orderBy criterium to sort by. see self::ORDER_WEIGHT, etc.
|
||||
* @param bool $desc whether to return biggest (true) instead of smallest (default:false)
|
||||
* @return Edge
|
||||
* @throws InvalidArgumentException if criterium is unknown
|
||||
* @throws UnderflowException if no edges exist
|
||||
*/
|
||||
public function getEdgeOrder($orderBy, $desc=false)
|
||||
{
|
||||
if (!$this->edges) {
|
||||
throw new UnderflowException('No edge found');
|
||||
}
|
||||
// random order
|
||||
if ($orderBy === self::ORDER_RANDOM) {
|
||||
// just return by random key (no need to check for DESC flag)
|
||||
return $this->edges[array_rand($this->edges)];
|
||||
}
|
||||
|
||||
$callback = $this->getCallback($orderBy);
|
||||
|
||||
$ret = NULL;
|
||||
$best = NULL;
|
||||
foreach ($this->edges as $edge) {
|
||||
$now = $callback($edge);
|
||||
|
||||
if ($ret === NULL || ($desc && $now > $best) || (!$desc && $now < $best)) {
|
||||
$ret = $edge;
|
||||
$best = $now;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* return self reference to Set of Edges
|
||||
*
|
||||
* @return Edges
|
||||
* @see self::factory()
|
||||
*/
|
||||
public function getEdges()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a new set of Edges where each Edge is distinct/unique
|
||||
*
|
||||
* @return Edges a new Edges instance
|
||||
*/
|
||||
public function getEdgesDistinct()
|
||||
{
|
||||
$edges = array();
|
||||
foreach ($this->edges as $edge) {
|
||||
// filter duplicate edges
|
||||
if (!in_array($edge, $edges, true)) {
|
||||
$edges []= $edge;
|
||||
}
|
||||
}
|
||||
|
||||
return new Edges($edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* get intersection of Edges with given other Edges
|
||||
*
|
||||
* The intersection contains all Edge instances that are present in BOTH
|
||||
* this set of Edges and the given set of other Edges.
|
||||
*
|
||||
* Edge index/keys will be preserved from original array.
|
||||
*
|
||||
* Duplicate Edge instances will be kept if the corresponding number of
|
||||
* Edge instances is also found in $otherEdges.
|
||||
*
|
||||
* @param Edges|Edge[] $otherEdges
|
||||
* @return Edges a new Edges set
|
||||
*/
|
||||
public function getEdgesIntersection($otherEdges)
|
||||
{
|
||||
$otherArray = self::factory($otherEdges)->getVector();
|
||||
|
||||
$edges = array();
|
||||
foreach ($this->edges as $eid => $edge) {
|
||||
$i = array_search($edge, $otherArray, true);
|
||||
|
||||
if ($i !== false) {
|
||||
// remove from other array in order to check for duplicate matches
|
||||
unset($otherArray[$i]);
|
||||
|
||||
$edges[$eid] = $edge;
|
||||
}
|
||||
}
|
||||
|
||||
return new static($edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* return array of Edge instances
|
||||
*
|
||||
* @return Edge[]
|
||||
*/
|
||||
public function getVector()
|
||||
{
|
||||
return array_values($this->edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* count number of Edges
|
||||
*
|
||||
* @return int
|
||||
* @see self::isEmpty()
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this Set of Edges is empty
|
||||
*
|
||||
* A Set if empty if no single Edge instance is added. This is faster
|
||||
* than calling `count() === 0`.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return !$this->edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* get Iterator
|
||||
*
|
||||
* This method implements the IteratorAggregate interface and allows this
|
||||
* Set of Edges to be used in foreach loops.
|
||||
*
|
||||
* @return \IteratorIterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \IteratorIterator(new \ArrayIterator($this->edges));
|
||||
}
|
||||
|
||||
/**
|
||||
* call given $callback on each Edge and sum their results
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return number
|
||||
* @throws InvalidArgumentException for invalid callbacks
|
||||
* @uses self::getCallback()
|
||||
*/
|
||||
public function getSumCallback($callback)
|
||||
{
|
||||
$callback = $this->getCallback($callback);
|
||||
|
||||
// return array_sum(array_map($callback, $this->edges));
|
||||
|
||||
$sum = 0;
|
||||
foreach ($this->edges as $edge) {
|
||||
$sum += $callback($edge);
|
||||
}
|
||||
return $sum;
|
||||
}
|
||||
|
||||
private function getEdgeMatchOrNull($callbackCheck)
|
||||
{
|
||||
$callbackCheck = $this->getCallback($callbackCheck);
|
||||
|
||||
foreach ($this->edges as $edge) {
|
||||
if ($callbackCheck($edge)) {
|
||||
return $edge;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get callback/Closure to be called on Edge instances for given callback identifier
|
||||
*
|
||||
* @param callable|int $callback
|
||||
* @throws InvalidArgumentException
|
||||
* @return callable
|
||||
*/
|
||||
private function getCallback($callback)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
if (is_array($callback)) {
|
||||
$callback = function (Edge $edge) use ($callback) {
|
||||
return call_user_func($callback, $edge);
|
||||
};
|
||||
}
|
||||
return $callback;
|
||||
}
|
||||
|
||||
static $methods = array(
|
||||
self::ORDER_WEIGHT => 'getWeight',
|
||||
self::ORDER_CAPACITY => 'getCapacity',
|
||||
self::ORDER_CAPACITY_REMAINING => 'getCapacityRemaining',
|
||||
self::ORDER_FLOW => 'getFlow'
|
||||
);
|
||||
|
||||
if (!is_int($callback) || !isset($methods[$callback])) {
|
||||
throw new InvalidArgumentException('Invalid callback given');
|
||||
}
|
||||
|
||||
$method = $methods[$callback];
|
||||
|
||||
return function (Edge $edge) use ($method) {
|
||||
return $edge->$method();
|
||||
};
|
||||
}
|
||||
}
|
14
vendor/clue/graph/src/Set/EdgesAggregate.php
vendored
Normal file
14
vendor/clue/graph/src/Set/EdgesAggregate.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Set;
|
||||
|
||||
/**
|
||||
* A basic interface for every class that provides access to its Set of Edges
|
||||
*/
|
||||
interface EdgesAggregate
|
||||
{
|
||||
/**
|
||||
* @return Edges
|
||||
*/
|
||||
public function getEdges();
|
||||
}
|
531
vendor/clue/graph/src/Set/Vertices.php
vendored
Normal file
531
vendor/clue/graph/src/Set/Vertices.php
vendored
Normal file
|
@ -0,0 +1,531 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Set;
|
||||
|
||||
use Fhaculty\Graph\Vertex;
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Exception\OutOfBoundsException;
|
||||
use Fhaculty\Graph\Exception\UnderflowException;
|
||||
|
||||
/**
|
||||
* A Set of Vertices
|
||||
*
|
||||
* Contains any number of Vertex instances.
|
||||
*
|
||||
* The Set is a readonly instance and it provides methods to get single Vertex
|
||||
* instances or to get a new Set of Vertices. This way it's safe to pass around
|
||||
* the original Set of Vertices, because it will never be modified.
|
||||
*/
|
||||
class Vertices implements \Countable, \IteratorAggregate, VerticesAggregate
|
||||
{
|
||||
/**
|
||||
* order by vertex ID
|
||||
*
|
||||
* @var int
|
||||
* @see Vertex::getId()
|
||||
*/
|
||||
const ORDER_ID = 1;
|
||||
|
||||
/**
|
||||
* random/shuffled order
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const ORDER_RANDOM = 5;
|
||||
|
||||
/**
|
||||
* order by vertex group
|
||||
*
|
||||
* @var int
|
||||
* @see Vertex::getGroup()
|
||||
*/
|
||||
const ORDER_GROUP = 6;
|
||||
|
||||
protected $vertices = array();
|
||||
|
||||
/**
|
||||
* create new Vertices instance
|
||||
*
|
||||
* You can pass in just about anything that can be expressed as a Set of
|
||||
* Vertices, such as:
|
||||
* - an array of Vertex instances
|
||||
* - any Algorithm that implements the VerticesAggregate interface
|
||||
* - a Graph instance or
|
||||
* - an existing Set of Vertices which will be returned as-is
|
||||
*
|
||||
* @param array|Vertices|VerticesAggregate $vertices
|
||||
* @return Vertices
|
||||
*/
|
||||
public static function factory($vertices)
|
||||
{
|
||||
if ($vertices instanceof VerticesAggregate) {
|
||||
return $vertices->getVertices();
|
||||
}
|
||||
return new self($vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new Vertices instance that references the given source array of Vertex instances
|
||||
*
|
||||
* Any changes in the referenced source array will automatically be
|
||||
* reflected in this Set of Vertices, e.g. if you add a Vertex instance to
|
||||
* the array, it will automatically be included in this Set.
|
||||
*
|
||||
* @param array $verticesArray
|
||||
* @return Vertices
|
||||
*/
|
||||
public static function factoryArrayReference(array &$verticesArray)
|
||||
{
|
||||
$vertices = new static();
|
||||
$vertices->vertices =& $verticesArray;
|
||||
return $vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* instantiate new Set of Vertices
|
||||
*
|
||||
* @param array $vertices
|
||||
*/
|
||||
public function __construct(array $vertices = array())
|
||||
{
|
||||
$this->vertices = $vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* get Vertex with the given vertex $id
|
||||
*
|
||||
* @param int|string $id
|
||||
* @return Vertex
|
||||
* @throws OutOfBoundsException if no Vertex with the given ID exists
|
||||
* @uses self::getVertexMatch()
|
||||
*/
|
||||
public function getVertexId($id)
|
||||
{
|
||||
try {
|
||||
return $this->getVertexMatch($this->getCallbackId($id));
|
||||
}
|
||||
catch (UnderflowException $e) {
|
||||
throw new OutOfBoundsException('Vertex ' . $id . ' does not exist', 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether given vertex ID exists in this set of vertices
|
||||
*
|
||||
* @param int|string $id identifier of Vertex
|
||||
* @return bool
|
||||
* @uses self::hasVertexMatch()
|
||||
*/
|
||||
public function hasVertexId($id)
|
||||
{
|
||||
return $this->hasVertexMatch($this->getCallbackId($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* get array index for given Vertex
|
||||
*
|
||||
* not every set of Vertices represents a map, as such array index and
|
||||
* Vertex ID do not necessarily have to match.
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @throws OutOfBoundsException
|
||||
* @return mixed
|
||||
*/
|
||||
public function getIndexVertex(Vertex $vertex)
|
||||
{
|
||||
$id = array_search($vertex, $this->vertices, true);
|
||||
if ($id === false) {
|
||||
throw new OutOfBoundsException('Given vertex does NOT exist');
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* return first Vertex in this set of Vertices
|
||||
*
|
||||
* some algorithms do not need a particular vertex, but merely a (random)
|
||||
* starting point. this is a convenience function to just pick the first
|
||||
* vertex from the list of known vertices.
|
||||
*
|
||||
* @return Vertex first Vertex in this set of Vertices
|
||||
* @throws UnderflowException if set is empty
|
||||
* @see self::getVertexOrder() if you need to apply ordering first
|
||||
*/
|
||||
public function getVertexFirst()
|
||||
{
|
||||
if (!$this->vertices) {
|
||||
throw new UnderflowException('Does not contain any vertices');
|
||||
}
|
||||
reset($this->vertices);
|
||||
|
||||
return current($this->vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* return last Vertex in this set of Vertices
|
||||
*
|
||||
* @return Vertex last Vertex in this set of Vertices
|
||||
* @throws UnderflowException if set is empty
|
||||
*/
|
||||
public function getVertexLast()
|
||||
{
|
||||
if (!$this->vertices) {
|
||||
throw new UnderflowException('Does not contain any vertices');
|
||||
}
|
||||
end($this->vertices);
|
||||
|
||||
return current($this->vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* return first Vertex that matches the given callback filter function
|
||||
*
|
||||
* @param callable $callbackCheck
|
||||
* @return Vertex
|
||||
* @throws UnderflowException if no Vertex matches the given callback filter function
|
||||
* @uses self::getVertexMatchOrNull()
|
||||
* @see self::getVerticesMatch() if you want to return *all* Vertices that match
|
||||
*/
|
||||
public function getVertexMatch($callbackCheck)
|
||||
{
|
||||
$ret = $this->getVertexMatchOrNull($callbackCheck);
|
||||
if ($ret === null) {
|
||||
throw new UnderflowException('No vertex found');
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks whether there's a Vertex that matches the given callback filter function
|
||||
*
|
||||
* @param callable $callbackCheck
|
||||
* @return bool
|
||||
* @see self::getVertexMatch() to return the Vertex instance that matches the given callback filter function
|
||||
* @uses self::getVertexMatchOrNull()
|
||||
*/
|
||||
public function hasVertexMatch($callbackCheck)
|
||||
{
|
||||
return ($this->getVertexMatchOrNull($callbackCheck) !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a new set of Vertices that match the given callback filter function
|
||||
*
|
||||
* This only keeps Vertex elements if the $callbackCheck returns a bool
|
||||
* true and filters out everything else.
|
||||
*
|
||||
* Vertex index positions will be left unchanged, so if you call this method
|
||||
* on a VerticesMap, it will also return a VerticesMap.
|
||||
*
|
||||
* @param callable $callbackCheck
|
||||
* @return Vertices a new Vertices instance
|
||||
* @see self::getVertexMatch()
|
||||
*/
|
||||
public function getVerticesMatch($callbackCheck)
|
||||
{
|
||||
return new static(array_filter($this->vertices, $callbackCheck));
|
||||
}
|
||||
|
||||
/**
|
||||
* get new Set of Vertices ordered by given criterium $orderBy
|
||||
*
|
||||
* Vertex index positions will be left unchanged, so if you call this method
|
||||
* on a VerticesMap, it will also return a VerticesMap.
|
||||
*
|
||||
* @param int $orderBy criterium to sort by. see Vertex::ORDER_ID, etc.
|
||||
* @param bool $desc whether to return biggest first (true) instead of smallest first (default:false)
|
||||
* @return Vertices a new Vertices set ordered by the given $orderBy criterium
|
||||
* @throws InvalidArgumentException if criterium is unknown
|
||||
* @see self::getVertexOrder()
|
||||
*/
|
||||
public function getVerticesOrder($orderBy, $desc = false)
|
||||
{
|
||||
if ($orderBy === self::ORDER_RANDOM) {
|
||||
// shuffle the vertex positions
|
||||
$keys = array_keys($this->vertices);
|
||||
shuffle($keys);
|
||||
|
||||
// re-order according to shuffled vertex positions
|
||||
$vertices = array();
|
||||
foreach ($keys as $key) {
|
||||
$vertices[$key] = $this->vertices[$key];
|
||||
}
|
||||
|
||||
// create iterator for shuffled array (no need to check DESC flag)
|
||||
return new static($vertices);
|
||||
}
|
||||
|
||||
$callback = $this->getCallback($orderBy);
|
||||
$array = $this->vertices;
|
||||
|
||||
uasort($array, function (Vertex $va, Vertex $vb) use ($callback, $desc) {
|
||||
$ra = $callback($desc ? $vb : $va);
|
||||
$rb = $callback($desc ? $va : $vb);
|
||||
|
||||
if ($ra < $rb) {
|
||||
return -1;
|
||||
} elseif ($ra > $rb) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
return new static($array);
|
||||
}
|
||||
|
||||
/**
|
||||
* get intersection of Vertices with given other Vertices
|
||||
*
|
||||
* The intersection contains all Vertex instances that are present in BOTH
|
||||
* this set of Vertices and the given set of other Vertices.
|
||||
*
|
||||
* Vertex index/keys will be preserved from original array.
|
||||
*
|
||||
* Duplicate Vertex instances will be kept if the corresponding number of
|
||||
* Vertex instances is also found in $otherVertices.
|
||||
*
|
||||
* @param Vertices|Vertex[] $otherVertices
|
||||
* @return Vertices a new Vertices set
|
||||
*/
|
||||
public function getVerticesIntersection($otherVertices)
|
||||
{
|
||||
$otherArray = self::factory($otherVertices)->getVector();
|
||||
|
||||
$vertices = array();
|
||||
foreach ($this->vertices as $vid => $vertex) {
|
||||
$i = array_search($vertex, $otherArray, true);
|
||||
|
||||
if ($i !== false) {
|
||||
// remove from other array in order to check for duplicate matches
|
||||
unset($otherArray[$i]);
|
||||
|
||||
$vertices[$vid] = $vertex;
|
||||
}
|
||||
}
|
||||
|
||||
return new static($vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* get first vertex (optionally ordered by given criterium $by) from given array of vertices
|
||||
*
|
||||
* @param int $orderBy criterium to sort by. see Vertex::ORDER_ID, etc.
|
||||
* @param bool $desc whether to return biggest (true) instead of smallest (default:false)
|
||||
* @return Vertex
|
||||
* @throws InvalidArgumentException if criterium is unknown
|
||||
* @throws UnderflowException if no vertices exist
|
||||
* @see self::getVerticesOrder()
|
||||
*/
|
||||
public function getVertexOrder($orderBy, $desc=false)
|
||||
{
|
||||
if (!$this->vertices) {
|
||||
throw new UnderflowException('No vertex found');
|
||||
}
|
||||
// random order
|
||||
if ($orderBy === self::ORDER_RANDOM) {
|
||||
// just return by random key (no need to check for DESC flag)
|
||||
return $this->vertices[array_rand($this->vertices)];
|
||||
}
|
||||
|
||||
$callback = $this->getCallback($orderBy);
|
||||
|
||||
$ret = NULL;
|
||||
$best = NULL;
|
||||
foreach ($this->vertices as $vertex) {
|
||||
$now = $callback($vertex);
|
||||
|
||||
if ($ret === NULL || ($desc && $now > $best) || (!$desc && $now < $best)) {
|
||||
$ret = $vertex;
|
||||
$best = $now;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* return self reference to Set of Vertices
|
||||
*
|
||||
* @return Vertices
|
||||
* @see self::factory()
|
||||
*/
|
||||
public function getVertices()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get a new set of Vertices where each Vertex is distinct/unique
|
||||
*
|
||||
* @return VerticesMap a new VerticesMap instance
|
||||
* @uses self::getMap()
|
||||
*/
|
||||
public function getVerticesDistinct()
|
||||
{
|
||||
return new VerticesMap($this->getMap());
|
||||
}
|
||||
|
||||
/**
|
||||
* get a mapping array of Vertex ID => Vertex instance and thus remove duplicate vertices
|
||||
*
|
||||
* @return Vertex[] Vertex ID => Vertex instance
|
||||
* @uses Vertex::getId()
|
||||
*/
|
||||
public function getMap()
|
||||
{
|
||||
$vertices = array();
|
||||
foreach ($this->vertices as $vertex) {
|
||||
$vertices[$vertex->getId()] = $vertex;
|
||||
}
|
||||
return $vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* return array of Vertex IDs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getIds()
|
||||
{
|
||||
$ids = array();
|
||||
foreach ($this->vertices as $vertex) {
|
||||
$ids []= $vertex->getId();
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* return array of Vertex instances
|
||||
*
|
||||
* @return Vertex[]
|
||||
*/
|
||||
public function getVector()
|
||||
{
|
||||
return array_values($this->vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* count number of vertices
|
||||
*
|
||||
* @return int
|
||||
* @see self::isEmpty()
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function count()
|
||||
{
|
||||
return count($this->vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this Set of Vertices is empty
|
||||
*
|
||||
* A Set if empty if no single Vertex instance is added. This is faster
|
||||
* than calling `count() === 0`.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return !$this->vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this set contains any duplicate vertex instances
|
||||
*
|
||||
* @return bool
|
||||
* @uses self::getMap()
|
||||
*/
|
||||
public function hasDuplicates()
|
||||
{
|
||||
return (count($this->vertices) !== count($this->getMap()));
|
||||
}
|
||||
|
||||
/**
|
||||
* get Iterator
|
||||
*
|
||||
* This method implements the IteratorAggregate interface and allows this
|
||||
* Set of Vertices to be used in foreach loops.
|
||||
*
|
||||
* @return \IteratorIterator
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function getIterator()
|
||||
{
|
||||
return new \IteratorIterator(new \ArrayIterator($this->vertices));
|
||||
}
|
||||
|
||||
/**
|
||||
* call given $callback on each Vertex and sum their results
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return number
|
||||
* @throws InvalidArgumentException for invalid callbacks
|
||||
* @uses self::getCallback()
|
||||
*/
|
||||
public function getSumCallback($callback)
|
||||
{
|
||||
$callback = $this->getCallback($callback);
|
||||
|
||||
// return array_sum(array_map($callback, $this->vertices));
|
||||
|
||||
$sum = 0;
|
||||
foreach ($this->vertices as $vertex) {
|
||||
$sum += $callback($vertex);
|
||||
}
|
||||
return $sum;
|
||||
}
|
||||
|
||||
private function getCallbackId($id)
|
||||
{
|
||||
return function (Vertex $vertex) use ($id) {
|
||||
return ($vertex->getId() == $id);
|
||||
};
|
||||
}
|
||||
|
||||
private function getVertexMatchOrNull($callbackCheck)
|
||||
{
|
||||
$callbackCheck = $this->getCallback($callbackCheck);
|
||||
|
||||
foreach ($this->vertices as $vertex) {
|
||||
if ($callbackCheck($vertex)) {
|
||||
return $vertex;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get callback/Closure to be called on Vertex instances for given callback identifier
|
||||
*
|
||||
* @param callable|int $callback
|
||||
* @throws InvalidArgumentException
|
||||
* @return callable
|
||||
*/
|
||||
private function getCallback($callback)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
if (is_array($callback)) {
|
||||
$callback = function (Vertex $vertex) use ($callback) {
|
||||
return call_user_func($callback, $vertex);
|
||||
};
|
||||
}
|
||||
return $callback;
|
||||
}
|
||||
|
||||
static $methods = array(
|
||||
self::ORDER_ID => 'getId',
|
||||
self::ORDER_GROUP => 'getGroup'
|
||||
);
|
||||
|
||||
if (!is_int($callback) || !isset($methods[$callback])) {
|
||||
throw new InvalidArgumentException('Invalid callback given');
|
||||
}
|
||||
|
||||
$method = $methods[$callback];
|
||||
|
||||
return function (Vertex $vertex) use ($method) {
|
||||
return $vertex->$method();
|
||||
};
|
||||
}
|
||||
}
|
14
vendor/clue/graph/src/Set/VerticesAggregate.php
vendored
Normal file
14
vendor/clue/graph/src/Set/VerticesAggregate.php
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Set;
|
||||
|
||||
/**
|
||||
* Basic interface for every class that provides access to its Set of Vertices
|
||||
*/
|
||||
interface VerticesAggregate
|
||||
{
|
||||
/**
|
||||
* @return Vertices
|
||||
*/
|
||||
public function getVertices();
|
||||
}
|
67
vendor/clue/graph/src/Set/VerticesMap.php
vendored
Normal file
67
vendor/clue/graph/src/Set/VerticesMap.php
vendored
Normal file
|
@ -0,0 +1,67 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph\Set;
|
||||
|
||||
use Fhaculty\Graph\Exception\OutOfBoundsException;
|
||||
use Fhaculty\Graph\Vertex;
|
||||
|
||||
/**
|
||||
* A set of Vertices that are already stored in a vertex ID => Vertex instance mapping array
|
||||
*
|
||||
* Among others, using a mapped array significantly speeds up accessing vertices
|
||||
* by ID. However, there's no way to store multiple vertices with the same ID
|
||||
* (i.e. each Vertex ID has to be unique).
|
||||
*/
|
||||
class VerticesMap extends Vertices
|
||||
{
|
||||
public function getMap()
|
||||
{
|
||||
return $this->vertices;
|
||||
}
|
||||
|
||||
public function getVertexId($id)
|
||||
{
|
||||
if (!isset($this->vertices[$id])) {
|
||||
throw new OutOfBoundsException('Invalid vertex ID');
|
||||
}
|
||||
return $this->vertices[$id];
|
||||
}
|
||||
|
||||
public function hasVertexId($id)
|
||||
{
|
||||
return isset($this->vertices[$id]);
|
||||
}
|
||||
|
||||
public function getVerticesDistinct()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIds()
|
||||
{
|
||||
return array_keys($this->vertices);
|
||||
}
|
||||
|
||||
public function getIndexVertex(Vertex $vertex)
|
||||
{
|
||||
$id = $vertex->getId();
|
||||
if (!isset($this->vertices[$id]) || $this->vertices[$id] !== $vertex) {
|
||||
throw new OutOfBoundsException();
|
||||
}
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return VerticesMap
|
||||
*/
|
||||
public function getVertices()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hasDuplicates()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
406
vendor/clue/graph/src/Vertex.php
vendored
Normal file
406
vendor/clue/graph/src/Vertex.php
vendored
Normal file
|
@ -0,0 +1,406 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph;
|
||||
|
||||
use Fhaculty\Graph\Attribute\AttributeAware;
|
||||
use Fhaculty\Graph\Attribute\AttributeBagReference;
|
||||
use Fhaculty\Graph\Edge\Base as Edge;
|
||||
use Fhaculty\Graph\Edge\Directed as EdgeDirected;
|
||||
use Fhaculty\Graph\Edge\Undirected as EdgeUndirected;
|
||||
use Fhaculty\Graph\Exception\BadMethodCallException;
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Set\Edges;
|
||||
use Fhaculty\Graph\Set\EdgesAggregate;
|
||||
use Fhaculty\Graph\Set\Vertices;
|
||||
|
||||
class Vertex implements EdgesAggregate, AttributeAware
|
||||
{
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @var Edge[]
|
||||
*/
|
||||
private $edges = array();
|
||||
|
||||
/**
|
||||
* @var Graph
|
||||
*/
|
||||
private $graph;
|
||||
|
||||
/**
|
||||
* vertex balance
|
||||
*
|
||||
* @var int|float|NULL
|
||||
* @see Vertex::setBalance()
|
||||
*/
|
||||
private $balance;
|
||||
|
||||
/**
|
||||
* group number
|
||||
*
|
||||
* @var int
|
||||
* @see Vertex::setGroup()
|
||||
*/
|
||||
private $group = 0;
|
||||
|
||||
private $attributes = array();
|
||||
|
||||
/**
|
||||
* Create a new Vertex
|
||||
*
|
||||
* @param Graph $graph graph to be added to
|
||||
* @param string|int $id identifier used to uniquely identify this vertex in the graph
|
||||
* @see Graph::createVertex() to create new vertices
|
||||
*/
|
||||
public function __construct(Graph $graph, $id)
|
||||
{
|
||||
if (!is_int($id) && !is_string($id)) {
|
||||
throw new InvalidArgumentException('Vertex ID has to be of type integer or string');
|
||||
}
|
||||
|
||||
$this->id = $id;
|
||||
$this->graph = $graph;
|
||||
|
||||
$graph->addVertex($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* get graph this vertex is attached to
|
||||
*
|
||||
* @return Graph
|
||||
*/
|
||||
public function getGraph()
|
||||
{
|
||||
return $this->graph;
|
||||
}
|
||||
|
||||
public function getBalance()
|
||||
{
|
||||
return $this->balance;
|
||||
}
|
||||
|
||||
public function setBalance($balance)
|
||||
{
|
||||
if ($balance !== NULL && !is_float($balance) && !is_int($balance)) {
|
||||
throw new InvalidArgumentException('Invalid balance given - must be numeric');
|
||||
}
|
||||
$this->balance = $balance;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* set group number of this vertex
|
||||
*
|
||||
* @param int $group
|
||||
* @return Vertex $this (chainable)
|
||||
* @throws InvalidArgumentException if group is not numeric
|
||||
*/
|
||||
public function setGroup($group)
|
||||
{
|
||||
if (!is_int($group)) {
|
||||
throw new InvalidArgumentException('Invalid group number');
|
||||
}
|
||||
$this->group = $group;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get group number
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getGroup()
|
||||
{
|
||||
return $this->group;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns id of this Vertex
|
||||
*
|
||||
* @return int|string
|
||||
*/
|
||||
public function getId()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new directed edge from this start vertex to given target vertex
|
||||
*
|
||||
* @param Vertex $vertex target vertex
|
||||
* @return EdgeDirected
|
||||
* @throws InvalidArgumentException
|
||||
* @uses Graph::addEdge()
|
||||
*/
|
||||
public function createEdgeTo(Vertex $vertex)
|
||||
{
|
||||
return new EdgeDirected($this, $vertex);
|
||||
}
|
||||
|
||||
/**
|
||||
* add new undirected (bidirectional) edge between this vertex and given vertex
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @return EdgeUndirected
|
||||
* @throws InvalidArgumentException
|
||||
* @uses Graph::addEdge()
|
||||
*/
|
||||
public function createEdge(Vertex $vertex)
|
||||
{
|
||||
return new EdgeUndirected($this, $vertex);
|
||||
}
|
||||
|
||||
/**
|
||||
* add the given edge to list of connected edges (MUST NOT be called manually)
|
||||
*
|
||||
* @param Edge $edge
|
||||
* @return void
|
||||
* @internal
|
||||
* @see self::createEdge() instead!
|
||||
*/
|
||||
public function addEdge(Edge $edge)
|
||||
{
|
||||
$this->edges[] = $edge;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove the given edge from list of connected edges (MUST NOT be called manually)
|
||||
*
|
||||
* @param Edge $edge
|
||||
* @return void
|
||||
* @throws InvalidArgumentException if given edge does not exist
|
||||
* @internal
|
||||
* @see Edge::destroy() instead!
|
||||
*/
|
||||
public function removeEdge(Edge $edge)
|
||||
{
|
||||
$id = array_search($edge, $this->edges, true);
|
||||
if ($id === false) {
|
||||
throw new InvalidArgumentException('Given edge does NOT exist');
|
||||
}
|
||||
unset($this->edges[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether this vertex has a direct edge to given $vertex
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @return bool
|
||||
* @uses Edge::hasVertexTarget()
|
||||
*/
|
||||
public function hasEdgeTo(Vertex $vertex)
|
||||
{
|
||||
$that = $this;
|
||||
|
||||
return $this->getEdges()->hasEdgeMatch(function (Edge $edge) use ($that, $vertex) {
|
||||
return $edge->isConnection($that, $vertex);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* check whether the given vertex has a direct edge to THIS vertex
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @return bool
|
||||
* @uses Vertex::hasEdgeTo()
|
||||
*/
|
||||
public function hasEdgeFrom(Vertex $vertex)
|
||||
{
|
||||
return $vertex->hasEdgeTo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of ALL Edges attached to this vertex
|
||||
*
|
||||
* @return Edges
|
||||
*/
|
||||
public function getEdges()
|
||||
{
|
||||
return new Edges($this->edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of all outgoing Edges attached to this vertex
|
||||
*
|
||||
* @return Edges
|
||||
*/
|
||||
public function getEdgesOut()
|
||||
{
|
||||
$that = $this;
|
||||
$prev = null;
|
||||
|
||||
return $this->getEdges()->getEdgesMatch(function (Edge $edge) use ($that, &$prev) {
|
||||
$ret = $edge->hasVertexStart($that);
|
||||
|
||||
// skip duplicate directed loop edges
|
||||
if ($edge === $prev && $edge instanceof EdgeDirected) {
|
||||
$ret = false;
|
||||
}
|
||||
$prev = $edge;
|
||||
|
||||
return $ret;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of all ingoing Edges attached to this vertex
|
||||
*
|
||||
* @return Edges
|
||||
*/
|
||||
public function getEdgesIn()
|
||||
{
|
||||
$that = $this;
|
||||
$prev = null;
|
||||
|
||||
return $this->getEdges()->getEdgesMatch(function (Edge $edge) use ($that, &$prev) {
|
||||
$ret = $edge->hasVertexTarget($that);
|
||||
|
||||
// skip duplicate directed loop edges
|
||||
if ($edge === $prev && $edge instanceof EdgeDirected) {
|
||||
$ret = false;
|
||||
}
|
||||
$prev = $edge;
|
||||
|
||||
return $ret;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of Edges FROM this vertex TO the given vertex
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @return Edges
|
||||
* @uses Edge::hasVertexTarget()
|
||||
*/
|
||||
public function getEdgesTo(Vertex $vertex)
|
||||
{
|
||||
$that = $this;
|
||||
|
||||
return $this->getEdges()->getEdgesMatch(function (Edge $edge) use ($that, $vertex) {
|
||||
return $edge->isConnection($that, $vertex);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of Edges FROM the given vertex TO this vertex
|
||||
*
|
||||
* @param Vertex $vertex
|
||||
* @return Edges
|
||||
* @uses Vertex::getEdgesTo()
|
||||
*/
|
||||
public function getEdgesFrom(Vertex $vertex)
|
||||
{
|
||||
return $vertex->getEdgesTo($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of adjacent Vertices of this vertex (edge FROM or TO this vertex)
|
||||
*
|
||||
* If there are multiple parallel edges between the same Vertex, it will be
|
||||
* returned several times in the resulting Set of Vertices. If you only
|
||||
* want unique Vertex instances, use `getVerticesDistinct()`.
|
||||
*
|
||||
* @return Vertices
|
||||
* @uses Edge::hasVertexStart()
|
||||
* @uses Edge::getVerticesToFrom()
|
||||
* @uses Edge::getVerticesFromTo()
|
||||
*/
|
||||
public function getVerticesEdge()
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($this->edges as $edge) {
|
||||
if ($edge->hasVertexStart($this)) {
|
||||
$ret []= $edge->getVertexToFrom($this);
|
||||
} else {
|
||||
$ret []= $edge->getVertexFromTo($this);
|
||||
}
|
||||
}
|
||||
|
||||
return new Vertices($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of all Vertices this vertex has an edge to
|
||||
*
|
||||
* If there are multiple parallel edges to the same Vertex, it will be
|
||||
* returned several times in the resulting Set of Vertices. If you only
|
||||
* want unique Vertex instances, use `getVerticesDistinct()`.
|
||||
*
|
||||
* @return Vertices
|
||||
* @uses Vertex::getEdgesOut()
|
||||
* @uses Edge::getVerticesToFrom()
|
||||
*/
|
||||
public function getVerticesEdgeTo()
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($this->getEdgesOut() as $edge) {
|
||||
$ret []= $edge->getVertexToFrom($this);
|
||||
}
|
||||
|
||||
return new Vertices($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* get set of all Vertices that have an edge TO this vertex
|
||||
*
|
||||
* If there are multiple parallel edges from the same Vertex, it will be
|
||||
* returned several times in the resulting Set of Vertices. If you only
|
||||
* want unique Vertex instances, use `getVerticesDistinct()`.
|
||||
*
|
||||
* @return Vertices
|
||||
* @uses Vertex::getEdgesIn()
|
||||
* @uses Edge::getVerticesFromTo()
|
||||
*/
|
||||
public function getVerticesEdgeFrom()
|
||||
{
|
||||
$ret = array();
|
||||
foreach ($this->getEdgesIn() as $edge) {
|
||||
$ret []= $edge->getVertexFromTo($this);
|
||||
}
|
||||
|
||||
return new Vertices($ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy vertex and all edges connected to it and remove reference from graph
|
||||
*
|
||||
* @uses Edge::destroy()
|
||||
* @uses Graph::removeVertex()
|
||||
*/
|
||||
public function destroy()
|
||||
{
|
||||
foreach ($this->getEdges()->getEdgesDistinct() as $edge) {
|
||||
$edge->destroy();
|
||||
}
|
||||
$this->graph->removeVertex($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* do NOT allow cloning of objects
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new BadMethodCallException();
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
public function getAttribute($name, $default = null)
|
||||
{
|
||||
return isset($this->attributes[$name]) ? $this->attributes[$name] : $default;
|
||||
}
|
||||
|
||||
public function setAttribute($name, $value)
|
||||
{
|
||||
$this->attributes[$name] = $value;
|
||||
}
|
||||
|
||||
public function getAttributeBag()
|
||||
{
|
||||
return new AttributeBagReference($this->attributes);
|
||||
}
|
||||
}
|
311
vendor/clue/graph/src/Walk.php
vendored
Normal file
311
vendor/clue/graph/src/Walk.php
vendored
Normal file
|
@ -0,0 +1,311 @@
|
|||
<?php
|
||||
|
||||
namespace Fhaculty\Graph;
|
||||
|
||||
use Fhaculty\Graph\Set\Edges;
|
||||
use Fhaculty\Graph\Set\Vertices;
|
||||
use Fhaculty\Graph\Edge\Base as Edge;
|
||||
use Fhaculty\Graph\Exception\UnderflowException;
|
||||
use Fhaculty\Graph\Exception\InvalidArgumentException;
|
||||
use Fhaculty\Graph\Set\DualAggregate;
|
||||
|
||||
/**
|
||||
* Base Walk class
|
||||
*
|
||||
* The general term "Walk" bundles the following mathematical concepts:
|
||||
* walk, path, cycle, circuit, loop, trail, tour, etc.
|
||||
*
|
||||
* @link http://en.wikipedia.org/wiki/Path_%28graph_theory%29
|
||||
* @link http://en.wikipedia.org/wiki/Glossary_of_graph_theory#Walks
|
||||
* @see Fhaculty\Graph\Algorithm\Property\WalkProperty for checking special cases, such as cycles, loops, closed trails, etc.
|
||||
*/
|
||||
class Walk implements DualAggregate
|
||||
{
|
||||
/**
|
||||
* construct new walk from given start vertex and given array of edges
|
||||
*
|
||||
* @param Edges|Edge[] $edges
|
||||
* @param Vertex $startVertex
|
||||
* @return Walk
|
||||
*/
|
||||
public static function factoryFromEdges($edges, Vertex $startVertex)
|
||||
{
|
||||
$vertices = array($startVertex);
|
||||
$vertexCurrent = $startVertex;
|
||||
foreach ($edges as $edge) {
|
||||
$vertexCurrent = $edge->getVertexToFrom($vertexCurrent);
|
||||
$vertices []= $vertexCurrent;
|
||||
}
|
||||
|
||||
return new self($vertices, $edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new walk instance between given set of Vertices / array of Vertex instances
|
||||
*
|
||||
* @param Vertices|Vertex[] $vertices
|
||||
* @param int|null $by
|
||||
* @param bool $desc
|
||||
* @return Walk
|
||||
* @throws UnderflowException if no vertices were given
|
||||
* @see Edges::getEdgeOrder() for parameters $by and $desc
|
||||
*/
|
||||
public static function factoryFromVertices($vertices, $by = null, $desc = false)
|
||||
{
|
||||
$edges = array();
|
||||
$last = NULL;
|
||||
foreach ($vertices as $vertex) {
|
||||
// skip first vertex as last is unknown
|
||||
if ($last !== NULL) {
|
||||
// pick edge between last vertex and this vertex
|
||||
/* @var $last Vertex */
|
||||
if ($by === null) {
|
||||
$edges []= $last->getEdgesTo($vertex)->getEdgeFirst();
|
||||
} else {
|
||||
$edges []= $last->getEdgesTo($vertex)->getEdgeOrder($by, $desc);
|
||||
}
|
||||
}
|
||||
$last = $vertex;
|
||||
}
|
||||
if ($last === NULL) {
|
||||
throw new UnderflowException('No vertices given');
|
||||
}
|
||||
|
||||
return new self($vertices, $edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new cycle instance from given predecessor map
|
||||
*
|
||||
* @param Vertex[] $predecessors map of vid => predecessor vertex instance
|
||||
* @param Vertex $vertex start vertex to search predecessors from
|
||||
* @param int|null $by
|
||||
* @param bool $desc
|
||||
* @return Walk
|
||||
* @throws UnderflowException
|
||||
* @see Edges::getEdgeOrder() for parameters $by and $desc
|
||||
* @uses self::factoryFromVertices()
|
||||
*/
|
||||
public static function factoryCycleFromPredecessorMap(array $predecessors, Vertex $vertex, $by = null, $desc = false)
|
||||
{
|
||||
// find a vertex in the cycle
|
||||
$vid = $vertex->getId();
|
||||
$startVertices = array();
|
||||
do {
|
||||
if (!isset($predecessors[$vid])) {
|
||||
throw new InvalidArgumentException('Predecessor map is incomplete and does not form a cycle');
|
||||
}
|
||||
|
||||
$startVertices[$vid] = $vertex;
|
||||
|
||||
$vertex = $predecessors[$vid];
|
||||
$vid = $vertex->getId();
|
||||
} while (!isset($startVertices[$vid]));
|
||||
|
||||
// find negative cycle
|
||||
$vid = $vertex->getId();
|
||||
// build array of vertices in cycle
|
||||
$vertices = array();
|
||||
do {
|
||||
// add new vertex to cycle
|
||||
$vertices[$vid] = $vertex;
|
||||
|
||||
// get predecessor of vertex
|
||||
$vertex = $predecessors[$vid];
|
||||
$vid = $vertex->getId();
|
||||
// continue until we find a vertex that's already in the circle (i.e. circle is closed)
|
||||
} while (!isset($vertices[$vid]));
|
||||
|
||||
// reverse cycle, because cycle is actually built in opposite direction due to checking predecessors
|
||||
$vertices = array_reverse($vertices, true);
|
||||
|
||||
// additional edge from last vertex to first vertex
|
||||
$vertices[] = reset($vertices);
|
||||
|
||||
return self::factoryCycleFromVertices($vertices, $by, $desc);
|
||||
}
|
||||
|
||||
/**
|
||||
* create new cycle instance with edges between given vertices
|
||||
*
|
||||
* @param Vertex[]|Vertices $vertices
|
||||
* @param int|null $by
|
||||
* @param bool $desc
|
||||
* @return Walk
|
||||
* @throws UnderflowException if no vertices were given
|
||||
* @see Edges::getEdgeOrder() for parameters $by and $desc
|
||||
* @uses self::factoryFromVertices()
|
||||
*/
|
||||
public static function factoryCycleFromVertices($vertices, $by = null, $desc = false)
|
||||
{
|
||||
$cycle = self::factoryFromVertices($vertices, $by, $desc);
|
||||
|
||||
if ($cycle->getEdges()->isEmpty()) {
|
||||
throw new InvalidArgumentException('Cycle with no edges can not exist');
|
||||
}
|
||||
|
||||
if ($cycle->getVertices()->getVertexFirst() !== $cycle->getVertices()->getVertexLast()) {
|
||||
throw new InvalidArgumentException('Cycle has to start and end at the same vertex');
|
||||
}
|
||||
|
||||
return $cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new cycle instance with vertices connected by given edges
|
||||
*
|
||||
* @param Edges|Edge[] $edges
|
||||
* @param Vertex $startVertex
|
||||
* @return Walk
|
||||
* @throws InvalidArgumentException if the given array of edges does not represent a valid cycle
|
||||
* @uses self::factoryFromEdges()
|
||||
*/
|
||||
public static function factoryCycleFromEdges($edges, Vertex $startVertex)
|
||||
{
|
||||
$cycle = self::factoryFromEdges($edges, $startVertex);
|
||||
|
||||
// ensure this walk is actually a cycle by checking start = end
|
||||
if ($cycle->getVertices()->getVertexLast() !== $startVertex) {
|
||||
throw new InvalidArgumentException('The given array of edges does not represent a cycle');
|
||||
}
|
||||
|
||||
return $cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Vertices
|
||||
*/
|
||||
protected $vertices;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Edges
|
||||
*/
|
||||
protected $edges;
|
||||
|
||||
protected function __construct($vertices, $edges)
|
||||
{
|
||||
$this->vertices = Vertices::factory($vertices);
|
||||
$this->edges = Edges::factory($edges);
|
||||
}
|
||||
|
||||
/**
|
||||
* return original graph
|
||||
*
|
||||
* @return Graph
|
||||
* @uses self::getVertices()
|
||||
* @uses Vertices::getVertexFirst()
|
||||
* @uses Vertex::getGraph()
|
||||
*/
|
||||
public function getGraph()
|
||||
{
|
||||
return $this->getVertices()->getVertexFirst()->getGraph();
|
||||
}
|
||||
|
||||
/**
|
||||
* create new graph clone with only vertices and edges actually in the walk
|
||||
*
|
||||
* do not add duplicate vertices and edges for loops and intersections, etc.
|
||||
*
|
||||
* @return Graph
|
||||
* @uses Walk::getEdges()
|
||||
* @uses Graph::createGraphCloneEdges()
|
||||
*/
|
||||
public function createGraph()
|
||||
{
|
||||
// create new graph clone with only edges of walk
|
||||
$graph = $this->getGraph()->createGraphCloneEdges($this->getEdges());
|
||||
$vertices = $this->getVertices()->getMap();
|
||||
// get all vertices
|
||||
foreach ($graph->getVertices()->getMap() as $vid => $vertex) {
|
||||
if (!isset($vertices[$vid])) {
|
||||
// remove those not present in the walk (isolated vertices, etc.)
|
||||
$vertex->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
return $graph;
|
||||
}
|
||||
|
||||
/**
|
||||
* return set of all Edges of walk (in sequence visited in walk, may contain duplicates)
|
||||
*
|
||||
* If you need to return set a of all unique Edges of walk, use
|
||||
* `Walk::getEdges()->getEdgesDistinct()` instead.
|
||||
*
|
||||
* @return Edges
|
||||
*/
|
||||
public function getEdges()
|
||||
{
|
||||
return $this->edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* return set of all Vertices of walk (in sequence visited in walk, may contain duplicates)
|
||||
*
|
||||
* If you need to return set a of all unique Vertices of walk, use
|
||||
* `Walk::getVertices()->getVerticesDistinct()` instead.
|
||||
*
|
||||
* If you need to return the source vertex (first vertex of walk), use
|
||||
* `Walk::getVertices()->getVertexFirst()` instead.
|
||||
*
|
||||
* If you need to return the target/destination vertex (last vertex of walk), use
|
||||
* `Walk::getVertices()->getVertexLast()` instead.
|
||||
*
|
||||
* @return Vertices
|
||||
*/
|
||||
public function getVertices()
|
||||
{
|
||||
return $this->vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* get alternating sequence of vertex, edge, vertex, edge, ..., vertex
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAlternatingSequence()
|
||||
{
|
||||
$edges = $this->edges->getVector();
|
||||
$vertices = $this->vertices->getVector();
|
||||
|
||||
$ret = array();
|
||||
for ($i = 0, $l = count($this->edges); $i < $l; ++$i) {
|
||||
$ret []= $vertices[$i];
|
||||
$ret []= $edges[$i];
|
||||
}
|
||||
$ret[] = $vertices[$i];
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* check to make sure this walk is still valid (i.e. source graph still contains all vertices and edges)
|
||||
*
|
||||
* @return bool
|
||||
* @uses Walk::getGraph()
|
||||
* @uses Graph::getVertices()
|
||||
* @uses Graph::getEdges()
|
||||
*/
|
||||
public function isValid()
|
||||
{
|
||||
$vertices = $this->getGraph()->getVertices()->getMap();
|
||||
// check source graph contains all vertices
|
||||
foreach ($this->getVertices()->getMap() as $vid => $vertex) {
|
||||
// make sure vertex ID exists and has not been replaced
|
||||
if (!isset($vertices[$vid]) || $vertices[$vid] !== $vertex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$edges = $this->getGraph()->getEdges()->getVector();
|
||||
// check source graph contains all edges
|
||||
foreach ($this->edges as $edge) {
|
||||
if (!in_array($edge, $edges, true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
43
vendor/composer/ClassLoader.php
vendored
43
vendor/composer/ClassLoader.php
vendored
|
@ -42,9 +42,6 @@ namespace Composer\Autoload;
|
|||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var \Closure(string):void */
|
||||
private static $includeFile;
|
||||
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
|
@ -109,7 +106,6 @@ class ClassLoader
|
|||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
self::initializeIncludeClosure();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -429,8 +425,7 @@ class ClassLoader
|
|||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -560,26 +555,18 @@ class ClassLoader
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
* @private
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
|
|
14
vendor/composer/InstalledVersions.php
vendored
14
vendor/composer/InstalledVersions.php
vendored
|
@ -28,7 +28,7 @@ class InstalledVersions
|
|||
{
|
||||
/**
|
||||
* @var mixed[]|null
|
||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
|
||||
*/
|
||||
private static $installed;
|
||||
|
||||
|
@ -39,7 +39,7 @@ class InstalledVersions
|
|||
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
private static $installedByVendor = array();
|
||||
|
||||
|
@ -243,7 +243,7 @@ class InstalledVersions
|
|||
|
||||
/**
|
||||
* @return array
|
||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
|
||||
*/
|
||||
public static function getRootPackage()
|
||||
{
|
||||
|
@ -257,7 +257,7 @@ class InstalledVersions
|
|||
*
|
||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||
* @return array[]
|
||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
|
||||
*/
|
||||
public static function getRawData()
|
||||
{
|
||||
|
@ -280,7 +280,7 @@ class InstalledVersions
|
|||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||
*
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
public static function getAllRawData()
|
||||
{
|
||||
|
@ -303,7 +303,7 @@ class InstalledVersions
|
|||
* @param array[] $data A vendor/composer/installed.php data set
|
||||
* @return void
|
||||
*
|
||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
|
||||
*/
|
||||
public static function reload($data)
|
||||
{
|
||||
|
@ -313,7 +313,7 @@ class InstalledVersions
|
|||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
|
||||
*/
|
||||
private static function getInstalled()
|
||||
{
|
||||
|
|
27
vendor/composer/autoload_real.php
vendored
27
vendor/composer/autoload_real.php
vendored
|
@ -31,18 +31,25 @@ class ComposerAutoloaderInitc3a61dba26daada128f5891f1a57c504
|
|||
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInitc3a61dba26daada128f5891f1a57c504::$files;
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
$requireFile($fileIdentifier, $file);
|
||||
$includeFiles = \Composer\Autoload\ComposerStaticInitc3a61dba26daada128f5891f1a57c504::$files;
|
||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||
composerRequirec3a61dba26daada128f5891f1a57c504($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileIdentifier
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
function composerRequirec3a61dba26daada128f5891f1a57c504($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
}
|
||||
|
|
28
vendor/composer/installed.json
vendored
28
vendor/composer/installed.json
vendored
|
@ -283,17 +283,17 @@
|
|||
},
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
"version": "3.258.10",
|
||||
"version_normalized": "3.258.10.0",
|
||||
"version": "3.258.12",
|
||||
"version_normalized": "3.258.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/aws/aws-sdk-php.git",
|
||||
"reference": "e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337"
|
||||
"reference": "43ee875456822ee7772cfc51da57bfa558ccb30c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337",
|
||||
"reference": "e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337",
|
||||
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/43ee875456822ee7772cfc51da57bfa558ccb30c",
|
||||
"reference": "43ee875456822ee7772cfc51da57bfa558ccb30c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -333,7 +333,7 @@
|
|||
"ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages",
|
||||
"ext-sockets": "To use client-side monitoring"
|
||||
},
|
||||
"time": "2023-02-14T19:21:16+00:00",
|
||||
"time": "2023-02-16T19:21:12+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
@ -374,7 +374,7 @@
|
|||
"support": {
|
||||
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
|
||||
"issues": "https://github.com/aws/aws-sdk-php/issues",
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.258.10"
|
||||
"source": "https://github.com/aws/aws-sdk-php/tree/3.258.12"
|
||||
},
|
||||
"install-path": "../aws/aws-sdk-php"
|
||||
},
|
||||
|
@ -4219,17 +4219,17 @@
|
|||
},
|
||||
{
|
||||
"name": "stripe/stripe-php",
|
||||
"version": "v10.5.0",
|
||||
"version_normalized": "10.5.0.0",
|
||||
"version": "v10.6.0",
|
||||
"version_normalized": "10.6.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/stripe/stripe-php.git",
|
||||
"reference": "331415b232d60d7c0449de7bde4cb7d4fedf982e"
|
||||
"reference": "5fc46f43c743c715cb5edeb7be3383efb7b4bb2e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/331415b232d60d7c0449de7bde4cb7d4fedf982e",
|
||||
"reference": "331415b232d60d7c0449de7bde4cb7d4fedf982e",
|
||||
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/5fc46f43c743c715cb5edeb7be3383efb7b4bb2e",
|
||||
"reference": "5fc46f43c743c715cb5edeb7be3383efb7b4bb2e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4245,7 +4245,7 @@
|
|||
"phpunit/phpunit": "^5.7 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.3"
|
||||
},
|
||||
"time": "2023-02-02T21:02:09+00:00",
|
||||
"time": "2023-02-16T23:01:54+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
|
@ -4277,7 +4277,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/stripe/stripe-php/issues",
|
||||
"source": "https://github.com/stripe/stripe-php/tree/v10.5.0"
|
||||
"source": "https://github.com/stripe/stripe-php/tree/v10.6.0"
|
||||
},
|
||||
"install-path": "../stripe/stripe-php"
|
||||
},
|
||||
|
|
184
vendor/composer/installed.php
vendored
184
vendor/composer/installed.php
vendored
|
@ -1,328 +1,328 @@
|
|||
<?php return array(
|
||||
'root' => array(
|
||||
'name' => 'wwbn/avideo',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '12049cba3aca6bee3afa9171482be6456f692f4c',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f0314f6e4ea30d9f762110d1d0005edb51a2c42c',
|
||||
'name' => 'wwbn/avideo',
|
||||
'dev' => true,
|
||||
),
|
||||
'versions' => array(
|
||||
'abraham/twitteroauth' => array(
|
||||
'pretty_version' => '3.1.0',
|
||||
'version' => '3.1.0.0',
|
||||
'reference' => '51a502cde3c4f414ea0f98827afbeca1f19dfe2d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../abraham/twitteroauth',
|
||||
'aliases' => array(),
|
||||
'reference' => '51a502cde3c4f414ea0f98827afbeca1f19dfe2d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'amphp/amp' => array(
|
||||
'pretty_version' => 'v2.6.2',
|
||||
'version' => '2.6.2.0',
|
||||
'reference' => '9d5100cebffa729aaffecd3ad25dc5aeea4f13bb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../amphp/amp',
|
||||
'aliases' => array(),
|
||||
'reference' => '9d5100cebffa729aaffecd3ad25dc5aeea4f13bb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ankitpokhrel/tus-php' => array(
|
||||
'pretty_version' => 'v2.3.0',
|
||||
'version' => '2.3.0.0',
|
||||
'reference' => '20671422b433aa45196f89906acf7c4328043ab8',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ankitpokhrel/tus-php',
|
||||
'aliases' => array(),
|
||||
'reference' => '20671422b433aa45196f89906acf7c4328043ab8',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'aws/aws-crt-php' => array(
|
||||
'pretty_version' => 'v1.0.4',
|
||||
'version' => '1.0.4.0',
|
||||
'reference' => 'f5c64ee7c5fce196e2519b3d9b7138649efe032d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../aws/aws-crt-php',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f5c64ee7c5fce196e2519b3d9b7138649efe032d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'aws/aws-sdk-php' => array(
|
||||
'pretty_version' => '3.258.10',
|
||||
'version' => '3.258.10.0',
|
||||
'reference' => 'e164c9c5faf3965bd27ff2a4e9b7b3048ba8a337',
|
||||
'pretty_version' => '3.258.12',
|
||||
'version' => '3.258.12.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../aws/aws-sdk-php',
|
||||
'aliases' => array(),
|
||||
'reference' => '43ee875456822ee7772cfc51da57bfa558ccb30c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'brick/math' => array(
|
||||
'pretty_version' => '0.9.3',
|
||||
'version' => '0.9.3.0',
|
||||
'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../brick/math',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'cboden/ratchet' => array(
|
||||
'pretty_version' => 'v0.4.4',
|
||||
'version' => '0.4.4.0',
|
||||
'reference' => '5012dc954541b40c5599d286fd40653f5716a38f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../cboden/ratchet',
|
||||
'aliases' => array(),
|
||||
'reference' => '5012dc954541b40c5599d286fd40653f5716a38f',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'chrisjean/php-ico' => array(
|
||||
'pretty_version' => '1.0.4',
|
||||
'version' => '1.0.4.0',
|
||||
'reference' => 'ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../chrisjean/php-ico',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ccd5c0d56554f3ddcd7a823e695be83e0d1e43b6',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'composer/ca-bundle' => array(
|
||||
'pretty_version' => '1.3.5',
|
||||
'version' => '1.3.5.0',
|
||||
'reference' => '74780ccf8c19d6acb8d65c5f39cd72110e132bbd',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/./ca-bundle',
|
||||
'aliases' => array(),
|
||||
'reference' => '74780ccf8c19d6acb8d65c5f39cd72110e132bbd',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'emojione/assets' => array(
|
||||
'pretty_version' => '4.5',
|
||||
'version' => '4.5.0.0',
|
||||
'reference' => '88478c659a64af0176c7b0cd0778f1f9cb8f916f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../emojione/assets',
|
||||
'aliases' => array(),
|
||||
'reference' => '88478c659a64af0176c7b0cd0778f1f9cb8f916f',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'emojione/emojione' => array(
|
||||
'pretty_version' => '4.5.0',
|
||||
'version' => '4.5.0.0',
|
||||
'reference' => '79e685356877cbb6128074a71b7f88f435b58412',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../emojione/emojione',
|
||||
'aliases' => array(),
|
||||
'reference' => '79e685356877cbb6128074a71b7f88f435b58412',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'evenement/evenement' => array(
|
||||
'pretty_version' => 'v3.0.1',
|
||||
'version' => '3.0.1.0',
|
||||
'reference' => '531bfb9d15f8aa57454f5f0285b18bec903b8fb7',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../evenement/evenement',
|
||||
'aliases' => array(),
|
||||
'reference' => '531bfb9d15f8aa57454f5f0285b18bec903b8fb7',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ezyang/htmlpurifier' => array(
|
||||
'pretty_version' => 'v4.16.0',
|
||||
'version' => '4.16.0.0',
|
||||
'reference' => '523407fb06eb9e5f3d59889b3978d5bfe94299c8',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
|
||||
'aliases' => array(),
|
||||
'reference' => '523407fb06eb9e5f3d59889b3978d5bfe94299c8',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'firebase/php-jwt' => array(
|
||||
'pretty_version' => 'v6.4.0',
|
||||
'version' => '6.4.0.0',
|
||||
'reference' => '4dd1e007f22a927ac77da5a3fbb067b42d3bc224',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../firebase/php-jwt',
|
||||
'aliases' => array(),
|
||||
'reference' => '4dd1e007f22a927ac77da5a3fbb067b42d3bc224',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'gliterd/backblaze-b2' => array(
|
||||
'pretty_version' => '1.5.4',
|
||||
'version' => '1.5.4.0',
|
||||
'reference' => '3abcf1ae5b093199c230d4ad82d64fb16ea4fd1a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../gliterd/backblaze-b2',
|
||||
'aliases' => array(),
|
||||
'reference' => '3abcf1ae5b093199c230d4ad82d64fb16ea4fd1a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'google/apiclient' => array(
|
||||
'pretty_version' => 'v2.13.0',
|
||||
'version' => '2.13.0.0',
|
||||
'reference' => 'b653a338c5a658adf6df4bb2f44c2cc02fe7eb1d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../google/apiclient',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b653a338c5a658adf6df4bb2f44c2cc02fe7eb1d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'google/apiclient-services' => array(
|
||||
'pretty_version' => 'v0.287.0',
|
||||
'version' => '0.287.0.0',
|
||||
'reference' => 'ed58596d34272a5cd0dc2c0595d9a678b9834880',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../google/apiclient-services',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ed58596d34272a5cd0dc2c0595d9a678b9834880',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'google/auth' => array(
|
||||
'pretty_version' => 'v1.25.0',
|
||||
'version' => '1.25.0.0',
|
||||
'reference' => '0865c44ab50378f7b145827dfcbd1e7a238f7759',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../google/auth',
|
||||
'aliases' => array(),
|
||||
'reference' => '0865c44ab50378f7b145827dfcbd1e7a238f7759',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/guzzle' => array(
|
||||
'pretty_version' => '7.5.0',
|
||||
'version' => '7.5.0.0',
|
||||
'reference' => 'b50a2a1251152e43f6a37f0fa053e730a67d25ba',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/guzzle',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b50a2a1251152e43f6a37f0fa053e730a67d25ba',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/promises' => array(
|
||||
'pretty_version' => '1.5.2',
|
||||
'version' => '1.5.2.0',
|
||||
'reference' => 'b94b2807d85443f9719887892882d0329d1e2598',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/promises',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b94b2807d85443f9719887892882d0329d1e2598',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'guzzlehttp/psr7' => array(
|
||||
'pretty_version' => '2.4.3',
|
||||
'version' => '2.4.3.0',
|
||||
'reference' => '67c26b443f348a51926030c83481b85718457d3d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
|
||||
'aliases' => array(),
|
||||
'reference' => '67c26b443f348a51926030c83481b85718457d3d',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'hybridauth/hybridauth' => array(
|
||||
'pretty_version' => 'v3.8.2',
|
||||
'version' => '3.8.2.0',
|
||||
'reference' => '0d6e31482c544e5ed2bdc83bd3c033054129c482',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../hybridauth/hybridauth',
|
||||
'aliases' => array(),
|
||||
'reference' => '0d6e31482c544e5ed2bdc83bd3c033054129c482',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'james-heinrich/getid3' => array(
|
||||
'pretty_version' => 'v1.9.22',
|
||||
'version' => '1.9.22.0',
|
||||
'reference' => '45f20faa0f0a24489740392c5b512ddcc36deccd',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../james-heinrich/getid3',
|
||||
'aliases' => array(),
|
||||
'reference' => '45f20faa0f0a24489740392c5b512ddcc36deccd',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mervick/emojionearea' => array(
|
||||
'pretty_version' => 'v3.4.2',
|
||||
'version' => '3.4.2.0',
|
||||
'reference' => '99129f789f2e7619ce553c038783a13f47cbc846',
|
||||
'type' => 'plugin',
|
||||
'install_path' => __DIR__ . '/../mervick/emojionearea',
|
||||
'aliases' => array(),
|
||||
'reference' => '99129f789f2e7619ce553c038783a13f47cbc846',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'monolog/monolog' => array(
|
||||
'pretty_version' => '2.9.1',
|
||||
'version' => '2.9.1.0',
|
||||
'reference' => 'f259e2b15fb95494c83f52d3caad003bbf5ffaa1',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../monolog/monolog',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f259e2b15fb95494c83f52d3caad003bbf5ffaa1',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'mtdowling/jmespath.php' => array(
|
||||
'pretty_version' => '2.6.1',
|
||||
'version' => '2.6.1.0',
|
||||
'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../mtdowling/jmespath.php',
|
||||
'aliases' => array(),
|
||||
'reference' => '9b87907a81b87bc76d19a7fb2d61e61486ee9edb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nesbot/carbon' => array(
|
||||
'pretty_version' => '2.66.0',
|
||||
'version' => '2.66.0.0',
|
||||
'reference' => '496712849902241f04902033b0441b269effe001',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nesbot/carbon',
|
||||
'aliases' => array(),
|
||||
'reference' => '496712849902241f04902033b0441b269effe001',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'norkunas/onesignal-php-api' => array(
|
||||
'pretty_version' => 'v2.10.0',
|
||||
'version' => '2.10.0.0',
|
||||
'reference' => '6d8539d472bd408e52cf8fd71a8e6f9c7f3b8f80',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../norkunas/onesignal-php-api',
|
||||
'aliases' => array(),
|
||||
'reference' => '6d8539d472bd408e52cf8fd71a8e6f9c7f3b8f80',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'nyholm/psr7' => array(
|
||||
'pretty_version' => '1.5.1',
|
||||
'version' => '1.5.1.0',
|
||||
'reference' => 'f734364e38a876a23be4d906a2a089e1315be18a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../nyholm/psr7',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f734364e38a876a23be4d906a2a089e1315be18a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/constant_time_encoding' => array(
|
||||
'pretty_version' => 'v2.6.3',
|
||||
'version' => '2.6.3.0',
|
||||
'reference' => '58c3f47f650c94ec05a151692652a868995d2938',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paragonie/constant_time_encoding',
|
||||
'aliases' => array(),
|
||||
'reference' => '58c3f47f650c94ec05a151692652a868995d2938',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/random_compat' => array(
|
||||
'pretty_version' => 'v9.99.100',
|
||||
'version' => '9.99.100.0',
|
||||
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paragonie/random_compat',
|
||||
'aliases' => array(),
|
||||
'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paypal/paypal-checkout-sdk' => array(
|
||||
'pretty_version' => '1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => '19992ce7051ff9e47e643f28abb8cc1b3e5f1812',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paypal/paypal-checkout-sdk',
|
||||
'aliases' => array(),
|
||||
'reference' => '19992ce7051ff9e47e643f28abb8cc1b3e5f1812',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paypal/paypal-payouts-sdk' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '3bdafe3d79b08bb4c3467f911adc1601300b7149',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paypal/paypal-payouts-sdk',
|
||||
'aliases' => array(),
|
||||
'reference' => '3bdafe3d79b08bb4c3467f911adc1601300b7149',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paypal/paypalhttp' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '7b09c89c80828e842c79230e7f156b61fbb68d25',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paypal/paypalhttp',
|
||||
'aliases' => array(),
|
||||
'reference' => '7b09c89c80828e842c79230e7f156b61fbb68d25',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paypal/rest-api-sdk-php' => array(
|
||||
'pretty_version' => '1.14.0',
|
||||
'version' => '1.14.0.0',
|
||||
'reference' => '72e2f2466975bf128a31e02b15110180f059fc04',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paypal/rest-api-sdk-php',
|
||||
'aliases' => array(),
|
||||
'reference' => '72e2f2466975bf128a31e02b15110180f059fc04',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'php-http/async-client-implementation' => array(
|
||||
|
@ -340,64 +340,64 @@
|
|||
'php-http/message-factory' => array(
|
||||
'pretty_version' => 'v1.0.2',
|
||||
'version' => '1.0.2.0',
|
||||
'reference' => 'a478cb11f66a6ac48d8954216cfed9aa06a501a1',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../php-http/message-factory',
|
||||
'aliases' => array(),
|
||||
'reference' => 'a478cb11f66a6ac48d8954216cfed9aa06a501a1',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpmailer/phpmailer' => array(
|
||||
'pretty_version' => 'v6.7.1',
|
||||
'version' => '6.7.1.0',
|
||||
'reference' => '49cd7ea3d2563f028d7811f06864a53b1f15ff55',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpmailer/phpmailer',
|
||||
'aliases' => array(),
|
||||
'reference' => '49cd7ea3d2563f028d7811f06864a53b1f15ff55',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'phpseclib/phpseclib' => array(
|
||||
'pretty_version' => '3.0.18',
|
||||
'version' => '3.0.18.0',
|
||||
'reference' => 'f28693d38ba21bb0d9f0c411ee5dae2b178201da',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../phpseclib/phpseclib',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f28693d38ba21bb0d9f0c411ee5dae2b178201da',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'predis/predis' => array(
|
||||
'pretty_version' => 'v2.1.1',
|
||||
'version' => '2.1.1.0',
|
||||
'reference' => 'c5b60884e89630f9518a7919f0566db438f0fc9a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../predis/predis',
|
||||
'aliases' => array(),
|
||||
'reference' => 'c5b60884e89630f9518a7919f0566db438f0fc9a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/cache' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/cache',
|
||||
'aliases' => array(),
|
||||
'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/container' => array(
|
||||
'pretty_version' => '1.1.1',
|
||||
'version' => '1.1.1.0',
|
||||
'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/container',
|
||||
'aliases' => array(),
|
||||
'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/event-dispatcher' => array(
|
||||
'pretty_version' => '1.0.0',
|
||||
'version' => '1.0.0.0',
|
||||
'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/event-dispatcher',
|
||||
'aliases' => array(),
|
||||
'reference' => 'dbefd12671e8a14ec7f180cab83036ed26714bb0',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/event-dispatcher-implementation' => array(
|
||||
|
@ -409,10 +409,10 @@
|
|||
'psr/http-client' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-client',
|
||||
'aliases' => array(),
|
||||
'reference' => '2dfb5f6c5eff0e91e20e913f8c5452ed95b86621',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-client-implementation' => array(
|
||||
|
@ -424,10 +424,10 @@
|
|||
'psr/http-factory' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-factory',
|
||||
'aliases' => array(),
|
||||
'reference' => '12ac7fcd07e5b077433f5f2bee95b3a771bf61be',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-factory-implementation' => array(
|
||||
|
@ -439,10 +439,10 @@
|
|||
'psr/http-message' => array(
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/http-message',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f6561bf28d520154e4b0ec72be95418abe6d9363',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/http-message-implementation' => array(
|
||||
|
@ -454,10 +454,10 @@
|
|||
'psr/log' => array(
|
||||
'pretty_version' => '1.1.4',
|
||||
'version' => '1.1.4.0',
|
||||
'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../psr/log',
|
||||
'aliases' => array(),
|
||||
'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'psr/log-implementation' => array(
|
||||
|
@ -470,109 +470,109 @@
|
|||
'ralouphie/getallheaders' => array(
|
||||
'pretty_version' => '3.0.3',
|
||||
'version' => '3.0.3.0',
|
||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
|
||||
'aliases' => array(),
|
||||
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ramsey/collection' => array(
|
||||
'pretty_version' => '1.2.2',
|
||||
'version' => '1.2.2.0',
|
||||
'reference' => 'cccc74ee5e328031b15640b51056ee8d3bb66c0a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ramsey/collection',
|
||||
'aliases' => array(),
|
||||
'reference' => 'cccc74ee5e328031b15640b51056ee8d3bb66c0a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ramsey/uuid' => array(
|
||||
'pretty_version' => '4.2.3',
|
||||
'version' => '4.2.3.0',
|
||||
'reference' => 'fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ramsey/uuid',
|
||||
'aliases' => array(),
|
||||
'reference' => 'fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ratchet/pawl' => array(
|
||||
'pretty_version' => 'v0.4.1',
|
||||
'version' => '0.4.1.0',
|
||||
'reference' => 'af70198bab77a582b31169d3cc3982bed25c161f',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ratchet/pawl',
|
||||
'aliases' => array(),
|
||||
'reference' => 'af70198bab77a582b31169d3cc3982bed25c161f',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'ratchet/rfc6455' => array(
|
||||
'pretty_version' => 'v0.3.1',
|
||||
'version' => '0.3.1.0',
|
||||
'reference' => '7c964514e93456a52a99a20fcfa0de242a43ccdb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../ratchet/rfc6455',
|
||||
'aliases' => array(),
|
||||
'reference' => '7c964514e93456a52a99a20fcfa0de242a43ccdb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/cache' => array(
|
||||
'pretty_version' => 'v1.2.0',
|
||||
'version' => '1.2.0.0',
|
||||
'reference' => 'd47c472b64aa5608225f47965a484b75c7817d5b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/cache',
|
||||
'aliases' => array(),
|
||||
'reference' => 'd47c472b64aa5608225f47965a484b75c7817d5b',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/dns' => array(
|
||||
'pretty_version' => 'v1.10.0',
|
||||
'version' => '1.10.0.0',
|
||||
'reference' => 'a5427e7dfa47713e438016905605819d101f238c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/dns',
|
||||
'aliases' => array(),
|
||||
'reference' => 'a5427e7dfa47713e438016905605819d101f238c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/event-loop' => array(
|
||||
'pretty_version' => 'v1.3.0',
|
||||
'version' => '1.3.0.0',
|
||||
'reference' => '187fb56f46d424afb6ec4ad089269c72eec2e137',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/event-loop',
|
||||
'aliases' => array(),
|
||||
'reference' => '187fb56f46d424afb6ec4ad089269c72eec2e137',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/promise' => array(
|
||||
'pretty_version' => 'v2.9.0',
|
||||
'version' => '2.9.0.0',
|
||||
'reference' => '234f8fd1023c9158e2314fa9d7d0e6a83db42910',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/promise',
|
||||
'aliases' => array(),
|
||||
'reference' => '234f8fd1023c9158e2314fa9d7d0e6a83db42910',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/promise-timer' => array(
|
||||
'pretty_version' => 'v1.9.0',
|
||||
'version' => '1.9.0.0',
|
||||
'reference' => 'aa7a73c74b8d8c0f622f5982ff7b0351bc29e495',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/promise-timer',
|
||||
'aliases' => array(),
|
||||
'reference' => 'aa7a73c74b8d8c0f622f5982ff7b0351bc29e495',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/socket' => array(
|
||||
'pretty_version' => 'v1.12.0',
|
||||
'version' => '1.12.0.0',
|
||||
'reference' => '81e1b4d7f5450ebd8d2e9a95bb008bb15ca95a7b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/socket',
|
||||
'aliases' => array(),
|
||||
'reference' => '81e1b4d7f5450ebd8d2e9a95bb008bb15ca95a7b',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'react/stream' => array(
|
||||
'pretty_version' => 'v1.2.0',
|
||||
'version' => '1.2.0.0',
|
||||
'reference' => '7a423506ee1903e89f1e08ec5f0ed430ff784ae9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../react/stream',
|
||||
'aliases' => array(),
|
||||
'reference' => '7a423506ee1903e89f1e08ec5f0ed430ff784ae9',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'rhumsaa/uuid' => array(
|
||||
|
@ -584,64 +584,64 @@
|
|||
'scssphp/scssphp' => array(
|
||||
'pretty_version' => 'v1.11.0',
|
||||
'version' => '1.11.0.0',
|
||||
'reference' => '33749d12c2569bb24071f94e9af828662dabb068',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../scssphp/scssphp',
|
||||
'aliases' => array(),
|
||||
'reference' => '33749d12c2569bb24071f94e9af828662dabb068',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'singpolyma/openpgp-php' => array(
|
||||
'pretty_version' => '0.6.0',
|
||||
'version' => '0.6.0.0',
|
||||
'reference' => '1c3bdcd2d9c6113c2d6b768e208e7432a48d3a1e',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../singpolyma/openpgp-php',
|
||||
'aliases' => array(),
|
||||
'reference' => '1c3bdcd2d9c6113c2d6b768e208e7432a48d3a1e',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'stripe/stripe-php' => array(
|
||||
'pretty_version' => 'v10.5.0',
|
||||
'version' => '10.5.0.0',
|
||||
'reference' => '331415b232d60d7c0449de7bde4cb7d4fedf982e',
|
||||
'pretty_version' => 'v10.6.0',
|
||||
'version' => '10.6.0.0',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../stripe/stripe-php',
|
||||
'aliases' => array(),
|
||||
'reference' => '5fc46f43c743c715cb5edeb7be3383efb7b4bb2e',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/console' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => 'dccb8d251a9017d5994c988b034d3e18aaabf740',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/console',
|
||||
'aliases' => array(),
|
||||
'reference' => 'dccb8d251a9017d5994c988b034d3e18aaabf740',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/deprecation-contracts' => array(
|
||||
'pretty_version' => 'v2.5.2',
|
||||
'version' => '2.5.2.0',
|
||||
'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
|
||||
'aliases' => array(),
|
||||
'reference' => 'e8b495ea28c1d97b5e0c121748d6f9b53d075c66',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/event-dispatcher' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => 'abf49cc084c087d94b4cb939c3f3672971784e0c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
|
||||
'aliases' => array(),
|
||||
'reference' => 'abf49cc084c087d94b4cb939c3f3672971784e0c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/event-dispatcher-contracts' => array(
|
||||
'pretty_version' => 'v2.5.2',
|
||||
'version' => '2.5.2.0',
|
||||
'reference' => 'f98b54df6ad059855739db6fcbc2d36995283fe1',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f98b54df6ad059855739db6fcbc2d36995283fe1',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/event-dispatcher-implementation' => array(
|
||||
|
@ -653,19 +653,19 @@
|
|||
'symfony/http-client' => array(
|
||||
'pretty_version' => 'v5.4.20',
|
||||
'version' => '5.4.20.0',
|
||||
'reference' => 'b4d936b657c7952a41e89efd0ddcea51f8c90f34',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-client',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b4d936b657c7952a41e89efd0ddcea51f8c90f34',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-client-contracts' => array(
|
||||
'pretty_version' => 'v2.5.2',
|
||||
'version' => '2.5.2.0',
|
||||
'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-client-contracts',
|
||||
'aliases' => array(),
|
||||
'reference' => 'ba6a9f0e8f3edd190520ee3b9a958596b6ca2e70',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/http-client-implementation' => array(
|
||||
|
@ -677,154 +677,154 @@
|
|||
'symfony/http-foundation' => array(
|
||||
'pretty_version' => 'v5.4.20',
|
||||
'version' => '5.4.20.0',
|
||||
'reference' => 'd0435363362a47c14e9cf50663cb8ffbf491875a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/http-foundation',
|
||||
'aliases' => array(),
|
||||
'reference' => 'd0435363362a47c14e9cf50663cb8ffbf491875a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/mime' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => 'a858429a9c704edc53fe057228cf9ca282ba48eb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/mime',
|
||||
'aliases' => array(),
|
||||
'reference' => 'a858429a9c704edc53fe057228cf9ca282ba48eb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/options-resolver' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => 'b03c99236445492f20c61666e8f7e5d388b078e5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/options-resolver',
|
||||
'aliases' => array(),
|
||||
'reference' => 'b03c99236445492f20c61666e8f7e5d388b078e5',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-ctype' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
|
||||
'aliases' => array(),
|
||||
'reference' => '5bbc823adecdae860bb64756d639ecfec17b050a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-grapheme' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '511a08c03c1960e08a883f4cffcacd219b758354',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
|
||||
'aliases' => array(),
|
||||
'reference' => '511a08c03c1960e08a883f4cffcacd219b758354',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-idn' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '639084e360537a19f9ee352433b84ce831f3d2da',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
|
||||
'aliases' => array(),
|
||||
'reference' => '639084e360537a19f9ee352433b84ce831f3d2da',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-intl-normalizer' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '19bd1e4fcd5b91116f14d8533c57831ed00571b6',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
|
||||
'aliases' => array(),
|
||||
'reference' => '19bd1e4fcd5b91116f14d8533c57831ed00571b6',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-mbstring' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
|
||||
'aliases' => array(),
|
||||
'reference' => '8ad114f6b39e2c98a8b0e3bd907732c207c2b534',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php72' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
|
||||
'aliases' => array(),
|
||||
'reference' => '869329b1e9894268a8a61dabb69153029b7a8c97',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php73' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '9e8ecb5f92152187c4799efd3c96b78ccab18ff9',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php73',
|
||||
'aliases' => array(),
|
||||
'reference' => '9e8ecb5f92152187c4799efd3c96b78ccab18ff9',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php80' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php80',
|
||||
'aliases' => array(),
|
||||
'reference' => '7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php81' => array(
|
||||
'pretty_version' => 'v1.27.0',
|
||||
'version' => '1.27.0.0',
|
||||
'reference' => '707403074c8ea6e2edaf8794b0157a0bfa52157a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/polyfill-php81',
|
||||
'aliases' => array(),
|
||||
'reference' => '707403074c8ea6e2edaf8794b0157a0bfa52157a',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/routing' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => 'df1b28f37c8e78912213c58ef6ab2f2037bbfdc5',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/routing',
|
||||
'aliases' => array(),
|
||||
'reference' => 'df1b28f37c8e78912213c58ef6ab2f2037bbfdc5',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/service-contracts' => array(
|
||||
'pretty_version' => 'v2.5.2',
|
||||
'version' => '2.5.2.0',
|
||||
'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/service-contracts',
|
||||
'aliases' => array(),
|
||||
'reference' => '4b426aac47d6427cc1a1d0f7e2ac724627f5966c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/string' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => '0a01071610fd861cc160dfb7e2682ceec66064cb',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/string',
|
||||
'aliases' => array(),
|
||||
'reference' => '0a01071610fd861cc160dfb7e2682ceec66064cb',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/translation' => array(
|
||||
'pretty_version' => 'v5.4.19',
|
||||
'version' => '5.4.19.0',
|
||||
'reference' => '83d487b13b7fb4c0a6ad079f4e4c9b4525e1b695',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/translation',
|
||||
'aliases' => array(),
|
||||
'reference' => '83d487b13b7fb4c0a6ad079f4e4c9b4525e1b695',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/translation-contracts' => array(
|
||||
'pretty_version' => 'v2.5.2',
|
||||
'version' => '2.5.2.0',
|
||||
'reference' => '136b19dd05cdf0709db6537d058bcab6dd6e2dbe',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../symfony/translation-contracts',
|
||||
'aliases' => array(),
|
||||
'reference' => '136b19dd05cdf0709db6537d058bcab6dd6e2dbe',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/translation-implementation' => array(
|
||||
|
@ -836,19 +836,19 @@
|
|||
'vimeo/vimeo-api' => array(
|
||||
'pretty_version' => '3.0.10',
|
||||
'version' => '3.0.10.0',
|
||||
'reference' => '79885b642594b17f6c356dc949d3e4a58c356c9b',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../vimeo/vimeo-api',
|
||||
'aliases' => array(),
|
||||
'reference' => '79885b642594b17f6c356dc949d3e4a58c356c9b',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'wwbn/avideo' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => '12049cba3aca6bee3afa9171482be6456f692f4c',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
'reference' => 'f0314f6e4ea30d9f762110d1d0005edb51a2c42c',
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
),
|
||||
|
|
19
vendor/composer/pcre/LICENSE
vendored
Normal file
19
vendor/composer/pcre/LICENSE
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (C) 2021 Composer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
134
vendor/composer/pcre/README.md
vendored
Normal file
134
vendor/composer/pcre/README.md
vendored
Normal file
|
@ -0,0 +1,134 @@
|
|||
composer/pcre
|
||||
=============
|
||||
|
||||
PCRE wrapping library that offers type-safe `preg_*` replacements.
|
||||
|
||||
This library gives you a way to ensure `preg_*` functions do not fail silently, returning
|
||||
unexpected `null`s that may not be handled.
|
||||
|
||||
It also makes it easier ot work with static analysis tools like PHPStan or Psalm as it
|
||||
simplifies and reduces the possible return values from all the `preg_*` functions which
|
||||
are quite packed with edge cases.
|
||||
|
||||
This library is a thin wrapper around `preg_*` functions with [some limitations](#restrictions--limitations).
|
||||
If you are looking for a richer API to handle regular expressions have a look at
|
||||
[rawr/t-regx](https://packagist.org/packages/rawr/t-regx) instead.
|
||||
|
||||
[](https://github.com/composer/pcre/actions)
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Install the latest version with:
|
||||
|
||||
```bash
|
||||
$ composer require composer/pcre
|
||||
```
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
* PHP 5.3.2 is required but using the latest version of PHP is highly recommended.
|
||||
|
||||
|
||||
Basic usage
|
||||
-----------
|
||||
|
||||
Instead of:
|
||||
|
||||
```php
|
||||
if (preg_match('{fo+}', $string, $matches)) { ... }
|
||||
if (preg_match('{fo+}', $string, $matches, PREG_OFFSET_CAPTURE)) { ... }
|
||||
if (preg_match_all('{fo+}', $string, $matches)) { ... }
|
||||
$newString = preg_replace('{fo+}', 'bar', $string);
|
||||
$newString = preg_replace_callback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);
|
||||
$newString = preg_replace_callback_array(['{fo+}' => fn ($match) => strtoupper($match[0])], $string);
|
||||
$filtered = preg_grep('{[a-z]}', $elements);
|
||||
$array = preg_split('{[a-z]+}', $string);
|
||||
```
|
||||
|
||||
You can now call these on the `Preg` class:
|
||||
|
||||
```php
|
||||
use Composer\Pcre\Preg;
|
||||
|
||||
if (Preg::match('{fo+}', $string, $matches)) { ... }
|
||||
if (Preg::matchWithOffsets('{fo+}', $string, $matches)) { ... }
|
||||
if (Preg::matchAll('{fo+}', $string, $matches)) { ... }
|
||||
$newString = Preg::replace('{fo+}', 'bar', $string);
|
||||
$newString = Preg::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string);
|
||||
$newString = Preg::replaceCallbackArray(['{fo+}' => fn ($match) => strtoupper($match[0])], $string);
|
||||
$filtered = Preg::grep('{[a-z]}', $elements);
|
||||
$array = Preg::split('{[a-z]+}', $string);
|
||||
```
|
||||
|
||||
The main difference is if anything fails to match/replace/.., it will throw a `Composer\Pcre\PcreException`
|
||||
instead of returning `null` (or false in some cases), so you can now use the return values safely relying on
|
||||
the fact that they can only be strings (for replace), ints (for match) or arrays (for grep/split).
|
||||
|
||||
Additionally the `Preg` class provides match methods that return `bool` rather than `int`, for stricter type safety
|
||||
when the number of pattern matches is not useful:
|
||||
|
||||
```php
|
||||
use Composer\Pcre\Preg;
|
||||
|
||||
if (Preg::isMatch('{fo+}', $string, $matches)) // bool
|
||||
if (Preg::isMatchAll('{fo+}', $string, $matches)) // bool
|
||||
```
|
||||
|
||||
If you would prefer a slightly more verbose usage, replacing by-ref arguments by result objects, you can use the `Regex` class:
|
||||
|
||||
```php
|
||||
use Composer\Pcre\Regex;
|
||||
|
||||
// this is useful when you are just interested in knowing if something matched
|
||||
// as it returns a bool instead of int(1/0) for match
|
||||
$bool = Regex::isMatch('{fo+}', $string);
|
||||
|
||||
$result = Regex::match('{fo+}', $string);
|
||||
if ($result->matched) { something($result->matches); }
|
||||
|
||||
$result = Regex::matchWithOffsets('{fo+}', $string);
|
||||
if ($result->matched) { something($result->matches); }
|
||||
|
||||
$result = Regex::matchAll('{fo+}', $string);
|
||||
if ($result->matched && $result->count > 3) { something($result->matches); }
|
||||
|
||||
$newString = Regex::replace('{fo+}', 'bar', $string)->result;
|
||||
$newString = Regex::replaceCallback('{fo+}', function ($match) { return strtoupper($match[0]); }, $string)->result;
|
||||
$newString = Regex::replaceCallbackArray(['{fo+}' => fn ($match) => strtoupper($match[0])], $string)->result;
|
||||
```
|
||||
|
||||
Note that `preg_grep` and `preg_split` are only callable via the `Preg` class as they do not have
|
||||
complex return types warranting a specific result object.
|
||||
|
||||
See the [MatchResult](src/MatchResult.php), [MatchWithOffsetsResult](src/MatchWithOffsetsResult.php), [MatchAllResult](src/MatchAllResult.php),
|
||||
[MatchAllWithOffsetsResult](src/MatchAllWithOffsetsResult.php), and [ReplaceResult](src/ReplaceResult.php) class sources for more details.
|
||||
|
||||
Restrictions / Limitations
|
||||
--------------------------
|
||||
|
||||
Due to type safety requirements a few restrictions are in place.matchWithOffsets
|
||||
|
||||
- matching using `PREG_OFFSET_CAPTURE` is made available via `matchWithOffsets` and `matchAllWithOffsets`.
|
||||
You cannot pass the flag to `match`/`matchAll`.
|
||||
- `Preg::split` will also reject `PREG_SPLIT_OFFSET_CAPTURE` and you should use `splitWithOffsets`
|
||||
instead.
|
||||
- `matchAll` rejects `PREG_SET_ORDER` as it also changes the shape of the returned matches. There
|
||||
is no alternative provided as you can fairly easily code around it.
|
||||
- `preg_filter` is not supported as it has a rather crazy API, most likely you should rather
|
||||
use `Preg::grep` in combination with some loop and `Preg::replace`.
|
||||
- `replace`, `replaceCallback` and `replaceCallbackArray` do not support an array `$subject`,
|
||||
only simple strings.
|
||||
- in 2.x, we plan to always implicitly use `PREG_UNMATCHED_AS_NULL` for matching, which offers much
|
||||
saner/predictable results. This is currently not doable due to the PHP version requirement and to
|
||||
keep things working the same across all PHP versions. If you use the library on a PHP 7.2+ project
|
||||
however we highly recommend using `PREG_UNMATCHED_AS_NULL` with all `match*` and `replaceCallback*`
|
||||
methods.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
composer/pcre is licensed under the MIT License, see the LICENSE file for details.
|
46
vendor/composer/pcre/composer.json
vendored
Normal file
46
vendor/composer/pcre/composer.json
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "composer/pcre",
|
||||
"description": "PCRE wrapping library that offers type-safe preg_* replacements.",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"pcre",
|
||||
"regex",
|
||||
"preg",
|
||||
"regular expression"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5",
|
||||
"phpstan/phpstan": "^1.3",
|
||||
"phpstan/phpstan-strict-rules": "^1.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Composer\\Pcre\\": "tests"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.x-dev"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "SYMFONY_PHPUNIT_REMOVE_RETURN_TYPEHINT=1 vendor/bin/simple-phpunit",
|
||||
"phpstan": "phpstan analyse"
|
||||
}
|
||||
}
|
46
vendor/composer/pcre/src/MatchAllResult.php
vendored
Normal file
46
vendor/composer/pcre/src/MatchAllResult.php
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
final class MatchAllResult
|
||||
{
|
||||
/**
|
||||
* An array of match group => list of matched strings
|
||||
*
|
||||
* @readonly
|
||||
* @var array<int|string, list<string|null>>
|
||||
*/
|
||||
public $matches;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var 0|positive-int
|
||||
*/
|
||||
public $count;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var bool
|
||||
*/
|
||||
public $matched;
|
||||
|
||||
/**
|
||||
* @param 0|positive-int $count
|
||||
* @param array<array<string|null>> $matches
|
||||
*/
|
||||
public function __construct($count, array $matches)
|
||||
{
|
||||
$this->matches = $matches;
|
||||
$this->matched = (bool) $count;
|
||||
$this->count = $count;
|
||||
}
|
||||
}
|
48
vendor/composer/pcre/src/MatchAllWithOffsetsResult.php
vendored
Normal file
48
vendor/composer/pcre/src/MatchAllWithOffsetsResult.php
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
final class MatchAllWithOffsetsResult
|
||||
{
|
||||
/**
|
||||
* An array of match group => list of matches, every match being a pair of string matched + offset in bytes (or -1 if no match)
|
||||
*
|
||||
* @readonly
|
||||
* @var array<int|string, list<array{string|null, int}>>
|
||||
* @phpstan-var array<int|string, list<array{string|null, int<-1, max>}>>
|
||||
*/
|
||||
public $matches;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var 0|positive-int
|
||||
*/
|
||||
public $count;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var bool
|
||||
*/
|
||||
public $matched;
|
||||
|
||||
/**
|
||||
* @param 0|positive-int $count
|
||||
* @param array<int|string, list<array{string|null, int}>> $matches
|
||||
* @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
|
||||
*/
|
||||
public function __construct($count, array $matches)
|
||||
{
|
||||
$this->matches = $matches;
|
||||
$this->matched = (bool) $count;
|
||||
$this->count = $count;
|
||||
}
|
||||
}
|
39
vendor/composer/pcre/src/MatchResult.php
vendored
Normal file
39
vendor/composer/pcre/src/MatchResult.php
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
final class MatchResult
|
||||
{
|
||||
/**
|
||||
* An array of match group => string matched
|
||||
*
|
||||
* @readonly
|
||||
* @var array<int|string, string|null>
|
||||
*/
|
||||
public $matches;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var bool
|
||||
*/
|
||||
public $matched;
|
||||
|
||||
/**
|
||||
* @param 0|positive-int $count
|
||||
* @param array<string|null> $matches
|
||||
*/
|
||||
public function __construct($count, array $matches)
|
||||
{
|
||||
$this->matches = $matches;
|
||||
$this->matched = (bool) $count;
|
||||
}
|
||||
}
|
41
vendor/composer/pcre/src/MatchWithOffsetsResult.php
vendored
Normal file
41
vendor/composer/pcre/src/MatchWithOffsetsResult.php
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
final class MatchWithOffsetsResult
|
||||
{
|
||||
/**
|
||||
* An array of match group => pair of string matched + offset in bytes (or -1 if no match)
|
||||
*
|
||||
* @readonly
|
||||
* @var array<int|string, array{string|null, int}>
|
||||
* @phpstan-var array<int|string, array{string|null, int<-1, max>}>
|
||||
*/
|
||||
public $matches;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var bool
|
||||
*/
|
||||
public $matched;
|
||||
|
||||
/**
|
||||
* @param 0|positive-int $count
|
||||
* @param array<array{string|null, int}> $matches
|
||||
* @phpstan-param array<int|string, array{string|null, int<-1, max>}> $matches
|
||||
*/
|
||||
public function __construct($count, array $matches)
|
||||
{
|
||||
$this->matches = $matches;
|
||||
$this->matched = (bool) $count;
|
||||
}
|
||||
}
|
60
vendor/composer/pcre/src/PcreException.php
vendored
Normal file
60
vendor/composer/pcre/src/PcreException.php
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
class PcreException extends \RuntimeException
|
||||
{
|
||||
/**
|
||||
* @param string $function
|
||||
* @param string|string[] $pattern
|
||||
* @return self
|
||||
*/
|
||||
public static function fromFunction($function, $pattern)
|
||||
{
|
||||
$code = preg_last_error();
|
||||
|
||||
if (is_array($pattern)) {
|
||||
$pattern = implode(', ', $pattern);
|
||||
}
|
||||
|
||||
return new PcreException($function.'(): failed executing "'.$pattern.'": '.self::pcreLastErrorMessage($code), $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $code
|
||||
* @return string
|
||||
*/
|
||||
private static function pcreLastErrorMessage($code)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 80000) {
|
||||
return preg_last_error_msg();
|
||||
}
|
||||
|
||||
// older php versions did not set the code properly in all cases
|
||||
if (PHP_VERSION_ID < 70201 && $code === 0) {
|
||||
return 'UNDEFINED_ERROR';
|
||||
}
|
||||
|
||||
$constants = get_defined_constants(true);
|
||||
if (!isset($constants['pcre'])) {
|
||||
return 'UNDEFINED_ERROR';
|
||||
}
|
||||
|
||||
foreach ($constants['pcre'] as $const => $val) {
|
||||
if ($val === $code && substr($const, -6) === '_ERROR') {
|
||||
return $const;
|
||||
}
|
||||
}
|
||||
|
||||
return 'UNDEFINED_ERROR';
|
||||
}
|
||||
}
|
303
vendor/composer/pcre/src/Preg.php
vendored
Normal file
303
vendor/composer/pcre/src/Preg.php
vendored
Normal file
|
@ -0,0 +1,303 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
class Preg
|
||||
{
|
||||
const ARRAY_MSG = '$subject as an array is not supported. You can use \'foreach\' instead.';
|
||||
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<string|null> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return 0|1
|
||||
*/
|
||||
public static function match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
|
||||
{
|
||||
if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use matchWithOffsets() instead');
|
||||
}
|
||||
|
||||
$result = preg_match($pattern, $subject, $matches, $flags, $offset);
|
||||
if ($result === false) {
|
||||
throw PcreException::fromFunction('preg_match', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs preg_match with PREG_OFFSET_CAPTURE
|
||||
*
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<int|string, array{string|null, int}> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return 0|1
|
||||
*
|
||||
* @phpstan-param array<int|string, array{string|null, int<-1, max>}> $matches
|
||||
*/
|
||||
public static function matchWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
|
||||
{
|
||||
$result = preg_match($pattern, $subject, $matches, $flags | PREG_OFFSET_CAPTURE, $offset);
|
||||
if ($result === false) {
|
||||
throw PcreException::fromFunction('preg_match', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<int|string, list<string|null>> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return 0|positive-int
|
||||
*/
|
||||
public static function matchAll($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
|
||||
{
|
||||
if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the type of $matches, use matchAllWithOffsets() instead');
|
||||
}
|
||||
|
||||
if (($flags & PREG_SET_ORDER) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the type of $matches');
|
||||
}
|
||||
|
||||
$result = preg_match_all($pattern, $subject, $matches, $flags, $offset);
|
||||
if ($result === false || $result === null) {
|
||||
throw PcreException::fromFunction('preg_match_all', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs preg_match_all with PREG_OFFSET_CAPTURE
|
||||
*
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<int|string, list<array{string|null, int}>> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return 0|positive-int
|
||||
*
|
||||
* @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
|
||||
*/
|
||||
public static function matchAllWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
|
||||
{
|
||||
$result = preg_match_all($pattern, $subject, $matches, $flags | PREG_OFFSET_CAPTURE, $offset);
|
||||
if ($result === false || $result === null) {
|
||||
throw PcreException::fromFunction('preg_match_all', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $pattern
|
||||
* @param string|string[] $replacement
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $count Set by method
|
||||
* @return string
|
||||
*/
|
||||
public static function replace($pattern, $replacement, $subject, $limit = -1, &$count = null)
|
||||
{
|
||||
if (is_array($subject)) { // @phpstan-ignore-line
|
||||
throw new \InvalidArgumentException(static::ARRAY_MSG);
|
||||
}
|
||||
|
||||
$result = preg_replace($pattern, $replacement, $subject, $limit, $count);
|
||||
if ($result === null) {
|
||||
throw PcreException::fromFunction('preg_replace', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $pattern
|
||||
* @param callable $replacement
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $count Set by method
|
||||
* @param int $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceCallback($pattern, $replacement, $subject, $limit = -1, &$count = null, $flags = 0)
|
||||
{
|
||||
if (is_array($subject)) { // @phpstan-ignore-line
|
||||
throw new \InvalidArgumentException(static::ARRAY_MSG);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 70400) {
|
||||
$result = preg_replace_callback($pattern, $replacement, $subject, $limit, $count, $flags);
|
||||
} else {
|
||||
$result = preg_replace_callback($pattern, $replacement, $subject, $limit, $count);
|
||||
}
|
||||
if ($result === null) {
|
||||
throw PcreException::fromFunction('preg_replace_callback', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Available from PHP 7.0
|
||||
*
|
||||
* @param array<string, callable> $pattern
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $count Set by method
|
||||
* @param int $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
|
||||
* @return string
|
||||
*/
|
||||
public static function replaceCallbackArray(array $pattern, $subject, $limit = -1, &$count = null, $flags = 0)
|
||||
{
|
||||
if (is_array($subject)) { // @phpstan-ignore-line
|
||||
throw new \InvalidArgumentException(static::ARRAY_MSG);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID >= 70400) {
|
||||
$result = preg_replace_callback_array($pattern, $subject, $limit, $count, $flags);
|
||||
} else {
|
||||
$result = preg_replace_callback_array($pattern, $subject, $limit, $count);
|
||||
}
|
||||
if ($result === null) {
|
||||
$pattern = array_keys($pattern);
|
||||
throw PcreException::fromFunction('preg_replace_callback_array', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pattern
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $flags PREG_SPLIT_NO_EMPTY or PREG_SPLIT_DELIM_CAPTURE
|
||||
* @return list<string>
|
||||
*/
|
||||
public static function split($pattern, $subject, $limit = -1, $flags = 0)
|
||||
{
|
||||
if (($flags & PREG_SPLIT_OFFSET_CAPTURE) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_SPLIT_OFFSET_CAPTURE is not supported as it changes the type of $matches, use splitWithOffsets() instead');
|
||||
}
|
||||
|
||||
$result = preg_split($pattern, $subject, $limit, $flags);
|
||||
if ($result === false) {
|
||||
throw PcreException::fromFunction('preg_split', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $pattern
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $flags PREG_SPLIT_NO_EMPTY or PREG_SPLIT_DELIM_CAPTURE
|
||||
* @return list<array{string, int}>
|
||||
* @phpstan-return list<array{string, int<0, max>}>
|
||||
*/
|
||||
public static function splitWithOffsets($pattern, $subject, $limit = -1, $flags = 0)
|
||||
{
|
||||
$result = preg_split($pattern, $subject, $limit, $flags | PREG_SPLIT_OFFSET_CAPTURE);
|
||||
if ($result === false) {
|
||||
throw PcreException::fromFunction('preg_split', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T of string|\Stringable
|
||||
* @param string $pattern
|
||||
* @param array<T> $array
|
||||
* @param int $flags PREG_GREP_INVERT
|
||||
* @return array<T>
|
||||
*/
|
||||
public static function grep($pattern, array $array, $flags = 0)
|
||||
{
|
||||
$result = preg_grep($pattern, $array, $flags);
|
||||
if ($result === false) {
|
||||
throw PcreException::fromFunction('preg_grep', $pattern);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<string|null> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
public static function isMatch($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
|
||||
{
|
||||
return (bool) static::match($pattern, $subject, $matches, $flags, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<int|string, list<string|null>> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
public static function isMatchAll($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
|
||||
{
|
||||
return (bool) static::matchAll($pattern, $subject, $matches, $flags, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs preg_match with PREG_OFFSET_CAPTURE
|
||||
*
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<int|string, array{string|null, int}> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param array<int|string, array{string|null, int<-1, max>}> $matches
|
||||
*/
|
||||
public static function isMatchWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
|
||||
{
|
||||
return (bool) static::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs preg_match_all with PREG_OFFSET_CAPTURE
|
||||
*
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param array<int|string, list<array{string|null, int}>> $matches Set by method
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*
|
||||
* @phpstan-param array<int|string, list<array{string|null, int<-1, max>}>> $matches
|
||||
*/
|
||||
public static function isMatchAllWithOffsets($pattern, $subject, &$matches, $flags = 0, $offset = 0)
|
||||
{
|
||||
return (bool) static::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||
}
|
||||
}
|
142
vendor/composer/pcre/src/Regex.php
vendored
Normal file
142
vendor/composer/pcre/src/Regex.php
vendored
Normal file
|
@ -0,0 +1,142 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
class Regex
|
||||
{
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param int $offset
|
||||
* @return bool
|
||||
*/
|
||||
public static function isMatch($pattern, $subject, $offset = 0)
|
||||
{
|
||||
return (bool) Preg::match($pattern, $subject, $matches, 0, $offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return MatchResult
|
||||
*/
|
||||
public static function match($pattern, $subject, $flags = 0, $offset = 0)
|
||||
{
|
||||
if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use matchWithOffsets() instead');
|
||||
}
|
||||
|
||||
$count = Preg::match($pattern, $subject, $matches, $flags, $offset);
|
||||
|
||||
return new MatchResult($count, $matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs preg_match with PREG_OFFSET_CAPTURE
|
||||
*
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return MatchWithOffsetsResult
|
||||
*/
|
||||
public static function matchWithOffsets($pattern, $subject, $flags = 0, $offset = 0)
|
||||
{
|
||||
$count = Preg::matchWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||
|
||||
return new MatchWithOffsetsResult($count, $matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return MatchAllResult
|
||||
*/
|
||||
public static function matchAll($pattern, $subject, $flags = 0, $offset = 0)
|
||||
{
|
||||
if (($flags & PREG_OFFSET_CAPTURE) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_OFFSET_CAPTURE is not supported as it changes the return type, use matchAllWithOffsets() instead');
|
||||
}
|
||||
|
||||
if (($flags & PREG_SET_ORDER) !== 0) {
|
||||
throw new \InvalidArgumentException('PREG_SET_ORDER is not supported as it changes the return type');
|
||||
}
|
||||
|
||||
$count = Preg::matchAll($pattern, $subject, $matches, $flags, $offset);
|
||||
|
||||
return new MatchAllResult($count, $matches);
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs preg_match_all with PREG_OFFSET_CAPTURE
|
||||
*
|
||||
* @param non-empty-string $pattern
|
||||
* @param string $subject
|
||||
* @param int $flags PREG_UNMATCHED_AS_NULL, only available on PHP 7.2+
|
||||
* @param int $offset
|
||||
* @return MatchAllWithOffsetsResult
|
||||
*/
|
||||
public static function matchAllWithOffsets($pattern, $subject, $flags = 0, $offset = 0)
|
||||
{
|
||||
$count = Preg::matchAllWithOffsets($pattern, $subject, $matches, $flags, $offset);
|
||||
|
||||
return new MatchAllWithOffsetsResult($count, $matches);
|
||||
}
|
||||
/**
|
||||
* @param string|string[] $pattern
|
||||
* @param string|string[] $replacement
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @return ReplaceResult
|
||||
*/
|
||||
public static function replace($pattern, $replacement, $subject, $limit = -1)
|
||||
{
|
||||
$result = Preg::replace($pattern, $replacement, $subject, $limit, $count);
|
||||
|
||||
return new ReplaceResult($count, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[] $pattern
|
||||
* @param callable $replacement
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
|
||||
* @return ReplaceResult
|
||||
*/
|
||||
public static function replaceCallback($pattern, $replacement, $subject, $limit = -1, $flags = 0)
|
||||
{
|
||||
$result = Preg::replaceCallback($pattern, $replacement, $subject, $limit, $count, $flags);
|
||||
|
||||
return new ReplaceResult($count, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Available from PHP 7.0
|
||||
*
|
||||
* @param array<string, callable> $pattern
|
||||
* @param string $subject
|
||||
* @param int $limit
|
||||
* @param int $flags PREG_OFFSET_CAPTURE or PREG_UNMATCHED_AS_NULL, only available on PHP 7.4+
|
||||
* @return ReplaceResult
|
||||
*/
|
||||
public static function replaceCallbackArray($pattern, $subject, $limit = -1, $flags = 0)
|
||||
{
|
||||
$result = Preg::replaceCallbackArray($pattern, $subject, $limit, $count, $flags);
|
||||
|
||||
return new ReplaceResult($count, $result);
|
||||
}
|
||||
}
|
44
vendor/composer/pcre/src/ReplaceResult.php
vendored
Normal file
44
vendor/composer/pcre/src/ReplaceResult.php
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/pcre.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Pcre;
|
||||
|
||||
final class ReplaceResult
|
||||
{
|
||||
/**
|
||||
* @readonly
|
||||
* @var string
|
||||
*/
|
||||
public $result;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var 0|positive-int
|
||||
*/
|
||||
public $count;
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @var bool
|
||||
*/
|
||||
public $matched;
|
||||
|
||||
/**
|
||||
* @param 0|positive-int $count
|
||||
* @param string $result
|
||||
*/
|
||||
public function __construct($count, $result)
|
||||
{
|
||||
$this->count = $count;
|
||||
$this->matched = (bool) $count;
|
||||
$this->result = $result;
|
||||
}
|
||||
}
|
124
vendor/composer/xdebug-handler/CHANGELOG.md
vendored
Normal file
124
vendor/composer/xdebug-handler/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
## [Unreleased]
|
||||
|
||||
## [2.0.5] - 2022-02-24
|
||||
* Fixed: regression in 2.0.4 affecting Xdebug 2.
|
||||
|
||||
## [2.0.4] - 2022-01-04
|
||||
* Fixed: allow calling `isXdebugActive` before class instantiation.
|
||||
|
||||
## [2.0.3] - 2021-12-08
|
||||
* Added: support, type annotations and refactoring for stricter PHPStan analysis.
|
||||
|
||||
## [2.0.2] - 2021-07-31
|
||||
* Added: support for `xdebug_info('mode')` in Xdebug 3.1.
|
||||
* Added: support for Psr\Log versions 2 and 3.
|
||||
* Fixed: remove ini directives from non-cli HOST/PATH sections.
|
||||
|
||||
## [2.0.1] - 2021-05-05
|
||||
* Fixed: don't restart if the cwd is a UNC path and cmd.exe will be invoked.
|
||||
|
||||
## [2.0.0] - 2021-04-09
|
||||
* Break: this is a major release, see [UPGRADE.md](UPGRADE.md) for more information.
|
||||
* Break: removed optional `$colorOption` constructor param and passthru fallback.
|
||||
* Break: renamed `requiresRestart` param from `$isLoaded` to `$default`.
|
||||
* Break: changed `restart` param `$command` from a string to an array.
|
||||
* Added: support for Xdebug3 to only restart if Xdebug is not running with `xdebug.mode=off`.
|
||||
* Added: `isXdebugActive()` method to determine if Xdebug is still running in the restart.
|
||||
* Added: feature to bypass the shell in PHP-7.4+ by giving `proc_open` an array of arguments.
|
||||
* Added: Process utility class to the API.
|
||||
|
||||
## [1.4.6] - 2021-03-25
|
||||
* Fixed: fail restart if `proc_open` has been disabled in `disable_functions`.
|
||||
* Fixed: enable Windows CTRL event handling in the restarted process.
|
||||
|
||||
## [1.4.5] - 2020-11-13
|
||||
* Fixed: use `proc_open` when available for correct FD forwarding to the restarted process.
|
||||
|
||||
## [1.4.4] - 2020-10-24
|
||||
* Fixed: exception if 'pcntl_signal' is disabled.
|
||||
|
||||
## [1.4.3] - 2020-08-19
|
||||
* Fixed: restore SIGINT to default handler in restarted process if no other handler exists.
|
||||
|
||||
## [1.4.2] - 2020-06-04
|
||||
* Fixed: ignore SIGINTs to let the restarted process handle them.
|
||||
|
||||
## [1.4.1] - 2020-03-01
|
||||
* Fixed: restart fails if an ini file is empty.
|
||||
|
||||
## [1.4.0] - 2019-11-06
|
||||
* Added: support for `NO_COLOR` environment variable: https://no-color.org
|
||||
* Added: color support for Hyper terminal: https://github.com/zeit/hyper
|
||||
* Fixed: correct capitalization of Xdebug (apparently).
|
||||
* Fixed: improved handling for uopz extension.
|
||||
|
||||
## [1.3.3] - 2019-05-27
|
||||
* Fixed: add environment changes to `$_ENV` if it is being used.
|
||||
|
||||
## [1.3.2] - 2019-01-28
|
||||
* Fixed: exit call being blocked by uopz extension, resulting in application code running twice.
|
||||
|
||||
## [1.3.1] - 2018-11-29
|
||||
* Fixed: fail restart if `passthru` has been disabled in `disable_functions`.
|
||||
* Fixed: fail restart if an ini file cannot be opened, otherwise settings will be missing.
|
||||
|
||||
## [1.3.0] - 2018-08-31
|
||||
* Added: `setPersistent` method to use environment variables for the restart.
|
||||
* Fixed: improved debugging by writing output to stderr.
|
||||
* Fixed: no restart when `php_ini_scanned_files` is not functional and is needed.
|
||||
|
||||
## [1.2.1] - 2018-08-23
|
||||
* Fixed: fatal error with apc, when using `apc.mmap_file_mask`.
|
||||
|
||||
## [1.2.0] - 2018-08-16
|
||||
* Added: debug information using `XDEBUG_HANDLER_DEBUG`.
|
||||
* Added: fluent interface for setters.
|
||||
* Added: `PhpConfig` helper class for calling PHP sub-processes.
|
||||
* Added: `PHPRC` original value to restart stettings, for use in a restarted process.
|
||||
* Changed: internal procedure to disable ini-scanning, using `-n` command-line option.
|
||||
* Fixed: replaced `escapeshellarg` usage to avoid locale problems.
|
||||
* Fixed: improved color-option handling to respect double-dash delimiter.
|
||||
* Fixed: color-option handling regression from main script changes.
|
||||
* Fixed: improved handling when checking main script.
|
||||
* Fixed: handling for standard input, that never actually did anything.
|
||||
* Fixed: fatal error when ctype extension is not available.
|
||||
|
||||
## [1.1.0] - 2018-04-11
|
||||
* Added: `getRestartSettings` method for calling PHP processes in a restarted process.
|
||||
* Added: API definition and @internal class annotations.
|
||||
* Added: protected `requiresRestart` method for extending classes.
|
||||
* Added: `setMainScript` method for applications that change the working directory.
|
||||
* Changed: private `tmpIni` variable to protected for extending classes.
|
||||
* Fixed: environment variables not available in $_SERVER when restored in the restart.
|
||||
* Fixed: relative path problems caused by Phar::interceptFileFuncs.
|
||||
* Fixed: incorrect handling when script file cannot be found.
|
||||
|
||||
## [1.0.0] - 2018-03-08
|
||||
* Added: PSR3 logging for optional status output.
|
||||
* Added: existing ini settings are merged to catch command-line overrides.
|
||||
* Added: code, tests and other artefacts to decouple from Composer.
|
||||
* Break: the following class was renamed:
|
||||
- `Composer\XdebugHandler` -> `Composer\XdebugHandler\XdebugHandler`
|
||||
|
||||
[Unreleased]: https://github.com/composer/xdebug-handler/compare/2.0.5...HEAD
|
||||
[2.0.5]: https://github.com/composer/xdebug-handler/compare/2.0.4...2.0.5
|
||||
[2.0.4]: https://github.com/composer/xdebug-handler/compare/2.0.3...2.0.4
|
||||
[2.0.3]: https://github.com/composer/xdebug-handler/compare/2.0.2...2.0.3
|
||||
[2.0.2]: https://github.com/composer/xdebug-handler/compare/2.0.1...2.0.2
|
||||
[2.0.1]: https://github.com/composer/xdebug-handler/compare/2.0.0...2.0.1
|
||||
[2.0.0]: https://github.com/composer/xdebug-handler/compare/1.4.6...2.0.0
|
||||
[1.4.6]: https://github.com/composer/xdebug-handler/compare/1.4.5...1.4.6
|
||||
[1.4.5]: https://github.com/composer/xdebug-handler/compare/1.4.4...1.4.5
|
||||
[1.4.4]: https://github.com/composer/xdebug-handler/compare/1.4.3...1.4.4
|
||||
[1.4.3]: https://github.com/composer/xdebug-handler/compare/1.4.2...1.4.3
|
||||
[1.4.2]: https://github.com/composer/xdebug-handler/compare/1.4.1...1.4.2
|
||||
[1.4.1]: https://github.com/composer/xdebug-handler/compare/1.4.0...1.4.1
|
||||
[1.4.0]: https://github.com/composer/xdebug-handler/compare/1.3.3...1.4.0
|
||||
[1.3.3]: https://github.com/composer/xdebug-handler/compare/1.3.2...1.3.3
|
||||
[1.3.2]: https://github.com/composer/xdebug-handler/compare/1.3.1...1.3.2
|
||||
[1.3.1]: https://github.com/composer/xdebug-handler/compare/1.3.0...1.3.1
|
||||
[1.3.0]: https://github.com/composer/xdebug-handler/compare/1.2.1...1.3.0
|
||||
[1.2.1]: https://github.com/composer/xdebug-handler/compare/1.2.0...1.2.1
|
||||
[1.2.0]: https://github.com/composer/xdebug-handler/compare/1.1.0...1.2.0
|
||||
[1.1.0]: https://github.com/composer/xdebug-handler/compare/1.0.0...1.1.0
|
||||
[1.0.0]: https://github.com/composer/xdebug-handler/compare/d66f0d15cb57...1.0.0
|
21
vendor/composer/xdebug-handler/LICENSE
vendored
Normal file
21
vendor/composer/xdebug-handler/LICENSE
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2017 Composer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
291
vendor/composer/xdebug-handler/README.md
vendored
Normal file
291
vendor/composer/xdebug-handler/README.md
vendored
Normal file
|
@ -0,0 +1,291 @@
|
|||
# composer/xdebug-handler
|
||||
|
||||
[](https://packagist.org/packages/composer/xdebug-handler#2.0.4)
|
||||
[](https://github.com/composer/xdebug-handler/actions?query=branch:2.0)
|
||||

|
||||

|
||||
|
||||
Restart a CLI process without loading the Xdebug extension, unless `xdebug.mode=off`.
|
||||
|
||||
Originally written as part of [composer/composer](https://github.com/composer/composer),
|
||||
now extracted and made available as a stand-alone library.
|
||||
|
||||
### Version 2
|
||||
|
||||
Support added for Xdebug3. See [UPGRADE](UPGRADE.md) for more information.
|
||||
|
||||
## Installation
|
||||
|
||||
Install the latest version with:
|
||||
|
||||
```bash
|
||||
$ composer require composer/xdebug-handler
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
* PHP 5.3.2 minimum, although functionality is disabled below PHP 5.4.0. Using the latest PHP version is highly recommended.
|
||||
|
||||
## Basic Usage
|
||||
```php
|
||||
use Composer\XdebugHandler\XdebugHandler;
|
||||
|
||||
$xdebug = new XdebugHandler('myapp');
|
||||
$xdebug->check();
|
||||
unset($xdebug);
|
||||
```
|
||||
|
||||
The constructor takes a single parameter, `$envPrefix`, which is upper-cased and prepended to default base values to create two distinct environment variables. The above example enables the use of:
|
||||
|
||||
- `MYAPP_ALLOW_XDEBUG=1` to override automatic restart and allow Xdebug
|
||||
- `MYAPP_ORIGINAL_INIS` to obtain ini file locations in a restarted process
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
* [How it works](#how-it-works)
|
||||
* [Limitations](#limitations)
|
||||
* [Helper methods](#helper-methods)
|
||||
* [Setter methods](#setter-methods)
|
||||
* [Process configuration](#process-configuration)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [Extending the library](#extending-the-library)
|
||||
|
||||
### How it works
|
||||
|
||||
A temporary ini file is created from the loaded (and scanned) ini files, with any references to the Xdebug extension commented out. Current ini settings are merged, so that most ini settings made on the command-line or by the application are included (see [Limitations](#limitations))
|
||||
|
||||
* `MYAPP_ALLOW_XDEBUG` is set with internal data to flag and use in the restart.
|
||||
* The command-line and environment are [configured](#process-configuration) for the restart.
|
||||
* The application is restarted in a new process.
|
||||
* The restart settings are stored in the environment.
|
||||
* `MYAPP_ALLOW_XDEBUG` is unset.
|
||||
* The application runs and exits.
|
||||
* The main process exits with the exit code from the restarted process.
|
||||
|
||||
#### Signal handling
|
||||
From PHP 7.1 with the pcntl extension loaded, asynchronous signal handling is automatically enabled. `SIGINT` is set to `SIG_IGN` in the parent
|
||||
process and restored to `SIG_DFL` in the restarted process (if no other handler has been set).
|
||||
|
||||
From PHP 7.4 on Windows, `CTRL+C` and `CTRL+BREAK` handling is ignored in the parent process and automatically enabled in the restarted process.
|
||||
|
||||
### Limitations
|
||||
There are a few things to be aware of when running inside a restarted process.
|
||||
|
||||
* Extensions set on the command-line will not be loaded.
|
||||
* Ini file locations will be reported as per the restart - see [getAllIniFiles()](#getallinifiles).
|
||||
* Php sub-processes may be loaded with Xdebug enabled - see [Process configuration](#process-configuration).
|
||||
|
||||
### Helper methods
|
||||
These static methods provide information from the current process, regardless of whether it has been restarted or not.
|
||||
|
||||
#### _getAllIniFiles()_
|
||||
Returns an array of the original ini file locations. Use this instead of calling `php_ini_loaded_file` and `php_ini_scanned_files`, which will report the wrong values in a restarted process.
|
||||
|
||||
```php
|
||||
use Composer\XdebugHandler\XdebugHandler;
|
||||
|
||||
$files = XdebugHandler::getAllIniFiles();
|
||||
|
||||
# $files[0] always exists, it could be an empty string
|
||||
$loadedIni = array_shift($files);
|
||||
$scannedInis = $files;
|
||||
```
|
||||
|
||||
These locations are also available in the `MYAPP_ORIGINAL_INIS` environment variable. This is a path-separated string comprising the location returned from `php_ini_loaded_file`, which could be empty, followed by locations parsed from calling `php_ini_scanned_files`.
|
||||
|
||||
#### _getRestartSettings()_
|
||||
Returns an array of settings that can be used with PHP [sub-processes](#sub-processes), or null if the process was not restarted.
|
||||
|
||||
```php
|
||||
use Composer\XdebugHandler\XdebugHandler;
|
||||
|
||||
$settings = XdebugHandler::getRestartSettings();
|
||||
/**
|
||||
* $settings: array (if the current process was restarted,
|
||||
* or called with the settings from a previous restart), or null
|
||||
*
|
||||
* 'tmpIni' => the temporary ini file used in the restart (string)
|
||||
* 'scannedInis' => if there were any scanned inis (bool)
|
||||
* 'scanDir' => the original PHP_INI_SCAN_DIR value (false|string)
|
||||
* 'phprc' => the original PHPRC value (false|string)
|
||||
* 'inis' => the original inis from getAllIniFiles (array)
|
||||
* 'skipped' => the skipped version from getSkippedVersion (string)
|
||||
*/
|
||||
```
|
||||
|
||||
#### _getSkippedVersion()_
|
||||
Returns the Xdebug version string that was skipped by the restart, or an empty value if there was no restart (or Xdebug is still loaded, perhaps by an extending class restarting for a reason other than removing Xdebug).
|
||||
|
||||
```php
|
||||
use Composer\XdebugHandler\XdebugHandler;
|
||||
|
||||
$version = XdebugHandler::getSkippedVersion();
|
||||
# $version: '2.6.0' (for example), or an empty string
|
||||
```
|
||||
|
||||
#### _isXdebugActive()_
|
||||
Returns true if Xdebug is loaded and is running in an active mode (if it supports modes). Returns false if Xdebug is not loaded, or it is running with `xdebug.mode=off`.
|
||||
|
||||
### Setter methods
|
||||
These methods implement a fluent interface and must be called before the main `check()` method.
|
||||
|
||||
#### _setLogger($logger)_
|
||||
Enables the output of status messages to an external PSR3 logger. All messages are reported with either `DEBUG` or `WARNING` log levels. For example (showing the level and message):
|
||||
|
||||
```
|
||||
// Restart overridden
|
||||
DEBUG Checking MYAPP_ALLOW_XDEBUG
|
||||
DEBUG The Xdebug extension is loaded (2.5.0)
|
||||
DEBUG No restart (MYAPP_ALLOW_XDEBUG=1)
|
||||
|
||||
// Failed restart
|
||||
DEBUG Checking MYAPP_ALLOW_XDEBUG
|
||||
DEBUG The Xdebug extension is loaded (2.5.0)
|
||||
WARNING No restart (Unable to create temp ini file at: ...)
|
||||
```
|
||||
|
||||
Status messages can also be output with `XDEBUG_HANDLER_DEBUG`. See [Troubleshooting](#troubleshooting).
|
||||
|
||||
#### _setMainScript($script)_
|
||||
Sets the location of the main script to run in the restart. This is only needed in more esoteric use-cases, or if the `argv[0]` location is inaccessible. The script name `--` is supported for standard input.
|
||||
|
||||
#### _setPersistent()_
|
||||
Configures the restart using [persistent settings](#persistent-settings), so that Xdebug is not loaded in any sub-process.
|
||||
|
||||
Use this method if your application invokes one or more PHP sub-process and the Xdebug extension is not needed. This avoids the overhead of implementing specific [sub-process](#sub-processes) strategies.
|
||||
|
||||
Alternatively, this method can be used to set up a default _Xdebug-free_ environment which can be changed if a sub-process requires Xdebug, then restored afterwards:
|
||||
|
||||
```php
|
||||
function SubProcessWithXdebug()
|
||||
{
|
||||
$phpConfig = new Composer\XdebugHandler\PhpConfig();
|
||||
|
||||
# Set the environment to the original configuration
|
||||
$phpConfig->useOriginal();
|
||||
|
||||
# run the process with Xdebug loaded
|
||||
...
|
||||
|
||||
# Restore Xdebug-free environment
|
||||
$phpConfig->usePersistent();
|
||||
}
|
||||
```
|
||||
|
||||
### Process configuration
|
||||
The library offers two strategies to invoke a new PHP process without loading Xdebug, using either _standard_ or _persistent_ settings. Note that this is only important if the application calls a PHP sub-process.
|
||||
|
||||
#### Standard settings
|
||||
Uses command-line options to remove Xdebug from the new process only.
|
||||
|
||||
* The -n option is added to the command-line. This tells PHP not to scan for additional inis.
|
||||
* The temporary ini is added to the command-line with the -c option.
|
||||
|
||||
>_If the new process calls a PHP sub-process, Xdebug will be loaded in that sub-process (unless it implements xdebug-handler, in which case there will be another restart)._
|
||||
|
||||
This is the default strategy used in the restart.
|
||||
|
||||
#### Persistent settings
|
||||
Uses environment variables to remove Xdebug from the new process and persist these settings to any sub-process.
|
||||
|
||||
* `PHP_INI_SCAN_DIR` is set to an empty string. This tells PHP not to scan for additional inis.
|
||||
* `PHPRC` is set to the temporary ini.
|
||||
|
||||
>_If the new process calls a PHP sub-process, Xdebug will not be loaded in that sub-process._
|
||||
|
||||
This strategy can be used in the restart by calling [setPersistent()](#setpersistent).
|
||||
|
||||
#### Sub-processes
|
||||
The `PhpConfig` helper class makes it easy to invoke a PHP sub-process (with or without Xdebug loaded), regardless of whether there has been a restart.
|
||||
|
||||
Each of its methods returns an array of PHP options (to add to the command-line) and sets up the environment for the required strategy. The [getRestartSettings()](#getrestartsettings) method is used internally.
|
||||
|
||||
* `useOriginal()` - Xdebug will be loaded in the new process.
|
||||
* `useStandard()` - Xdebug will **not** be loaded in the new process - see [standard settings](#standard-settings).
|
||||
* `userPersistent()` - Xdebug will **not** be loaded in the new process - see [persistent settings](#persistent-settings)
|
||||
|
||||
If there was no restart, an empty options array is returned and the environment is not changed.
|
||||
|
||||
```php
|
||||
use Composer\XdebugHandler\PhpConfig;
|
||||
|
||||
$config = new PhpConfig;
|
||||
|
||||
$options = $config->useOriginal();
|
||||
# $options: empty array
|
||||
# environment: PHPRC and PHP_INI_SCAN_DIR set to original values
|
||||
|
||||
$options = $config->useStandard();
|
||||
# $options: [-n, -c, tmpIni]
|
||||
# environment: PHPRC and PHP_INI_SCAN_DIR set to original values
|
||||
|
||||
$options = $config->usePersistent();
|
||||
# $options: empty array
|
||||
# environment: PHPRC=tmpIni, PHP_INI_SCAN_DIR=''
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
The following environment settings can be used to troubleshoot unexpected behavior:
|
||||
|
||||
* `XDEBUG_HANDLER_DEBUG=1` Outputs status messages to `STDERR`, if it is defined, irrespective of any PSR3 logger. Each message is prefixed `xdebug-handler[pid]`, where pid is the process identifier.
|
||||
|
||||
* `XDEBUG_HANDLER_DEBUG=2` As above, but additionally saves the temporary ini file and reports its location in a status message.
|
||||
|
||||
### Extending the library
|
||||
The API is defined by classes and their accessible elements that are not annotated as @internal. The main class has two protected methods that can be overridden to provide additional functionality:
|
||||
|
||||
#### _requiresRestart($default)_
|
||||
By default the process will restart if Xdebug is loaded and not running with `xdebug.mode=off`. Extending this method allows an application to decide, by returning a boolean (or equivalent) value.
|
||||
It is only called if `MYAPP_ALLOW_XDEBUG` is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden.
|
||||
|
||||
Note that the [setMainScript()](#setmainscriptscript) and [setPersistent()](#setpersistent) setters can be used here, if required.
|
||||
|
||||
#### _restart($command)_
|
||||
An application can extend this to modify the temporary ini file, its location given in the `tmpIni` property. New settings can be safely appended to the end of the data, which is `PHP_EOL` terminated.
|
||||
|
||||
The `$command` parameter is an array of unescaped command-line arguments that will be used for the new process.
|
||||
|
||||
Remember to finish with `parent::restart($command)`.
|
||||
|
||||
#### Example
|
||||
This example demonstrates two ways to extend basic functionality:
|
||||
|
||||
* To avoid the overhead of spinning up a new process, the restart is skipped if a simple help command is requested.
|
||||
|
||||
* The application needs write-access to phar files, so it will force a restart if `phar.readonly` is set (regardless of whether Xdebug is loaded) and change this value in the temporary ini file.
|
||||
|
||||
```php
|
||||
use Composer\XdebugHandler\XdebugHandler;
|
||||
use MyApp\Command;
|
||||
|
||||
class MyRestarter extends XdebugHandler
|
||||
{
|
||||
private $required;
|
||||
|
||||
protected function requiresRestart($default)
|
||||
{
|
||||
if (Command::isHelp()) {
|
||||
# No need to disable Xdebug for this
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->required = (bool) ini_get('phar.readonly');
|
||||
return $this->required || $default;
|
||||
}
|
||||
|
||||
protected function restart($command)
|
||||
{
|
||||
if ($this->required) {
|
||||
# Add required ini setting to tmpIni
|
||||
$content = file_get_contents($this->tmpIni);
|
||||
$content .= 'phar.readonly=0'.PHP_EOL;
|
||||
file_put_contents($this->tmpIni, $content);
|
||||
}
|
||||
|
||||
parent::restart($command);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
composer/xdebug-handler is licensed under the MIT License, see the LICENSE file for details.
|
30
vendor/composer/xdebug-handler/UPGRADE.md
vendored
Normal file
30
vendor/composer/xdebug-handler/UPGRADE.md
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
## Upgrading from 1.x
|
||||
|
||||
The default behaviour has changed from always restarting if Xdebug is loaded, to only restarting if
|
||||
Xdebug is _active_. This has been introduced to support Xdebug3
|
||||
[modes](https://xdebug.org/docs/all_settings#mode). Xdebug is considered active if it is loaded, and
|
||||
for Xdebug3, if it is running in a mode other than `xdebug.mode=off`.
|
||||
|
||||
* Break: removed optional `$colorOption` constructor param and passthru fallback.
|
||||
|
||||
Just use `new XdebugHandler('myapp')` to instantiate the class and color support will be
|
||||
detectable in the restarted process.
|
||||
|
||||
* Added: `isXdebugActive()` method to determine if Xdebug is still running in the restart.
|
||||
|
||||
Returns true if Xdebug is loaded and is running in an active mode (if it supports modes).
|
||||
Returns false if Xdebug is not loaded, or it is running with `xdebug.mode=off`.
|
||||
|
||||
### Extending classes
|
||||
|
||||
* Break: renamed `requiresRestart` param from `$isLoaded` to `$default`.
|
||||
|
||||
This reflects the new default behaviour which is to restart only if Xdebug is active.
|
||||
|
||||
* Break: changed `restart` param `$command` from a string to an array.
|
||||
|
||||
Only important if you modified the string. `$command` is now an array of unescaped arguments.
|
||||
|
||||
* Added: Process utility class to the API.
|
||||
|
||||
This class was previously annotated as @internal and has been refactored due to recent changes.
|
44
vendor/composer/xdebug-handler/composer.json
vendored
Normal file
44
vendor/composer/xdebug-handler/composer.json
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "composer/xdebug-handler",
|
||||
"description": "Restarts a process without Xdebug.",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"xdebug",
|
||||
"performance"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "John Stevenson",
|
||||
"email": "john-stevenson@blueyonder.co.uk"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"irc": "irc://irc.freenode.org/composer",
|
||||
"issues": "https://github.com/composer/xdebug-handler/issues"
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0",
|
||||
"psr/log": "^1 || ^2 || ^3",
|
||||
"composer/pcre": "^1"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\XdebugHandler\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Composer\\XdebugHandler\\Tests\\": "tests"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "vendor/bin/simple-phpunit",
|
||||
"phpstan": "vendor/bin/phpstan analyse"
|
||||
}
|
||||
}
|
92
vendor/composer/xdebug-handler/src/PhpConfig.php
vendored
Normal file
92
vendor/composer/xdebug-handler/src/PhpConfig.php
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/xdebug-handler.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\XdebugHandler;
|
||||
|
||||
/**
|
||||
* @author John Stevenson <john-stevenson@blueyonder.co.uk>
|
||||
*
|
||||
* @phpstan-type restartData array{tmpIni: string, scannedInis: bool, scanDir: false|string, phprc: false|string, inis: string[], skipped: string}
|
||||
*/
|
||||
class PhpConfig
|
||||
{
|
||||
/**
|
||||
* Use the original PHP configuration
|
||||
*
|
||||
* @return string[] Empty array of PHP cli options
|
||||
*/
|
||||
public function useOriginal()
|
||||
{
|
||||
$this->getDataAndReset();
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use standard restart settings
|
||||
*
|
||||
* @return string[] PHP cli options
|
||||
*/
|
||||
public function useStandard()
|
||||
{
|
||||
$data = $this->getDataAndReset();
|
||||
if ($data !== null) {
|
||||
return array('-n', '-c', $data['tmpIni']);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use environment variables to persist settings
|
||||
*
|
||||
* @return string[] Empty array of PHP cli options
|
||||
*/
|
||||
public function usePersistent()
|
||||
{
|
||||
$data = $this->getDataAndReset();
|
||||
if ($data !== null) {
|
||||
$this->updateEnv('PHPRC', $data['tmpIni']);
|
||||
$this->updateEnv('PHP_INI_SCAN_DIR', '');
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns restart data if available and resets the environment
|
||||
*
|
||||
* @return array|null
|
||||
* @phpstan-return restartData|null
|
||||
*/
|
||||
private function getDataAndReset()
|
||||
{
|
||||
$data = XdebugHandler::getRestartSettings();
|
||||
if ($data !== null) {
|
||||
$this->updateEnv('PHPRC', $data['phprc']);
|
||||
$this->updateEnv('PHP_INI_SCAN_DIR', $data['scanDir']);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a restart settings value in the environment
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|false $value
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function updateEnv($name, $value)
|
||||
{
|
||||
Process::setEnv($name, false !== $value ? $value : null);
|
||||
}
|
||||
}
|
122
vendor/composer/xdebug-handler/src/Process.php
vendored
Normal file
122
vendor/composer/xdebug-handler/src/Process.php
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/xdebug-handler.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\XdebugHandler;
|
||||
|
||||
use Composer\Pcre\Preg;
|
||||
|
||||
/**
|
||||
* Process utility functions
|
||||
*
|
||||
* @author John Stevenson <john-stevenson@blueyonder.co.uk>
|
||||
*/
|
||||
class Process
|
||||
{
|
||||
/**
|
||||
* Escapes a string to be used as a shell argument.
|
||||
*
|
||||
* From https://github.com/johnstevenson/winbox-args
|
||||
* MIT Licensed (c) John Stevenson <john-stevenson@blueyonder.co.uk>
|
||||
*
|
||||
* @param string $arg The argument to be escaped
|
||||
* @param bool $meta Additionally escape cmd.exe meta characters
|
||||
* @param bool $module The argument is the module to invoke
|
||||
*
|
||||
* @return string The escaped argument
|
||||
*/
|
||||
public static function escape($arg, $meta = true, $module = false)
|
||||
{
|
||||
if (!defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
return "'".str_replace("'", "'\\''", $arg)."'";
|
||||
}
|
||||
|
||||
$quote = strpbrk($arg, " \t") !== false || $arg === '';
|
||||
|
||||
$arg = Preg::replace('/(\\\\*)"/', '$1$1\\"', $arg, -1, $dquotes);
|
||||
|
||||
if ($meta) {
|
||||
$meta = $dquotes || Preg::isMatch('/%[^%]+%/', $arg);
|
||||
|
||||
if (!$meta) {
|
||||
$quote = $quote || strpbrk($arg, '^&|<>()') !== false;
|
||||
} elseif ($module && !$dquotes && $quote) {
|
||||
$meta = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($quote) {
|
||||
$arg = '"'.(Preg::replace('/(\\\\*)$/', '$1$1', $arg)).'"';
|
||||
}
|
||||
|
||||
if ($meta) {
|
||||
$arg = Preg::replace('/(["^&|<>()%])/', '^$1', $arg);
|
||||
}
|
||||
|
||||
return $arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes an array of arguments that make up a shell command
|
||||
*
|
||||
* @param string[] $args Argument list, with the module name first
|
||||
*
|
||||
* @return string The escaped command line
|
||||
*/
|
||||
public static function escapeShellCommand(array $args)
|
||||
{
|
||||
$command = '';
|
||||
$module = array_shift($args);
|
||||
|
||||
if ($module !== null) {
|
||||
$command = self::escape($module, true, true);
|
||||
|
||||
foreach ($args as $arg) {
|
||||
$command .= ' '.self::escape($arg);
|
||||
}
|
||||
}
|
||||
|
||||
return $command;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes putenv environment changes available in $_SERVER and $_ENV
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|null $value A null value unsets the variable
|
||||
*
|
||||
* @return bool Whether the environment variable was set
|
||||
*/
|
||||
public static function setEnv($name, $value = null)
|
||||
{
|
||||
$unset = null === $value;
|
||||
|
||||
if (!putenv($unset ? $name : $name.'='.$value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($unset) {
|
||||
unset($_SERVER[$name]);
|
||||
} else {
|
||||
$_SERVER[$name] = $value;
|
||||
}
|
||||
|
||||
// Update $_ENV if it is being used
|
||||
if (false !== stripos((string) ini_get('variables_order'), 'E')) {
|
||||
if ($unset) {
|
||||
unset($_ENV[$name]);
|
||||
} else {
|
||||
$_ENV[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
224
vendor/composer/xdebug-handler/src/Status.php
vendored
Normal file
224
vendor/composer/xdebug-handler/src/Status.php
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/xdebug-handler.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\XdebugHandler;
|
||||
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Psr\Log\LogLevel;
|
||||
|
||||
/**
|
||||
* @author John Stevenson <john-stevenson@blueyonder.co.uk>
|
||||
* @internal
|
||||
*/
|
||||
class Status
|
||||
{
|
||||
const ENV_RESTART = 'XDEBUG_HANDLER_RESTART';
|
||||
const CHECK = 'Check';
|
||||
const ERROR = 'Error';
|
||||
const INFO = 'Info';
|
||||
const NORESTART = 'NoRestart';
|
||||
const RESTART = 'Restart';
|
||||
const RESTARTING = 'Restarting';
|
||||
const RESTARTED = 'Restarted';
|
||||
|
||||
/** @var bool */
|
||||
private $debug;
|
||||
|
||||
/** @var string */
|
||||
private $envAllowXdebug;
|
||||
|
||||
/** @var string|null */
|
||||
private $loaded;
|
||||
|
||||
/** @var LoggerInterface|null */
|
||||
private $logger;
|
||||
|
||||
/** @var bool */
|
||||
private $modeOff;
|
||||
|
||||
/** @var float */
|
||||
private $time;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $envAllowXdebug Prefixed _ALLOW_XDEBUG name
|
||||
* @param bool $debug Whether debug output is required
|
||||
*/
|
||||
public function __construct($envAllowXdebug, $debug)
|
||||
{
|
||||
$start = getenv(self::ENV_RESTART);
|
||||
Process::setEnv(self::ENV_RESTART);
|
||||
$this->time = is_numeric($start) ? round((microtime(true) - $start) * 1000) : 0;
|
||||
|
||||
$this->envAllowXdebug = $envAllowXdebug;
|
||||
$this->debug = $debug && defined('STDERR');
|
||||
$this->modeOff = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param LoggerInterface $logger
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls a handler method to report a message
|
||||
*
|
||||
* @param string $op The handler constant
|
||||
* @param null|string $data Data required by the handler
|
||||
*
|
||||
* @return void
|
||||
* @throws \InvalidArgumentException If $op is not known
|
||||
*/
|
||||
public function report($op, $data)
|
||||
{
|
||||
if ($this->logger !== null || $this->debug) {
|
||||
$callable = array($this, 'report'.$op);
|
||||
|
||||
if (!is_callable($callable)) {
|
||||
throw new \InvalidArgumentException('Unknown op handler: '.$op);
|
||||
}
|
||||
|
||||
$params = $data !== null ? $data : array();
|
||||
call_user_func_array($callable, array($params));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a status message
|
||||
*
|
||||
* @param string $text
|
||||
* @param string $level
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function output($text, $level = null)
|
||||
{
|
||||
if ($this->logger !== null) {
|
||||
$this->logger->log($level !== null ? $level: LogLevel::DEBUG, $text);
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
fwrite(STDERR, sprintf('xdebug-handler[%d] %s', getmypid(), $text.PHP_EOL));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $loaded
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reportCheck($loaded)
|
||||
{
|
||||
list($version, $mode) = explode('|', $loaded);
|
||||
|
||||
if ($version !== '') {
|
||||
$this->loaded = '('.$version.')'.($mode !== '' ? ' mode='.$mode : '');
|
||||
}
|
||||
$this->modeOff = $mode === 'off';
|
||||
$this->output('Checking '.$this->envAllowXdebug);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $error
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reportError($error)
|
||||
{
|
||||
$this->output(sprintf('No restart (%s)', $error), LogLevel::WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $info
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reportInfo($info)
|
||||
{
|
||||
$this->output($info);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function reportNoRestart()
|
||||
{
|
||||
$this->output($this->getLoadedMessage());
|
||||
|
||||
if ($this->loaded !== null) {
|
||||
$text = sprintf('No restart (%s)', $this->getEnvAllow());
|
||||
if (!((bool) getenv($this->envAllowXdebug))) {
|
||||
$text .= ' Allowed by '.($this->modeOff ? 'mode' : 'application');
|
||||
}
|
||||
$this->output($text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function reportRestart()
|
||||
{
|
||||
$this->output($this->getLoadedMessage());
|
||||
Process::setEnv(self::ENV_RESTART, (string) microtime(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private function reportRestarted()
|
||||
{
|
||||
$loaded = $this->getLoadedMessage();
|
||||
$text = sprintf('Restarted (%d ms). %s', $this->time, $loaded);
|
||||
$level = $this->loaded !== null ? LogLevel::WARNING : null;
|
||||
$this->output($text, $level);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function reportRestarting($command)
|
||||
{
|
||||
$text = sprintf('Process restarting (%s)', $this->getEnvAllow());
|
||||
$this->output($text);
|
||||
$text = 'Running '.$command;
|
||||
$this->output($text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the _ALLOW_XDEBUG environment variable as name=value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getEnvAllow()
|
||||
{
|
||||
return $this->envAllowXdebug.'='.getenv($this->envAllowXdebug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Xdebug status and version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getLoadedMessage()
|
||||
{
|
||||
$loaded = $this->loaded !== null ? sprintf('loaded %s', $this->loaded) : 'not loaded';
|
||||
return 'The Xdebug extension is '.$loaded;
|
||||
}
|
||||
}
|
745
vendor/composer/xdebug-handler/src/XdebugHandler.php
vendored
Normal file
745
vendor/composer/xdebug-handler/src/XdebugHandler.php
vendored
Normal file
|
@ -0,0 +1,745 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of composer/xdebug-handler.
|
||||
*
|
||||
* (c) Composer <https://github.com/composer>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\XdebugHandler;
|
||||
|
||||
use Composer\Pcre\Preg;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
/**
|
||||
* @author John Stevenson <john-stevenson@blueyonder.co.uk>
|
||||
*
|
||||
* @phpstan-import-type restartData from PhpConfig
|
||||
*/
|
||||
class XdebugHandler
|
||||
{
|
||||
const SUFFIX_ALLOW = '_ALLOW_XDEBUG';
|
||||
const SUFFIX_INIS = '_ORIGINAL_INIS';
|
||||
const RESTART_ID = 'internal';
|
||||
const RESTART_SETTINGS = 'XDEBUG_HANDLER_SETTINGS';
|
||||
const DEBUG = 'XDEBUG_HANDLER_DEBUG';
|
||||
|
||||
/** @var string|null */
|
||||
protected $tmpIni;
|
||||
|
||||
/** @var bool */
|
||||
private static $inRestart;
|
||||
|
||||
/** @var string */
|
||||
private static $name;
|
||||
|
||||
/** @var string|null */
|
||||
private static $skipped;
|
||||
|
||||
/** @var bool */
|
||||
private static $xdebugActive;
|
||||
|
||||
/** @var string|null */
|
||||
private static $xdebugMode;
|
||||
|
||||
/** @var string|null */
|
||||
private static $xdebugVersion;
|
||||
|
||||
/** @var bool */
|
||||
private $cli;
|
||||
|
||||
/** @var string|null */
|
||||
private $debug;
|
||||
|
||||
/** @var string */
|
||||
private $envAllowXdebug;
|
||||
|
||||
/** @var string */
|
||||
private $envOriginalInis;
|
||||
|
||||
/** @var bool */
|
||||
private $persistent;
|
||||
|
||||
/** @var string|null */
|
||||
private $script;
|
||||
|
||||
/** @var Status */
|
||||
private $statusWriter;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* The $envPrefix is used to create distinct environment variables. It is
|
||||
* uppercased and prepended to the default base values. For example 'myapp'
|
||||
* would result in MYAPP_ALLOW_XDEBUG and MYAPP_ORIGINAL_INIS.
|
||||
*
|
||||
* @param string $envPrefix Value used in environment variables
|
||||
* @throws \RuntimeException If the parameter is invalid
|
||||
*/
|
||||
public function __construct($envPrefix)
|
||||
{
|
||||
if (!is_string($envPrefix) || $envPrefix === '') {
|
||||
throw new \RuntimeException('Invalid constructor parameter');
|
||||
}
|
||||
|
||||
self::$name = strtoupper($envPrefix);
|
||||
$this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW;
|
||||
$this->envOriginalInis = self::$name.self::SUFFIX_INIS;
|
||||
|
||||
self::setXdebugDetails();
|
||||
self::$inRestart = false;
|
||||
|
||||
if ($this->cli = PHP_SAPI === 'cli') {
|
||||
$this->debug = (string) getenv(self::DEBUG);
|
||||
}
|
||||
|
||||
$this->statusWriter = new Status($this->envAllowXdebug, (bool) $this->debug);
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates status message output to a PSR3 logger
|
||||
*
|
||||
* @param LoggerInterface $logger
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->statusWriter->setLogger($logger);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the main script location if it cannot be called from argv
|
||||
*
|
||||
* @param string $script
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMainScript($script)
|
||||
{
|
||||
$this->script = $script;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist the settings to keep Xdebug out of sub-processes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPersistent()
|
||||
{
|
||||
$this->persistent = true;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Xdebug is loaded and the process needs to be restarted
|
||||
*
|
||||
* This behaviour can be disabled by setting the MYAPP_ALLOW_XDEBUG
|
||||
* environment variable to 1. This variable is used internally so that
|
||||
* the restarted process is created only once.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function check()
|
||||
{
|
||||
$this->notify(Status::CHECK, self::$xdebugVersion.'|'.self::$xdebugMode);
|
||||
$envArgs = explode('|', (string) getenv($this->envAllowXdebug));
|
||||
|
||||
if (!((bool) $envArgs[0]) && $this->requiresRestart(self::$xdebugActive)) {
|
||||
// Restart required
|
||||
$this->notify(Status::RESTART);
|
||||
|
||||
if ($this->prepareRestart()) {
|
||||
$command = $this->getCommand();
|
||||
$this->restart($command);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (self::RESTART_ID === $envArgs[0] && count($envArgs) === 5) {
|
||||
// Restarted, so unset environment variable and use saved values
|
||||
$this->notify(Status::RESTARTED);
|
||||
|
||||
Process::setEnv($this->envAllowXdebug);
|
||||
self::$inRestart = true;
|
||||
|
||||
if (self::$xdebugVersion === null) {
|
||||
// Skipped version is only set if Xdebug is not loaded
|
||||
self::$skipped = $envArgs[1];
|
||||
}
|
||||
|
||||
$this->tryEnableSignals();
|
||||
|
||||
// Put restart settings in the environment
|
||||
$this->setEnvRestartSettings($envArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->notify(Status::NORESTART);
|
||||
$settings = self::getRestartSettings();
|
||||
|
||||
if ($settings !== null) {
|
||||
// Called with existing settings, so sync our settings
|
||||
$this->syncSettings($settings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of php.ini locations with at least one entry
|
||||
*
|
||||
* The equivalent of calling php_ini_loaded_file then php_ini_scanned_files.
|
||||
* The loaded ini location is the first entry and may be empty.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function getAllIniFiles()
|
||||
{
|
||||
if (self::$name !== null) {
|
||||
$env = getenv(self::$name.self::SUFFIX_INIS);
|
||||
|
||||
if (false !== $env) {
|
||||
return explode(PATH_SEPARATOR, $env);
|
||||
}
|
||||
}
|
||||
|
||||
$paths = array((string) php_ini_loaded_file());
|
||||
$scanned = php_ini_scanned_files();
|
||||
|
||||
if ($scanned !== false) {
|
||||
$paths = array_merge($paths, array_map('trim', explode(',', $scanned)));
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of restart settings or null
|
||||
*
|
||||
* Settings will be available if the current process was restarted, or
|
||||
* called with the settings from an existing restart.
|
||||
*
|
||||
* @return array|null
|
||||
* @phpstan-return restartData|null
|
||||
*/
|
||||
public static function getRestartSettings()
|
||||
{
|
||||
$envArgs = explode('|', (string) getenv(self::RESTART_SETTINGS));
|
||||
|
||||
if (count($envArgs) !== 6
|
||||
|| (!self::$inRestart && php_ini_loaded_file() !== $envArgs[0])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return array(
|
||||
'tmpIni' => $envArgs[0],
|
||||
'scannedInis' => (bool) $envArgs[1],
|
||||
'scanDir' => '*' === $envArgs[2] ? false : $envArgs[2],
|
||||
'phprc' => '*' === $envArgs[3] ? false : $envArgs[3],
|
||||
'inis' => explode(PATH_SEPARATOR, $envArgs[4]),
|
||||
'skipped' => $envArgs[5],
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Xdebug version that triggered a successful restart
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getSkippedVersion()
|
||||
{
|
||||
return (string) self::$skipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether Xdebug is loaded and active
|
||||
*
|
||||
* true: if Xdebug is loaded and is running in an active mode.
|
||||
* false: if Xdebug is not loaded, or it is running with xdebug.mode=off.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isXdebugActive()
|
||||
{
|
||||
self::setXdebugDetails();
|
||||
return self::$xdebugActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows an extending class to decide if there should be a restart
|
||||
*
|
||||
* The default is to restart if Xdebug is loaded and its mode is not "off".
|
||||
* Do not typehint for 1.x compatibility.
|
||||
*
|
||||
* @param bool $default The default behaviour
|
||||
*
|
||||
* @return bool Whether the process should restart
|
||||
*/
|
||||
protected function requiresRestart($default)
|
||||
{
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows an extending class to access the tmpIni
|
||||
*
|
||||
* Do not typehint for 1.x compatibility
|
||||
*
|
||||
* @param string[] $command
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function restart($command)
|
||||
{
|
||||
$this->doRestart($command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the restarted command then deletes the tmp ini
|
||||
*
|
||||
* @param string[] $command
|
||||
*
|
||||
* @return void
|
||||
* @phpstan-return never
|
||||
*/
|
||||
private function doRestart(array $command)
|
||||
{
|
||||
$this->tryEnableSignals();
|
||||
$this->notify(Status::RESTARTING, implode(' ', $command));
|
||||
|
||||
if (PHP_VERSION_ID >= 70400) {
|
||||
$cmd = $command;
|
||||
} else {
|
||||
$cmd = Process::escapeShellCommand($command);
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
// Outer quotes required on cmd string below PHP 8
|
||||
$cmd = '"'.$cmd.'"';
|
||||
}
|
||||
}
|
||||
|
||||
$process = proc_open($cmd, array(), $pipes);
|
||||
if (is_resource($process)) {
|
||||
$exitCode = proc_close($process);
|
||||
}
|
||||
|
||||
if (!isset($exitCode)) {
|
||||
// Unlikely that php or the default shell cannot be invoked
|
||||
$this->notify(Status::ERROR, 'Unable to restart process');
|
||||
$exitCode = -1;
|
||||
} else {
|
||||
$this->notify(Status::INFO, 'Restarted process exited '.$exitCode);
|
||||
}
|
||||
|
||||
if ($this->debug === '2') {
|
||||
$this->notify(Status::INFO, 'Temp ini saved: '.$this->tmpIni);
|
||||
} else {
|
||||
@unlink((string) $this->tmpIni);
|
||||
}
|
||||
|
||||
exit($exitCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if everything was written for the restart
|
||||
*
|
||||
* If any of the following fails (however unlikely) we must return false to
|
||||
* stop potential recursion:
|
||||
* - tmp ini file creation
|
||||
* - environment variable creation
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function prepareRestart()
|
||||
{
|
||||
$error = null;
|
||||
$iniFiles = self::getAllIniFiles();
|
||||
$scannedInis = count($iniFiles) > 1;
|
||||
$tmpDir = sys_get_temp_dir();
|
||||
|
||||
if (!$this->cli) {
|
||||
$error = 'Unsupported SAPI: '.PHP_SAPI;
|
||||
} elseif (!defined('PHP_BINARY')) {
|
||||
$error = 'PHP version is too old: '.PHP_VERSION;
|
||||
} elseif (!$this->checkConfiguration($info)) {
|
||||
$error = $info;
|
||||
} elseif (!$this->checkScanDirConfig()) {
|
||||
$error = 'PHP version does not report scanned inis: '.PHP_VERSION;
|
||||
} elseif (!$this->checkMainScript()) {
|
||||
$error = 'Unable to access main script: '.$this->script;
|
||||
} elseif (!$this->writeTmpIni($iniFiles, $tmpDir, $error)) {
|
||||
$error = $error !== null ? $error : 'Unable to create temp ini file at: '.$tmpDir;
|
||||
} elseif (!$this->setEnvironment($scannedInis, $iniFiles)) {
|
||||
$error = 'Unable to set environment variables';
|
||||
}
|
||||
|
||||
if ($error !== null) {
|
||||
$this->notify(Status::ERROR, $error);
|
||||
}
|
||||
|
||||
return $error === null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the tmp ini file was written
|
||||
*
|
||||
* @param string[] $iniFiles All ini files used in the current process
|
||||
* @param string $tmpDir The system temporary directory
|
||||
* @param null|string $error Set by method if ini file cannot be read
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function writeTmpIni(array $iniFiles, $tmpDir, &$error)
|
||||
{
|
||||
if (($tmpfile = @tempnam($tmpDir, '')) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->tmpIni = $tmpfile;
|
||||
|
||||
// $iniFiles has at least one item and it may be empty
|
||||
if ($iniFiles[0] === '') {
|
||||
array_shift($iniFiles);
|
||||
}
|
||||
|
||||
$content = '';
|
||||
$sectionRegex = '/^\s*\[(?:PATH|HOST)\s*=/mi';
|
||||
$xdebugRegex = '/^\s*(zend_extension\s*=.*xdebug.*)$/mi';
|
||||
|
||||
foreach ($iniFiles as $file) {
|
||||
// Check for inaccessible ini files
|
||||
if (($data = @file_get_contents($file)) === false) {
|
||||
$error = 'Unable to read ini: '.$file;
|
||||
return false;
|
||||
}
|
||||
// Check and remove directives after HOST and PATH sections
|
||||
if (Preg::isMatchWithOffsets($sectionRegex, $data, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
$data = substr($data, 0, $matches[0][1]);
|
||||
}
|
||||
$content .= Preg::replace($xdebugRegex, ';$1', $data).PHP_EOL;
|
||||
}
|
||||
|
||||
// Merge loaded settings into our ini content, if it is valid
|
||||
$config = parse_ini_string($content);
|
||||
$loaded = ini_get_all(null, false);
|
||||
|
||||
if (false === $config || false === $loaded) {
|
||||
$error = 'Unable to parse ini data';
|
||||
return false;
|
||||
}
|
||||
|
||||
$content .= $this->mergeLoadedConfig($loaded, $config);
|
||||
|
||||
// Work-around for https://bugs.php.net/bug.php?id=75932
|
||||
$content .= 'opcache.enable_cli=0'.PHP_EOL;
|
||||
|
||||
return (bool) @file_put_contents($this->tmpIni, $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command line arguments for the restart
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function getCommand()
|
||||
{
|
||||
$php = array(PHP_BINARY);
|
||||
$args = array_slice($_SERVER['argv'], 1);
|
||||
|
||||
if (!$this->persistent) {
|
||||
// Use command-line options
|
||||
array_push($php, '-n', '-c', $this->tmpIni);
|
||||
}
|
||||
|
||||
return array_merge($php, array($this->script), $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the restart environment variables were set
|
||||
*
|
||||
* No need to update $_SERVER since this is set in the restarted process.
|
||||
*
|
||||
* @param bool $scannedInis Whether there were scanned ini files
|
||||
* @param string[] $iniFiles All ini files used in the current process
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function setEnvironment($scannedInis, array $iniFiles)
|
||||
{
|
||||
$scanDir = getenv('PHP_INI_SCAN_DIR');
|
||||
$phprc = getenv('PHPRC');
|
||||
|
||||
// Make original inis available to restarted process
|
||||
if (!putenv($this->envOriginalInis.'='.implode(PATH_SEPARATOR, $iniFiles))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->persistent) {
|
||||
// Use the environment to persist the settings
|
||||
if (!putenv('PHP_INI_SCAN_DIR=') || !putenv('PHPRC='.$this->tmpIni)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Flag restarted process and save values for it to use
|
||||
$envArgs = array(
|
||||
self::RESTART_ID,
|
||||
self::$xdebugVersion,
|
||||
(int) $scannedInis,
|
||||
false === $scanDir ? '*' : $scanDir,
|
||||
false === $phprc ? '*' : $phprc,
|
||||
);
|
||||
|
||||
return putenv($this->envAllowXdebug.'='.implode('|', $envArgs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs status messages
|
||||
*
|
||||
* @param string $op Status handler constant
|
||||
* @param null|string $data Optional data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function notify($op, $data = null)
|
||||
{
|
||||
$this->statusWriter->report($op, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default, changed and command-line ini settings
|
||||
*
|
||||
* @param mixed[] $loadedConfig All current ini settings
|
||||
* @param mixed[] $iniConfig Settings from user ini files
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function mergeLoadedConfig(array $loadedConfig, array $iniConfig)
|
||||
{
|
||||
$content = '';
|
||||
|
||||
foreach ($loadedConfig as $name => $value) {
|
||||
// Value will either be null, string or array (HHVM only)
|
||||
if (!is_string($value)
|
||||
|| strpos($name, 'xdebug') === 0
|
||||
|| $name === 'apc.mmap_file_mask') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($iniConfig[$name]) || $iniConfig[$name] !== $value) {
|
||||
// Double-quote escape each value
|
||||
$content .= $name.'="'.addcslashes($value, '\\"').'"'.PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the script name can be used
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkMainScript()
|
||||
{
|
||||
if (null !== $this->script) {
|
||||
// Allow an application to set -- for standard input
|
||||
return file_exists($this->script) || '--' === $this->script;
|
||||
}
|
||||
|
||||
if (file_exists($this->script = $_SERVER['argv'][0])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use a backtrace to resolve Phar and chdir issues.
|
||||
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
$main = end($trace);
|
||||
|
||||
if ($main !== false && isset($main['file'])) {
|
||||
return file_exists($this->script = $main['file']);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds restart settings to the environment
|
||||
*
|
||||
* @param string[] $envArgs
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function setEnvRestartSettings($envArgs)
|
||||
{
|
||||
$settings = array(
|
||||
php_ini_loaded_file(),
|
||||
$envArgs[2],
|
||||
$envArgs[3],
|
||||
$envArgs[4],
|
||||
getenv($this->envOriginalInis),
|
||||
self::$skipped,
|
||||
);
|
||||
|
||||
Process::setEnv(self::RESTART_SETTINGS, implode('|', $settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs settings and the environment if called with existing settings
|
||||
*
|
||||
* @param array $settings
|
||||
* @phpstan-param restartData $settings
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function syncSettings(array $settings)
|
||||
{
|
||||
if (false === getenv($this->envOriginalInis)) {
|
||||
// Called by another app, so make original inis available
|
||||
Process::setEnv($this->envOriginalInis, implode(PATH_SEPARATOR, $settings['inis']));
|
||||
}
|
||||
|
||||
self::$skipped = $settings['skipped'];
|
||||
$this->notify(Status::INFO, 'Process called with existing restart settings');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are scanned inis and PHP is able to report them
|
||||
*
|
||||
* php_ini_scanned_files will fail when PHP_CONFIG_FILE_SCAN_DIR is empty.
|
||||
* Fixed in 7.1.13 and 7.2.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function checkScanDirConfig()
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70113 && PHP_VERSION_ID !== 70200) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ((string) getenv('PHP_INI_SCAN_DIR') === '')
|
||||
|| PHP_CONFIG_FILE_SCAN_DIR !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there are no known configuration issues
|
||||
*
|
||||
* @param string $info Set by method
|
||||
* @return bool
|
||||
*/
|
||||
private function checkConfiguration(&$info)
|
||||
{
|
||||
if (!function_exists('proc_open')) {
|
||||
$info = 'proc_open function is disabled';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extension_loaded('uopz') && !((bool) ini_get('uopz.disable'))) {
|
||||
// uopz works at opcode level and disables exit calls
|
||||
if (function_exists('uopz_allow_exit')) {
|
||||
@uopz_allow_exit(true);
|
||||
} else {
|
||||
$info = 'uopz extension is not compatible';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check UNC paths when using cmd.exe
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD') && PHP_VERSION_ID < 70400) {
|
||||
$workingDir = getcwd();
|
||||
|
||||
if ($workingDir === false) {
|
||||
$info = 'unable to determine working directory';
|
||||
return false;
|
||||
}
|
||||
|
||||
if (0 === strpos($workingDir, '\\\\')) {
|
||||
$info = 'cmd.exe does not support UNC paths: '.$workingDir;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables async signals and control interrupts in the restarted process
|
||||
*
|
||||
* Available on Unix PHP 7.1+ with the pcntl extension and Windows PHP 7.4+.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function tryEnableSignals()
|
||||
{
|
||||
if (function_exists('pcntl_async_signals') && function_exists('pcntl_signal')) {
|
||||
pcntl_async_signals(true);
|
||||
$message = 'Async signals enabled';
|
||||
|
||||
if (!self::$inRestart) {
|
||||
// Restarting, so ignore SIGINT in parent
|
||||
pcntl_signal(SIGINT, SIG_IGN);
|
||||
} elseif (is_int(pcntl_signal_get_handler(SIGINT))) {
|
||||
// Restarted, no handler set so force default action
|
||||
pcntl_signal(SIGINT, SIG_DFL);
|
||||
}
|
||||
}
|
||||
|
||||
if (!self::$inRestart && function_exists('sapi_windows_set_ctrl_handler')) {
|
||||
// Restarting, so set a handler to ignore CTRL events in the parent.
|
||||
// This ensures that CTRL+C events will be available in the child
|
||||
// process without having to enable them there, which is unreliable.
|
||||
sapi_windows_set_ctrl_handler(function ($evt) {});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets static properties $xdebugActive, $xdebugVersion and $xdebugMode
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private static function setXdebugDetails()
|
||||
{
|
||||
if (self::$xdebugActive !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$xdebugActive = false;
|
||||
if (!extension_loaded('xdebug')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$version = phpversion('xdebug');
|
||||
self::$xdebugVersion = $version !== false ? $version : 'unknown';
|
||||
|
||||
if (version_compare(self::$xdebugVersion, '3.1', '>=')) {
|
||||
$modes = xdebug_info('mode');
|
||||
self::$xdebugMode = count($modes) === 0 ? 'off' : implode(',', $modes);
|
||||
self::$xdebugActive = self::$xdebugMode !== 'off';
|
||||
return;
|
||||
}
|
||||
|
||||
// See if xdebug.mode is supported in this version
|
||||
$iniMode = ini_get('xdebug.mode');
|
||||
if ($iniMode === false) {
|
||||
self::$xdebugActive = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Environment value wins but cannot be empty
|
||||
$envMode = (string) getenv('XDEBUG_MODE');
|
||||
if ($envMode !== '') {
|
||||
self::$xdebugMode = $envMode;
|
||||
} else {
|
||||
self::$xdebugMode = $iniMode !== '' ? $iniMode : 'off';
|
||||
}
|
||||
|
||||
// An empty comma-separated list is treated as mode 'off'
|
||||
if (Preg::isMatch('/^,+$/', str_replace(' ', '', self::$xdebugMode))) {
|
||||
self::$xdebugMode = 'off';
|
||||
}
|
||||
|
||||
self::$xdebugActive = self::$xdebugMode !== 'off';
|
||||
}
|
||||
}
|
2
vendor/graphp/graphviz/.gitignore
vendored
Normal file
2
vendor/graphp/graphviz/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/vendor
|
||||
/composer.lock
|
34
vendor/graphp/graphviz/.travis.yml
vendored
Normal file
34
vendor/graphp/graphviz/.travis.yml
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
language: php
|
||||
|
||||
php:
|
||||
# - 5.3 # requires old distro, see below
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
- 7.2
|
||||
- hhvm # ignore errors, see below
|
||||
|
||||
# lock distro so future defaults will not break the build
|
||||
dist: trusty
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
dist: precise
|
||||
allow_failures:
|
||||
- php: hhvm
|
||||
|
||||
sudo: false
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- graphviz
|
||||
|
||||
install:
|
||||
- composer install --no-interaction
|
||||
|
||||
script:
|
||||
- vendor/bin/phpunit --coverage-text
|
44
vendor/graphp/graphviz/CHANGELOG.md
vendored
Normal file
44
vendor/graphp/graphviz/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Changelog
|
||||
|
||||
## 0.2.2 (2019-10-04)
|
||||
|
||||
* Feature: Omit root graph name unless explicitly assigned via `graphviz.name` attribute.
|
||||
(#28 by @rhelms and @clue)
|
||||
|
||||
```php
|
||||
$graph = new Graph();
|
||||
$graph->setAttribute('graphviz.name', 'g');
|
||||
```
|
||||
|
||||
* Feature: Remove unneeded dependency on `graphp/algorithms`.
|
||||
(#39 by @clue)
|
||||
|
||||
* Feature / Fix: Use UTF-8 encoding (Unicode) by default and respect charset attribute.
|
||||
(#27 by @Ithilias and @clue)
|
||||
|
||||
* Fix: Fix representing directed loop edges as directed edge
|
||||
(#37 by @clue)
|
||||
|
||||
* Add examples and documentation for GraphViz attributes, labels and record shapes.
|
||||
(#26 by @clue)
|
||||
|
||||
* Update test suite to support PHPUnit 6 and PHPUnit 5 and support running on legacy PHP 5.3 through PHP 7.2 and HHVM.
|
||||
(#24 by @clue)
|
||||
|
||||
## 0.2.1 (2015-03-08)
|
||||
|
||||
* Support graph v0.9 (while keeping BC)
|
||||
([#9](https://github.com/graphp/graphviz/pull/9))
|
||||
|
||||
## 0.2.0 (2015-01-19)
|
||||
|
||||
* BC break: Refactor to inject Graph into GraphViz on demand, inject GraphViz into exporters
|
||||
([#6](https://github.com/graphp/graphviz/pull/6))
|
||||
|
||||
* BC break: Remove legacy layout helper
|
||||
([#5](https://github.com/graphp/graphviz/pull/5))
|
||||
|
||||
## 0.1.0 (2014-12-31)
|
||||
|
||||
* First tagged release, split off from [clue/graph](https://github.com/clue/graph) v0.8.0
|
||||
([#1](https://github.com/graphp/graphviz/issues/1))
|
22
vendor/graphp/graphviz/LICENSE
vendored
Normal file
22
vendor/graphp/graphviz/LICENSE
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012+ Christian Lück (Maintainer)
|
||||
Copyright (c) 2012+ Fhaculty Core Team and our awesome contributors <https://github.com/clue/graph/graphs/contributors>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
425
vendor/graphp/graphviz/README.md
vendored
Normal file
425
vendor/graphp/graphviz/README.md
vendored
Normal file
|
@ -0,0 +1,425 @@
|
|||
# graphp/graphviz [](https://travis-ci.org/graphp/graphviz)
|
||||
|
||||
GraphViz graph drawing for the mathematical graph/network library GraPHP.
|
||||
|
||||
The library supports visualizing graph images, including them into webpages,
|
||||
opening up images from within CLI applications and exporting them
|
||||
as PNG, JPEG or SVG file formats (among many others).
|
||||
Because [graph drawing](http://en.wikipedia.org/wiki/Graph_drawing) is a complex area on its own,
|
||||
the actual layouting of the graph is left up to the excelent [GraphViz](http://www.graphviz.org/)
|
||||
"Graph Visualization Software" and we merely provide some convenient APIs to interface with GraphViz.
|
||||
|
||||
> Note: This project is in beta stage! Feel free to report any issues you encounter.
|
||||
|
||||
**Table of contents**
|
||||
|
||||
* [Quickstart examples](#quickstart-examples)
|
||||
* [Attributes](#attributes)
|
||||
* [Graph attributes](#graph-attributes)
|
||||
* [Vertex attributes](#vertex-attributes)
|
||||
* [Edge attributes](#edge-attributes)
|
||||
* [Labels](#labels)
|
||||
* [Vertex labels](#vertex-labels)
|
||||
* [Edge labels](#edge-labels)
|
||||
* [HTML-like labels](#html-like-labels)
|
||||
* [Record-based nodes](#record-based-nodes)
|
||||
* [Install](#install)
|
||||
* [Tests](#tests)
|
||||
* [License](#license)
|
||||
|
||||
## Quickstart examples
|
||||
|
||||
Once [installed](#install), let's build and display a sample graph:
|
||||
|
||||
````php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
$blue->setAttribute('graphviz.color', 'blue');
|
||||
|
||||
$red = $graph->createVertex('red');
|
||||
$red->setAttribute('graphviz.color', 'red');
|
||||
|
||||
$edge = $blue->createEdgeTo($red);
|
||||
$edge->setAttribute('graphviz.color', 'grey');
|
||||
|
||||
$graphviz = new Graphp\GraphViz\GraphViz();
|
||||
$graphviz->display($graph);
|
||||
````
|
||||
|
||||
The above code will open your default image viewer with the following image:
|
||||
|
||||

|
||||
|
||||
See also the [examples](examples/).
|
||||
|
||||
## Attributes
|
||||
|
||||
GraphViz supports a number of attributes on the graph instance itself, each
|
||||
vertex instance (GraphViz calls these "nodes") and edge instance. Any of these
|
||||
GraphViz attributes are supported by this library and have to be assigned using
|
||||
GraPHP attributes as documented below.
|
||||
|
||||
For the full list of all GraphViz attributes, please refer to the
|
||||
[GraphViz documentation](https://graphviz.gitlab.io/_pages/doc/info/attrs.html).
|
||||
|
||||
Note that all attributes use UTF-8 encoding (Unicode) and will be quoted and
|
||||
escaped by default, so a `ö` and `>` will appear as-is and will not be
|
||||
interpreted as HTML. See also [HTML-like labels](#html-like-labels) below for
|
||||
more details.
|
||||
|
||||
### Graph attributes
|
||||
|
||||
GraphViz supports a number of attributes on the graph instance itself. Any of
|
||||
these GraphViz attributes are supported by this library and have to be assigned
|
||||
on the graph instance with the `graphviz.graph.` prefix like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.graph.bgcolor', 'transparent');
|
||||
```
|
||||
|
||||
> Note how this uses the `graphviz.graph.` prefix and not just `graphviz.`. This
|
||||
is done for consistency reasons with respect to default vertex and edge
|
||||
attributes as documented below.
|
||||
|
||||
For example, the `rankdir` attribute can be used to change the orientation to
|
||||
horizontal mode (left to right) like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.graph.rankdir', 'LR');
|
||||
|
||||
$hello = $graph->createVertex('hello');
|
||||
$world = $graph->createVertex('wörld');
|
||||
$hello->createEdgeTo($world);
|
||||
```
|
||||
|
||||

|
||||
|
||||
See also the [examples](examples/).
|
||||
|
||||
Additionally, this library accepts an optional `graphviz.name` attribute that
|
||||
will be used as the name (or ID) for the root graph object in the DOT output if
|
||||
given. Unless explicitly assigned, this will be omitted by default. It is common
|
||||
to assign a `G` here, but usually there should be no need to assign this. Among
|
||||
others, this may be used as the title or tooltip in SVG output.
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.name', 'G');
|
||||
|
||||
$graph->createVertex('first');
|
||||
```
|
||||
|
||||
### Vertex attributes
|
||||
|
||||
GraphViz supports a number of attributes on each vertex instance (GraphViz calls
|
||||
these "node" attributes). Any of these GraphViz attributes are supported by this
|
||||
library and have to be assigned on the respective vertex instance with the
|
||||
`graphviz.` prefix like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
$blue->setAttribute('graphviz.color', 'blue');
|
||||
```
|
||||
|
||||
Additionally, GraphViz also supports default attributes for all vertices. Any of
|
||||
these GraphViz attributes are supported by this library and have to be assigned
|
||||
on the graph instance with the `graphviz.node.` prefix like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.node.color', 'grey');
|
||||
|
||||
$grey = $graph->createVertex('grey');
|
||||
```
|
||||
|
||||
These default attributes can be overriden on each vertex instance by explicitly
|
||||
assigning the same attribute on the respective vertex instance like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.node.color', 'grey');
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
$blue->setAttribute('graphviz.color', 'blue');
|
||||
```
|
||||
|
||||
> Note how this uses the `graphviz.node.` prefix and not `graphviz.vertex.`. This
|
||||
is done for consistency reasons with respect to how GraphViz assigns these
|
||||
default attributes in its DOT output.
|
||||
|
||||
### Edge attributes
|
||||
|
||||
GraphViz supports a number of attributes on each edge instance. Any of these
|
||||
GraphViz attributes are supported by this library and have to be assigned on the
|
||||
respective edge instance with the `graphviz.` prefix like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$blue = $a->createEdgeTo($b);
|
||||
$blue->setAttribute('graphviz.color', 'blue');
|
||||
```
|
||||
|
||||
Additionally, GraphViz also supports default attributes for all edges. Any of
|
||||
these GraphViz attributes are supported by this library and have to be assigned
|
||||
on the graph instance with the `graphviz.edge.` prefix like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.edge.color', 'grey');
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$grey = $a->createEdgeTo($b);
|
||||
```
|
||||
|
||||
These default attributes can be overriden on each edge instance by explicitly
|
||||
assigning the same attribute on the respective edge instance like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.edge.color', 'grey');
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$blue = $a->createEdgeTo($b);
|
||||
$blue->setAttribute('graphviz.color', 'blue');
|
||||
```
|
||||
|
||||
## Labels
|
||||
|
||||
### Vertex labels
|
||||
|
||||
By default, GraphViz will always render the vertex ID as the label:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
```
|
||||
|
||||
If you assign a vertex balance, this library will automatically include a
|
||||
`label` attribute that includes the balance value. The following example will
|
||||
automatically assign `blue (+10)` as the label:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
$blue->setBalance(10);
|
||||
```
|
||||
|
||||
You can use [vertex attributes](#vertex-attributes) to explicitly assign a
|
||||
custom `label` attribute. Note that any balance value will still be appended
|
||||
like in the previous example.
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
$blue->setAttribute('graphviz.label', 'Hello world!');
|
||||
```
|
||||
|
||||
Note that all [attributes](#attributes) will be quoted and escaped by default,
|
||||
so a `>` will appear as-is and will not be interpreted as HTML. See also
|
||||
[HTML-like labels](#html-like-labels) below for more details.
|
||||
|
||||
### Edge labels
|
||||
|
||||
By default, GraphViz will not render any label on an edge:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$edge = $a->createEdgeTo($b);
|
||||
```
|
||||
|
||||
If you assign an edge flow, capacity or weight, this library will automatically
|
||||
include a `label` attribute that includes these values. The following example
|
||||
will automatically assign `100` as the label for the weighted edge:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$edge = $a->createEdgeTo($b);
|
||||
$edge->setWeight(100);
|
||||
```
|
||||
|
||||
The following example will automatically assign `4/10` as the label for an edge
|
||||
with both flow and maximum capacity set:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$edge = $a->createEdgeTo($b);
|
||||
$edge->setFlow(4);
|
||||
$edge->setCapacity(10);
|
||||
```
|
||||
|
||||
The following example will automatically assign `4/∞/100` as the label for a
|
||||
weighted edge with a flow and unlimited capacity:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$edge = $a->createEdgeTo($b);
|
||||
$edge->setFlow(4);
|
||||
$edge->setCapacity(null);
|
||||
$edge->setWeight(100);
|
||||
```
|
||||
|
||||
You can use [edge attributes](#edge-attributes) to explicitly assign any
|
||||
custom `label` attribute. Note that any flow, capacity or weight value will still
|
||||
be appended like in the previous examples.
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('a');
|
||||
$b = $graph->createVertex('b');
|
||||
|
||||
$edge = $a->createEdgeTo($b);
|
||||
$edge->setAttribute('graphviz.label', 'important');
|
||||
```
|
||||
|
||||
### HTML-like labels
|
||||
|
||||
Note that all [attributes](#attributes) will be quoted and escaped by default,
|
||||
so a `>` will appear as-is and will not be interpreted as HTML. GraphViz also
|
||||
supports [HTML-like labels](https://graphviz.gitlab.io/_pages/doc/info/shapes.html#html)
|
||||
that support a subset of HTML features.
|
||||
|
||||
GraphViz requires any HTML-like label to be wrapped in `<` and `>` and only
|
||||
supports a limited subset of HTML features as documented above. In order to
|
||||
prevent automatic quoting and escaping, all attribute values have to be passed
|
||||
to the static `GraphViz::raw()` helper like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex('Entity');
|
||||
$a->setAttribute('graphviz.shape', 'none');
|
||||
$a->setAttribute('graphviz.label', GraphViz::raw('<
|
||||
<table cellspacing="0" border="0" cellborder="1">
|
||||
<tr><td bgcolor="#eeeeee"><b>\N</b></td></tr>
|
||||
<tr><td></td></tr><tr>
|
||||
<td>+ touch()</td></tr>
|
||||
</table>>'));
|
||||
|
||||
$b = $graph->createVertex('Block');
|
||||
$b->createEdgeTo($a);
|
||||
$b->setAttribute('graphviz.shape', 'none');
|
||||
$b->setAttribute('graphviz.label', GraphViz::raw('<
|
||||
<table cellspacing="0" border="0" cellborder="1">
|
||||
<tr><td bgcolor="#eeeeee"><b>\N</b></td></tr>
|
||||
<tr><td>- size:int</td></tr>
|
||||
<tr><td>+ touch()</td></tr>
|
||||
</table>>'));
|
||||
```
|
||||
|
||||

|
||||
|
||||
See also the [examples](examples/).
|
||||
|
||||
### Record-based nodes
|
||||
|
||||
Note that all [attributes](#attributes) will be quoted and escaped by default,
|
||||
so a `>` will appear as-is and will not be interpreted as HTML. Similar to the
|
||||
above [HTML-like labels](#html-like-labels), GraphViz also supports simple
|
||||
[record-based nodes](https://graphviz.gitlab.io/_pages/doc/info/shapes.html#record)
|
||||
using the `record` and `Mrecord` shape attributes and structured label attributes.
|
||||
|
||||
GraphViz requires any record-based node label to be quoted, but uses special
|
||||
syntax to mark record fields and optional port names. In order to prevent
|
||||
automatic quoting and escaping, all attribute values have to be quoted manually
|
||||
and passed to the static `GraphViz::raw()` helper like this:
|
||||
|
||||
```php
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$a = $graph->createVertex();
|
||||
$a->setAttribute('graphviz.shape', 'Mrecord');
|
||||
$a->setAttribute('graphviz.label', GraphViz::raw('"<f0> left |<middle> middle |<f2> right"'));
|
||||
|
||||
$b = $graph->createVertex();
|
||||
$b->setAttribute('graphviz.shape', 'Mrecord');
|
||||
$b->setAttribute('graphviz.label', GraphViz::raw('"<f0> left |<f1> middle |<right> right"'));
|
||||
|
||||
// a:middle -> b:right
|
||||
$edge = $a->createEdgeTo($b);
|
||||
$edge->setAttribute('graphviz.tailport', 'middle');
|
||||
$edge->setAttribute('graphviz.headport', 'right');
|
||||
```
|
||||
|
||||

|
||||
|
||||
See also the [examples](examples/).
|
||||
|
||||
## Install
|
||||
|
||||
The recommended way to install this library is [through Composer](https://getcomposer.org).
|
||||
[New to Composer?](https://getcomposer.org/doc/00-intro.md)
|
||||
|
||||
This will install the latest supported version:
|
||||
|
||||
```bash
|
||||
$ composer require graphp/graphviz:^0.2.2
|
||||
```
|
||||
|
||||
See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
|
||||
|
||||
This project aims to run on any platform and thus does not require any PHP
|
||||
extensions and supports running on legacy PHP 5.3 through current PHP 7+ and
|
||||
HHVM.
|
||||
It's *highly recommended to use PHP 7+* for this project.
|
||||
|
||||
The graph drawing feature is powered by the excellent [GraphViz](https://www.graphviz.org)
|
||||
software. This means you'll have to install GraphViz (`dot` executable).
|
||||
The [Graphviz homepage](https://www.graphviz.org/download/) includes complete
|
||||
installation instructions for most common platforms, users of Debian/Ubuntu-based
|
||||
distributions may simply invoke:
|
||||
|
||||
```bash
|
||||
$ sudo apt install graphviz
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
To run the test suite, you first need to clone this repo and then install all
|
||||
dependencies [through Composer](https://getcomposer.org):
|
||||
|
||||
```bash
|
||||
$ composer install
|
||||
```
|
||||
|
||||
To run the test suite, go to the project root and run:
|
||||
|
||||
```bash
|
||||
$ php vendor/bin/phpunit
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
Released under the terms of the permissive [MIT license](http://opensource.org/licenses/MIT).
|
18
vendor/graphp/graphviz/composer.json
vendored
Normal file
18
vendor/graphp/graphviz/composer.json
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "graphp/graphviz",
|
||||
"type": "library",
|
||||
"description": "GraphViz graph drawing for the mathematical graph/network library GraPHP.",
|
||||
"keywords": ["GraphViz", "graph drawing", "graph image", "dot output", "GraPHP"],
|
||||
"homepage": "https://github.com/graphp/graphviz",
|
||||
"license": "MIT",
|
||||
"autoload": {
|
||||
"psr-4": {"Graphp\\GraphViz\\": "src/"}
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"clue/graph": "~0.9.0|~0.8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35"
|
||||
}
|
||||
}
|
17
vendor/graphp/graphviz/examples/01-simple.php
vendored
Normal file
17
vendor/graphp/graphviz/examples/01-simple.php
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
|
||||
$blue = $graph->createVertex('blue');
|
||||
$blue->setAttribute('graphviz.color', 'blue');
|
||||
|
||||
$red = $graph->createVertex('red');
|
||||
$red->setAttribute('graphviz.color', 'red');
|
||||
|
||||
$edge = $blue->createEdgeTo($red);
|
||||
$edge->setAttribute('graphviz.color', 'grey');
|
||||
|
||||
$graphviz = new Graphp\GraphViz\GraphViz();
|
||||
$graphviz->display($graph);
|
BIN
vendor/graphp/graphviz/examples/01-simple.png
vendored
Normal file
BIN
vendor/graphp/graphviz/examples/01-simple.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
25
vendor/graphp/graphviz/examples/02-html.php
vendored
Normal file
25
vendor/graphp/graphviz/examples/02-html.php
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
// $ php -S localhost:8080 examples/02-html.php
|
||||
|
||||
require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$graph = new Fhaculty\Graph\Graph();
|
||||
$graph->setAttribute('graphviz.graph.rankdir', 'LR');
|
||||
|
||||
$hello = $graph->createVertex('hello');
|
||||
$world = $graph->createVertex('wörld');
|
||||
$hello->createEdgeTo($world);
|
||||
|
||||
$graphviz = new Graphp\GraphViz\GraphViz();
|
||||
$graphviz->setFormat('svg');
|
||||
|
||||
echo '<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>hello wörld</title>
|
||||
<body>
|
||||
' . $graphviz->createImageHtml($graph) . '
|
||||
</body>
|
||||
</html>
|
||||
';
|
BIN
vendor/graphp/graphviz/examples/02-html.png
vendored
Normal file
BIN
vendor/graphp/graphviz/examples/02-html.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue