Vendor
This commit is contained in:
parent
e74df463f2
commit
499abe195e
921
vendor/symfony/polyfill-intl-idn/Idn.php
vendored
Normal file
921
vendor/symfony/polyfill-intl-idn/Idn.php
vendored
Normal file
@ -0,0 +1,921 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com> and Trevor Rowbotham <trevor.rowbotham@pm.me>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Intl\Idn;
|
||||
|
||||
use Exception;
|
||||
use Normalizer;
|
||||
use Symfony\Polyfill\Intl\Idn\Resources\unidata\DisallowedRanges;
|
||||
use Symfony\Polyfill\Intl\Idn\Resources\unidata\Regex;
|
||||
|
||||
/**
|
||||
* @see https://www.unicode.org/reports/tr46/
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Idn
|
||||
{
|
||||
const ERROR_EMPTY_LABEL = 1;
|
||||
const ERROR_LABEL_TOO_LONG = 2;
|
||||
const ERROR_DOMAIN_NAME_TOO_LONG = 4;
|
||||
const ERROR_LEADING_HYPHEN = 8;
|
||||
const ERROR_TRAILING_HYPHEN = 0x10;
|
||||
const ERROR_HYPHEN_3_4 = 0x20;
|
||||
const ERROR_LEADING_COMBINING_MARK = 0x40;
|
||||
const ERROR_DISALLOWED = 0x80;
|
||||
const ERROR_PUNYCODE = 0x100;
|
||||
const ERROR_LABEL_HAS_DOT = 0x200;
|
||||
const ERROR_INVALID_ACE_LABEL = 0x400;
|
||||
const ERROR_BIDI = 0x800;
|
||||
const ERROR_CONTEXTJ = 0x1000;
|
||||
const ERROR_CONTEXTO_PUNCTUATION = 0x2000;
|
||||
const ERROR_CONTEXTO_DIGITS = 0x4000;
|
||||
|
||||
const INTL_IDNA_VARIANT_2003 = 0;
|
||||
const INTL_IDNA_VARIANT_UTS46 = 1;
|
||||
|
||||
const MAX_DOMAIN_SIZE = 253;
|
||||
const MAX_LABEL_SIZE = 63;
|
||||
|
||||
const BASE = 36;
|
||||
const TMIN = 1;
|
||||
const TMAX = 26;
|
||||
const SKEW = 38;
|
||||
const DAMP = 700;
|
||||
const INITIAL_BIAS = 72;
|
||||
const INITIAL_N = 128;
|
||||
const DELIMITER = '-';
|
||||
const MAX_INT = 2147483647;
|
||||
|
||||
/**
|
||||
* Contains the numeric value of a basic code point (for use in representing integers) in the
|
||||
* range 0 to BASE-1, or -1 if b is does not represent a value.
|
||||
*
|
||||
* @var array<int, int>
|
||||
*/
|
||||
private static $basicToDigit = array(
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array<int, int>
|
||||
*/
|
||||
private static $virama;
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private static $mapped;
|
||||
|
||||
/**
|
||||
* @var array<int, bool>
|
||||
*/
|
||||
private static $ignored;
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private static $deviation;
|
||||
|
||||
/**
|
||||
* @var array<int, bool>
|
||||
*/
|
||||
private static $disallowed;
|
||||
|
||||
/**
|
||||
* @var array<int, string>
|
||||
*/
|
||||
private static $disallowed_STD3_mapped;
|
||||
|
||||
/**
|
||||
* @var array<int, bool>
|
||||
*/
|
||||
private static $disallowed_STD3_valid;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private static $mappingTableLoaded = false;
|
||||
|
||||
/**
|
||||
* @see https://www.unicode.org/reports/tr46/#ToASCII
|
||||
*
|
||||
* @param string $domainName
|
||||
* @param int $options
|
||||
* @param int $variant
|
||||
* @param array $idna_info
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public static function idn_to_ascii($domainName, $options = IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = array())
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
|
||||
@trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'CheckHyphens' => true,
|
||||
'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & \IDNA_CHECK_BIDI),
|
||||
'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & \IDNA_CHECK_CONTEXTJ),
|
||||
'UseSTD3ASCIIRules' => 0 !== ($options & \IDNA_USE_STD3_RULES),
|
||||
'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & \IDNA_NONTRANSITIONAL_TO_ASCII),
|
||||
'VerifyDnsLength' => true,
|
||||
);
|
||||
$info = new Info();
|
||||
$labels = self::process((string) $domainName, $options, $info);
|
||||
|
||||
foreach ($labels as $i => $label) {
|
||||
// Only convert labels to punycode that contain non-ASCII code points and only if that
|
||||
// label does not contain a character from the gen-delims set specified in
|
||||
// {@link https://ietf.org/rfc/rfc3987.html#section-2.2}
|
||||
if (1 === preg_match('/[^\x00-\x7F]/', $label)) {
|
||||
if (false !== strpbrk($label, ':/?#[]@')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$label = 'xn--'.self::punycodeEncode($label);
|
||||
} catch (Exception $e) {
|
||||
$info->errors |= self::ERROR_PUNYCODE;
|
||||
}
|
||||
|
||||
$labels[$i] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
if ($options['VerifyDnsLength']) {
|
||||
self::validateDomainAndLabelLength($labels, $info);
|
||||
}
|
||||
|
||||
$idna_info = array(
|
||||
'result' => implode('.', $labels),
|
||||
'isTransitionalDifferent' => $info->transitionalDifferent,
|
||||
'errors' => $info->errors,
|
||||
);
|
||||
|
||||
return 0 === $info->errors ? $idna_info['result'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://www.unicode.org/reports/tr46/#ToUnicode
|
||||
*
|
||||
* @param string $domainName
|
||||
* @param int $options
|
||||
* @param int $variant
|
||||
* @param array $idna_info
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
public static function idn_to_utf8($domainName, $options = IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = array())
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
|
||||
@trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$info = new Info();
|
||||
$labels = self::process((string) $domainName, array(
|
||||
'CheckHyphens' => true,
|
||||
'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & \IDNA_CHECK_BIDI),
|
||||
'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & \IDNA_CHECK_CONTEXTJ),
|
||||
'UseSTD3ASCIIRules' => 0 !== ($options & \IDNA_USE_STD3_RULES),
|
||||
'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & \IDNA_NONTRANSITIONAL_TO_UNICODE),
|
||||
), $info);
|
||||
$idna_info = array(
|
||||
'result' => implode('.', $labels),
|
||||
'isTransitionalDifferent' => $info->transitionalDifferent,
|
||||
'errors' => $info->errors,
|
||||
);
|
||||
|
||||
return 0 === $info->errors ? $idna_info['result'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $label
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function isValidContextJ(array $codePoints, $label)
|
||||
{
|
||||
if (!isset(self::$virama)) {
|
||||
self::$virama = require __DIR__.\DIRECTORY_SEPARATOR.'Resources'.\DIRECTORY_SEPARATOR.'unidata'.\DIRECTORY_SEPARATOR.'virama.php';
|
||||
}
|
||||
|
||||
$offset = 0;
|
||||
|
||||
foreach ($codePoints as $i => $codePoint) {
|
||||
if (0x200C !== $codePoint && 0x200D !== $codePoint) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($codePoints[$i - 1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If Canonical_Combining_Class(Before(cp)) .eq. Virama Then True;
|
||||
if (isset(self::$virama[$codePoints[$i - 1]])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If RegExpMatch((Joining_Type:{L,D})(Joining_Type:T)*\u200C(Joining_Type:T)*(Joining_Type:{R,D})) Then
|
||||
// True;
|
||||
// Generated RegExp = ([Joining_Type:{L,D}][Joining_Type:T]*\u200C[Joining_Type:T]*)[Joining_Type:{R,D}]
|
||||
if (0x200C === $codePoint && 1 === preg_match(Regex::ZWNJ, $label, $matches, PREG_OFFSET_CAPTURE, $offset)) {
|
||||
$offset += \strlen($matches[1][0]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://www.unicode.org/reports/tr46/#ProcessingStepMap
|
||||
*
|
||||
* @param string $input
|
||||
* @param array<string, bool> $options
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function mapCodePoints($input, array $options, Info $info)
|
||||
{
|
||||
$str = '';
|
||||
$useSTD3ASCIIRules = $options['UseSTD3ASCIIRules'];
|
||||
$transitional = $options['Transitional_Processing'];
|
||||
|
||||
foreach (self::utf8Decode($input) as $codePoint) {
|
||||
$data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);
|
||||
|
||||
switch ($data['status']) {
|
||||
case 'disallowed':
|
||||
$info->errors |= self::ERROR_DISALLOWED;
|
||||
|
||||
// no break.
|
||||
|
||||
case 'valid':
|
||||
$str .= mb_chr($codePoint, 'utf-8');
|
||||
|
||||
break;
|
||||
|
||||
case 'ignored':
|
||||
// Do nothing.
|
||||
break;
|
||||
|
||||
case 'mapped':
|
||||
$str .= $data['mapping'];
|
||||
|
||||
break;
|
||||
|
||||
case 'deviation':
|
||||
$info->transitionalDifferent = true;
|
||||
$str .= ($transitional ? $data['mapping'] : mb_chr($codePoint, 'utf-8'));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://www.unicode.org/reports/tr46/#Processing
|
||||
*
|
||||
* @param string $domain
|
||||
* @param array<string, bool> $options
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
private static function process($domain, array $options, Info $info)
|
||||
{
|
||||
// If VerifyDnsLength is not set, we are doing ToUnicode otherwise we are doing ToASCII and
|
||||
// we need to respect the VerifyDnsLength option.
|
||||
$checkForEmptyLabels = !isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'];
|
||||
|
||||
if ($checkForEmptyLabels && '' === $domain) {
|
||||
$info->errors |= self::ERROR_EMPTY_LABEL;
|
||||
|
||||
return array($domain);
|
||||
}
|
||||
|
||||
// Step 1. Map each code point in the domain name string
|
||||
$domain = self::mapCodePoints($domain, $options, $info);
|
||||
|
||||
// Step 2. Normalize the domain name string to Unicode Normalization Form C.
|
||||
if (!Normalizer::isNormalized($domain, Normalizer::FORM_C)) {
|
||||
$domain = Normalizer::normalize($domain, Normalizer::FORM_C);
|
||||
}
|
||||
|
||||
// Step 3. Break the string into labels at U+002E (.) FULL STOP.
|
||||
$labels = explode('.', $domain);
|
||||
$lastLabelIndex = \count($labels) - 1;
|
||||
|
||||
// Step 4. Convert and validate each label in the domain name string.
|
||||
foreach ($labels as $i => $label) {
|
||||
$validationOptions = $options;
|
||||
|
||||
if ('xn--' === substr($label, 0, 4)) {
|
||||
try {
|
||||
$label = self::punycodeDecode(substr($label, 4));
|
||||
} catch (Exception $e) {
|
||||
$info->errors |= self::ERROR_PUNYCODE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$validationOptions['Transitional_Processing'] = false;
|
||||
$labels[$i] = $label;
|
||||
}
|
||||
|
||||
self::validateLabel($label, $info, $validationOptions, $i > 0 && $i === $lastLabelIndex);
|
||||
}
|
||||
|
||||
if ($info->bidiDomain && !$info->validBidiDomain) {
|
||||
$info->errors |= self::ERROR_BIDI;
|
||||
}
|
||||
|
||||
// Any input domain name string that does not record an error has been successfully
|
||||
// processed according to this specification. Conversely, if an input domain_name string
|
||||
// causes an error, then the processing of the input domain_name string fails. Determining
|
||||
// what to do with error input is up to the caller, and not in the scope of this document.
|
||||
return $labels;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://tools.ietf.org/html/rfc5893#section-2
|
||||
*
|
||||
* @param string $label
|
||||
*/
|
||||
private static function validateBidiLabel($label, Info $info)
|
||||
{
|
||||
if (1 === preg_match(Regex::RTL_LABEL, $label)) {
|
||||
$info->bidiDomain = true;
|
||||
|
||||
// Step 1. The first character must be a character with Bidi property L, R, or AL.
|
||||
// If it has the R or AL property, it is an RTL label
|
||||
if (1 !== preg_match(Regex::BIDI_STEP_1_RTL, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 2. In an RTL label, only characters with the Bidi properties R, AL, AN, EN, ES,
|
||||
// CS, ET, ON, BN, or NSM are allowed.
|
||||
if (1 === preg_match(Regex::BIDI_STEP_2, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 3. In an RTL label, the end of the label must be a character with Bidi property
|
||||
// R, AL, EN, or AN, followed by zero or more characters with Bidi property NSM.
|
||||
if (1 !== preg_match(Regex::BIDI_STEP_3, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 4. In an RTL label, if an EN is present, no AN may be present, and vice versa.
|
||||
if (1 === preg_match(Regex::BIDI_STEP_4_AN, $label) && 1 === preg_match(Regex::BIDI_STEP_4_EN, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We are a LTR label
|
||||
// Step 1. The first character must be a character with Bidi property L, R, or AL.
|
||||
// If it has the L property, it is an LTR label.
|
||||
if (1 !== preg_match(Regex::BIDI_STEP_1_LTR, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 5. In an LTR label, only characters with the Bidi properties L, EN,
|
||||
// ES, CS, ET, ON, BN, or NSM are allowed.
|
||||
if (1 === preg_match(Regex::BIDI_STEP_5, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 6.In an LTR label, the end of the label must be a character with Bidi property L or
|
||||
// EN, followed by zero or more characters with Bidi property NSM.
|
||||
if (1 !== preg_match(Regex::BIDI_STEP_6, $label)) {
|
||||
$info->validBidiDomain = false;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, string> $labels
|
||||
*/
|
||||
private static function validateDomainAndLabelLength(array $labels, Info $info)
|
||||
{
|
||||
$maxDomainSize = self::MAX_DOMAIN_SIZE;
|
||||
$length = \count($labels);
|
||||
|
||||
// Number of "." delimiters.
|
||||
$domainLength = $length - 1;
|
||||
|
||||
// If the last label is empty and it is not the first label, then it is the root label.
|
||||
// Increase the max size by 1, making it 254, to account for the root label's "."
|
||||
// delimiter. This also means we don't need to check the last label's length for being too
|
||||
// long.
|
||||
if ($length > 1 && '' === $labels[$length - 1]) {
|
||||
++$maxDomainSize;
|
||||
--$length;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$bytes = \strlen($labels[$i]);
|
||||
$domainLength += $bytes;
|
||||
|
||||
if ($bytes > self::MAX_LABEL_SIZE) {
|
||||
$info->errors |= self::ERROR_LABEL_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
if ($domainLength > $maxDomainSize) {
|
||||
$info->errors |= self::ERROR_DOMAIN_NAME_TOO_LONG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://www.unicode.org/reports/tr46/#Validity_Criteria
|
||||
*
|
||||
* @param string $label
|
||||
* @param array<string, bool> $options
|
||||
* @param bool $canBeEmpty
|
||||
*/
|
||||
private static function validateLabel($label, Info $info, array $options, $canBeEmpty)
|
||||
{
|
||||
if ('' === $label) {
|
||||
if (!$canBeEmpty && (!isset($options['VerifyDnsLength']) || $options['VerifyDnsLength'])) {
|
||||
$info->errors |= self::ERROR_EMPTY_LABEL;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 1. The label must be in Unicode Normalization Form C.
|
||||
if (!Normalizer::isNormalized($label, Normalizer::FORM_C)) {
|
||||
$info->errors |= self::ERROR_INVALID_ACE_LABEL;
|
||||
}
|
||||
|
||||
$codePoints = self::utf8Decode($label);
|
||||
|
||||
if ($options['CheckHyphens']) {
|
||||
// Step 2. If CheckHyphens, the label must not contain a U+002D HYPHEN-MINUS character
|
||||
// in both the thrid and fourth positions.
|
||||
if (isset($codePoints[2], $codePoints[3]) && 0x002D === $codePoints[2] && 0x002D === $codePoints[3]) {
|
||||
$info->errors |= self::ERROR_HYPHEN_3_4;
|
||||
}
|
||||
|
||||
// Step 3. If CheckHyphens, the label must neither begin nor end with a U+002D
|
||||
// HYPHEN-MINUS character.
|
||||
if ('-' === substr($label, 0, 1)) {
|
||||
$info->errors |= self::ERROR_LEADING_HYPHEN;
|
||||
}
|
||||
|
||||
if ('-' === substr($label, -1, 1)) {
|
||||
$info->errors |= self::ERROR_TRAILING_HYPHEN;
|
||||
}
|
||||
}
|
||||
|
||||
// Step 4. The label must not contain a U+002E (.) FULL STOP.
|
||||
if (false !== strpos($label, '.')) {
|
||||
$info->errors |= self::ERROR_LABEL_HAS_DOT;
|
||||
}
|
||||
|
||||
// Step 5. The label must not begin with a combining mark, that is: General_Category=Mark.
|
||||
if (1 === preg_match(Regex::COMBINING_MARK, $label)) {
|
||||
$info->errors |= self::ERROR_LEADING_COMBINING_MARK;
|
||||
}
|
||||
|
||||
// Step 6. Each code point in the label must only have certain status values according to
|
||||
// Section 5, IDNA Mapping Table:
|
||||
$transitional = $options['Transitional_Processing'];
|
||||
$useSTD3ASCIIRules = $options['UseSTD3ASCIIRules'];
|
||||
|
||||
foreach ($codePoints as $codePoint) {
|
||||
$data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);
|
||||
$status = $data['status'];
|
||||
|
||||
if ('valid' === $status || (!$transitional && 'deviation' === $status)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$info->errors |= self::ERROR_DISALLOWED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Step 7. If CheckJoiners, the label must satisify the ContextJ rules from Appendix A, in
|
||||
// The Unicode Code Points and Internationalized Domain Names for Applications (IDNA)
|
||||
// [IDNA2008].
|
||||
if ($options['CheckJoiners'] && !self::isValidContextJ($codePoints, $label)) {
|
||||
$info->errors |= self::ERROR_CONTEXTJ;
|
||||
}
|
||||
|
||||
// Step 8. If CheckBidi, and if the domain name is a Bidi domain name, then the label must
|
||||
// satisfy all six of the numbered conditions in [IDNA2008] RFC 5893, Section 2.
|
||||
if ($options['CheckBidi'] && (!$info->bidiDomain || $info->validBidiDomain)) {
|
||||
self::validateBidiLabel($label, $info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://tools.ietf.org/html/rfc3492#section-6.2
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function punycodeDecode($input)
|
||||
{
|
||||
$n = self::INITIAL_N;
|
||||
$out = 0;
|
||||
$i = 0;
|
||||
$bias = self::INITIAL_BIAS;
|
||||
$lastDelimIndex = strrpos($input, self::DELIMITER);
|
||||
$b = false === $lastDelimIndex ? 0 : $lastDelimIndex;
|
||||
$inputLength = \strlen($input);
|
||||
$output = array();
|
||||
$bytes = array_map('ord', str_split($input));
|
||||
|
||||
for ($j = 0; $j < $b; ++$j) {
|
||||
if ($bytes[$j] > 0x7F) {
|
||||
throw new Exception('Invalid input');
|
||||
}
|
||||
|
||||
$output[$out++] = $input[$j];
|
||||
}
|
||||
|
||||
if ($b > 0) {
|
||||
++$b;
|
||||
}
|
||||
|
||||
for ($in = $b; $in < $inputLength; ++$out) {
|
||||
$oldi = $i;
|
||||
$w = 1;
|
||||
|
||||
for ($k = self::BASE; /* no condition */; $k += self::BASE) {
|
||||
if ($in >= $inputLength) {
|
||||
throw new Exception('Invalid input');
|
||||
}
|
||||
|
||||
$digit = self::$basicToDigit[$bytes[$in++] & 0xFF];
|
||||
|
||||
if ($digit < 0) {
|
||||
throw new Exception('Invalid input');
|
||||
}
|
||||
|
||||
if ($digit > intdiv(self::MAX_INT - $i, $w)) {
|
||||
throw new Exception('Integer overflow');
|
||||
}
|
||||
|
||||
$i += $digit * $w;
|
||||
|
||||
if ($k <= $bias) {
|
||||
$t = self::TMIN;
|
||||
} elseif ($k >= $bias + self::TMAX) {
|
||||
$t = self::TMAX;
|
||||
} else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
|
||||
if ($digit < $t) {
|
||||
break;
|
||||
}
|
||||
|
||||
$baseMinusT = self::BASE - $t;
|
||||
|
||||
if ($w > intdiv(self::MAX_INT, $baseMinusT)) {
|
||||
throw new Exception('Integer overflow');
|
||||
}
|
||||
|
||||
$w *= $baseMinusT;
|
||||
}
|
||||
|
||||
$outPlusOne = $out + 1;
|
||||
$bias = self::adaptBias($i - $oldi, $outPlusOne, 0 === $oldi);
|
||||
|
||||
if (intdiv($i, $outPlusOne) > self::MAX_INT - $n) {
|
||||
throw new Exception('Integer overflow');
|
||||
}
|
||||
|
||||
$n += intdiv($i, $outPlusOne);
|
||||
$i %= $outPlusOne;
|
||||
array_splice($output, $i++, 0, array(mb_chr($n, 'utf-8')));
|
||||
}
|
||||
|
||||
return implode('', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://tools.ietf.org/html/rfc3492#section-6.3
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function punycodeEncode($input)
|
||||
{
|
||||
$n = self::INITIAL_N;
|
||||
$delta = 0;
|
||||
$out = 0;
|
||||
$bias = self::INITIAL_BIAS;
|
||||
$inputLength = 0;
|
||||
$output = '';
|
||||
$iter = self::utf8Decode($input);
|
||||
|
||||
foreach ($iter as $codePoint) {
|
||||
++$inputLength;
|
||||
|
||||
if ($codePoint < 0x80) {
|
||||
$output .= \chr($codePoint);
|
||||
++$out;
|
||||
}
|
||||
}
|
||||
|
||||
$h = $out;
|
||||
$b = $out;
|
||||
|
||||
if ($b > 0) {
|
||||
$output .= self::DELIMITER;
|
||||
++$out;
|
||||
}
|
||||
|
||||
while ($h < $inputLength) {
|
||||
$m = self::MAX_INT;
|
||||
|
||||
foreach ($iter as $codePoint) {
|
||||
if ($codePoint >= $n && $codePoint < $m) {
|
||||
$m = $codePoint;
|
||||
}
|
||||
}
|
||||
|
||||
if ($m - $n > intdiv(self::MAX_INT - $delta, $h + 1)) {
|
||||
throw new Exception('Integer overflow');
|
||||
}
|
||||
|
||||
$delta += ($m - $n) * ($h + 1);
|
||||
$n = $m;
|
||||
|
||||
foreach ($iter as $codePoint) {
|
||||
if ($codePoint < $n && 0 === ++$delta) {
|
||||
throw new Exception('Integer overflow');
|
||||
} elseif ($codePoint === $n) {
|
||||
$q = $delta;
|
||||
|
||||
for ($k = self::BASE; /* no condition */; $k += self::BASE) {
|
||||
if ($k <= $bias) {
|
||||
$t = self::TMIN;
|
||||
} elseif ($k >= $bias + self::TMAX) {
|
||||
$t = self::TMAX;
|
||||
} else {
|
||||
$t = $k - $bias;
|
||||
}
|
||||
|
||||
if ($q < $t) {
|
||||
break;
|
||||
}
|
||||
|
||||
$qMinusT = $q - $t;
|
||||
$baseMinusT = self::BASE - $t;
|
||||
$output .= self::encodeDigit($t + ($qMinusT) % ($baseMinusT), false);
|
||||
++$out;
|
||||
$q = intdiv($qMinusT, $baseMinusT);
|
||||
}
|
||||
|
||||
$output .= self::encodeDigit($q, false);
|
||||
++$out;
|
||||
$bias = self::adaptBias($delta, $h + 1, $h === $b);
|
||||
$delta = 0;
|
||||
++$h;
|
||||
}
|
||||
}
|
||||
|
||||
++$delta;
|
||||
++$n;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://tools.ietf.org/html/rfc3492#section-6.1
|
||||
*
|
||||
* @param int $delta
|
||||
* @param int $numPoints
|
||||
* @param bool $firstTime
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private static function adaptBias($delta, $numPoints, $firstTime)
|
||||
{
|
||||
// xxx >> 1 is a faster way of doing intdiv(xxx, 2)
|
||||
$delta = $firstTime ? intdiv($delta, self::DAMP) : $delta >> 1;
|
||||
$delta += intdiv($delta, $numPoints);
|
||||
$k = 0;
|
||||
|
||||
while ($delta > ((self::BASE - self::TMIN) * self::TMAX) >> 1) {
|
||||
$delta = intdiv($delta, self::BASE - self::TMIN);
|
||||
$k += self::BASE;
|
||||
}
|
||||
|
||||
return $k + intdiv((self::BASE - self::TMIN + 1) * $delta, $delta + self::SKEW);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $d
|
||||
* @param bool $flag
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function encodeDigit($d, $flag)
|
||||
{
|
||||
return \chr($d + 22 + 75 * ($d < 26 ? 1 : 0) - (($flag ? 1 : 0) << 5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a UTF-8 encoded string and converts it into a series of integer code points. Any
|
||||
* invalid byte sequences will be replaced by a U+FFFD replacement code point.
|
||||
*
|
||||
* @see https://encoding.spec.whatwg.org/#utf-8-decoder
|
||||
*
|
||||
* @param string $input
|
||||
*
|
||||
* @return array<int, int>
|
||||
*/
|
||||
private static function utf8Decode($input)
|
||||
{
|
||||
$bytesSeen = 0;
|
||||
$bytesNeeded = 0;
|
||||
$lowerBoundary = 0x80;
|
||||
$upperBoundary = 0xBF;
|
||||
$codePoint = 0;
|
||||
$codePoints = array();
|
||||
$length = \strlen($input);
|
||||
|
||||
for ($i = 0; $i < $length; ++$i) {
|
||||
$byte = \ord($input[$i]);
|
||||
|
||||
if (0 === $bytesNeeded) {
|
||||
if ($byte >= 0x00 && $byte <= 0x7F) {
|
||||
$codePoints[] = $byte;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($byte >= 0xC2 && $byte <= 0xDF) {
|
||||
$bytesNeeded = 1;
|
||||
$codePoint = $byte & 0x1F;
|
||||
} elseif ($byte >= 0xE0 && $byte <= 0xEF) {
|
||||
if (0xE0 === $byte) {
|
||||
$lowerBoundary = 0xA0;
|
||||
} elseif (0xED === $byte) {
|
||||
$upperBoundary = 0x9F;
|
||||
}
|
||||
|
||||
$bytesNeeded = 2;
|
||||
$codePoint = $byte & 0xF;
|
||||
} elseif ($byte >= 0xF0 && $byte <= 0xF4) {
|
||||
if (0xF0 === $byte) {
|
||||
$lowerBoundary = 0x90;
|
||||
} elseif (0xF4 === $byte) {
|
||||
$upperBoundary = 0x8F;
|
||||
}
|
||||
|
||||
$bytesNeeded = 3;
|
||||
$codePoint = $byte & 0x7;
|
||||
} else {
|
||||
$codePoints[] = 0xFFFD;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($byte < $lowerBoundary || $byte > $upperBoundary) {
|
||||
$codePoint = 0;
|
||||
$bytesNeeded = 0;
|
||||
$bytesSeen = 0;
|
||||
$lowerBoundary = 0x80;
|
||||
$upperBoundary = 0xBF;
|
||||
--$i;
|
||||
$codePoints[] = 0xFFFD;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$lowerBoundary = 0x80;
|
||||
$upperBoundary = 0xBF;
|
||||
$codePoint = ($codePoint << 6) | ($byte & 0x3F);
|
||||
|
||||
if (++$bytesSeen !== $bytesNeeded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$codePoints[] = $codePoint;
|
||||
$codePoint = 0;
|
||||
$bytesNeeded = 0;
|
||||
$bytesSeen = 0;
|
||||
}
|
||||
|
||||
// String unexpectedly ended, so append a U+FFFD code point.
|
||||
if (0 !== $bytesNeeded) {
|
||||
$codePoints[] = 0xFFFD;
|
||||
}
|
||||
|
||||
return $codePoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $codePoint
|
||||
* @param bool $useSTD3ASCIIRules
|
||||
*
|
||||
* @return array{status: string, mapping?: string}
|
||||
*/
|
||||
private static function lookupCodePointStatus($codePoint, $useSTD3ASCIIRules)
|
||||
{
|
||||
if (!self::$mappingTableLoaded) {
|
||||
self::$mappingTableLoaded = true;
|
||||
self::$mapped = require __DIR__.'/Resources/unidata/mapped.php';
|
||||
self::$ignored = require __DIR__.'/Resources/unidata/ignored.php';
|
||||
self::$deviation = require __DIR__.'/Resources/unidata/deviation.php';
|
||||
self::$disallowed = require __DIR__.'/Resources/unidata/disallowed.php';
|
||||
self::$disallowed_STD3_mapped = require __DIR__.'/Resources/unidata/disallowed_STD3_mapped.php';
|
||||
self::$disallowed_STD3_valid = require __DIR__.'/Resources/unidata/disallowed_STD3_valid.php';
|
||||
}
|
||||
|
||||
if (isset(self::$mapped[$codePoint])) {
|
||||
return array('status' => 'mapped', 'mapping' => self::$mapped[$codePoint]);
|
||||
}
|
||||
|
||||
if (isset(self::$ignored[$codePoint])) {
|
||||
return array('status' => 'ignored');
|
||||
}
|
||||
|
||||
if (isset(self::$deviation[$codePoint])) {
|
||||
return array('status' => 'deviation', 'mapping' => self::$deviation[$codePoint]);
|
||||
}
|
||||
|
||||
if (isset(self::$disallowed[$codePoint]) || DisallowedRanges::inRange($codePoint)) {
|
||||
return array('status' => 'disallowed');
|
||||
}
|
||||
|
||||
$isDisallowedMapped = isset(self::$disallowed_STD3_mapped[$codePoint]);
|
||||
|
||||
if ($isDisallowedMapped || isset(self::$disallowed_STD3_valid[$codePoint])) {
|
||||
$status = 'disallowed';
|
||||
|
||||
if (!$useSTD3ASCIIRules) {
|
||||
$status = $isDisallowedMapped ? 'mapped' : 'valid';
|
||||
}
|
||||
|
||||
if ($isDisallowedMapped) {
|
||||
return array('status' => $status, 'mapping' => self::$disallowed_STD3_mapped[$codePoint]);
|
||||
}
|
||||
|
||||
return array('status' => $status);
|
||||
}
|
||||
|
||||
return array('status' => 'valid');
|
||||
}
|
||||
}
|
||||
23
vendor/symfony/polyfill-intl-idn/Info.php
vendored
Normal file
23
vendor/symfony/polyfill-intl-idn/Info.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com> and Trevor Rowbotham <trevor.rowbotham@pm.me>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Intl\Idn;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class Info
|
||||
{
|
||||
public $bidiDomain = false;
|
||||
public $errors = 0;
|
||||
public $validBidiDomain = true;
|
||||
public $transitionalDifferent = false;
|
||||
}
|
||||
19
vendor/symfony/polyfill-intl-idn/LICENSE
vendored
Normal file
19
vendor/symfony/polyfill-intl-idn/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2018-2019 Fabien Potencier and Trevor Rowbotham <trevor.rowbotham@pm.me>
|
||||
|
||||
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.
|
||||
12
vendor/symfony/polyfill-intl-idn/README.md
vendored
Normal file
12
vendor/symfony/polyfill-intl-idn/README.md
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
Symfony Polyfill / Intl: Idn
|
||||
============================
|
||||
|
||||
This component provides [`idn_to_ascii`](https://php.net/idn-to-ascii) and [`idn_to_utf8`](https://php.net/idn-to-utf8) functions to users who run php versions without the [Intl](https://php.net/intl) extension.
|
||||
|
||||
More information can be found in the
|
||||
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
This library is released under the [MIT license](LICENSE).
|
||||
375
vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php
vendored
Normal file
375
vendor/symfony/polyfill-intl-idn/Resources/unidata/DisallowedRanges.php
vendored
Normal file
@ -0,0 +1,375 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Polyfill\Intl\Idn\Resources\unidata;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class DisallowedRanges
|
||||
{
|
||||
/**
|
||||
* @param int $codePoint
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function inRange($codePoint)
|
||||
{
|
||||
if ($codePoint >= 128 && $codePoint <= 159) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 2155 && $codePoint <= 2207) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 3676 && $codePoint <= 3712) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 3808 && $codePoint <= 3839) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 4059 && $codePoint <= 4095) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 4256 && $codePoint <= 4293) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 6849 && $codePoint <= 6911) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 11859 && $codePoint <= 11903) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 42955 && $codePoint <= 42996) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 55296 && $codePoint <= 57343) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 57344 && $codePoint <= 63743) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 64218 && $codePoint <= 64255) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 64976 && $codePoint <= 65007) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 65630 && $codePoint <= 65663) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 65953 && $codePoint <= 65999) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 66046 && $codePoint <= 66175) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 66518 && $codePoint <= 66559) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 66928 && $codePoint <= 67071) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 67432 && $codePoint <= 67583) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 67760 && $codePoint <= 67807) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 67904 && $codePoint <= 67967) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 68256 && $codePoint <= 68287) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 68528 && $codePoint <= 68607) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 68681 && $codePoint <= 68735) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 68922 && $codePoint <= 69215) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 69298 && $codePoint <= 69375) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 69466 && $codePoint <= 69551) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 70207 && $codePoint <= 70271) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 70517 && $codePoint <= 70655) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 70874 && $codePoint <= 71039) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 71134 && $codePoint <= 71167) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 71370 && $codePoint <= 71423) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 71488 && $codePoint <= 71679) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 71740 && $codePoint <= 71839) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 72026 && $codePoint <= 72095) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 72441 && $codePoint <= 72703) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 72887 && $codePoint <= 72959) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 73130 && $codePoint <= 73439) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 73465 && $codePoint <= 73647) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 74650 && $codePoint <= 74751) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 75076 && $codePoint <= 77823) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 78905 && $codePoint <= 82943) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 83527 && $codePoint <= 92159) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 92784 && $codePoint <= 92879) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 93072 && $codePoint <= 93759) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 93851 && $codePoint <= 93951) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 94112 && $codePoint <= 94175) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 101590 && $codePoint <= 101631) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 101641 && $codePoint <= 110591) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 110879 && $codePoint <= 110927) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 111356 && $codePoint <= 113663) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 113828 && $codePoint <= 118783) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 119366 && $codePoint <= 119519) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 119673 && $codePoint <= 119807) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 121520 && $codePoint <= 122879) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 122923 && $codePoint <= 123135) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 123216 && $codePoint <= 123583) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 123648 && $codePoint <= 124927) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 125143 && $codePoint <= 125183) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 125280 && $codePoint <= 126064) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 126133 && $codePoint <= 126208) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 126270 && $codePoint <= 126463) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 126652 && $codePoint <= 126703) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 126706 && $codePoint <= 126975) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 127406 && $codePoint <= 127461) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 127590 && $codePoint <= 127743) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 129202 && $codePoint <= 129279) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 129751 && $codePoint <= 129791) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 129995 && $codePoint <= 130031) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 130042 && $codePoint <= 131069) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 173790 && $codePoint <= 173823) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 191457 && $codePoint <= 194559) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 195102 && $codePoint <= 196605) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 201547 && $codePoint <= 262141) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 262144 && $codePoint <= 327677) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 327680 && $codePoint <= 393213) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 393216 && $codePoint <= 458749) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 458752 && $codePoint <= 524285) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 524288 && $codePoint <= 589821) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 589824 && $codePoint <= 655357) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 655360 && $codePoint <= 720893) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 720896 && $codePoint <= 786429) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 786432 && $codePoint <= 851965) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 851968 && $codePoint <= 917501) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 917536 && $codePoint <= 917631) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 917632 && $codePoint <= 917759) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 918000 && $codePoint <= 983037) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 983040 && $codePoint <= 1048573) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($codePoint >= 1048576 && $codePoint <= 1114109) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
24
vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php
vendored
Normal file
24
vendor/symfony/polyfill-intl-idn/Resources/unidata/Regex.php
vendored
Normal file
File diff suppressed because one or more lines are too long
8
vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php
vendored
Normal file
8
vendor/symfony/polyfill-intl-idn/Resources/unidata/deviation.php
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
223 => 'ss',
|
||||
962 => 'σ',
|
||||
8204 => '',
|
||||
8205 => '',
|
||||
);
|
||||
2638
vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php
vendored
Normal file
2638
vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
308
vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php
vendored
Normal file
308
vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_mapped.php
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
160 => ' ',
|
||||
168 => ' ̈',
|
||||
175 => ' ̄',
|
||||
180 => ' ́',
|
||||
184 => ' ̧',
|
||||
728 => ' ̆',
|
||||
729 => ' ̇',
|
||||
730 => ' ̊',
|
||||
731 => ' ̨',
|
||||
732 => ' ̃',
|
||||
733 => ' ̋',
|
||||
890 => ' ι',
|
||||
894 => ';',
|
||||
900 => ' ́',
|
||||
901 => ' ̈́',
|
||||
8125 => ' ̓',
|
||||
8127 => ' ̓',
|
||||
8128 => ' ͂',
|
||||
8129 => ' ̈͂',
|
||||
8141 => ' ̓̀',
|
||||
8142 => ' ̓́',
|
||||
8143 => ' ̓͂',
|
||||
8157 => ' ̔̀',
|
||||
8158 => ' ̔́',
|
||||
8159 => ' ̔͂',
|
||||
8173 => ' ̈̀',
|
||||
8174 => ' ̈́',
|
||||
8175 => '`',
|
||||
8189 => ' ́',
|
||||
8190 => ' ̔',
|
||||
8192 => ' ',
|
||||
8193 => ' ',
|
||||
8194 => ' ',
|
||||
8195 => ' ',
|
||||
8196 => ' ',
|
||||
8197 => ' ',
|
||||
8198 => ' ',
|
||||
8199 => ' ',
|
||||
8200 => ' ',
|
||||
8201 => ' ',
|
||||
8202 => ' ',
|
||||
8215 => ' ̳',
|
||||
8239 => ' ',
|
||||
8252 => '!!',
|
||||
8254 => ' ̅',
|
||||
8263 => '??',
|
||||
8264 => '?!',
|
||||
8265 => '!?',
|
||||
8287 => ' ',
|
||||
8314 => '+',
|
||||
8316 => '=',
|
||||
8317 => '(',
|
||||
8318 => ')',
|
||||
8330 => '+',
|
||||
8332 => '=',
|
||||
8333 => '(',
|
||||
8334 => ')',
|
||||
8448 => 'a/c',
|
||||
8449 => 'a/s',
|
||||
8453 => 'c/o',
|
||||
8454 => 'c/u',
|
||||
9332 => '(1)',
|
||||
9333 => '(2)',
|
||||
9334 => '(3)',
|
||||
9335 => '(4)',
|
||||
9336 => '(5)',
|
||||
9337 => '(6)',
|
||||
9338 => '(7)',
|
||||
9339 => '(8)',
|
||||
9340 => '(9)',
|
||||
9341 => '(10)',
|
||||
9342 => '(11)',
|
||||
9343 => '(12)',
|
||||
9344 => '(13)',
|
||||
9345 => '(14)',
|
||||
9346 => '(15)',
|
||||
9347 => '(16)',
|
||||
9348 => '(17)',
|
||||
9349 => '(18)',
|
||||
9350 => '(19)',
|
||||
9351 => '(20)',
|
||||
9372 => '(a)',
|
||||
9373 => '(b)',
|
||||
9374 => '(c)',
|
||||
9375 => '(d)',
|
||||
9376 => '(e)',
|
||||
9377 => '(f)',
|
||||
9378 => '(g)',
|
||||
9379 => '(h)',
|
||||
9380 => '(i)',
|
||||
9381 => '(j)',
|
||||
9382 => '(k)',
|
||||
9383 => '(l)',
|
||||
9384 => '(m)',
|
||||
9385 => '(n)',
|
||||
9386 => '(o)',
|
||||
9387 => '(p)',
|
||||
9388 => '(q)',
|
||||
9389 => '(r)',
|
||||
9390 => '(s)',
|
||||
9391 => '(t)',
|
||||
9392 => '(u)',
|
||||
9393 => '(v)',
|
||||
9394 => '(w)',
|
||||
9395 => '(x)',
|
||||
9396 => '(y)',
|
||||
9397 => '(z)',
|
||||
10868 => '::=',
|
||||
10869 => '==',
|
||||
10870 => '===',
|
||||
12288 => ' ',
|
||||
12443 => ' ゙',
|
||||
12444 => ' ゚',
|
||||
12800 => '(ᄀ)',
|
||||
12801 => '(ᄂ)',
|
||||
12802 => '(ᄃ)',
|
||||
12803 => '(ᄅ)',
|
||||
12804 => '(ᄆ)',
|
||||
12805 => '(ᄇ)',
|
||||
12806 => '(ᄉ)',
|
||||
12807 => '(ᄋ)',
|
||||
12808 => '(ᄌ)',
|
||||
12809 => '(ᄎ)',
|
||||
12810 => '(ᄏ)',
|
||||
12811 => '(ᄐ)',
|
||||
12812 => '(ᄑ)',
|
||||
12813 => '(ᄒ)',
|
||||
12814 => '(가)',
|
||||
12815 => '(나)',
|
||||
12816 => '(다)',
|
||||
12817 => '(라)',
|
||||
12818 => '(마)',
|
||||
12819 => '(바)',
|
||||
12820 => '(사)',
|
||||
12821 => '(아)',
|
||||
12822 => '(자)',
|
||||
12823 => '(차)',
|
||||
12824 => '(카)',
|
||||
12825 => '(타)',
|
||||
12826 => '(파)',
|
||||
12827 => '(하)',
|
||||
12828 => '(주)',
|
||||
12829 => '(오전)',
|
||||
12830 => '(오후)',
|
||||
12832 => '(一)',
|
||||
12833 => '(二)',
|
||||
12834 => '(三)',
|
||||
12835 => '(四)',
|
||||
12836 => '(五)',
|
||||
12837 => '(六)',
|
||||
12838 => '(七)',
|
||||
12839 => '(八)',
|
||||
12840 => '(九)',
|
||||
12841 => '(十)',
|
||||
12842 => '(月)',
|
||||
12843 => '(火)',
|
||||
12844 => '(水)',
|
||||
12845 => '(木)',
|
||||
12846 => '(金)',
|
||||
12847 => '(土)',
|
||||
12848 => '(日)',
|
||||
12849 => '(株)',
|
||||
12850 => '(有)',
|
||||
12851 => '(社)',
|
||||
12852 => '(名)',
|
||||
12853 => '(特)',
|
||||
12854 => '(財)',
|
||||
12855 => '(祝)',
|
||||
12856 => '(労)',
|
||||
12857 => '(代)',
|
||||
12858 => '(呼)',
|
||||
12859 => '(学)',
|
||||
12860 => '(監)',
|
||||
12861 => '(企)',
|
||||
12862 => '(資)',
|
||||
12863 => '(協)',
|
||||
12864 => '(祭)',
|
||||
12865 => '(休)',
|
||||
12866 => '(自)',
|
||||
12867 => '(至)',
|
||||
64297 => '+',
|
||||
64606 => ' ٌّ',
|
||||
64607 => ' ٍّ',
|
||||
64608 => ' َّ',
|
||||
64609 => ' ُّ',
|
||||
64610 => ' ِّ',
|
||||
64611 => ' ّٰ',
|
||||
65018 => 'صلى الله عليه وسلم',
|
||||
65019 => 'جل جلاله',
|
||||
65040 => ',',
|
||||
65043 => ':',
|
||||
65044 => ';',
|
||||
65045 => '!',
|
||||
65046 => '?',
|
||||
65075 => '_',
|
||||
65076 => '_',
|
||||
65077 => '(',
|
||||
65078 => ')',
|
||||
65079 => '{',
|
||||
65080 => '}',
|
||||
65095 => '[',
|
||||
65096 => ']',
|
||||
65097 => ' ̅',
|
||||
65098 => ' ̅',
|
||||
65099 => ' ̅',
|
||||
65100 => ' ̅',
|
||||
65101 => '_',
|
||||
65102 => '_',
|
||||
65103 => '_',
|
||||
65104 => ',',
|
||||
65108 => ';',
|
||||
65109 => ':',
|
||||
65110 => '?',
|
||||
65111 => '!',
|
||||
65113 => '(',
|
||||
65114 => ')',
|
||||
65115 => '{',
|
||||
65116 => '}',
|
||||
65119 => '#',
|
||||
65120 => '&',
|
||||
65121 => '*',
|
||||
65122 => '+',
|
||||
65124 => '<',
|
||||
65125 => '>',
|
||||
65126 => '=',
|
||||
65128 => '\\',
|
||||
65129 => '$',
|
||||
65130 => '%',
|
||||
65131 => '@',
|
||||
65136 => ' ً',
|
||||
65138 => ' ٌ',
|
||||
65140 => ' ٍ',
|
||||
65142 => ' َ',
|
||||
65144 => ' ُ',
|
||||
65146 => ' ِ',
|
||||
65148 => ' ّ',
|
||||
65150 => ' ْ',
|
||||
65281 => '!',
|
||||
65282 => '"',
|
||||
65283 => '#',
|
||||
65284 => '$',
|
||||
65285 => '%',
|
||||
65286 => '&',
|
||||
65287 => '\'',
|
||||
65288 => '(',
|
||||
65289 => ')',
|
||||
65290 => '*',
|
||||
65291 => '+',
|
||||
65292 => ',',
|
||||
65295 => '/',
|
||||
65306 => ':',
|
||||
65307 => ';',
|
||||
65308 => '<',
|
||||
65309 => '=',
|
||||
65310 => '>',
|
||||
65311 => '?',
|
||||
65312 => '@',
|
||||
65339 => '[',
|
||||
65340 => '\\',
|
||||
65341 => ']',
|
||||
65342 => '^',
|
||||
65343 => '_',
|
||||
65344 => '`',
|
||||
65371 => '{',
|
||||
65372 => '|',
|
||||
65373 => '}',
|
||||
65374 => '~',
|
||||
65507 => ' ̄',
|
||||
127233 => '0,',
|
||||
127234 => '1,',
|
||||
127235 => '2,',
|
||||
127236 => '3,',
|
||||
127237 => '4,',
|
||||
127238 => '5,',
|
||||
127239 => '6,',
|
||||
127240 => '7,',
|
||||
127241 => '8,',
|
||||
127242 => '9,',
|
||||
127248 => '(a)',
|
||||
127249 => '(b)',
|
||||
127250 => '(c)',
|
||||
127251 => '(d)',
|
||||
127252 => '(e)',
|
||||
127253 => '(f)',
|
||||
127254 => '(g)',
|
||||
127255 => '(h)',
|
||||
127256 => '(i)',
|
||||
127257 => '(j)',
|
||||
127258 => '(k)',
|
||||
127259 => '(l)',
|
||||
127260 => '(m)',
|
||||
127261 => '(n)',
|
||||
127262 => '(o)',
|
||||
127263 => '(p)',
|
||||
127264 => '(q)',
|
||||
127265 => '(r)',
|
||||
127266 => '(s)',
|
||||
127267 => '(t)',
|
||||
127268 => '(u)',
|
||||
127269 => '(v)',
|
||||
127270 => '(w)',
|
||||
127271 => '(x)',
|
||||
127272 => '(y)',
|
||||
127273 => '(z)',
|
||||
);
|
||||
71
vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php
vendored
Normal file
71
vendor/symfony/polyfill-intl-idn/Resources/unidata/disallowed_STD3_valid.php
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
0 => true,
|
||||
1 => true,
|
||||
2 => true,
|
||||
3 => true,
|
||||
4 => true,
|
||||
5 => true,
|
||||
6 => true,
|
||||
7 => true,
|
||||
8 => true,
|
||||
9 => true,
|
||||
10 => true,
|
||||
11 => true,
|
||||
12 => true,
|
||||
13 => true,
|
||||
14 => true,
|
||||
15 => true,
|
||||
16 => true,
|
||||
17 => true,
|
||||
18 => true,
|
||||
19 => true,
|
||||
20 => true,
|
||||
21 => true,
|
||||
22 => true,
|
||||
23 => true,
|
||||
24 => true,
|
||||
25 => true,
|
||||
26 => true,
|
||||
27 => true,
|
||||
28 => true,
|
||||
29 => true,
|
||||
30 => true,
|
||||
31 => true,
|
||||
32 => true,
|
||||
33 => true,
|
||||
34 => true,
|
||||
35 => true,
|
||||
36 => true,
|
||||
37 => true,
|
||||
38 => true,
|
||||
39 => true,
|
||||
40 => true,
|
||||
41 => true,
|
||||
42 => true,
|
||||
43 => true,
|
||||
44 => true,
|
||||
47 => true,
|
||||
58 => true,
|
||||
59 => true,
|
||||
60 => true,
|
||||
61 => true,
|
||||
62 => true,
|
||||
63 => true,
|
||||
64 => true,
|
||||
91 => true,
|
||||
92 => true,
|
||||
93 => true,
|
||||
94 => true,
|
||||
95 => true,
|
||||
96 => true,
|
||||
123 => true,
|
||||
124 => true,
|
||||
125 => true,
|
||||
126 => true,
|
||||
127 => true,
|
||||
8800 => true,
|
||||
8814 => true,
|
||||
8815 => true,
|
||||
);
|
||||
273
vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php
vendored
Normal file
273
vendor/symfony/polyfill-intl-idn/Resources/unidata/ignored.php
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
173 => true,
|
||||
847 => true,
|
||||
6155 => true,
|
||||
6156 => true,
|
||||
6157 => true,
|
||||
8203 => true,
|
||||
8288 => true,
|
||||
8292 => true,
|
||||
65024 => true,
|
||||
65025 => true,
|
||||
65026 => true,
|
||||
65027 => true,
|
||||
65028 => true,
|
||||
65029 => true,
|
||||
65030 => true,
|
||||
65031 => true,
|
||||
65032 => true,
|
||||
65033 => true,
|
||||
65034 => true,
|
||||
65035 => true,
|
||||
65036 => true,
|
||||
65037 => true,
|
||||
65038 => true,
|
||||
65039 => true,
|
||||
65279 => true,
|
||||
113824 => true,
|
||||
113825 => true,
|
||||
113826 => true,
|
||||
113827 => true,
|
||||
917760 => true,
|
||||
917761 => true,
|
||||
917762 => true,
|
||||
917763 => true,
|
||||
917764 => true,
|
||||
917765 => true,
|
||||
917766 => true,
|
||||
917767 => true,
|
||||
917768 => true,
|
||||
917769 => true,
|
||||
917770 => true,
|
||||
917771 => true,
|
||||
917772 => true,
|
||||
917773 => true,
|
||||
917774 => true,
|
||||
917775 => true,
|
||||
917776 => true,
|
||||
917777 => true,
|
||||
917778 => true,
|
||||
917779 => true,
|
||||
917780 => true,
|
||||
917781 => true,
|
||||
917782 => true,
|
||||
917783 => true,
|
||||
917784 => true,
|
||||
917785 => true,
|
||||
917786 => true,
|
||||
917787 => true,
|
||||
917788 => true,
|
||||
917789 => true,
|
||||
917790 => true,
|
||||
917791 => true,
|
||||
917792 => true,
|
||||
917793 => true,
|
||||
917794 => true,
|
||||
917795 => true,
|
||||
917796 => true,
|
||||
917797 => true,
|
||||
917798 => true,
|
||||
917799 => true,
|
||||
917800 => true,
|
||||
917801 => true,
|
||||
917802 => true,
|
||||
917803 => true,
|
||||
917804 => true,
|
||||
917805 => true,
|
||||
917806 => true,
|
||||
917807 => true,
|
||||
917808 => true,
|
||||
917809 => true,
|
||||
917810 => true,
|
||||
917811 => true,
|
||||
917812 => true,
|
||||
917813 => true,
|
||||
917814 => true,
|
||||
917815 => true,
|
||||
917816 => true,
|
||||
917817 => true,
|
||||
917818 => true,
|
||||
917819 => true,
|
||||
917820 => true,
|
||||
917821 => true,
|
||||
917822 => true,
|
||||
917823 => true,
|
||||
917824 => true,
|
||||
917825 => true,
|
||||
917826 => true,
|
||||
917827 => true,
|
||||
917828 => true,
|
||||
917829 => true,
|
||||
917830 => true,
|
||||
917831 => true,
|
||||
917832 => true,
|
||||
917833 => true,
|
||||
917834 => true,
|
||||
917835 => true,
|
||||
917836 => true,
|
||||
917837 => true,
|
||||
917838 => true,
|
||||
917839 => true,
|
||||
917840 => true,
|
||||
917841 => true,
|
||||
917842 => true,
|
||||
917843 => true,
|
||||
917844 => true,
|
||||
917845 => true,
|
||||
917846 => true,
|
||||
917847 => true,
|
||||
917848 => true,
|
||||
917849 => true,
|
||||
917850 => true,
|
||||
917851 => true,
|
||||
917852 => true,
|
||||
917853 => true,
|
||||
917854 => true,
|
||||
917855 => true,
|
||||
917856 => true,
|
||||
917857 => true,
|
||||
917858 => true,
|
||||
917859 => true,
|
||||
917860 => true,
|
||||
917861 => true,
|
||||
917862 => true,
|
||||
917863 => true,
|
||||
917864 => true,
|
||||
917865 => true,
|
||||
917866 => true,
|
||||
917867 => true,
|
||||
917868 => true,
|
||||
917869 => true,
|
||||
917870 => true,
|
||||
917871 => true,
|
||||
917872 => true,
|
||||
917873 => true,
|
||||
917874 => true,
|
||||
917875 => true,
|
||||
917876 => true,
|
||||
917877 => true,
|
||||
917878 => true,
|
||||
917879 => true,
|
||||
917880 => true,
|
||||
917881 => true,
|
||||
917882 => true,
|
||||
917883 => true,
|
||||
917884 => true,
|
||||
917885 => true,
|
||||
917886 => true,
|
||||
917887 => true,
|
||||
917888 => true,
|
||||
917889 => true,
|
||||
917890 => true,
|
||||
917891 => true,
|
||||
917892 => true,
|
||||
917893 => true,
|
||||
917894 => true,
|
||||
917895 => true,
|
||||
917896 => true,
|
||||
917897 => true,
|
||||
917898 => true,
|
||||
917899 => true,
|
||||
917900 => true,
|
||||
917901 => true,
|
||||
917902 => true,
|
||||
917903 => true,
|
||||
917904 => true,
|
||||
917905 => true,
|
||||
917906 => true,
|
||||
917907 => true,
|
||||
917908 => true,
|
||||
917909 => true,
|
||||
917910 => true,
|
||||
917911 => true,
|
||||
917912 => true,
|
||||
917913 => true,
|
||||
917914 => true,
|
||||
917915 => true,
|
||||
917916 => true,
|
||||
917917 => true,
|
||||
917918 => true,
|
||||
917919 => true,
|
||||
917920 => true,
|
||||
917921 => true,
|
||||
917922 => true,
|
||||
917923 => true,
|
||||
917924 => true,
|
||||
917925 => true,
|
||||
917926 => true,
|
||||
917927 => true,
|
||||
917928 => true,
|
||||
917929 => true,
|
||||
917930 => true,
|
||||
917931 => true,
|
||||
917932 => true,
|
||||
917933 => true,
|
||||
917934 => true,
|
||||
917935 => true,
|
||||
917936 => true,
|
||||
917937 => true,
|
||||
917938 => true,
|
||||
917939 => true,
|
||||
917940 => true,
|
||||
917941 => true,
|
||||
917942 => true,
|
||||
917943 => true,
|
||||
917944 => true,
|
||||
917945 => true,
|
||||
917946 => true,
|
||||
917947 => true,
|
||||
917948 => true,
|
||||
917949 => true,
|
||||
917950 => true,
|
||||
917951 => true,
|
||||
917952 => true,
|
||||
917953 => true,
|
||||
917954 => true,
|
||||
917955 => true,
|
||||
917956 => true,
|
||||
917957 => true,
|
||||
917958 => true,
|
||||
917959 => true,
|
||||
917960 => true,
|
||||
917961 => true,
|
||||
917962 => true,
|
||||
917963 => true,
|
||||
917964 => true,
|
||||
917965 => true,
|
||||
917966 => true,
|
||||
917967 => true,
|
||||
917968 => true,
|
||||
917969 => true,
|
||||
917970 => true,
|
||||
917971 => true,
|
||||
917972 => true,
|
||||
917973 => true,
|
||||
917974 => true,
|
||||
917975 => true,
|
||||
917976 => true,
|
||||
917977 => true,
|
||||
917978 => true,
|
||||
917979 => true,
|
||||
917980 => true,
|
||||
917981 => true,
|
||||
917982 => true,
|
||||
917983 => true,
|
||||
917984 => true,
|
||||
917985 => true,
|
||||
917986 => true,
|
||||
917987 => true,
|
||||
917988 => true,
|
||||
917989 => true,
|
||||
917990 => true,
|
||||
917991 => true,
|
||||
917992 => true,
|
||||
917993 => true,
|
||||
917994 => true,
|
||||
917995 => true,
|
||||
917996 => true,
|
||||
917997 => true,
|
||||
917998 => true,
|
||||
917999 => true,
|
||||
);
|
||||
5778
vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php
vendored
Normal file
5778
vendor/symfony/polyfill-intl-idn/Resources/unidata/mapped.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
65
vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php
vendored
Normal file
65
vendor/symfony/polyfill-intl-idn/Resources/unidata/virama.php
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
2381 => 9,
|
||||
2509 => 9,
|
||||
2637 => 9,
|
||||
2765 => 9,
|
||||
2893 => 9,
|
||||
3021 => 9,
|
||||
3149 => 9,
|
||||
3277 => 9,
|
||||
3387 => 9,
|
||||
3388 => 9,
|
||||
3405 => 9,
|
||||
3530 => 9,
|
||||
3642 => 9,
|
||||
3770 => 9,
|
||||
3972 => 9,
|
||||
4153 => 9,
|
||||
4154 => 9,
|
||||
5908 => 9,
|
||||
5940 => 9,
|
||||
6098 => 9,
|
||||
6752 => 9,
|
||||
6980 => 9,
|
||||
7082 => 9,
|
||||
7083 => 9,
|
||||
7154 => 9,
|
||||
7155 => 9,
|
||||
11647 => 9,
|
||||
43014 => 9,
|
||||
43052 => 9,
|
||||
43204 => 9,
|
||||
43347 => 9,
|
||||
43456 => 9,
|
||||
43766 => 9,
|
||||
44013 => 9,
|
||||
68159 => 9,
|
||||
69702 => 9,
|
||||
69759 => 9,
|
||||
69817 => 9,
|
||||
69939 => 9,
|
||||
69940 => 9,
|
||||
70080 => 9,
|
||||
70197 => 9,
|
||||
70378 => 9,
|
||||
70477 => 9,
|
||||
70722 => 9,
|
||||
70850 => 9,
|
||||
71103 => 9,
|
||||
71231 => 9,
|
||||
71350 => 9,
|
||||
71467 => 9,
|
||||
71737 => 9,
|
||||
71997 => 9,
|
||||
71998 => 9,
|
||||
72160 => 9,
|
||||
72244 => 9,
|
||||
72263 => 9,
|
||||
72345 => 9,
|
||||
72767 => 9,
|
||||
73028 => 9,
|
||||
73029 => 9,
|
||||
73111 => 9,
|
||||
);
|
||||
141
vendor/symfony/polyfill-intl-idn/bootstrap.php
vendored
Normal file
141
vendor/symfony/polyfill-intl-idn/bootstrap.php
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Intl\Idn as p;
|
||||
|
||||
if (extension_loaded('intl')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('U_IDNA_PROHIBITED_ERROR')) {
|
||||
define('U_IDNA_PROHIBITED_ERROR', 66560);
|
||||
}
|
||||
if (!defined('U_IDNA_ERROR_START')) {
|
||||
define('U_IDNA_ERROR_START', 66560);
|
||||
}
|
||||
if (!defined('U_IDNA_UNASSIGNED_ERROR')) {
|
||||
define('U_IDNA_UNASSIGNED_ERROR', 66561);
|
||||
}
|
||||
if (!defined('U_IDNA_CHECK_BIDI_ERROR')) {
|
||||
define('U_IDNA_CHECK_BIDI_ERROR', 66562);
|
||||
}
|
||||
if (!defined('U_IDNA_STD3_ASCII_RULES_ERROR')) {
|
||||
define('U_IDNA_STD3_ASCII_RULES_ERROR', 66563);
|
||||
}
|
||||
if (!defined('U_IDNA_ACE_PREFIX_ERROR')) {
|
||||
define('U_IDNA_ACE_PREFIX_ERROR', 66564);
|
||||
}
|
||||
if (!defined('U_IDNA_VERIFICATION_ERROR')) {
|
||||
define('U_IDNA_VERIFICATION_ERROR', 66565);
|
||||
}
|
||||
if (!defined('U_IDNA_LABEL_TOO_LONG_ERROR')) {
|
||||
define('U_IDNA_LABEL_TOO_LONG_ERROR', 66566);
|
||||
}
|
||||
if (!defined('U_IDNA_ZERO_LENGTH_LABEL_ERROR')) {
|
||||
define('U_IDNA_ZERO_LENGTH_LABEL_ERROR', 66567);
|
||||
}
|
||||
if (!defined('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR')) {
|
||||
define('U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR', 66568);
|
||||
}
|
||||
if (!defined('U_IDNA_ERROR_LIMIT')) {
|
||||
define('U_IDNA_ERROR_LIMIT', 66569);
|
||||
}
|
||||
if (!defined('U_STRINGPREP_PROHIBITED_ERROR')) {
|
||||
define('U_STRINGPREP_PROHIBITED_ERROR', 66560);
|
||||
}
|
||||
if (!defined('U_STRINGPREP_UNASSIGNED_ERROR')) {
|
||||
define('U_STRINGPREP_UNASSIGNED_ERROR', 66561);
|
||||
}
|
||||
if (!defined('U_STRINGPREP_CHECK_BIDI_ERROR')) {
|
||||
define('U_STRINGPREP_CHECK_BIDI_ERROR', 66562);
|
||||
}
|
||||
if (!defined('IDNA_DEFAULT')) {
|
||||
define('IDNA_DEFAULT', 0);
|
||||
}
|
||||
if (!defined('IDNA_ALLOW_UNASSIGNED')) {
|
||||
define('IDNA_ALLOW_UNASSIGNED', 1);
|
||||
}
|
||||
if (!defined('IDNA_USE_STD3_RULES')) {
|
||||
define('IDNA_USE_STD3_RULES', 2);
|
||||
}
|
||||
if (!defined('IDNA_CHECK_BIDI')) {
|
||||
define('IDNA_CHECK_BIDI', 4);
|
||||
}
|
||||
if (!defined('IDNA_CHECK_CONTEXTJ')) {
|
||||
define('IDNA_CHECK_CONTEXTJ', 8);
|
||||
}
|
||||
if (!defined('IDNA_NONTRANSITIONAL_TO_ASCII')) {
|
||||
define('IDNA_NONTRANSITIONAL_TO_ASCII', 16);
|
||||
}
|
||||
if (!defined('IDNA_NONTRANSITIONAL_TO_UNICODE')) {
|
||||
define('IDNA_NONTRANSITIONAL_TO_UNICODE', 32);
|
||||
}
|
||||
if (!defined('INTL_IDNA_VARIANT_2003')) {
|
||||
define('INTL_IDNA_VARIANT_2003', 0);
|
||||
}
|
||||
if (!defined('INTL_IDNA_VARIANT_UTS46')) {
|
||||
define('INTL_IDNA_VARIANT_UTS46', 1);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_EMPTY_LABEL')) {
|
||||
define('IDNA_ERROR_EMPTY_LABEL', 1);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LABEL_TOO_LONG')) {
|
||||
define('IDNA_ERROR_LABEL_TOO_LONG', 2);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_DOMAIN_NAME_TOO_LONG')) {
|
||||
define('IDNA_ERROR_DOMAIN_NAME_TOO_LONG', 4);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LEADING_HYPHEN')) {
|
||||
define('IDNA_ERROR_LEADING_HYPHEN', 8);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_TRAILING_HYPHEN')) {
|
||||
define('IDNA_ERROR_TRAILING_HYPHEN', 16);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_HYPHEN_3_4')) {
|
||||
define('IDNA_ERROR_HYPHEN_3_4', 32);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LEADING_COMBINING_MARK')) {
|
||||
define('IDNA_ERROR_LEADING_COMBINING_MARK', 64);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_DISALLOWED')) {
|
||||
define('IDNA_ERROR_DISALLOWED', 128);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_PUNYCODE')) {
|
||||
define('IDNA_ERROR_PUNYCODE', 256);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_LABEL_HAS_DOT')) {
|
||||
define('IDNA_ERROR_LABEL_HAS_DOT', 512);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_INVALID_ACE_LABEL')) {
|
||||
define('IDNA_ERROR_INVALID_ACE_LABEL', 1024);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_BIDI')) {
|
||||
define('IDNA_ERROR_BIDI', 2048);
|
||||
}
|
||||
if (!defined('IDNA_ERROR_CONTEXTJ')) {
|
||||
define('IDNA_ERROR_CONTEXTJ', 4096);
|
||||
}
|
||||
|
||||
if (PHP_VERSION_ID < 70400) {
|
||||
if (!function_exists('idn_to_ascii')) {
|
||||
function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
if (!function_exists('idn_to_utf8')) {
|
||||
function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_2003, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
} else {
|
||||
if (!function_exists('idn_to_ascii')) {
|
||||
function idn_to_ascii($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_ascii($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
if (!function_exists('idn_to_utf8')) {
|
||||
function idn_to_utf8($domain, $options = IDNA_DEFAULT, $variant = INTL_IDNA_VARIANT_UTS46, &$idna_info = array()) { return p\Idn::idn_to_utf8($domain, $options, $variant, $idna_info); }
|
||||
}
|
||||
}
|
||||
45
vendor/symfony/polyfill-intl-idn/composer.json
vendored
Normal file
45
vendor/symfony/polyfill-intl-idn/composer.json
vendored
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"name": "symfony/polyfill-intl-idn",
|
||||
"type": "library",
|
||||
"description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
|
||||
"keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "idn"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Laurent Bassin",
|
||||
"email": "laurent@bassin.info"
|
||||
},
|
||||
{
|
||||
"name": "Trevor Rowbotham",
|
||||
"email": "trevor.rowbotham@pm.me"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"symfony/polyfill-intl-normalizer": "^1.10",
|
||||
"symfony/polyfill-php70": "^1.10",
|
||||
"symfony/polyfill-php72": "^1.10"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" },
|
||||
"files": [ "bootstrap.php" ]
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.18-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
}
|
||||
}
|
||||
19
vendor/symfony/polyfill-intl-normalizer/LICENSE
vendored
Normal file
19
vendor/symfony/polyfill-intl-normalizer/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
308
vendor/symfony/polyfill-intl-normalizer/Normalizer.php
vendored
Normal file
308
vendor/symfony/polyfill-intl-normalizer/Normalizer.php
vendored
Normal file
@ -0,0 +1,308 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Intl\Normalizer;
|
||||
|
||||
/**
|
||||
* Normalizer is a PHP fallback implementation of the Normalizer class provided by the intl extension.
|
||||
*
|
||||
* It has been validated with Unicode 6.3 Normalization Conformance Test.
|
||||
* See http://www.unicode.org/reports/tr15/ for detailed info about Unicode normalizations.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class Normalizer
|
||||
{
|
||||
const FORM_D = \Normalizer::FORM_D;
|
||||
const FORM_KD = \Normalizer::FORM_KD;
|
||||
const FORM_C = \Normalizer::FORM_C;
|
||||
const FORM_KC = \Normalizer::FORM_KC;
|
||||
const NFD = \Normalizer::NFD;
|
||||
const NFKD = \Normalizer::NFKD;
|
||||
const NFC = \Normalizer::NFC;
|
||||
const NFKC = \Normalizer::NFKC;
|
||||
|
||||
private static $C;
|
||||
private static $D;
|
||||
private static $KD;
|
||||
private static $cC;
|
||||
private static $ulenMask = array("\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4);
|
||||
private static $ASCII = "\x20\x65\x69\x61\x73\x6E\x74\x72\x6F\x6C\x75\x64\x5D\x5B\x63\x6D\x70\x27\x0A\x67\x7C\x68\x76\x2E\x66\x62\x2C\x3A\x3D\x2D\x71\x31\x30\x43\x32\x2A\x79\x78\x29\x28\x4C\x39\x41\x53\x2F\x50\x22\x45\x6A\x4D\x49\x6B\x33\x3E\x35\x54\x3C\x44\x34\x7D\x42\x7B\x38\x46\x77\x52\x36\x37\x55\x47\x4E\x3B\x4A\x7A\x56\x23\x48\x4F\x57\x5F\x26\x21\x4B\x3F\x58\x51\x25\x59\x5C\x09\x5A\x2B\x7E\x5E\x24\x40\x60\x7F\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
|
||||
|
||||
public static function isNormalized($s, $form = self::NFC)
|
||||
{
|
||||
if (!\in_array($form, array(self::NFD, self::NFKD, self::NFC, self::NFKC))) {
|
||||
return false;
|
||||
}
|
||||
$s = (string) $s;
|
||||
if (!isset($s[strspn($s, self::$ASCII)])) {
|
||||
return true;
|
||||
}
|
||||
if (self::NFC == $form && preg_match('//u', $s) && !preg_match('/[^\x00-\x{2FF}]/u', $s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return self::normalize($s, $form) === $s;
|
||||
}
|
||||
|
||||
public static function normalize($s, $form = self::NFC)
|
||||
{
|
||||
$s = (string) $s;
|
||||
if (!preg_match('//u', $s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ($form) {
|
||||
case self::NFC: $C = true; $K = false; break;
|
||||
case self::NFD: $C = false; $K = false; break;
|
||||
case self::NFKC: $C = true; $K = true; break;
|
||||
case self::NFKD: $C = false; $K = true; break;
|
||||
default:
|
||||
if (\defined('Normalizer::NONE') && \Normalizer::NONE == $form) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('' === $s) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($K && null === self::$KD) {
|
||||
self::$KD = self::getData('compatibilityDecomposition');
|
||||
}
|
||||
|
||||
if (null === self::$D) {
|
||||
self::$D = self::getData('canonicalDecomposition');
|
||||
self::$cC = self::getData('combiningClass');
|
||||
}
|
||||
|
||||
if (null !== $mbEncoding = (2 /* MB_OVERLOAD_STRING */ & (int) ini_get('mbstring.func_overload')) ? mb_internal_encoding() : null) {
|
||||
mb_internal_encoding('8bit');
|
||||
}
|
||||
|
||||
$r = self::decompose($s, $K);
|
||||
|
||||
if ($C) {
|
||||
if (null === self::$C) {
|
||||
self::$C = self::getData('canonicalComposition');
|
||||
}
|
||||
|
||||
$r = self::recompose($r);
|
||||
}
|
||||
if (null !== $mbEncoding) {
|
||||
mb_internal_encoding($mbEncoding);
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
private static function recompose($s)
|
||||
{
|
||||
$ASCII = self::$ASCII;
|
||||
$compMap = self::$C;
|
||||
$combClass = self::$cC;
|
||||
$ulenMask = self::$ulenMask;
|
||||
|
||||
$result = $tail = '';
|
||||
|
||||
$i = $s[0] < "\x80" ? 1 : $ulenMask[$s[0] & "\xF0"];
|
||||
$len = \strlen($s);
|
||||
|
||||
$lastUchr = substr($s, 0, $i);
|
||||
$lastUcls = isset($combClass[$lastUchr]) ? 256 : 0;
|
||||
|
||||
while ($i < $len) {
|
||||
if ($s[$i] < "\x80") {
|
||||
// ASCII chars
|
||||
|
||||
if ($tail) {
|
||||
$lastUchr .= $tail;
|
||||
$tail = '';
|
||||
}
|
||||
|
||||
if ($j = strspn($s, $ASCII, $i + 1)) {
|
||||
$lastUchr .= substr($s, $i, $j);
|
||||
$i += $j;
|
||||
}
|
||||
|
||||
$result .= $lastUchr;
|
||||
$lastUchr = $s[$i];
|
||||
$lastUcls = 0;
|
||||
++$i;
|
||||
continue;
|
||||
}
|
||||
|
||||
$ulen = $ulenMask[$s[$i] & "\xF0"];
|
||||
$uchr = substr($s, $i, $ulen);
|
||||
|
||||
if ($lastUchr < "\xE1\x84\x80" || "\xE1\x84\x92" < $lastUchr
|
||||
|| $uchr < "\xE1\x85\xA1" || "\xE1\x85\xB5" < $uchr
|
||||
|| $lastUcls) {
|
||||
// Table lookup and combining chars composition
|
||||
|
||||
$ucls = isset($combClass[$uchr]) ? $combClass[$uchr] : 0;
|
||||
|
||||
if (isset($compMap[$lastUchr.$uchr]) && (!$lastUcls || $lastUcls < $ucls)) {
|
||||
$lastUchr = $compMap[$lastUchr.$uchr];
|
||||
} elseif ($lastUcls = $ucls) {
|
||||
$tail .= $uchr;
|
||||
} else {
|
||||
if ($tail) {
|
||||
$lastUchr .= $tail;
|
||||
$tail = '';
|
||||
}
|
||||
|
||||
$result .= $lastUchr;
|
||||
$lastUchr = $uchr;
|
||||
}
|
||||
} else {
|
||||
// Hangul chars
|
||||
|
||||
$L = \ord($lastUchr[2]) - 0x80;
|
||||
$V = \ord($uchr[2]) - 0xA1;
|
||||
$T = 0;
|
||||
|
||||
$uchr = substr($s, $i + $ulen, 3);
|
||||
|
||||
if ("\xE1\x86\xA7" <= $uchr && $uchr <= "\xE1\x87\x82") {
|
||||
$T = \ord($uchr[2]) - 0xA7;
|
||||
0 > $T && $T += 0x40;
|
||||
$ulen += 3;
|
||||
}
|
||||
|
||||
$L = 0xAC00 + ($L * 21 + $V) * 28 + $T;
|
||||
$lastUchr = \chr(0xE0 | $L >> 12).\chr(0x80 | $L >> 6 & 0x3F).\chr(0x80 | $L & 0x3F);
|
||||
}
|
||||
|
||||
$i += $ulen;
|
||||
}
|
||||
|
||||
return $result.$lastUchr.$tail;
|
||||
}
|
||||
|
||||
private static function decompose($s, $c)
|
||||
{
|
||||
$result = '';
|
||||
|
||||
$ASCII = self::$ASCII;
|
||||
$decompMap = self::$D;
|
||||
$combClass = self::$cC;
|
||||
$ulenMask = self::$ulenMask;
|
||||
if ($c) {
|
||||
$compatMap = self::$KD;
|
||||
}
|
||||
|
||||
$c = array();
|
||||
$i = 0;
|
||||
$len = \strlen($s);
|
||||
|
||||
while ($i < $len) {
|
||||
if ($s[$i] < "\x80") {
|
||||
// ASCII chars
|
||||
|
||||
if ($c) {
|
||||
ksort($c);
|
||||
$result .= implode('', $c);
|
||||
$c = array();
|
||||
}
|
||||
|
||||
$j = 1 + strspn($s, $ASCII, $i + 1);
|
||||
$result .= substr($s, $i, $j);
|
||||
$i += $j;
|
||||
continue;
|
||||
}
|
||||
|
||||
$ulen = $ulenMask[$s[$i] & "\xF0"];
|
||||
$uchr = substr($s, $i, $ulen);
|
||||
$i += $ulen;
|
||||
|
||||
if ($uchr < "\xEA\xB0\x80" || "\xED\x9E\xA3" < $uchr) {
|
||||
// Table lookup
|
||||
|
||||
if ($uchr !== $j = isset($compatMap[$uchr]) ? $compatMap[$uchr] : (isset($decompMap[$uchr]) ? $decompMap[$uchr] : $uchr)) {
|
||||
$uchr = $j;
|
||||
|
||||
$j = \strlen($uchr);
|
||||
$ulen = $uchr[0] < "\x80" ? 1 : $ulenMask[$uchr[0] & "\xF0"];
|
||||
|
||||
if ($ulen != $j) {
|
||||
// Put trailing chars in $s
|
||||
|
||||
$j -= $ulen;
|
||||
$i -= $j;
|
||||
|
||||
if (0 > $i) {
|
||||
$s = str_repeat(' ', -$i).$s;
|
||||
$len -= $i;
|
||||
$i = 0;
|
||||
}
|
||||
|
||||
while ($j--) {
|
||||
$s[$i + $j] = $uchr[$ulen + $j];
|
||||
}
|
||||
|
||||
$uchr = substr($uchr, 0, $ulen);
|
||||
}
|
||||
}
|
||||
if (isset($combClass[$uchr])) {
|
||||
// Combining chars, for sorting
|
||||
|
||||
if (!isset($c[$combClass[$uchr]])) {
|
||||
$c[$combClass[$uchr]] = '';
|
||||
}
|
||||
$c[$combClass[$uchr]] .= $uchr;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Hangul chars
|
||||
|
||||
$uchr = unpack('C*', $uchr);
|
||||
$j = (($uchr[1] - 224) << 12) + (($uchr[2] - 128) << 6) + $uchr[3] - 0xAC80;
|
||||
|
||||
$uchr = "\xE1\x84".\chr(0x80 + (int) ($j / 588))
|
||||
."\xE1\x85".\chr(0xA1 + (int) (($j % 588) / 28));
|
||||
|
||||
if ($j %= 28) {
|
||||
$uchr .= $j < 25
|
||||
? ("\xE1\x86".\chr(0xA7 + $j))
|
||||
: ("\xE1\x87".\chr(0x67 + $j));
|
||||
}
|
||||
}
|
||||
if ($c) {
|
||||
ksort($c);
|
||||
$result .= implode('', $c);
|
||||
$c = array();
|
||||
}
|
||||
|
||||
$result .= $uchr;
|
||||
}
|
||||
|
||||
if ($c) {
|
||||
ksort($c);
|
||||
$result .= implode('', $c);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
private static function getData($file)
|
||||
{
|
||||
if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) {
|
||||
return require $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
14
vendor/symfony/polyfill-intl-normalizer/README.md
vendored
Normal file
14
vendor/symfony/polyfill-intl-normalizer/README.md
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
Symfony Polyfill / Intl: Normalizer
|
||||
===================================
|
||||
|
||||
This component provides a fallback implementation for the
|
||||
[`Normalizer`](https://php.net/Normalizer) class provided
|
||||
by the [Intl](https://php.net/intl) extension.
|
||||
|
||||
More information can be found in the
|
||||
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
This library is released under the [MIT license](LICENSE).
|
||||
17
vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
vendored
Normal file
17
vendor/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class Normalizer extends Symfony\Polyfill\Intl\Normalizer\Normalizer
|
||||
{
|
||||
/**
|
||||
* @deprecated since ICU 56 and removed in PHP 8
|
||||
*/
|
||||
const NONE = 1;
|
||||
const FORM_D = 2;
|
||||
const FORM_KD = 3;
|
||||
const FORM_C = 4;
|
||||
const FORM_KC = 5;
|
||||
const NFD = 2;
|
||||
const NFKD = 3;
|
||||
const NFC = 4;
|
||||
const NFKC = 5;
|
||||
}
|
||||
945
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php
vendored
Normal file
945
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalComposition.php
vendored
Normal file
@ -0,0 +1,945 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
'À' => 'À',
|
||||
'Á' => 'Á',
|
||||
'Â' => 'Â',
|
||||
'Ã' => 'Ã',
|
||||
'Ä' => 'Ä',
|
||||
'Å' => 'Å',
|
||||
'Ç' => 'Ç',
|
||||
'È' => 'È',
|
||||
'É' => 'É',
|
||||
'Ê' => 'Ê',
|
||||
'Ë' => 'Ë',
|
||||
'Ì' => 'Ì',
|
||||
'Í' => 'Í',
|
||||
'Î' => 'Î',
|
||||
'Ï' => 'Ï',
|
||||
'Ñ' => 'Ñ',
|
||||
'Ò' => 'Ò',
|
||||
'Ó' => 'Ó',
|
||||
'Ô' => 'Ô',
|
||||
'Õ' => 'Õ',
|
||||
'Ö' => 'Ö',
|
||||
'Ù' => 'Ù',
|
||||
'Ú' => 'Ú',
|
||||
'Û' => 'Û',
|
||||
'Ü' => 'Ü',
|
||||
'Ý' => 'Ý',
|
||||
'à' => 'à',
|
||||
'á' => 'á',
|
||||
'â' => 'â',
|
||||
'ã' => 'ã',
|
||||
'ä' => 'ä',
|
||||
'å' => 'å',
|
||||
'ç' => 'ç',
|
||||
'è' => 'è',
|
||||
'é' => 'é',
|
||||
'ê' => 'ê',
|
||||
'ë' => 'ë',
|
||||
'ì' => 'ì',
|
||||
'í' => 'í',
|
||||
'î' => 'î',
|
||||
'ï' => 'ï',
|
||||
'ñ' => 'ñ',
|
||||
'ò' => 'ò',
|
||||
'ó' => 'ó',
|
||||
'ô' => 'ô',
|
||||
'õ' => 'õ',
|
||||
'ö' => 'ö',
|
||||
'ù' => 'ù',
|
||||
'ú' => 'ú',
|
||||
'û' => 'û',
|
||||
'ü' => 'ü',
|
||||
'ý' => 'ý',
|
||||
'ÿ' => 'ÿ',
|
||||
'Ā' => 'Ā',
|
||||
'ā' => 'ā',
|
||||
'Ă' => 'Ă',
|
||||
'ă' => 'ă',
|
||||
'Ą' => 'Ą',
|
||||
'ą' => 'ą',
|
||||
'Ć' => 'Ć',
|
||||
'ć' => 'ć',
|
||||
'Ĉ' => 'Ĉ',
|
||||
'ĉ' => 'ĉ',
|
||||
'Ċ' => 'Ċ',
|
||||
'ċ' => 'ċ',
|
||||
'Č' => 'Č',
|
||||
'č' => 'č',
|
||||
'Ď' => 'Ď',
|
||||
'ď' => 'ď',
|
||||
'Ē' => 'Ē',
|
||||
'ē' => 'ē',
|
||||
'Ĕ' => 'Ĕ',
|
||||
'ĕ' => 'ĕ',
|
||||
'Ė' => 'Ė',
|
||||
'ė' => 'ė',
|
||||
'Ę' => 'Ę',
|
||||
'ę' => 'ę',
|
||||
'Ě' => 'Ě',
|
||||
'ě' => 'ě',
|
||||
'Ĝ' => 'Ĝ',
|
||||
'ĝ' => 'ĝ',
|
||||
'Ğ' => 'Ğ',
|
||||
'ğ' => 'ğ',
|
||||
'Ġ' => 'Ġ',
|
||||
'ġ' => 'ġ',
|
||||
'Ģ' => 'Ģ',
|
||||
'ģ' => 'ģ',
|
||||
'Ĥ' => 'Ĥ',
|
||||
'ĥ' => 'ĥ',
|
||||
'Ĩ' => 'Ĩ',
|
||||
'ĩ' => 'ĩ',
|
||||
'Ī' => 'Ī',
|
||||
'ī' => 'ī',
|
||||
'Ĭ' => 'Ĭ',
|
||||
'ĭ' => 'ĭ',
|
||||
'Į' => 'Į',
|
||||
'į' => 'į',
|
||||
'İ' => 'İ',
|
||||
'Ĵ' => 'Ĵ',
|
||||
'ĵ' => 'ĵ',
|
||||
'Ķ' => 'Ķ',
|
||||
'ķ' => 'ķ',
|
||||
'Ĺ' => 'Ĺ',
|
||||
'ĺ' => 'ĺ',
|
||||
'Ļ' => 'Ļ',
|
||||
'ļ' => 'ļ',
|
||||
'Ľ' => 'Ľ',
|
||||
'ľ' => 'ľ',
|
||||
'Ń' => 'Ń',
|
||||
'ń' => 'ń',
|
||||
'Ņ' => 'Ņ',
|
||||
'ņ' => 'ņ',
|
||||
'Ň' => 'Ň',
|
||||
'ň' => 'ň',
|
||||
'Ō' => 'Ō',
|
||||
'ō' => 'ō',
|
||||
'Ŏ' => 'Ŏ',
|
||||
'ŏ' => 'ŏ',
|
||||
'Ő' => 'Ő',
|
||||
'ő' => 'ő',
|
||||
'Ŕ' => 'Ŕ',
|
||||
'ŕ' => 'ŕ',
|
||||
'Ŗ' => 'Ŗ',
|
||||
'ŗ' => 'ŗ',
|
||||
'Ř' => 'Ř',
|
||||
'ř' => 'ř',
|
||||
'Ś' => 'Ś',
|
||||
'ś' => 'ś',
|
||||
'Ŝ' => 'Ŝ',
|
||||
'ŝ' => 'ŝ',
|
||||
'Ş' => 'Ş',
|
||||
'ş' => 'ş',
|
||||
'Š' => 'Š',
|
||||
'š' => 'š',
|
||||
'Ţ' => 'Ţ',
|
||||
'ţ' => 'ţ',
|
||||
'Ť' => 'Ť',
|
||||
'ť' => 'ť',
|
||||
'Ũ' => 'Ũ',
|
||||
'ũ' => 'ũ',
|
||||
'Ū' => 'Ū',
|
||||
'ū' => 'ū',
|
||||
'Ŭ' => 'Ŭ',
|
||||
'ŭ' => 'ŭ',
|
||||
'Ů' => 'Ů',
|
||||
'ů' => 'ů',
|
||||
'Ű' => 'Ű',
|
||||
'ű' => 'ű',
|
||||
'Ų' => 'Ų',
|
||||
'ų' => 'ų',
|
||||
'Ŵ' => 'Ŵ',
|
||||
'ŵ' => 'ŵ',
|
||||
'Ŷ' => 'Ŷ',
|
||||
'ŷ' => 'ŷ',
|
||||
'Ÿ' => 'Ÿ',
|
||||
'Ź' => 'Ź',
|
||||
'ź' => 'ź',
|
||||
'Ż' => 'Ż',
|
||||
'ż' => 'ż',
|
||||
'Ž' => 'Ž',
|
||||
'ž' => 'ž',
|
||||
'Ơ' => 'Ơ',
|
||||
'ơ' => 'ơ',
|
||||
'Ư' => 'Ư',
|
||||
'ư' => 'ư',
|
||||
'Ǎ' => 'Ǎ',
|
||||
'ǎ' => 'ǎ',
|
||||
'Ǐ' => 'Ǐ',
|
||||
'ǐ' => 'ǐ',
|
||||
'Ǒ' => 'Ǒ',
|
||||
'ǒ' => 'ǒ',
|
||||
'Ǔ' => 'Ǔ',
|
||||
'ǔ' => 'ǔ',
|
||||
'Ǖ' => 'Ǖ',
|
||||
'ǖ' => 'ǖ',
|
||||
'Ǘ' => 'Ǘ',
|
||||
'ǘ' => 'ǘ',
|
||||
'Ǚ' => 'Ǚ',
|
||||
'ǚ' => 'ǚ',
|
||||
'Ǜ' => 'Ǜ',
|
||||
'ǜ' => 'ǜ',
|
||||
'Ǟ' => 'Ǟ',
|
||||
'ǟ' => 'ǟ',
|
||||
'Ǡ' => 'Ǡ',
|
||||
'ǡ' => 'ǡ',
|
||||
'Ǣ' => 'Ǣ',
|
||||
'ǣ' => 'ǣ',
|
||||
'Ǧ' => 'Ǧ',
|
||||
'ǧ' => 'ǧ',
|
||||
'Ǩ' => 'Ǩ',
|
||||
'ǩ' => 'ǩ',
|
||||
'Ǫ' => 'Ǫ',
|
||||
'ǫ' => 'ǫ',
|
||||
'Ǭ' => 'Ǭ',
|
||||
'ǭ' => 'ǭ',
|
||||
'Ǯ' => 'Ǯ',
|
||||
'ǯ' => 'ǯ',
|
||||
'ǰ' => 'ǰ',
|
||||
'Ǵ' => 'Ǵ',
|
||||
'ǵ' => 'ǵ',
|
||||
'Ǹ' => 'Ǹ',
|
||||
'ǹ' => 'ǹ',
|
||||
'Ǻ' => 'Ǻ',
|
||||
'ǻ' => 'ǻ',
|
||||
'Ǽ' => 'Ǽ',
|
||||
'ǽ' => 'ǽ',
|
||||
'Ǿ' => 'Ǿ',
|
||||
'ǿ' => 'ǿ',
|
||||
'Ȁ' => 'Ȁ',
|
||||
'ȁ' => 'ȁ',
|
||||
'Ȃ' => 'Ȃ',
|
||||
'ȃ' => 'ȃ',
|
||||
'Ȅ' => 'Ȅ',
|
||||
'ȅ' => 'ȅ',
|
||||
'Ȇ' => 'Ȇ',
|
||||
'ȇ' => 'ȇ',
|
||||
'Ȉ' => 'Ȉ',
|
||||
'ȉ' => 'ȉ',
|
||||
'Ȋ' => 'Ȋ',
|
||||
'ȋ' => 'ȋ',
|
||||
'Ȍ' => 'Ȍ',
|
||||
'ȍ' => 'ȍ',
|
||||
'Ȏ' => 'Ȏ',
|
||||
'ȏ' => 'ȏ',
|
||||
'Ȑ' => 'Ȑ',
|
||||
'ȑ' => 'ȑ',
|
||||
'Ȓ' => 'Ȓ',
|
||||
'ȓ' => 'ȓ',
|
||||
'Ȕ' => 'Ȕ',
|
||||
'ȕ' => 'ȕ',
|
||||
'Ȗ' => 'Ȗ',
|
||||
'ȗ' => 'ȗ',
|
||||
'Ș' => 'Ș',
|
||||
'ș' => 'ș',
|
||||
'Ț' => 'Ț',
|
||||
'ț' => 'ț',
|
||||
'Ȟ' => 'Ȟ',
|
||||
'ȟ' => 'ȟ',
|
||||
'Ȧ' => 'Ȧ',
|
||||
'ȧ' => 'ȧ',
|
||||
'Ȩ' => 'Ȩ',
|
||||
'ȩ' => 'ȩ',
|
||||
'Ȫ' => 'Ȫ',
|
||||
'ȫ' => 'ȫ',
|
||||
'Ȭ' => 'Ȭ',
|
||||
'ȭ' => 'ȭ',
|
||||
'Ȯ' => 'Ȯ',
|
||||
'ȯ' => 'ȯ',
|
||||
'Ȱ' => 'Ȱ',
|
||||
'ȱ' => 'ȱ',
|
||||
'Ȳ' => 'Ȳ',
|
||||
'ȳ' => 'ȳ',
|
||||
'΅' => '΅',
|
||||
'Ά' => 'Ά',
|
||||
'Έ' => 'Έ',
|
||||
'Ή' => 'Ή',
|
||||
'Ί' => 'Ί',
|
||||
'Ό' => 'Ό',
|
||||
'Ύ' => 'Ύ',
|
||||
'Ώ' => 'Ώ',
|
||||
'ΐ' => 'ΐ',
|
||||
'Ϊ' => 'Ϊ',
|
||||
'Ϋ' => 'Ϋ',
|
||||
'ά' => 'ά',
|
||||
'έ' => 'έ',
|
||||
'ή' => 'ή',
|
||||
'ί' => 'ί',
|
||||
'ΰ' => 'ΰ',
|
||||
'ϊ' => 'ϊ',
|
||||
'ϋ' => 'ϋ',
|
||||
'ό' => 'ό',
|
||||
'ύ' => 'ύ',
|
||||
'ώ' => 'ώ',
|
||||
'ϓ' => 'ϓ',
|
||||
'ϔ' => 'ϔ',
|
||||
'Ѐ' => 'Ѐ',
|
||||
'Ё' => 'Ё',
|
||||
'Ѓ' => 'Ѓ',
|
||||
'Ї' => 'Ї',
|
||||
'Ќ' => 'Ќ',
|
||||
'Ѝ' => 'Ѝ',
|
||||
'Ў' => 'Ў',
|
||||
'Й' => 'Й',
|
||||
'й' => 'й',
|
||||
'ѐ' => 'ѐ',
|
||||
'ё' => 'ё',
|
||||
'ѓ' => 'ѓ',
|
||||
'ї' => 'ї',
|
||||
'ќ' => 'ќ',
|
||||
'ѝ' => 'ѝ',
|
||||
'ў' => 'ў',
|
||||
'Ѷ' => 'Ѷ',
|
||||
'ѷ' => 'ѷ',
|
||||
'Ӂ' => 'Ӂ',
|
||||
'ӂ' => 'ӂ',
|
||||
'Ӑ' => 'Ӑ',
|
||||
'ӑ' => 'ӑ',
|
||||
'Ӓ' => 'Ӓ',
|
||||
'ӓ' => 'ӓ',
|
||||
'Ӗ' => 'Ӗ',
|
||||
'ӗ' => 'ӗ',
|
||||
'Ӛ' => 'Ӛ',
|
||||
'ӛ' => 'ӛ',
|
||||
'Ӝ' => 'Ӝ',
|
||||
'ӝ' => 'ӝ',
|
||||
'Ӟ' => 'Ӟ',
|
||||
'ӟ' => 'ӟ',
|
||||
'Ӣ' => 'Ӣ',
|
||||
'ӣ' => 'ӣ',
|
||||
'Ӥ' => 'Ӥ',
|
||||
'ӥ' => 'ӥ',
|
||||
'Ӧ' => 'Ӧ',
|
||||
'ӧ' => 'ӧ',
|
||||
'Ӫ' => 'Ӫ',
|
||||
'ӫ' => 'ӫ',
|
||||
'Ӭ' => 'Ӭ',
|
||||
'ӭ' => 'ӭ',
|
||||
'Ӯ' => 'Ӯ',
|
||||
'ӯ' => 'ӯ',
|
||||
'Ӱ' => 'Ӱ',
|
||||
'ӱ' => 'ӱ',
|
||||
'Ӳ' => 'Ӳ',
|
||||
'ӳ' => 'ӳ',
|
||||
'Ӵ' => 'Ӵ',
|
||||
'ӵ' => 'ӵ',
|
||||
'Ӹ' => 'Ӹ',
|
||||
'ӹ' => 'ӹ',
|
||||
'آ' => 'آ',
|
||||
'أ' => 'أ',
|
||||
'ؤ' => 'ؤ',
|
||||
'إ' => 'إ',
|
||||
'ئ' => 'ئ',
|
||||
'ۀ' => 'ۀ',
|
||||
'ۂ' => 'ۂ',
|
||||
'ۓ' => 'ۓ',
|
||||
'ऩ' => 'ऩ',
|
||||
'ऱ' => 'ऱ',
|
||||
'ऴ' => 'ऴ',
|
||||
'ো' => 'ো',
|
||||
'ৌ' => 'ৌ',
|
||||
'ୈ' => 'ୈ',
|
||||
'ୋ' => 'ୋ',
|
||||
'ୌ' => 'ୌ',
|
||||
'ஔ' => 'ஔ',
|
||||
'ொ' => 'ொ',
|
||||
'ோ' => 'ோ',
|
||||
'ௌ' => 'ௌ',
|
||||
'ై' => 'ై',
|
||||
'ೀ' => 'ೀ',
|
||||
'ೇ' => 'ೇ',
|
||||
'ೈ' => 'ೈ',
|
||||
'ೊ' => 'ೊ',
|
||||
'ೋ' => 'ೋ',
|
||||
'ൊ' => 'ൊ',
|
||||
'ോ' => 'ോ',
|
||||
'ൌ' => 'ൌ',
|
||||
'ේ' => 'ේ',
|
||||
'ො' => 'ො',
|
||||
'ෝ' => 'ෝ',
|
||||
'ෞ' => 'ෞ',
|
||||
'ဦ' => 'ဦ',
|
||||
'ᬆ' => 'ᬆ',
|
||||
'ᬈ' => 'ᬈ',
|
||||
'ᬊ' => 'ᬊ',
|
||||
'ᬌ' => 'ᬌ',
|
||||
'ᬎ' => 'ᬎ',
|
||||
'ᬒ' => 'ᬒ',
|
||||
'ᬻ' => 'ᬻ',
|
||||
'ᬽ' => 'ᬽ',
|
||||
'ᭀ' => 'ᭀ',
|
||||
'ᭁ' => 'ᭁ',
|
||||
'ᭃ' => 'ᭃ',
|
||||
'Ḁ' => 'Ḁ',
|
||||
'ḁ' => 'ḁ',
|
||||
'Ḃ' => 'Ḃ',
|
||||
'ḃ' => 'ḃ',
|
||||
'Ḅ' => 'Ḅ',
|
||||
'ḅ' => 'ḅ',
|
||||
'Ḇ' => 'Ḇ',
|
||||
'ḇ' => 'ḇ',
|
||||
'Ḉ' => 'Ḉ',
|
||||
'ḉ' => 'ḉ',
|
||||
'Ḋ' => 'Ḋ',
|
||||
'ḋ' => 'ḋ',
|
||||
'Ḍ' => 'Ḍ',
|
||||
'ḍ' => 'ḍ',
|
||||
'Ḏ' => 'Ḏ',
|
||||
'ḏ' => 'ḏ',
|
||||
'Ḑ' => 'Ḑ',
|
||||
'ḑ' => 'ḑ',
|
||||
'Ḓ' => 'Ḓ',
|
||||
'ḓ' => 'ḓ',
|
||||
'Ḕ' => 'Ḕ',
|
||||
'ḕ' => 'ḕ',
|
||||
'Ḗ' => 'Ḗ',
|
||||
'ḗ' => 'ḗ',
|
||||
'Ḙ' => 'Ḙ',
|
||||
'ḙ' => 'ḙ',
|
||||
'Ḛ' => 'Ḛ',
|
||||
'ḛ' => 'ḛ',
|
||||
'Ḝ' => 'Ḝ',
|
||||
'ḝ' => 'ḝ',
|
||||
'Ḟ' => 'Ḟ',
|
||||
'ḟ' => 'ḟ',
|
||||
'Ḡ' => 'Ḡ',
|
||||
'ḡ' => 'ḡ',
|
||||
'Ḣ' => 'Ḣ',
|
||||
'ḣ' => 'ḣ',
|
||||
'Ḥ' => 'Ḥ',
|
||||
'ḥ' => 'ḥ',
|
||||
'Ḧ' => 'Ḧ',
|
||||
'ḧ' => 'ḧ',
|
||||
'Ḩ' => 'Ḩ',
|
||||
'ḩ' => 'ḩ',
|
||||
'Ḫ' => 'Ḫ',
|
||||
'ḫ' => 'ḫ',
|
||||
'Ḭ' => 'Ḭ',
|
||||
'ḭ' => 'ḭ',
|
||||
'Ḯ' => 'Ḯ',
|
||||
'ḯ' => 'ḯ',
|
||||
'Ḱ' => 'Ḱ',
|
||||
'ḱ' => 'ḱ',
|
||||
'Ḳ' => 'Ḳ',
|
||||
'ḳ' => 'ḳ',
|
||||
'Ḵ' => 'Ḵ',
|
||||
'ḵ' => 'ḵ',
|
||||
'Ḷ' => 'Ḷ',
|
||||
'ḷ' => 'ḷ',
|
||||
'Ḹ' => 'Ḹ',
|
||||
'ḹ' => 'ḹ',
|
||||
'Ḻ' => 'Ḻ',
|
||||
'ḻ' => 'ḻ',
|
||||
'Ḽ' => 'Ḽ',
|
||||
'ḽ' => 'ḽ',
|
||||
'Ḿ' => 'Ḿ',
|
||||
'ḿ' => 'ḿ',
|
||||
'Ṁ' => 'Ṁ',
|
||||
'ṁ' => 'ṁ',
|
||||
'Ṃ' => 'Ṃ',
|
||||
'ṃ' => 'ṃ',
|
||||
'Ṅ' => 'Ṅ',
|
||||
'ṅ' => 'ṅ',
|
||||
'Ṇ' => 'Ṇ',
|
||||
'ṇ' => 'ṇ',
|
||||
'Ṉ' => 'Ṉ',
|
||||
'ṉ' => 'ṉ',
|
||||
'Ṋ' => 'Ṋ',
|
||||
'ṋ' => 'ṋ',
|
||||
'Ṍ' => 'Ṍ',
|
||||
'ṍ' => 'ṍ',
|
||||
'Ṏ' => 'Ṏ',
|
||||
'ṏ' => 'ṏ',
|
||||
'Ṑ' => 'Ṑ',
|
||||
'ṑ' => 'ṑ',
|
||||
'Ṓ' => 'Ṓ',
|
||||
'ṓ' => 'ṓ',
|
||||
'Ṕ' => 'Ṕ',
|
||||
'ṕ' => 'ṕ',
|
||||
'Ṗ' => 'Ṗ',
|
||||
'ṗ' => 'ṗ',
|
||||
'Ṙ' => 'Ṙ',
|
||||
'ṙ' => 'ṙ',
|
||||
'Ṛ' => 'Ṛ',
|
||||
'ṛ' => 'ṛ',
|
||||
'Ṝ' => 'Ṝ',
|
||||
'ṝ' => 'ṝ',
|
||||
'Ṟ' => 'Ṟ',
|
||||
'ṟ' => 'ṟ',
|
||||
'Ṡ' => 'Ṡ',
|
||||
'ṡ' => 'ṡ',
|
||||
'Ṣ' => 'Ṣ',
|
||||
'ṣ' => 'ṣ',
|
||||
'Ṥ' => 'Ṥ',
|
||||
'ṥ' => 'ṥ',
|
||||
'Ṧ' => 'Ṧ',
|
||||
'ṧ' => 'ṧ',
|
||||
'Ṩ' => 'Ṩ',
|
||||
'ṩ' => 'ṩ',
|
||||
'Ṫ' => 'Ṫ',
|
||||
'ṫ' => 'ṫ',
|
||||
'Ṭ' => 'Ṭ',
|
||||
'ṭ' => 'ṭ',
|
||||
'Ṯ' => 'Ṯ',
|
||||
'ṯ' => 'ṯ',
|
||||
'Ṱ' => 'Ṱ',
|
||||
'ṱ' => 'ṱ',
|
||||
'Ṳ' => 'Ṳ',
|
||||
'ṳ' => 'ṳ',
|
||||
'Ṵ' => 'Ṵ',
|
||||
'ṵ' => 'ṵ',
|
||||
'Ṷ' => 'Ṷ',
|
||||
'ṷ' => 'ṷ',
|
||||
'Ṹ' => 'Ṹ',
|
||||
'ṹ' => 'ṹ',
|
||||
'Ṻ' => 'Ṻ',
|
||||
'ṻ' => 'ṻ',
|
||||
'Ṽ' => 'Ṽ',
|
||||
'ṽ' => 'ṽ',
|
||||
'Ṿ' => 'Ṿ',
|
||||
'ṿ' => 'ṿ',
|
||||
'Ẁ' => 'Ẁ',
|
||||
'ẁ' => 'ẁ',
|
||||
'Ẃ' => 'Ẃ',
|
||||
'ẃ' => 'ẃ',
|
||||
'Ẅ' => 'Ẅ',
|
||||
'ẅ' => 'ẅ',
|
||||
'Ẇ' => 'Ẇ',
|
||||
'ẇ' => 'ẇ',
|
||||
'Ẉ' => 'Ẉ',
|
||||
'ẉ' => 'ẉ',
|
||||
'Ẋ' => 'Ẋ',
|
||||
'ẋ' => 'ẋ',
|
||||
'Ẍ' => 'Ẍ',
|
||||
'ẍ' => 'ẍ',
|
||||
'Ẏ' => 'Ẏ',
|
||||
'ẏ' => 'ẏ',
|
||||
'Ẑ' => 'Ẑ',
|
||||
'ẑ' => 'ẑ',
|
||||
'Ẓ' => 'Ẓ',
|
||||
'ẓ' => 'ẓ',
|
||||
'Ẕ' => 'Ẕ',
|
||||
'ẕ' => 'ẕ',
|
||||
'ẖ' => 'ẖ',
|
||||
'ẗ' => 'ẗ',
|
||||
'ẘ' => 'ẘ',
|
||||
'ẙ' => 'ẙ',
|
||||
'ẛ' => 'ẛ',
|
||||
'Ạ' => 'Ạ',
|
||||
'ạ' => 'ạ',
|
||||
'Ả' => 'Ả',
|
||||
'ả' => 'ả',
|
||||
'Ấ' => 'Ấ',
|
||||
'ấ' => 'ấ',
|
||||
'Ầ' => 'Ầ',
|
||||
'ầ' => 'ầ',
|
||||
'Ẩ' => 'Ẩ',
|
||||
'ẩ' => 'ẩ',
|
||||
'Ẫ' => 'Ẫ',
|
||||
'ẫ' => 'ẫ',
|
||||
'Ậ' => 'Ậ',
|
||||
'ậ' => 'ậ',
|
||||
'Ắ' => 'Ắ',
|
||||
'ắ' => 'ắ',
|
||||
'Ằ' => 'Ằ',
|
||||
'ằ' => 'ằ',
|
||||
'Ẳ' => 'Ẳ',
|
||||
'ẳ' => 'ẳ',
|
||||
'Ẵ' => 'Ẵ',
|
||||
'ẵ' => 'ẵ',
|
||||
'Ặ' => 'Ặ',
|
||||
'ặ' => 'ặ',
|
||||
'Ẹ' => 'Ẹ',
|
||||
'ẹ' => 'ẹ',
|
||||
'Ẻ' => 'Ẻ',
|
||||
'ẻ' => 'ẻ',
|
||||
'Ẽ' => 'Ẽ',
|
||||
'ẽ' => 'ẽ',
|
||||
'Ế' => 'Ế',
|
||||
'ế' => 'ế',
|
||||
'Ề' => 'Ề',
|
||||
'ề' => 'ề',
|
||||
'Ể' => 'Ể',
|
||||
'ể' => 'ể',
|
||||
'Ễ' => 'Ễ',
|
||||
'ễ' => 'ễ',
|
||||
'Ệ' => 'Ệ',
|
||||
'ệ' => 'ệ',
|
||||
'Ỉ' => 'Ỉ',
|
||||
'ỉ' => 'ỉ',
|
||||
'Ị' => 'Ị',
|
||||
'ị' => 'ị',
|
||||
'Ọ' => 'Ọ',
|
||||
'ọ' => 'ọ',
|
||||
'Ỏ' => 'Ỏ',
|
||||
'ỏ' => 'ỏ',
|
||||
'Ố' => 'Ố',
|
||||
'ố' => 'ố',
|
||||
'Ồ' => 'Ồ',
|
||||
'ồ' => 'ồ',
|
||||
'Ổ' => 'Ổ',
|
||||
'ổ' => 'ổ',
|
||||
'Ỗ' => 'Ỗ',
|
||||
'ỗ' => 'ỗ',
|
||||
'Ộ' => 'Ộ',
|
||||
'ộ' => 'ộ',
|
||||
'Ớ' => 'Ớ',
|
||||
'ớ' => 'ớ',
|
||||
'Ờ' => 'Ờ',
|
||||
'ờ' => 'ờ',
|
||||
'Ở' => 'Ở',
|
||||
'ở' => 'ở',
|
||||
'Ỡ' => 'Ỡ',
|
||||
'ỡ' => 'ỡ',
|
||||
'Ợ' => 'Ợ',
|
||||
'ợ' => 'ợ',
|
||||
'Ụ' => 'Ụ',
|
||||
'ụ' => 'ụ',
|
||||
'Ủ' => 'Ủ',
|
||||
'ủ' => 'ủ',
|
||||
'Ứ' => 'Ứ',
|
||||
'ứ' => 'ứ',
|
||||
'Ừ' => 'Ừ',
|
||||
'ừ' => 'ừ',
|
||||
'Ử' => 'Ử',
|
||||
'ử' => 'ử',
|
||||
'Ữ' => 'Ữ',
|
||||
'ữ' => 'ữ',
|
||||
'Ự' => 'Ự',
|
||||
'ự' => 'ự',
|
||||
'Ỳ' => 'Ỳ',
|
||||
'ỳ' => 'ỳ',
|
||||
'Ỵ' => 'Ỵ',
|
||||
'ỵ' => 'ỵ',
|
||||
'Ỷ' => 'Ỷ',
|
||||
'ỷ' => 'ỷ',
|
||||
'Ỹ' => 'Ỹ',
|
||||
'ỹ' => 'ỹ',
|
||||
'ἀ' => 'ἀ',
|
||||
'ἁ' => 'ἁ',
|
||||
'ἂ' => 'ἂ',
|
||||
'ἃ' => 'ἃ',
|
||||
'ἄ' => 'ἄ',
|
||||
'ἅ' => 'ἅ',
|
||||
'ἆ' => 'ἆ',
|
||||
'ἇ' => 'ἇ',
|
||||
'Ἀ' => 'Ἀ',
|
||||
'Ἁ' => 'Ἁ',
|
||||
'Ἂ' => 'Ἂ',
|
||||
'Ἃ' => 'Ἃ',
|
||||
'Ἄ' => 'Ἄ',
|
||||
'Ἅ' => 'Ἅ',
|
||||
'Ἆ' => 'Ἆ',
|
||||
'Ἇ' => 'Ἇ',
|
||||
'ἐ' => 'ἐ',
|
||||
'ἑ' => 'ἑ',
|
||||
'ἒ' => 'ἒ',
|
||||
'ἓ' => 'ἓ',
|
||||
'ἔ' => 'ἔ',
|
||||
'ἕ' => 'ἕ',
|
||||
'Ἐ' => 'Ἐ',
|
||||
'Ἑ' => 'Ἑ',
|
||||
'Ἒ' => 'Ἒ',
|
||||
'Ἓ' => 'Ἓ',
|
||||
'Ἔ' => 'Ἔ',
|
||||
'Ἕ' => 'Ἕ',
|
||||
'ἠ' => 'ἠ',
|
||||
'ἡ' => 'ἡ',
|
||||
'ἢ' => 'ἢ',
|
||||
'ἣ' => 'ἣ',
|
||||
'ἤ' => 'ἤ',
|
||||
'ἥ' => 'ἥ',
|
||||
'ἦ' => 'ἦ',
|
||||
'ἧ' => 'ἧ',
|
||||
'Ἠ' => 'Ἠ',
|
||||
'Ἡ' => 'Ἡ',
|
||||
'Ἢ' => 'Ἢ',
|
||||
'Ἣ' => 'Ἣ',
|
||||
'Ἤ' => 'Ἤ',
|
||||
'Ἥ' => 'Ἥ',
|
||||
'Ἦ' => 'Ἦ',
|
||||
'Ἧ' => 'Ἧ',
|
||||
'ἰ' => 'ἰ',
|
||||
'ἱ' => 'ἱ',
|
||||
'ἲ' => 'ἲ',
|
||||
'ἳ' => 'ἳ',
|
||||
'ἴ' => 'ἴ',
|
||||
'ἵ' => 'ἵ',
|
||||
'ἶ' => 'ἶ',
|
||||
'ἷ' => 'ἷ',
|
||||
'Ἰ' => 'Ἰ',
|
||||
'Ἱ' => 'Ἱ',
|
||||
'Ἲ' => 'Ἲ',
|
||||
'Ἳ' => 'Ἳ',
|
||||
'Ἴ' => 'Ἴ',
|
||||
'Ἵ' => 'Ἵ',
|
||||
'Ἶ' => 'Ἶ',
|
||||
'Ἷ' => 'Ἷ',
|
||||
'ὀ' => 'ὀ',
|
||||
'ὁ' => 'ὁ',
|
||||
'ὂ' => 'ὂ',
|
||||
'ὃ' => 'ὃ',
|
||||
'ὄ' => 'ὄ',
|
||||
'ὅ' => 'ὅ',
|
||||
'Ὀ' => 'Ὀ',
|
||||
'Ὁ' => 'Ὁ',
|
||||
'Ὂ' => 'Ὂ',
|
||||
'Ὃ' => 'Ὃ',
|
||||
'Ὄ' => 'Ὄ',
|
||||
'Ὅ' => 'Ὅ',
|
||||
'ὐ' => 'ὐ',
|
||||
'ὑ' => 'ὑ',
|
||||
'ὒ' => 'ὒ',
|
||||
'ὓ' => 'ὓ',
|
||||
'ὔ' => 'ὔ',
|
||||
'ὕ' => 'ὕ',
|
||||
'ὖ' => 'ὖ',
|
||||
'ὗ' => 'ὗ',
|
||||
'Ὑ' => 'Ὑ',
|
||||
'Ὓ' => 'Ὓ',
|
||||
'Ὕ' => 'Ὕ',
|
||||
'Ὗ' => 'Ὗ',
|
||||
'ὠ' => 'ὠ',
|
||||
'ὡ' => 'ὡ',
|
||||
'ὢ' => 'ὢ',
|
||||
'ὣ' => 'ὣ',
|
||||
'ὤ' => 'ὤ',
|
||||
'ὥ' => 'ὥ',
|
||||
'ὦ' => 'ὦ',
|
||||
'ὧ' => 'ὧ',
|
||||
'Ὠ' => 'Ὠ',
|
||||
'Ὡ' => 'Ὡ',
|
||||
'Ὢ' => 'Ὢ',
|
||||
'Ὣ' => 'Ὣ',
|
||||
'Ὤ' => 'Ὤ',
|
||||
'Ὥ' => 'Ὥ',
|
||||
'Ὦ' => 'Ὦ',
|
||||
'Ὧ' => 'Ὧ',
|
||||
'ὰ' => 'ὰ',
|
||||
'ὲ' => 'ὲ',
|
||||
'ὴ' => 'ὴ',
|
||||
'ὶ' => 'ὶ',
|
||||
'ὸ' => 'ὸ',
|
||||
'ὺ' => 'ὺ',
|
||||
'ὼ' => 'ὼ',
|
||||
'ᾀ' => 'ᾀ',
|
||||
'ᾁ' => 'ᾁ',
|
||||
'ᾂ' => 'ᾂ',
|
||||
'ᾃ' => 'ᾃ',
|
||||
'ᾄ' => 'ᾄ',
|
||||
'ᾅ' => 'ᾅ',
|
||||
'ᾆ' => 'ᾆ',
|
||||
'ᾇ' => 'ᾇ',
|
||||
'ᾈ' => 'ᾈ',
|
||||
'ᾉ' => 'ᾉ',
|
||||
'ᾊ' => 'ᾊ',
|
||||
'ᾋ' => 'ᾋ',
|
||||
'ᾌ' => 'ᾌ',
|
||||
'ᾍ' => 'ᾍ',
|
||||
'ᾎ' => 'ᾎ',
|
||||
'ᾏ' => 'ᾏ',
|
||||
'ᾐ' => 'ᾐ',
|
||||
'ᾑ' => 'ᾑ',
|
||||
'ᾒ' => 'ᾒ',
|
||||
'ᾓ' => 'ᾓ',
|
||||
'ᾔ' => 'ᾔ',
|
||||
'ᾕ' => 'ᾕ',
|
||||
'ᾖ' => 'ᾖ',
|
||||
'ᾗ' => 'ᾗ',
|
||||
'ᾘ' => 'ᾘ',
|
||||
'ᾙ' => 'ᾙ',
|
||||
'ᾚ' => 'ᾚ',
|
||||
'ᾛ' => 'ᾛ',
|
||||
'ᾜ' => 'ᾜ',
|
||||
'ᾝ' => 'ᾝ',
|
||||
'ᾞ' => 'ᾞ',
|
||||
'ᾟ' => 'ᾟ',
|
||||
'ᾠ' => 'ᾠ',
|
||||
'ᾡ' => 'ᾡ',
|
||||
'ᾢ' => 'ᾢ',
|
||||
'ᾣ' => 'ᾣ',
|
||||
'ᾤ' => 'ᾤ',
|
||||
'ᾥ' => 'ᾥ',
|
||||
'ᾦ' => 'ᾦ',
|
||||
'ᾧ' => 'ᾧ',
|
||||
'ᾨ' => 'ᾨ',
|
||||
'ᾩ' => 'ᾩ',
|
||||
'ᾪ' => 'ᾪ',
|
||||
'ᾫ' => 'ᾫ',
|
||||
'ᾬ' => 'ᾬ',
|
||||
'ᾭ' => 'ᾭ',
|
||||
'ᾮ' => 'ᾮ',
|
||||
'ᾯ' => 'ᾯ',
|
||||
'ᾰ' => 'ᾰ',
|
||||
'ᾱ' => 'ᾱ',
|
||||
'ᾲ' => 'ᾲ',
|
||||
'ᾳ' => 'ᾳ',
|
||||
'ᾴ' => 'ᾴ',
|
||||
'ᾶ' => 'ᾶ',
|
||||
'ᾷ' => 'ᾷ',
|
||||
'Ᾰ' => 'Ᾰ',
|
||||
'Ᾱ' => 'Ᾱ',
|
||||
'Ὰ' => 'Ὰ',
|
||||
'ᾼ' => 'ᾼ',
|
||||
'῁' => '῁',
|
||||
'ῂ' => 'ῂ',
|
||||
'ῃ' => 'ῃ',
|
||||
'ῄ' => 'ῄ',
|
||||
'ῆ' => 'ῆ',
|
||||
'ῇ' => 'ῇ',
|
||||
'Ὲ' => 'Ὲ',
|
||||
'Ὴ' => 'Ὴ',
|
||||
'ῌ' => 'ῌ',
|
||||
'῍' => '῍',
|
||||
'῎' => '῎',
|
||||
'῏' => '῏',
|
||||
'ῐ' => 'ῐ',
|
||||
'ῑ' => 'ῑ',
|
||||
'ῒ' => 'ῒ',
|
||||
'ῖ' => 'ῖ',
|
||||
'ῗ' => 'ῗ',
|
||||
'Ῐ' => 'Ῐ',
|
||||
'Ῑ' => 'Ῑ',
|
||||
'Ὶ' => 'Ὶ',
|
||||
'῝' => '῝',
|
||||
'῞' => '῞',
|
||||
'῟' => '῟',
|
||||
'ῠ' => 'ῠ',
|
||||
'ῡ' => 'ῡ',
|
||||
'ῢ' => 'ῢ',
|
||||
'ῤ' => 'ῤ',
|
||||
'ῥ' => 'ῥ',
|
||||
'ῦ' => 'ῦ',
|
||||
'ῧ' => 'ῧ',
|
||||
'Ῠ' => 'Ῠ',
|
||||
'Ῡ' => 'Ῡ',
|
||||
'Ὺ' => 'Ὺ',
|
||||
'Ῥ' => 'Ῥ',
|
||||
'῭' => '῭',
|
||||
'ῲ' => 'ῲ',
|
||||
'ῳ' => 'ῳ',
|
||||
'ῴ' => 'ῴ',
|
||||
'ῶ' => 'ῶ',
|
||||
'ῷ' => 'ῷ',
|
||||
'Ὸ' => 'Ὸ',
|
||||
'Ὼ' => 'Ὼ',
|
||||
'ῼ' => 'ῼ',
|
||||
'↚' => '↚',
|
||||
'↛' => '↛',
|
||||
'↮' => '↮',
|
||||
'⇍' => '⇍',
|
||||
'⇎' => '⇎',
|
||||
'⇏' => '⇏',
|
||||
'∄' => '∄',
|
||||
'∉' => '∉',
|
||||
'∌' => '∌',
|
||||
'∤' => '∤',
|
||||
'∦' => '∦',
|
||||
'≁' => '≁',
|
||||
'≄' => '≄',
|
||||
'≇' => '≇',
|
||||
'≉' => '≉',
|
||||
'≠' => '≠',
|
||||
'≢' => '≢',
|
||||
'≭' => '≭',
|
||||
'≮' => '≮',
|
||||
'≯' => '≯',
|
||||
'≰' => '≰',
|
||||
'≱' => '≱',
|
||||
'≴' => '≴',
|
||||
'≵' => '≵',
|
||||
'≸' => '≸',
|
||||
'≹' => '≹',
|
||||
'⊀' => '⊀',
|
||||
'⊁' => '⊁',
|
||||
'⊄' => '⊄',
|
||||
'⊅' => '⊅',
|
||||
'⊈' => '⊈',
|
||||
'⊉' => '⊉',
|
||||
'⊬' => '⊬',
|
||||
'⊭' => '⊭',
|
||||
'⊮' => '⊮',
|
||||
'⊯' => '⊯',
|
||||
'⋠' => '⋠',
|
||||
'⋡' => '⋡',
|
||||
'⋢' => '⋢',
|
||||
'⋣' => '⋣',
|
||||
'⋪' => '⋪',
|
||||
'⋫' => '⋫',
|
||||
'⋬' => '⋬',
|
||||
'⋭' => '⋭',
|
||||
'が' => 'が',
|
||||
'ぎ' => 'ぎ',
|
||||
'ぐ' => 'ぐ',
|
||||
'げ' => 'げ',
|
||||
'ご' => 'ご',
|
||||
'ざ' => 'ざ',
|
||||
'じ' => 'じ',
|
||||
'ず' => 'ず',
|
||||
'ぜ' => 'ぜ',
|
||||
'ぞ' => 'ぞ',
|
||||
'だ' => 'だ',
|
||||
'ぢ' => 'ぢ',
|
||||
'づ' => 'づ',
|
||||
'で' => 'で',
|
||||
'ど' => 'ど',
|
||||
'ば' => 'ば',
|
||||
'ぱ' => 'ぱ',
|
||||
'び' => 'び',
|
||||
'ぴ' => 'ぴ',
|
||||
'ぶ' => 'ぶ',
|
||||
'ぷ' => 'ぷ',
|
||||
'べ' => 'べ',
|
||||
'ぺ' => 'ぺ',
|
||||
'ぼ' => 'ぼ',
|
||||
'ぽ' => 'ぽ',
|
||||
'ゔ' => 'ゔ',
|
||||
'ゞ' => 'ゞ',
|
||||
'ガ' => 'ガ',
|
||||
'ギ' => 'ギ',
|
||||
'グ' => 'グ',
|
||||
'ゲ' => 'ゲ',
|
||||
'ゴ' => 'ゴ',
|
||||
'ザ' => 'ザ',
|
||||
'ジ' => 'ジ',
|
||||
'ズ' => 'ズ',
|
||||
'ゼ' => 'ゼ',
|
||||
'ゾ' => 'ゾ',
|
||||
'ダ' => 'ダ',
|
||||
'ヂ' => 'ヂ',
|
||||
'ヅ' => 'ヅ',
|
||||
'デ' => 'デ',
|
||||
'ド' => 'ド',
|
||||
'バ' => 'バ',
|
||||
'パ' => 'パ',
|
||||
'ビ' => 'ビ',
|
||||
'ピ' => 'ピ',
|
||||
'ブ' => 'ブ',
|
||||
'プ' => 'プ',
|
||||
'ベ' => 'ベ',
|
||||
'ペ' => 'ペ',
|
||||
'ボ' => 'ボ',
|
||||
'ポ' => 'ポ',
|
||||
'ヴ' => 'ヴ',
|
||||
'ヷ' => 'ヷ',
|
||||
'ヸ' => 'ヸ',
|
||||
'ヹ' => 'ヹ',
|
||||
'ヺ' => 'ヺ',
|
||||
'ヾ' => 'ヾ',
|
||||
'𑂚' => '𑂚',
|
||||
'𑂜' => '𑂜',
|
||||
'𑂫' => '𑂫',
|
||||
'𑄮' => '𑄮',
|
||||
'𑄯' => '𑄯',
|
||||
'𑍋' => '𑍋',
|
||||
'𑍌' => '𑍌',
|
||||
'𑒻' => '𑒻',
|
||||
'𑒼' => '𑒼',
|
||||
'𑒾' => '𑒾',
|
||||
'𑖺' => '𑖺',
|
||||
'𑖻' => '𑖻',
|
||||
'𑤸' => '𑤸',
|
||||
);
|
||||
2065
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
vendored
Normal file
2065
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/canonicalDecomposition.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
876
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
vendored
Normal file
876
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/combiningClass.php
vendored
Normal file
@ -0,0 +1,876 @@
|
||||
<?php
|
||||
|
||||
return array (
|
||||
'̀' => 230,
|
||||
'́' => 230,
|
||||
'̂' => 230,
|
||||
'̃' => 230,
|
||||
'̄' => 230,
|
||||
'̅' => 230,
|
||||
'̆' => 230,
|
||||
'̇' => 230,
|
||||
'̈' => 230,
|
||||
'̉' => 230,
|
||||
'̊' => 230,
|
||||
'̋' => 230,
|
||||
'̌' => 230,
|
||||
'̍' => 230,
|
||||
'̎' => 230,
|
||||
'̏' => 230,
|
||||
'̐' => 230,
|
||||
'̑' => 230,
|
||||
'̒' => 230,
|
||||
'̓' => 230,
|
||||
'̔' => 230,
|
||||
'̕' => 232,
|
||||
'̖' => 220,
|
||||
'̗' => 220,
|
||||
'̘' => 220,
|
||||
'̙' => 220,
|
||||
'̚' => 232,
|
||||
'̛' => 216,
|
||||
'̜' => 220,
|
||||
'̝' => 220,
|
||||
'̞' => 220,
|
||||
'̟' => 220,
|
||||
'̠' => 220,
|
||||
'̡' => 202,
|
||||
'̢' => 202,
|
||||
'̣' => 220,
|
||||
'̤' => 220,
|
||||
'̥' => 220,
|
||||
'̦' => 220,
|
||||
'̧' => 202,
|
||||
'̨' => 202,
|
||||
'̩' => 220,
|
||||
'̪' => 220,
|
||||
'̫' => 220,
|
||||
'̬' => 220,
|
||||
'̭' => 220,
|
||||
'̮' => 220,
|
||||
'̯' => 220,
|
||||
'̰' => 220,
|
||||
'̱' => 220,
|
||||
'̲' => 220,
|
||||
'̳' => 220,
|
||||
'̴' => 1,
|
||||
'̵' => 1,
|
||||
'̶' => 1,
|
||||
'̷' => 1,
|
||||
'̸' => 1,
|
||||
'̹' => 220,
|
||||
'̺' => 220,
|
||||
'̻' => 220,
|
||||
'̼' => 220,
|
||||
'̽' => 230,
|
||||
'̾' => 230,
|
||||
'̿' => 230,
|
||||
'̀' => 230,
|
||||
'́' => 230,
|
||||
'͂' => 230,
|
||||
'̓' => 230,
|
||||
'̈́' => 230,
|
||||
'ͅ' => 240,
|
||||
'͆' => 230,
|
||||
'͇' => 220,
|
||||
'͈' => 220,
|
||||
'͉' => 220,
|
||||
'͊' => 230,
|
||||
'͋' => 230,
|
||||
'͌' => 230,
|
||||
'͍' => 220,
|
||||
'͎' => 220,
|
||||
'͐' => 230,
|
||||
'͑' => 230,
|
||||
'͒' => 230,
|
||||
'͓' => 220,
|
||||
'͔' => 220,
|
||||
'͕' => 220,
|
||||
'͖' => 220,
|
||||
'͗' => 230,
|
||||
'͘' => 232,
|
||||
'͙' => 220,
|
||||
'͚' => 220,
|
||||
'͛' => 230,
|
||||
'͜' => 233,
|
||||
'͝' => 234,
|
||||
'͞' => 234,
|
||||
'͟' => 233,
|
||||
'͠' => 234,
|
||||
'͡' => 234,
|
||||
'͢' => 233,
|
||||
'ͣ' => 230,
|
||||
'ͤ' => 230,
|
||||
'ͥ' => 230,
|
||||
'ͦ' => 230,
|
||||
'ͧ' => 230,
|
||||
'ͨ' => 230,
|
||||
'ͩ' => 230,
|
||||
'ͪ' => 230,
|
||||
'ͫ' => 230,
|
||||
'ͬ' => 230,
|
||||
'ͭ' => 230,
|
||||
'ͮ' => 230,
|
||||
'ͯ' => 230,
|
||||
'҃' => 230,
|
||||
'҄' => 230,
|
||||
'҅' => 230,
|
||||
'҆' => 230,
|
||||
'҇' => 230,
|
||||
'֑' => 220,
|
||||
'֒' => 230,
|
||||
'֓' => 230,
|
||||
'֔' => 230,
|
||||
'֕' => 230,
|
||||
'֖' => 220,
|
||||
'֗' => 230,
|
||||
'֘' => 230,
|
||||
'֙' => 230,
|
||||
'֚' => 222,
|
||||
'֛' => 220,
|
||||
'֜' => 230,
|
||||
'֝' => 230,
|
||||
'֞' => 230,
|
||||
'֟' => 230,
|
||||
'֠' => 230,
|
||||
'֡' => 230,
|
||||
'֢' => 220,
|
||||
'֣' => 220,
|
||||
'֤' => 220,
|
||||
'֥' => 220,
|
||||
'֦' => 220,
|
||||
'֧' => 220,
|
||||
'֨' => 230,
|
||||
'֩' => 230,
|
||||
'֪' => 220,
|
||||
'֫' => 230,
|
||||
'֬' => 230,
|
||||
'֭' => 222,
|
||||
'֮' => 228,
|
||||
'֯' => 230,
|
||||
'ְ' => 10,
|
||||
'ֱ' => 11,
|
||||
'ֲ' => 12,
|
||||
'ֳ' => 13,
|
||||
'ִ' => 14,
|
||||
'ֵ' => 15,
|
||||
'ֶ' => 16,
|
||||
'ַ' => 17,
|
||||
'ָ' => 18,
|
||||
'ֹ' => 19,
|
||||
'ֺ' => 19,
|
||||
'ֻ' => 20,
|
||||
'ּ' => 21,
|
||||
'ֽ' => 22,
|
||||
'ֿ' => 23,
|
||||
'ׁ' => 24,
|
||||
'ׂ' => 25,
|
||||
'ׄ' => 230,
|
||||
'ׅ' => 220,
|
||||
'ׇ' => 18,
|
||||
'ؐ' => 230,
|
||||
'ؑ' => 230,
|
||||
'ؒ' => 230,
|
||||
'ؓ' => 230,
|
||||
'ؔ' => 230,
|
||||
'ؕ' => 230,
|
||||
'ؖ' => 230,
|
||||
'ؗ' => 230,
|
||||
'ؘ' => 30,
|
||||
'ؙ' => 31,
|
||||
'ؚ' => 32,
|
||||
'ً' => 27,
|
||||
'ٌ' => 28,
|
||||
'ٍ' => 29,
|
||||
'َ' => 30,
|
||||
'ُ' => 31,
|
||||
'ِ' => 32,
|
||||
'ّ' => 33,
|
||||
'ْ' => 34,
|
||||
'ٓ' => 230,
|
||||
'ٔ' => 230,
|
||||
'ٕ' => 220,
|
||||
'ٖ' => 220,
|
||||
'ٗ' => 230,
|
||||
'٘' => 230,
|
||||
'ٙ' => 230,
|
||||
'ٚ' => 230,
|
||||
'ٛ' => 230,
|
||||
'ٜ' => 220,
|
||||
'ٝ' => 230,
|
||||
'ٞ' => 230,
|
||||
'ٟ' => 220,
|
||||
'ٰ' => 35,
|
||||
'ۖ' => 230,
|
||||
'ۗ' => 230,
|
||||
'ۘ' => 230,
|
||||
'ۙ' => 230,
|
||||
'ۚ' => 230,
|
||||
'ۛ' => 230,
|
||||
'ۜ' => 230,
|
||||
'۟' => 230,
|
||||
'۠' => 230,
|
||||
'ۡ' => 230,
|
||||
'ۢ' => 230,
|
||||
'ۣ' => 220,
|
||||
'ۤ' => 230,
|
||||
'ۧ' => 230,
|
||||
'ۨ' => 230,
|
||||
'۪' => 220,
|
||||
'۫' => 230,
|
||||
'۬' => 230,
|
||||
'ۭ' => 220,
|
||||
'ܑ' => 36,
|
||||
'ܰ' => 230,
|
||||
'ܱ' => 220,
|
||||
'ܲ' => 230,
|
||||
'ܳ' => 230,
|
||||
'ܴ' => 220,
|
||||
'ܵ' => 230,
|
||||
'ܶ' => 230,
|
||||
'ܷ' => 220,
|
||||
'ܸ' => 220,
|
||||
'ܹ' => 220,
|
||||
'ܺ' => 230,
|
||||
'ܻ' => 220,
|
||||
'ܼ' => 220,
|
||||
'ܽ' => 230,
|
||||
'ܾ' => 220,
|
||||
'ܿ' => 230,
|
||||
'݀' => 230,
|
||||
'݁' => 230,
|
||||
'݂' => 220,
|
||||
'݃' => 230,
|
||||
'݄' => 220,
|
||||
'݅' => 230,
|
||||
'݆' => 220,
|
||||
'݇' => 230,
|
||||
'݈' => 220,
|
||||
'݉' => 230,
|
||||
'݊' => 230,
|
||||
'߫' => 230,
|
||||
'߬' => 230,
|
||||
'߭' => 230,
|
||||
'߮' => 230,
|
||||
'߯' => 230,
|
||||
'߰' => 230,
|
||||
'߱' => 230,
|
||||
'߲' => 220,
|
||||
'߳' => 230,
|
||||
'߽' => 220,
|
||||
'ࠖ' => 230,
|
||||
'ࠗ' => 230,
|
||||
'࠘' => 230,
|
||||
'࠙' => 230,
|
||||
'ࠛ' => 230,
|
||||
'ࠜ' => 230,
|
||||
'ࠝ' => 230,
|
||||
'ࠞ' => 230,
|
||||
'ࠟ' => 230,
|
||||
'ࠠ' => 230,
|
||||
'ࠡ' => 230,
|
||||
'ࠢ' => 230,
|
||||
'ࠣ' => 230,
|
||||
'ࠥ' => 230,
|
||||
'ࠦ' => 230,
|
||||
'ࠧ' => 230,
|
||||
'ࠩ' => 230,
|
||||
'ࠪ' => 230,
|
||||
'ࠫ' => 230,
|
||||
'ࠬ' => 230,
|
||||
'࠭' => 230,
|
||||
'࡙' => 220,
|
||||
'࡚' => 220,
|
||||
'࡛' => 220,
|
||||
'࣓' => 220,
|
||||
'ࣔ' => 230,
|
||||
'ࣕ' => 230,
|
||||
'ࣖ' => 230,
|
||||
'ࣗ' => 230,
|
||||
'ࣘ' => 230,
|
||||
'ࣙ' => 230,
|
||||
'ࣚ' => 230,
|
||||
'ࣛ' => 230,
|
||||
'ࣜ' => 230,
|
||||
'ࣝ' => 230,
|
||||
'ࣞ' => 230,
|
||||
'ࣟ' => 230,
|
||||
'࣠' => 230,
|
||||
'࣡' => 230,
|
||||
'ࣣ' => 220,
|
||||
'ࣤ' => 230,
|
||||
'ࣥ' => 230,
|
||||
'ࣦ' => 220,
|
||||
'ࣧ' => 230,
|
||||
'ࣨ' => 230,
|
||||
'ࣩ' => 220,
|
||||
'࣪' => 230,
|
||||
'࣫' => 230,
|
||||
'࣬' => 230,
|
||||
'࣭' => 220,
|
||||
'࣮' => 220,
|
||||
'࣯' => 220,
|
||||
'ࣰ' => 27,
|
||||
'ࣱ' => 28,
|
||||
'ࣲ' => 29,
|
||||
'ࣳ' => 230,
|
||||
'ࣴ' => 230,
|
||||
'ࣵ' => 230,
|
||||
'ࣶ' => 220,
|
||||
'ࣷ' => 230,
|
||||
'ࣸ' => 230,
|
||||
'ࣹ' => 220,
|
||||
'ࣺ' => 220,
|
||||
'ࣻ' => 230,
|
||||
'ࣼ' => 230,
|
||||
'ࣽ' => 230,
|
||||
'ࣾ' => 230,
|
||||
'ࣿ' => 230,
|
||||
'़' => 7,
|
||||
'्' => 9,
|
||||
'॑' => 230,
|
||||
'॒' => 220,
|
||||
'॓' => 230,
|
||||
'॔' => 230,
|
||||
'়' => 7,
|
||||
'্' => 9,
|
||||
'৾' => 230,
|
||||
'਼' => 7,
|
||||
'੍' => 9,
|
||||
'઼' => 7,
|
||||
'્' => 9,
|
||||
'଼' => 7,
|
||||
'୍' => 9,
|
||||
'்' => 9,
|
||||
'్' => 9,
|
||||
'ౕ' => 84,
|
||||
'ౖ' => 91,
|
||||
'಼' => 7,
|
||||
'್' => 9,
|
||||
'഻' => 9,
|
||||
'഼' => 9,
|
||||
'്' => 9,
|
||||
'්' => 9,
|
||||
'ุ' => 103,
|
||||
'ู' => 103,
|
||||
'ฺ' => 9,
|
||||
'่' => 107,
|
||||
'้' => 107,
|
||||
'๊' => 107,
|
||||
'๋' => 107,
|
||||
'ຸ' => 118,
|
||||
'ູ' => 118,
|
||||
'຺' => 9,
|
||||
'່' => 122,
|
||||
'້' => 122,
|
||||
'໊' => 122,
|
||||
'໋' => 122,
|
||||
'༘' => 220,
|
||||
'༙' => 220,
|
||||
'༵' => 220,
|
||||
'༷' => 220,
|
||||
'༹' => 216,
|
||||
'ཱ' => 129,
|
||||
'ི' => 130,
|
||||
'ུ' => 132,
|
||||
'ེ' => 130,
|
||||
'ཻ' => 130,
|
||||
'ོ' => 130,
|
||||
'ཽ' => 130,
|
||||
'ྀ' => 130,
|
||||
'ྂ' => 230,
|
||||
'ྃ' => 230,
|
||||
'྄' => 9,
|
||||
'྆' => 230,
|
||||
'྇' => 230,
|
||||
'࿆' => 220,
|
||||
'့' => 7,
|
||||
'္' => 9,
|
||||
'်' => 9,
|
||||
'ႍ' => 220,
|
||||
'፝' => 230,
|
||||
'፞' => 230,
|
||||
'፟' => 230,
|
||||
'᜔' => 9,
|
||||
'᜴' => 9,
|
||||
'្' => 9,
|
||||
'៝' => 230,
|
||||
'ᢩ' => 228,
|
||||
'᤹' => 222,
|
||||
'᤺' => 230,
|
||||
'᤻' => 220,
|
||||
'ᨗ' => 230,
|
||||
'ᨘ' => 220,
|
||||
'᩠' => 9,
|
||||
'᩵' => 230,
|
||||
'᩶' => 230,
|
||||
'᩷' => 230,
|
||||
'᩸' => 230,
|
||||
'᩹' => 230,
|
||||
'᩺' => 230,
|
||||
'᩻' => 230,
|
||||
'᩼' => 230,
|
||||
'᩿' => 220,
|
||||
'᪰' => 230,
|
||||
'᪱' => 230,
|
||||
'᪲' => 230,
|
||||
'᪳' => 230,
|
||||
'᪴' => 230,
|
||||
'᪵' => 220,
|
||||
'᪶' => 220,
|
||||
'᪷' => 220,
|
||||
'᪸' => 220,
|
||||
'᪹' => 220,
|
||||
'᪺' => 220,
|
||||
'᪻' => 230,
|
||||
'᪼' => 230,
|
||||
'᪽' => 220,
|
||||
'ᪿ' => 220,
|
||||
'ᫀ' => 220,
|
||||
'᬴' => 7,
|
||||
'᭄' => 9,
|
||||
'᭫' => 230,
|
||||
'᭬' => 220,
|
||||
'᭭' => 230,
|
||||
'᭮' => 230,
|
||||
'᭯' => 230,
|
||||
'᭰' => 230,
|
||||
'᭱' => 230,
|
||||
'᭲' => 230,
|
||||
'᭳' => 230,
|
||||
'᮪' => 9,
|
||||
'᮫' => 9,
|
||||
'᯦' => 7,
|
||||
'᯲' => 9,
|
||||
'᯳' => 9,
|
||||
'᰷' => 7,
|
||||
'᳐' => 230,
|
||||
'᳑' => 230,
|
||||
'᳒' => 230,
|
||||
'᳔' => 1,
|
||||
'᳕' => 220,
|
||||
'᳖' => 220,
|
||||
'᳗' => 220,
|
||||
'᳘' => 220,
|
||||
'᳙' => 220,
|
||||
'᳚' => 230,
|
||||
'᳛' => 230,
|
||||
'᳜' => 220,
|
||||
'᳝' => 220,
|
||||
'᳞' => 220,
|
||||
'᳟' => 220,
|
||||
'᳠' => 230,
|
||||
'᳢' => 1,
|
||||
'᳣' => 1,
|
||||
'᳤' => 1,
|
||||
'᳥' => 1,
|
||||
'᳦' => 1,
|
||||
'᳧' => 1,
|
||||
'᳨' => 1,
|
||||
'᳭' => 220,
|
||||
'᳴' => 230,
|
||||
'᳸' => 230,
|
||||
'᳹' => 230,
|
||||
'᷀' => 230,
|
||||
'᷁' => 230,
|
||||
'᷂' => 220,
|
||||
'᷃' => 230,
|
||||
'᷄' => 230,
|
||||
'᷅' => 230,
|
||||
'᷆' => 230,
|
||||
'᷇' => 230,
|
||||
'᷈' => 230,
|
||||
'᷉' => 230,
|
||||
'᷊' => 220,
|
||||
'᷋' => 230,
|
||||
'᷌' => 230,
|
||||
'᷍' => 234,
|
||||
'᷎' => 214,
|
||||
'᷏' => 220,
|
||||
'᷐' => 202,
|
||||
'᷑' => 230,
|
||||
'᷒' => 230,
|
||||
'ᷓ' => 230,
|
||||
'ᷔ' => 230,
|
||||
'ᷕ' => 230,
|
||||
'ᷖ' => 230,
|
||||
'ᷗ' => 230,
|
||||
'ᷘ' => 230,
|
||||
'ᷙ' => 230,
|
||||
'ᷚ' => 230,
|
||||
'ᷛ' => 230,
|
||||
'ᷜ' => 230,
|
||||
'ᷝ' => 230,
|
||||
'ᷞ' => 230,
|
||||
'ᷟ' => 230,
|
||||
'ᷠ' => 230,
|
||||
'ᷡ' => 230,
|
||||
'ᷢ' => 230,
|
||||
'ᷣ' => 230,
|
||||
'ᷤ' => 230,
|
||||
'ᷥ' => 230,
|
||||
'ᷦ' => 230,
|
||||
'ᷧ' => 230,
|
||||
'ᷨ' => 230,
|
||||
'ᷩ' => 230,
|
||||
'ᷪ' => 230,
|
||||
'ᷫ' => 230,
|
||||
'ᷬ' => 230,
|
||||
'ᷭ' => 230,
|
||||
'ᷮ' => 230,
|
||||
'ᷯ' => 230,
|
||||
'ᷰ' => 230,
|
||||
'ᷱ' => 230,
|
||||
'ᷲ' => 230,
|
||||
'ᷳ' => 230,
|
||||
'ᷴ' => 230,
|
||||
'᷵' => 230,
|
||||
'᷶' => 232,
|
||||
'᷷' => 228,
|
||||
'᷸' => 228,
|
||||
'᷹' => 220,
|
||||
'᷻' => 230,
|
||||
'᷼' => 233,
|
||||
'᷽' => 220,
|
||||
'᷾' => 230,
|
||||
'᷿' => 220,
|
||||
'⃐' => 230,
|
||||
'⃑' => 230,
|
||||
'⃒' => 1,
|
||||
'⃓' => 1,
|
||||
'⃔' => 230,
|
||||
'⃕' => 230,
|
||||
'⃖' => 230,
|
||||
'⃗' => 230,
|
||||
'⃘' => 1,
|
||||
'⃙' => 1,
|
||||
'⃚' => 1,
|
||||
'⃛' => 230,
|
||||
'⃜' => 230,
|
||||
'⃡' => 230,
|
||||
'⃥' => 1,
|
||||
'⃦' => 1,
|
||||
'⃧' => 230,
|
||||
'⃨' => 220,
|
||||
'⃩' => 230,
|
||||
'⃪' => 1,
|
||||
'⃫' => 1,
|
||||
'⃬' => 220,
|
||||
'⃭' => 220,
|
||||
'⃮' => 220,
|
||||
'⃯' => 220,
|
||||
'⃰' => 230,
|
||||
'⳯' => 230,
|
||||
'⳰' => 230,
|
||||
'⳱' => 230,
|
||||
'⵿' => 9,
|
||||
'ⷠ' => 230,
|
||||
'ⷡ' => 230,
|
||||
'ⷢ' => 230,
|
||||
'ⷣ' => 230,
|
||||
'ⷤ' => 230,
|
||||
'ⷥ' => 230,
|
||||
'ⷦ' => 230,
|
||||
'ⷧ' => 230,
|
||||
'ⷨ' => 230,
|
||||
'ⷩ' => 230,
|
||||
'ⷪ' => 230,
|
||||
'ⷫ' => 230,
|
||||
'ⷬ' => 230,
|
||||
'ⷭ' => 230,
|
||||
'ⷮ' => 230,
|
||||
'ⷯ' => 230,
|
||||
'ⷰ' => 230,
|
||||
'ⷱ' => 230,
|
||||
'ⷲ' => 230,
|
||||
'ⷳ' => 230,
|
||||
'ⷴ' => 230,
|
||||
'ⷵ' => 230,
|
||||
'ⷶ' => 230,
|
||||
'ⷷ' => 230,
|
||||
'ⷸ' => 230,
|
||||
'ⷹ' => 230,
|
||||
'ⷺ' => 230,
|
||||
'ⷻ' => 230,
|
||||
'ⷼ' => 230,
|
||||
'ⷽ' => 230,
|
||||
'ⷾ' => 230,
|
||||
'ⷿ' => 230,
|
||||
'〪' => 218,
|
||||
'〫' => 228,
|
||||
'〬' => 232,
|
||||
'〭' => 222,
|
||||
'〮' => 224,
|
||||
'〯' => 224,
|
||||
'゙' => 8,
|
||||
'゚' => 8,
|
||||
'꙯' => 230,
|
||||
'ꙴ' => 230,
|
||||
'ꙵ' => 230,
|
||||
'ꙶ' => 230,
|
||||
'ꙷ' => 230,
|
||||
'ꙸ' => 230,
|
||||
'ꙹ' => 230,
|
||||
'ꙺ' => 230,
|
||||
'ꙻ' => 230,
|
||||
'꙼' => 230,
|
||||
'꙽' => 230,
|
||||
'ꚞ' => 230,
|
||||
'ꚟ' => 230,
|
||||
'꛰' => 230,
|
||||
'꛱' => 230,
|
||||
'꠆' => 9,
|
||||
'꠬' => 9,
|
||||
'꣄' => 9,
|
||||
'꣠' => 230,
|
||||
'꣡' => 230,
|
||||
'꣢' => 230,
|
||||
'꣣' => 230,
|
||||
'꣤' => 230,
|
||||
'꣥' => 230,
|
||||
'꣦' => 230,
|
||||
'꣧' => 230,
|
||||
'꣨' => 230,
|
||||
'꣩' => 230,
|
||||
'꣪' => 230,
|
||||
'꣫' => 230,
|
||||
'꣬' => 230,
|
||||
'꣭' => 230,
|
||||
'꣮' => 230,
|
||||
'꣯' => 230,
|
||||
'꣰' => 230,
|
||||
'꣱' => 230,
|
||||
'꤫' => 220,
|
||||
'꤬' => 220,
|
||||
'꤭' => 220,
|
||||
'꥓' => 9,
|
||||
'꦳' => 7,
|
||||
'꧀' => 9,
|
||||
'ꪰ' => 230,
|
||||
'ꪲ' => 230,
|
||||
'ꪳ' => 230,
|
||||
'ꪴ' => 220,
|
||||
'ꪷ' => 230,
|
||||
'ꪸ' => 230,
|
||||
'ꪾ' => 230,
|
||||
'꪿' => 230,
|
||||
'꫁' => 230,
|
||||
'꫶' => 9,
|
||||
'꯭' => 9,
|
||||
'ﬞ' => 26,
|
||||
'︠' => 230,
|
||||
'︡' => 230,
|
||||
'︢' => 230,
|
||||
'︣' => 230,
|
||||
'︤' => 230,
|
||||
'︥' => 230,
|
||||
'︦' => 230,
|
||||
'︧' => 220,
|
||||
'︨' => 220,
|
||||
'︩' => 220,
|
||||
'︪' => 220,
|
||||
'︫' => 220,
|
||||
'︬' => 220,
|
||||
'︭' => 220,
|
||||
'︮' => 230,
|
||||
'︯' => 230,
|
||||
'𐇽' => 220,
|
||||
'𐋠' => 220,
|
||||
'𐍶' => 230,
|
||||
'𐍷' => 230,
|
||||
'𐍸' => 230,
|
||||
'𐍹' => 230,
|
||||
'𐍺' => 230,
|
||||
'𐨍' => 220,
|
||||
'𐨏' => 230,
|
||||
'𐨸' => 230,
|
||||
'𐨹' => 1,
|
||||
'𐨺' => 220,
|
||||
'𐨿' => 9,
|
||||
'𐫥' => 230,
|
||||
'𐫦' => 220,
|
||||
'𐴤' => 230,
|
||||
'𐴥' => 230,
|
||||
'𐴦' => 230,
|
||||
'𐴧' => 230,
|
||||
'𐺫' => 230,
|
||||
'𐺬' => 230,
|
||||
'𐽆' => 220,
|
||||
'𐽇' => 220,
|
||||
'𐽈' => 230,
|
||||
'𐽉' => 230,
|
||||
'𐽊' => 230,
|
||||
'𐽋' => 220,
|
||||
'𐽌' => 230,
|
||||
'𐽍' => 220,
|
||||
'𐽎' => 220,
|
||||
'𐽏' => 220,
|
||||
'𐽐' => 220,
|
||||
'𑁆' => 9,
|
||||
'𑁿' => 9,
|
||||
'𑂹' => 9,
|
||||
'𑂺' => 7,
|
||||
'𑄀' => 230,
|
||||
'𑄁' => 230,
|
||||
'𑄂' => 230,
|
||||
'𑄳' => 9,
|
||||
'𑄴' => 9,
|
||||
'𑅳' => 7,
|
||||
'𑇀' => 9,
|
||||
'𑇊' => 7,
|
||||
'𑈵' => 9,
|
||||
'𑈶' => 7,
|
||||
'𑋩' => 7,
|
||||
'𑋪' => 9,
|
||||
'𑌻' => 7,
|
||||
'𑌼' => 7,
|
||||
'𑍍' => 9,
|
||||
'𑍦' => 230,
|
||||
'𑍧' => 230,
|
||||
'𑍨' => 230,
|
||||
'𑍩' => 230,
|
||||
'𑍪' => 230,
|
||||
'𑍫' => 230,
|
||||
'𑍬' => 230,
|
||||
'𑍰' => 230,
|
||||
'𑍱' => 230,
|
||||
'𑍲' => 230,
|
||||
'𑍳' => 230,
|
||||
'𑍴' => 230,
|
||||
'𑑂' => 9,
|
||||
'𑑆' => 7,
|
||||
'𑑞' => 230,
|
||||
'𑓂' => 9,
|
||||
'𑓃' => 7,
|
||||
'𑖿' => 9,
|
||||
'𑗀' => 7,
|
||||
'𑘿' => 9,
|
||||
'𑚶' => 9,
|
||||
'𑚷' => 7,
|
||||
'𑜫' => 9,
|
||||
'𑠹' => 9,
|
||||
'𑠺' => 7,
|
||||
'𑤽' => 9,
|
||||
'𑤾' => 9,
|
||||
'𑥃' => 7,
|
||||
'𑧠' => 9,
|
||||
'𑨴' => 9,
|
||||
'𑩇' => 9,
|
||||
'𑪙' => 9,
|
||||
'𑰿' => 9,
|
||||
'𑵂' => 7,
|
||||
'𑵄' => 9,
|
||||
'𑵅' => 9,
|
||||
'𑶗' => 9,
|
||||
'𖫰' => 1,
|
||||
'𖫱' => 1,
|
||||
'𖫲' => 1,
|
||||
'𖫳' => 1,
|
||||
'𖫴' => 1,
|
||||
'𖬰' => 230,
|
||||
'𖬱' => 230,
|
||||
'𖬲' => 230,
|
||||
'𖬳' => 230,
|
||||
'𖬴' => 230,
|
||||
'𖬵' => 230,
|
||||
'𖬶' => 230,
|
||||
'𖿰' => 6,
|
||||
'𖿱' => 6,
|
||||
'𛲞' => 1,
|
||||
'𝅥' => 216,
|
||||
'𝅦' => 216,
|
||||
'𝅧' => 1,
|
||||
'𝅨' => 1,
|
||||
'𝅩' => 1,
|
||||
'𝅭' => 226,
|
||||
'𝅮' => 216,
|
||||
'𝅯' => 216,
|
||||
'𝅰' => 216,
|
||||
'𝅱' => 216,
|
||||
'𝅲' => 216,
|
||||
'𝅻' => 220,
|
||||
'𝅼' => 220,
|
||||
'𝅽' => 220,
|
||||
'𝅾' => 220,
|
||||
'𝅿' => 220,
|
||||
'𝆀' => 220,
|
||||
'𝆁' => 220,
|
||||
'𝆂' => 220,
|
||||
'𝆅' => 230,
|
||||
'𝆆' => 230,
|
||||
'𝆇' => 230,
|
||||
'𝆈' => 230,
|
||||
'𝆉' => 230,
|
||||
'𝆊' => 220,
|
||||
'𝆋' => 220,
|
||||
'𝆪' => 230,
|
||||
'𝆫' => 230,
|
||||
'𝆬' => 230,
|
||||
'𝆭' => 230,
|
||||
'𝉂' => 230,
|
||||
'𝉃' => 230,
|
||||
'𝉄' => 230,
|
||||
'𞀀' => 230,
|
||||
'𞀁' => 230,
|
||||
'𞀂' => 230,
|
||||
'𞀃' => 230,
|
||||
'𞀄' => 230,
|
||||
'𞀅' => 230,
|
||||
'𞀆' => 230,
|
||||
'𞀈' => 230,
|
||||
'𞀉' => 230,
|
||||
'𞀊' => 230,
|
||||
'𞀋' => 230,
|
||||
'𞀌' => 230,
|
||||
'𞀍' => 230,
|
||||
'𞀎' => 230,
|
||||
'𞀏' => 230,
|
||||
'𞀐' => 230,
|
||||
'𞀑' => 230,
|
||||
'𞀒' => 230,
|
||||
'𞀓' => 230,
|
||||
'𞀔' => 230,
|
||||
'𞀕' => 230,
|
||||
'𞀖' => 230,
|
||||
'𞀗' => 230,
|
||||
'𞀘' => 230,
|
||||
'𞀛' => 230,
|
||||
'𞀜' => 230,
|
||||
'𞀝' => 230,
|
||||
'𞀞' => 230,
|
||||
'𞀟' => 230,
|
||||
'𞀠' => 230,
|
||||
'𞀡' => 230,
|
||||
'𞀣' => 230,
|
||||
'𞀤' => 230,
|
||||
'𞀦' => 230,
|
||||
'𞀧' => 230,
|
||||
'𞀨' => 230,
|
||||
'𞀩' => 230,
|
||||
'𞀪' => 230,
|
||||
'𞄰' => 230,
|
||||
'𞄱' => 230,
|
||||
'𞄲' => 230,
|
||||
'𞄳' => 230,
|
||||
'𞄴' => 230,
|
||||
'𞄵' => 230,
|
||||
'𞄶' => 230,
|
||||
'𞋬' => 230,
|
||||
'𞋭' => 230,
|
||||
'𞋮' => 230,
|
||||
'𞋯' => 230,
|
||||
'𞣐' => 220,
|
||||
'𞣑' => 220,
|
||||
'𞣒' => 220,
|
||||
'𞣓' => 220,
|
||||
'𞣔' => 220,
|
||||
'𞣕' => 220,
|
||||
'𞣖' => 220,
|
||||
'𞥄' => 230,
|
||||
'𞥅' => 230,
|
||||
'𞥆' => 230,
|
||||
'𞥇' => 230,
|
||||
'𞥈' => 230,
|
||||
'𞥉' => 230,
|
||||
'𞥊' => 7,
|
||||
);
|
||||
3695
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
vendored
Normal file
3695
vendor/symfony/polyfill-intl-normalizer/Resources/unidata/compatibilityDecomposition.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
vendor/symfony/polyfill-intl-normalizer/bootstrap.php
vendored
Normal file
19
vendor/symfony/polyfill-intl-normalizer/bootstrap.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Intl\Normalizer as p;
|
||||
|
||||
if (!function_exists('normalizer_is_normalized')) {
|
||||
function normalizer_is_normalized($s, $form = p\Normalizer::NFC) { return p\Normalizer::isNormalized($s, $form); }
|
||||
}
|
||||
if (!function_exists('normalizer_normalize')) {
|
||||
function normalizer_normalize($s, $form = p\Normalizer::NFC) { return p\Normalizer::normalize($s, $form); }
|
||||
}
|
||||
39
vendor/symfony/polyfill-intl-normalizer/composer.json
vendored
Normal file
39
vendor/symfony/polyfill-intl-normalizer/composer.json
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "symfony/polyfill-intl-normalizer",
|
||||
"type": "library",
|
||||
"description": "Symfony polyfill for intl's Normalizer class and related functions",
|
||||
"keywords": ["polyfill", "shim", "compatibility", "portable", "intl", "normalizer"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" },
|
||||
"files": [ "bootstrap.php" ],
|
||||
"classmap": [ "Resources/stubs" ]
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "For best performance"
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.18-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
}
|
||||
}
|
||||
19
vendor/symfony/polyfill-php70/LICENSE
vendored
Normal file
19
vendor/symfony/polyfill-php70/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
74
vendor/symfony/polyfill-php70/Php70.php
vendored
Normal file
74
vendor/symfony/polyfill-php70/Php70.php
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Php70;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Php70
|
||||
{
|
||||
public static function intdiv($dividend, $divisor)
|
||||
{
|
||||
$dividend = self::intArg($dividend, __FUNCTION__, 1);
|
||||
$divisor = self::intArg($divisor, __FUNCTION__, 2);
|
||||
|
||||
if (0 === $divisor) {
|
||||
throw new \DivisionByZeroError('Division by zero');
|
||||
}
|
||||
if (-1 === $divisor && ~PHP_INT_MAX === $dividend) {
|
||||
throw new \ArithmeticError('Division of PHP_INT_MIN by -1 is not an integer');
|
||||
}
|
||||
|
||||
return ($dividend - ($dividend % $divisor)) / $divisor;
|
||||
}
|
||||
|
||||
public static function preg_replace_callback_array(array $patterns, $subject, $limit = -1, &$count = 0)
|
||||
{
|
||||
$count = 0;
|
||||
$result = (string) $subject;
|
||||
if (0 === $limit = self::intArg($limit, __FUNCTION__, 3)) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
foreach ($patterns as $pattern => $callback) {
|
||||
$result = preg_replace_callback($pattern, $callback, $result, $limit, $c);
|
||||
$count += $c;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function error_clear_last()
|
||||
{
|
||||
static $handler;
|
||||
if (!$handler) {
|
||||
$handler = function () { return false; };
|
||||
}
|
||||
set_error_handler($handler);
|
||||
@trigger_error('');
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
private static function intArg($value, $caller, $pos)
|
||||
{
|
||||
if (\is_int($value)) {
|
||||
return $value;
|
||||
}
|
||||
if (!\is_numeric($value) || PHP_INT_MAX <= ($value += 0) || ~PHP_INT_MAX >= $value) {
|
||||
throw new \TypeError(sprintf('%s() expects parameter %d to be integer, %s given', $caller, $pos, \gettype($value)));
|
||||
}
|
||||
|
||||
return (int) $value;
|
||||
}
|
||||
}
|
||||
28
vendor/symfony/polyfill-php70/README.md
vendored
Normal file
28
vendor/symfony/polyfill-php70/README.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
Symfony Polyfill / Php70
|
||||
========================
|
||||
|
||||
This component provides features unavailable in releases prior to PHP 7.0:
|
||||
|
||||
- [`intdiv`](https://php.net/intdiv)
|
||||
- [`preg_replace_callback_array`](https://php.net/preg_replace_callback_array)
|
||||
- [`error_clear_last`](https://php.net/error_clear_last)
|
||||
- `random_bytes` and `random_int` (from [paragonie/random_compat](https://github.com/paragonie/random_compat))
|
||||
- [`*Error` throwable classes](https://php.net/Error)
|
||||
- [`PHP_INT_MIN`](https://php.net/reserved.constants#constant.php-int-min)
|
||||
- `SessionUpdateTimestampHandlerInterface`
|
||||
|
||||
More information can be found in the
|
||||
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
|
||||
|
||||
Compatibility notes
|
||||
===================
|
||||
|
||||
To write portable code between PHP5 and PHP7, some care must be taken:
|
||||
- `\*Error` exceptions must be caught before `\Exception`;
|
||||
- after calling `error_clear_last()`, the result of `$e = error_get_last()` must be
|
||||
verified using `isset($e['message'][0])` instead of `null !== $e`.
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
This library is released under the [MIT license](LICENSE).
|
||||
5
vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php
vendored
Normal file
5
vendor/symfony/polyfill-php70/Resources/stubs/ArithmeticError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class ArithmeticError extends Error
|
||||
{
|
||||
}
|
||||
5
vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php
vendored
Normal file
5
vendor/symfony/polyfill-php70/Resources/stubs/AssertionError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class AssertionError extends Error
|
||||
{
|
||||
}
|
||||
5
vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php
vendored
Normal file
5
vendor/symfony/polyfill-php70/Resources/stubs/DivisionByZeroError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class DivisionByZeroError extends Error
|
||||
{
|
||||
}
|
||||
5
vendor/symfony/polyfill-php70/Resources/stubs/Error.php
vendored
Normal file
5
vendor/symfony/polyfill-php70/Resources/stubs/Error.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class Error extends Exception
|
||||
{
|
||||
}
|
||||
5
vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php
vendored
Normal file
5
vendor/symfony/polyfill-php70/Resources/stubs/ParseError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class ParseError extends Error
|
||||
{
|
||||
}
|
||||
23
vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php
vendored
Normal file
23
vendor/symfony/polyfill-php70/Resources/stubs/SessionUpdateTimestampHandlerInterface.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
interface SessionUpdateTimestampHandlerInterface
|
||||
{
|
||||
/**
|
||||
* Checks if a session identifier already exists or not.
|
||||
*
|
||||
* @param string $key
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateId($key);
|
||||
|
||||
/**
|
||||
* Updates the timestamp of a session when its data didn't change.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $val
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function updateTimestamp($key, $val);
|
||||
}
|
||||
5
vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php
vendored
Normal file
5
vendor/symfony/polyfill-php70/Resources/stubs/TypeError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class TypeError extends Error
|
||||
{
|
||||
}
|
||||
30
vendor/symfony/polyfill-php70/bootstrap.php
vendored
Normal file
30
vendor/symfony/polyfill-php70/bootstrap.php
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Php70 as p;
|
||||
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('PHP_INT_MIN')) {
|
||||
define('PHP_INT_MIN', ~PHP_INT_MAX);
|
||||
}
|
||||
|
||||
if (!function_exists('intdiv')) {
|
||||
function intdiv($dividend, $divisor) { return p\Php70::intdiv($dividend, $divisor); }
|
||||
}
|
||||
if (!function_exists('preg_replace_callback_array')) {
|
||||
function preg_replace_callback_array(array $patterns, $subject, $limit = -1, &$count = 0) { return p\Php70::preg_replace_callback_array($patterns, $subject, $limit, $count); }
|
||||
}
|
||||
if (!function_exists('error_clear_last')) {
|
||||
function error_clear_last() { return p\Php70::error_clear_last(); }
|
||||
}
|
||||
37
vendor/symfony/polyfill-php70/composer.json
vendored
Normal file
37
vendor/symfony/polyfill-php70/composer.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "symfony/polyfill-php70",
|
||||
"type": "library",
|
||||
"description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions",
|
||||
"keywords": ["polyfill", "shim", "compatibility", "portable"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"paragonie/random_compat": "~1.0|~2.0|~9.99"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Polyfill\\Php70\\": "" },
|
||||
"files": [ "bootstrap.php" ],
|
||||
"classmap": [ "Resources/stubs" ]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.18-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
}
|
||||
}
|
||||
19
vendor/symfony/polyfill-php72/LICENSE
vendored
Normal file
19
vendor/symfony/polyfill-php72/LICENSE
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2015-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
217
vendor/symfony/polyfill-php72/Php72.php
vendored
Normal file
217
vendor/symfony/polyfill-php72/Php72.php
vendored
Normal file
@ -0,0 +1,217 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Polyfill\Php72;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class Php72
|
||||
{
|
||||
private static $hashMask;
|
||||
|
||||
public static function utf8_encode($s)
|
||||
{
|
||||
$s .= $s;
|
||||
$len = \strlen($s);
|
||||
|
||||
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
|
||||
switch (true) {
|
||||
case $s[$i] < "\x80": $s[$j] = $s[$i]; break;
|
||||
case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break;
|
||||
default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break;
|
||||
}
|
||||
}
|
||||
|
||||
return substr($s, 0, $j);
|
||||
}
|
||||
|
||||
public static function utf8_decode($s)
|
||||
{
|
||||
$s = (string) $s;
|
||||
$len = \strlen($s);
|
||||
|
||||
for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
|
||||
switch ($s[$i] & "\xF0") {
|
||||
case "\xC0":
|
||||
case "\xD0":
|
||||
$c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F");
|
||||
$s[$j] = $c < 256 ? \chr($c) : '?';
|
||||
break;
|
||||
|
||||
case "\xF0":
|
||||
++$i;
|
||||
// no break
|
||||
|
||||
case "\xE0":
|
||||
$s[$j] = '?';
|
||||
$i += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
$s[$j] = $s[$i];
|
||||
}
|
||||
}
|
||||
|
||||
return substr($s, 0, $j);
|
||||
}
|
||||
|
||||
public static function php_os_family()
|
||||
{
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
return 'Windows';
|
||||
}
|
||||
|
||||
$map = array(
|
||||
'Darwin' => 'Darwin',
|
||||
'DragonFly' => 'BSD',
|
||||
'FreeBSD' => 'BSD',
|
||||
'NetBSD' => 'BSD',
|
||||
'OpenBSD' => 'BSD',
|
||||
'Linux' => 'Linux',
|
||||
'SunOS' => 'Solaris',
|
||||
);
|
||||
|
||||
return isset($map[PHP_OS]) ? $map[PHP_OS] : 'Unknown';
|
||||
}
|
||||
|
||||
public static function spl_object_id($object)
|
||||
{
|
||||
if (null === self::$hashMask) {
|
||||
self::initHashMask();
|
||||
}
|
||||
if (null === $hash = spl_object_hash($object)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// On 32-bit systems, PHP_INT_SIZE is 4,
|
||||
return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
|
||||
}
|
||||
|
||||
public static function sapi_windows_vt100_support($stream, $enable = null)
|
||||
{
|
||||
if (!\is_resource($stream)) {
|
||||
trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$meta = stream_get_meta_data($stream);
|
||||
|
||||
if ('STDIO' !== $meta['stream_type']) {
|
||||
trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// We cannot actually disable vt100 support if it is set
|
||||
if (false === $enable || !self::stream_isatty($stream)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The native function does not apply to stdin
|
||||
$meta = array_map('strtolower', $meta);
|
||||
$stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri'];
|
||||
|
||||
return !$stdin
|
||||
&& (false !== getenv('ANSICON')
|
||||
|| 'ON' === getenv('ConEmuANSI')
|
||||
|| 'xterm' === getenv('TERM')
|
||||
|| 'Hyper' === getenv('TERM_PROGRAM'));
|
||||
}
|
||||
|
||||
public static function stream_isatty($stream)
|
||||
{
|
||||
if (!\is_resource($stream)) {
|
||||
trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', E_USER_WARNING);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR) {
|
||||
$stat = @fstat($stream);
|
||||
// Check if formatted mode is S_IFCHR
|
||||
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
|
||||
}
|
||||
|
||||
return \function_exists('posix_isatty') && @posix_isatty($stream);
|
||||
}
|
||||
|
||||
private static function initHashMask()
|
||||
{
|
||||
$obj = (object) array();
|
||||
self::$hashMask = -1;
|
||||
|
||||
// check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
|
||||
$obFuncs = array('ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush');
|
||||
foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
|
||||
if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
|
||||
$frame['line'] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!empty($frame['line'])) {
|
||||
ob_start();
|
||||
debug_zval_dump($obj);
|
||||
self::$hashMask = (int) substr(ob_get_clean(), 17);
|
||||
}
|
||||
|
||||
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), (\PHP_INT_SIZE * 2 - 1)));
|
||||
}
|
||||
|
||||
public static function mb_chr($code, $encoding = null)
|
||||
{
|
||||
if (0x80 > $code %= 0x200000) {
|
||||
$s = \chr($code);
|
||||
} elseif (0x800 > $code) {
|
||||
$s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
|
||||
} elseif (0x10000 > $code) {
|
||||
$s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
|
||||
} else {
|
||||
$s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
|
||||
}
|
||||
|
||||
if ('UTF-8' !== $encoding) {
|
||||
$s = mb_convert_encoding($s, $encoding, 'UTF-8');
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
public static function mb_ord($s, $encoding = null)
|
||||
{
|
||||
if (null == $encoding) {
|
||||
$s = mb_convert_encoding($s, 'UTF-8');
|
||||
} elseif ('UTF-8' !== $encoding) {
|
||||
$s = mb_convert_encoding($s, 'UTF-8', $encoding);
|
||||
}
|
||||
|
||||
if (1 === \strlen($s)) {
|
||||
return \ord($s);
|
||||
}
|
||||
|
||||
$code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
|
||||
if (0xF0 <= $code) {
|
||||
return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
|
||||
}
|
||||
if (0xE0 <= $code) {
|
||||
return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
|
||||
}
|
||||
if (0xC0 <= $code) {
|
||||
return (($code - 0xC0) << 6) + $s[2] - 0x80;
|
||||
}
|
||||
|
||||
return $code;
|
||||
}
|
||||
}
|
||||
28
vendor/symfony/polyfill-php72/README.md
vendored
Normal file
28
vendor/symfony/polyfill-php72/README.md
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
Symfony Polyfill / Php72
|
||||
========================
|
||||
|
||||
This component provides functions added to PHP 7.2 core:
|
||||
|
||||
- [`spl_object_id`](https://php.net/spl_object_id)
|
||||
- [`stream_isatty`](https://php.net/stream_isatty)
|
||||
|
||||
On Windows only:
|
||||
|
||||
- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support)
|
||||
|
||||
Moved to core since 7.2 (was in the optional XML extension earlier):
|
||||
|
||||
- [`utf8_encode`](https://php.net/utf8_encode)
|
||||
- [`utf8_decode`](https://php.net/utf8_decode)
|
||||
|
||||
Also, it provides constants added to PHP 7.2:
|
||||
- [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig)
|
||||
- [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family)
|
||||
|
||||
More information can be found in the
|
||||
[main Polyfill README](https://github.com/symfony/polyfill/blob/master/README.md).
|
||||
|
||||
License
|
||||
=======
|
||||
|
||||
This library is released under the [MIT license](LICENSE).
|
||||
57
vendor/symfony/polyfill-php72/bootstrap.php
vendored
Normal file
57
vendor/symfony/polyfill-php72/bootstrap.php
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
use Symfony\Polyfill\Php72 as p;
|
||||
|
||||
if (PHP_VERSION_ID >= 70200) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defined('PHP_FLOAT_DIG')) {
|
||||
define('PHP_FLOAT_DIG', 15);
|
||||
}
|
||||
if (!defined('PHP_FLOAT_EPSILON')) {
|
||||
define('PHP_FLOAT_EPSILON', 2.2204460492503E-16);
|
||||
}
|
||||
if (!defined('PHP_FLOAT_MIN')) {
|
||||
define('PHP_FLOAT_MIN', 2.2250738585072E-308);
|
||||
}
|
||||
if (!defined('PHP_FLOAT_MAX')) {
|
||||
define('PHP_FLOAT_MAX', 1.7976931348623157E+308);
|
||||
}
|
||||
if (!defined('PHP_OS_FAMILY')) {
|
||||
define('PHP_OS_FAMILY', p\Php72::php_os_family());
|
||||
}
|
||||
|
||||
if ('\\' === DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
|
||||
function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
|
||||
}
|
||||
if (!function_exists('stream_isatty')) {
|
||||
function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
|
||||
}
|
||||
if (!function_exists('utf8_encode')) {
|
||||
function utf8_encode($s) { return p\Php72::utf8_encode($s); }
|
||||
}
|
||||
if (!function_exists('utf8_decode')) {
|
||||
function utf8_decode($s) { return p\Php72::utf8_decode($s); }
|
||||
}
|
||||
if (!function_exists('spl_object_id')) {
|
||||
function spl_object_id($s) { return p\Php72::spl_object_id($s); }
|
||||
}
|
||||
if (!function_exists('mb_ord')) {
|
||||
function mb_ord($s, $enc = null) { return p\Php72::mb_ord($s, $enc); }
|
||||
}
|
||||
if (!function_exists('mb_chr')) {
|
||||
function mb_chr($code, $enc = null) { return p\Php72::mb_chr($code, $enc); }
|
||||
}
|
||||
if (!function_exists('mb_scrub')) {
|
||||
function mb_scrub($s, $enc = null) { $enc = null === $enc ? mb_internal_encoding() : $enc; return mb_convert_encoding($s, $enc, $enc); }
|
||||
}
|
||||
35
vendor/symfony/polyfill-php72/composer.json
vendored
Normal file
35
vendor/symfony/polyfill-php72/composer.json
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "symfony/polyfill-php72",
|
||||
"type": "library",
|
||||
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
|
||||
"keywords": ["polyfill", "shim", "compatibility", "portable"],
|
||||
"homepage": "https://symfony.com",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Symfony\\Polyfill\\Php72\\": "" },
|
||||
"files": [ "bootstrap.php" ]
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.18-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
}
|
||||
}
|
||||
208
vendor/webonyx/graphql-php/CHANGELOG.md
vendored
Normal file
208
vendor/webonyx/graphql-php/CHANGELOG.md
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
# Changelog
|
||||
### v0.13.8
|
||||
- Don't call global field resolver on introspection fields (#481)
|
||||
|
||||
### v0.13.7
|
||||
- Added retrieving query complexity once query has been completed (#316)
|
||||
- Allow input types to be passed in from variables using \stdClass instead of associative arrays (#535)
|
||||
|
||||
#### v0.13.6
|
||||
- QueryPlan can now be used on interfaces not only objects. (#495)
|
||||
- Array in variables in place of object shouldn't cause fatal error (fixes #467)
|
||||
- Scalar type ResolverInfo::getFieldSelection support (#529)
|
||||
|
||||
#### v0.13.5
|
||||
- Fix coroutine executor when using with promise (#486)
|
||||
|
||||
#### v0.13.4
|
||||
- Force int when setting max query depth (#477)
|
||||
|
||||
#### v0.13.3
|
||||
- Reverted minor possible breaking change (#476)
|
||||
|
||||
#### v0.13.2
|
||||
- Added QueryPlan support (#436)
|
||||
- Fixed an issue with NodeList iteration over missing keys (#475)
|
||||
|
||||
#### v0.13.1
|
||||
- Better validation of field/directive arguments
|
||||
- Support for apollo client/server persisted queries
|
||||
- Minor tweaks and fixes
|
||||
|
||||
## v0.13.0
|
||||
This release brings several breaking changes. Please refer to [UPGRADE](UPGRADE.md) document for details.
|
||||
|
||||
New features and notable changes:
|
||||
- PHP version required: 7.1+
|
||||
- Spec compliance: error `category` and extensions are displayed under `extensions` key when using default formatting (#389)
|
||||
- New experimental executor with improved performance (#314).<br>
|
||||
It is a one-line switch: `GraphQL::useExperimentalExecutor()`.<br>
|
||||
<br>
|
||||
**Please try it and post your feedback at https://github.com/webonyx/graphql-php/issues/397**
|
||||
(as it may become the default one in future)
|
||||
<br>
|
||||
<br>
|
||||
- Ported `extendSchema` from the reference implementation under `GraphQL\Utils\SchemaExtender` (#362)
|
||||
- Added ability to override standard types via `GraphQL::overrideStandardTypes(array $types)` (#401)
|
||||
- Added flag `Debug::RETHROW_UNSAFE_EXCEPTIONS` which would only rethrow app-specific exceptions (#337)
|
||||
- Several classes were renamed (see [UPGRADE.md](UPGRADE.md))
|
||||
- Schema Validation improvements
|
||||
|
||||
#### v0.12.6
|
||||
- Bugfix: Call to a member function getLocation() on null (#336)
|
||||
- Fixed several errors discovered by static analysis (#329)
|
||||
|
||||
#### v0.12.5
|
||||
- Execution performance optimization for lists
|
||||
|
||||
#### v0.12.4
|
||||
- Allow stringeable objects to be serialized by StringType (#303)
|
||||
|
||||
#### v0.12.3
|
||||
- StandardServer: add support for the multipart/form-data content type (#300)
|
||||
|
||||
#### v0.12.2
|
||||
- SchemaPrinter: Use multi-line block for trailing quote (#294)
|
||||
|
||||
#### v0.12.1
|
||||
- Fixed bug in validation rule OverlappingFieldsCanBeMerged (#292)
|
||||
- Added one more breaking change note in UPGRADE.md (#291)
|
||||
- Spec compliance: remove `data` entry from response on top-level error (#281)
|
||||
|
||||
## v0.12.0
|
||||
- RFC: Block String (multi-line strings via triple-quote """string""")
|
||||
- GraphQL Schema SDL: Descriptions as strings (including multi-line)
|
||||
- Changed minimum required PHP version to 5.6
|
||||
|
||||
Improvements:
|
||||
- Allow extending GraphQL errors with additional properties
|
||||
- Fixed parsing of default values in Schema SDL
|
||||
- Handling several more cases in findBreakingChanges
|
||||
- StandardServer: expect `operationName` (instead of `operation`) in input
|
||||
|
||||
|
||||
#### v0.11.5
|
||||
- Allow objects with __toString in IDType
|
||||
|
||||
#### v0.11.4
|
||||
- findBreakingChanges utility (see #199)
|
||||
|
||||
#### v0.11.3
|
||||
- StandardServer: Support non pre-parsed PSR-7 request body (see #202)
|
||||
|
||||
#### v0.11.2
|
||||
- Bugfix: provide descriptions to custom scalars (see #181)
|
||||
|
||||
#### v0.11.1
|
||||
- Ability to override internal types via `types` option of the schema (see #174).
|
||||
|
||||
## v0.11.0
|
||||
This release brings little changes but there are two reasons why it is released as major version:
|
||||
|
||||
1. To follow reference implementation versions (it matches 0.11.x series of graphql-js)
|
||||
2. It may break existing applications because scalar input coercion rules are stricter now:<br>
|
||||
In previous versions sloppy client input could leak through with unexpected results.
|
||||
For example string `"false"` accidentally sent in variables was converted to boolean `true`
|
||||
and passed to field arguments. In the new version, such input will produce an error
|
||||
(which is a spec-compliant behavior).
|
||||
|
||||
Improvements:
|
||||
- Stricter input coercion (see #171)
|
||||
- Types built with `BuildSchema` now have reference to AST node with corresponding AST definition (in $astNode property)
|
||||
- Account for query offset for error locations (e.g. when query is stored in `.graphql` file)
|
||||
|
||||
#### v0.10.2
|
||||
- StandardServer improvement: do not raise an error when variables are passed as empty string (see #156)
|
||||
|
||||
#### v0.10.1
|
||||
- Fixed infinite loop in the server (see #153)
|
||||
|
||||
## v0.10.0
|
||||
This release brings several breaking changes. Please refer to [UPGRADE](UPGRADE.md) document for details.
|
||||
|
||||
New features and notable changes:
|
||||
- Changed minimum PHP version from 5.4 to 5.5
|
||||
- Lazy loading of types without separate build step (see #69, see [docs](http://webonyx.github.io/graphql-php/type-system/schema/#lazy-loading-of-types))
|
||||
- PSR-7 compliant Standard Server (see [docs](http://webonyx.github.io/graphql-php/executing-queries/#using-server))
|
||||
- New default error formatting, which does not expose sensitive data (see [docs](http://webonyx.github.io/graphql-php/error-handling/))
|
||||
- Ability to define custom error handler to filter/log/re-throw exceptions after execution (see [docs](http://webonyx.github.io/graphql-php/error-handling/#custom-error-handling-and-formatting))
|
||||
- Allow defining schema configuration using objects with fluent setters vs array (see [docs](http://webonyx.github.io/graphql-php/type-system/schema/#using-config-class))
|
||||
- Allow serializing AST to array and re-creating AST from array lazily (see [docs](http://webonyx.github.io/graphql-php/reference/#graphqlutilsast))
|
||||
- [Apollo-style](https://dev-blog.apollodata.com/query-batching-in-apollo-63acfd859862) query batching support via server (see [docs](http://webonyx.github.io/graphql-php/executing-queries/#query-batching))
|
||||
- Schema validation, including validation of interface implementations (see [docs](http://webonyx.github.io/graphql-php/type-system/schema/#schema-validation))
|
||||
- Ability to pass custom config formatter when defining schema using [GraphQL type language](http://graphql.org/learn/schema/#type-language) (see [docs](http://webonyx.github.io/graphql-php/type-system/type-language/))
|
||||
|
||||
Improvements:
|
||||
- Significantly improved parser performance (see #137 and #128)
|
||||
- Support for PHP7 exceptions everywhere (see #127)
|
||||
- Improved [documentation](http://webonyx.github.io/graphql-php/) and docblock comments
|
||||
|
||||
Deprecations and breaking changes - see [UPGRADE](UPGRADE.md) document.
|
||||
|
||||
#### v0.9.14
|
||||
- Minor change to assist DataLoader project in fixing #150
|
||||
|
||||
#### v0.9.13
|
||||
- Fixed PHP notice and invalid conversion when non-scalar value is passed as ID or String type (see #121)
|
||||
|
||||
#### v0.9.12
|
||||
- Fixed bug occurring when enum `value` is bool, null or float (see #141)
|
||||
|
||||
#### v0.9.11
|
||||
- Ability to disable introspection (see #131)
|
||||
|
||||
#### v0.9.10
|
||||
- Fixed issue with query complexity throwing on invalid queries (see #125)
|
||||
- Fixed "Out of memory" error when `resolveType` returns unexpected result (see #119)
|
||||
|
||||
#### v0.9.9
|
||||
- Bugfix: throw UserError vs InvariantViolationError for errors caused by client (see #123)
|
||||
|
||||
#### v0.9.8
|
||||
- Bugfix: use directives when calculating query complexity (see #113)
|
||||
- Bugfix: `AST\Node::__toString()` will convert node to array recursively to encode to json without errors
|
||||
|
||||
#### v0.9.7
|
||||
- Bugfix: `ResolveInfo::getFieldSelection()` now correctly merges fragment selections (see #98)
|
||||
|
||||
#### v0.9.6
|
||||
- Bugfix: `ResolveInfo::getFieldSelection()` now respects inline fragments
|
||||
|
||||
#### v0.9.5
|
||||
- Fixed SyncPromiseAdapter::all() to not change the order of arrays (see #92)
|
||||
|
||||
#### v0.9.4
|
||||
- Tools to help building schema out of Schema definition language as well as printing existing
|
||||
schema in Schema definition language (see #91)
|
||||
|
||||
#### v0.9.3
|
||||
- Fixed Utils::assign() bug related to detecting missing required keys (see #89)
|
||||
|
||||
#### v0.9.2
|
||||
- Schema Definition Language: element descriptions can be set through comments (see #88)
|
||||
|
||||
#### v0.9.1
|
||||
- Fixed: `GraphQL\Server` now properly sets promise adapter before executing query
|
||||
|
||||
## v0.9.0
|
||||
- Deferred resolvers (see #66, see [docs](docs/data-fetching.md#solving-n1-problem))
|
||||
- New Facade class with fluid interface: `GraphQL\Server` (see #82)
|
||||
- Experimental: ability to load types in Schema lazily via custom `TypeResolutionStrategy` (see #69)
|
||||
|
||||
|
||||
## v0.8.0
|
||||
This release brings several minor breaking changes. Please refer to [UPGRADE](UPGRADE.md) document for details.
|
||||
|
||||
New features:
|
||||
- Support for `null` value (as required by latest GraphQL spec)
|
||||
- Shorthand definitions for field and argument types (see #47)
|
||||
- `path` entry in errors produced by resolvers for better debugging
|
||||
- `resolveType` for interface/union is now allowed to return string name of type
|
||||
- Ability to omit name when extending type class (vs defining inline)
|
||||
|
||||
Improvements:
|
||||
- Spec compliance improvements
|
||||
- New docs and examples
|
||||
|
||||
## Older versions
|
||||
Look at [GitHub Releases Page](https://github.com/webonyx/graphql-php/releases).
|
||||
21
vendor/webonyx/graphql-php/LICENSE
vendored
Normal file
21
vendor/webonyx/graphql-php/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015-present, Webonyx, LLC.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
52
vendor/webonyx/graphql-php/README.md
vendored
Normal file
52
vendor/webonyx/graphql-php/README.md
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
# graphql-php
|
||||
[](https://travis-ci.org/webonyx/graphql-php)
|
||||
[](https://scrutinizer-ci.com/g/webonyx/graphql-php)
|
||||
[](https://packagist.org/packages/webonyx/graphql-php)
|
||||
[](https://packagist.org/packages/webonyx/graphql-php)
|
||||
|
||||
This is a PHP implementation of the GraphQL [specification](https://github.com/facebook/graphql)
|
||||
based on the [reference implementation in JavaScript](https://github.com/graphql/graphql-js).
|
||||
|
||||
## Installation
|
||||
Via composer:
|
||||
```
|
||||
composer require webonyx/graphql-php
|
||||
```
|
||||
|
||||
## Documentation
|
||||
Full documentation is available on the [Documentation site](https://webonyx.github.io/graphql-php/) as well
|
||||
as in the [docs](docs/) folder of the distribution.
|
||||
|
||||
If you don't know what GraphQL is, visit this [official website](http://graphql.org)
|
||||
by the Facebook engineering team.
|
||||
|
||||
## Examples
|
||||
There are several ready examples in the [examples](examples/) folder of the distribution with specific
|
||||
README file per example.
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to [all the people](https://github.com/webonyx/graphql-php/graphs/contributors) who contribute. [[Contribute](CONTRIBUTING.md)].
|
||||
|
||||
## Backers
|
||||
|
||||
<a href="https://opencollective.com/webonyx-graphql-php#backers" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/backers.svg?width=890"></a>
|
||||
|
||||
## Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/webonyx-graphql-php#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/0/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/1/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/2/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/3/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/4/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/5/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/6/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/7/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/8/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/webonyx-graphql-php/sponsor/9/website" target="_blank"><img src="https://opencollective.com/webonyx-graphql-php/sponsor/9/avatar.svg"></a>
|
||||
|
||||
## License
|
||||
|
||||
See [LICENCE](LICENSE).
|
||||
527
vendor/webonyx/graphql-php/UPGRADE.md
vendored
Normal file
527
vendor/webonyx/graphql-php/UPGRADE.md
vendored
Normal file
@ -0,0 +1,527 @@
|
||||
## Upgrade v0.12.x > v0.13.x
|
||||
|
||||
### Breaking (major): minimum supported version of PHP
|
||||
New minimum required version of PHP is **7.1+**
|
||||
|
||||
### Breaking (major): default errors formatting changed according to spec
|
||||
**Category** and extensions assigned to errors are shown under `extensions` key
|
||||
```php
|
||||
$e = new Error(
|
||||
'msg',
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
['foo' => 'bar']
|
||||
);
|
||||
```
|
||||
Formatting before the change:
|
||||
```
|
||||
'errors' => [
|
||||
[
|
||||
'message' => 'msg',
|
||||
'category' => 'graphql',
|
||||
'foo' => 'bar'
|
||||
]
|
||||
]
|
||||
```
|
||||
After the change:
|
||||
```
|
||||
'errors' => [
|
||||
[
|
||||
'message' => 'msg',
|
||||
'extensions' => [
|
||||
'category' => 'graphql',
|
||||
'foo' => 'bar',
|
||||
],
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
Note: if error extensions contain `category` key - it has a priority over default category.
|
||||
|
||||
You can always switch to [custom error formatting](https://webonyx.github.io/graphql-php/error-handling/#custom-error-handling-and-formatting) to revert to the old format.
|
||||
|
||||
### Try it: Experimental Executor with improved performance
|
||||
It is disabled by default. To enable it, do the following
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Executor\Executor;
|
||||
use GraphQL\Experimental\Executor\CoroutineExecutor;
|
||||
|
||||
Executor::setImplementationFactory([CoroutineExecutor::class, 'create']);
|
||||
```
|
||||
|
||||
**Please post your feedback about new executor at https://github.com/webonyx/graphql-php/issues/397
|
||||
Especially if you had issues (because it may become the default in one of the next releases)**
|
||||
|
||||
### Breaking: multiple interfaces separated with & in SDL
|
||||
Before the change:
|
||||
```graphql
|
||||
type Foo implements Bar, Baz { field: Type }
|
||||
```
|
||||
|
||||
After the change:
|
||||
```graphql
|
||||
type Foo implements Bar & Baz { field: Type }
|
||||
```
|
||||
|
||||
To allow for an adaptive migration, use `allowLegacySDLImplementsInterfaces` option of parser:
|
||||
```php
|
||||
Parser::parse($source, [ 'allowLegacySDLImplementsInterfaces' => true])
|
||||
```
|
||||
|
||||
### Breaking: several classes renamed
|
||||
|
||||
- `AbstractValidationRule` renamed to `ValidationRule` (NS `GraphQL\Validator\Rules`)
|
||||
- `AbstractQuerySecurity` renamed to `QuerySecurityRule` (NS `GraphQL\Validator\Rules`)
|
||||
- `FindBreakingChanges` renamed to `BreakingChangesFinder` (NS `GraphQL\Utils`)
|
||||
|
||||
### Breaking: new constructors
|
||||
|
||||
`GraphQL\Type\Definition\ResolveInfo` now takes 10 arguments instead of one array.
|
||||
|
||||
## Upgrade v0.11.x > v0.12.x
|
||||
|
||||
### Breaking: Minimum supported version is PHP5.6
|
||||
Dropped support for PHP 5.5. This release still supports PHP 5.6 and PHP 7.0
|
||||
**But the next major release will require PHP7.1+**
|
||||
|
||||
### Breaking: Custom scalar types need to throw on invalid value
|
||||
As null might be a valid value custom types need to throw an
|
||||
Exception inside `parseLiteral()`, `parseValue()` and `serialize()`.
|
||||
|
||||
Returning null from any of these methods will now be treated as valid result.
|
||||
|
||||
### Breaking: Custom scalar types parseLiteral() declaration changed
|
||||
A new parameter was added to `parseLiteral()`, which also needs to be added to any custom scalar type extending from `ScalarType`
|
||||
|
||||
Before:
|
||||
```php
|
||||
class MyType extends ScalarType {
|
||||
|
||||
...
|
||||
|
||||
public function parseLiteral($valueNode) {
|
||||
//custom implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
After:
|
||||
```php
|
||||
class MyType extends ScalarType {
|
||||
|
||||
...
|
||||
|
||||
public function parseLiteral($valueNode, array $variables = null) {
|
||||
//custom implementation
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Breaking: Descriptions in comments are not used as descriptions by default anymore
|
||||
Descriptions now need to be inside Strings or BlockStrings in order to be picked up as
|
||||
description. If you want to keep the old behaviour you can supply the option `commentDescriptions`
|
||||
to BuildSchema::buildAST(), BuildSchema::build() or Printer::doPrint().
|
||||
|
||||
Here is the official way now to define descriptions in the graphQL language:
|
||||
|
||||
Old:
|
||||
|
||||
```graphql
|
||||
# Description
|
||||
type Dog {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
New:
|
||||
|
||||
```graphql
|
||||
"Description"
|
||||
type Dog {
|
||||
...
|
||||
}
|
||||
|
||||
"""
|
||||
Long Description
|
||||
"""
|
||||
type Dog {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Breaking: Cached AST of version 0.11.x is not compatible with 0.12.x.
|
||||
That's because description in AST is now a separate node, not just a string.
|
||||
Make sure to renew caches.
|
||||
|
||||
### Breaking: Most of previously deprecated classes and methods were removed
|
||||
See deprecation notices for previous versions in details.
|
||||
|
||||
### Breaking: Standard server expects `operationName` vs `operation` for multi-op queries
|
||||
Before the change:
|
||||
```json
|
||||
{
|
||||
"queryId": "persisted-query-id",
|
||||
"operation": "QueryFromPersistedDocument",
|
||||
"variables": {}
|
||||
}
|
||||
```
|
||||
After the change:
|
||||
```json
|
||||
{
|
||||
"queryId": "persisted-query-id",
|
||||
"operationName": "QueryFromPersistedDocument",
|
||||
"variables": {}
|
||||
}
|
||||
```
|
||||
This naming is aligned with graphql-express version.
|
||||
|
||||
### Possibly Breaking: AST to array serialization excludes nulls
|
||||
Most users won't be affected. It *may* affect you only if you do your own manipulations
|
||||
with exported AST.
|
||||
|
||||
Example of json-serialized AST before the change:
|
||||
```json
|
||||
{
|
||||
"kind": "Field",
|
||||
"loc": null,
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"loc": null,
|
||||
"value": "id"
|
||||
},
|
||||
"alias": null,
|
||||
"arguments": [],
|
||||
"directives": [],
|
||||
"selectionSet": null
|
||||
}
|
||||
```
|
||||
After the change:
|
||||
```json
|
||||
{
|
||||
"kind": "Field",
|
||||
"name": {
|
||||
"kind": "Name",
|
||||
"value": "id"
|
||||
},
|
||||
"arguments": [],
|
||||
"directives": []
|
||||
}
|
||||
```
|
||||
|
||||
## Upgrade v0.8.x, v0.9.x > v0.10.x
|
||||
|
||||
### Breaking: changed minimum PHP version from 5.4 to 5.5
|
||||
It allows us to leverage `::class` constant, `generators` and other features of newer PHP versions.
|
||||
|
||||
### Breaking: default error formatting
|
||||
By default exceptions thrown in resolvers will be reported with generic message `"Internal server error"`.
|
||||
Only exceptions implementing interface `GraphQL\Error\ClientAware` and claiming themselves as `safe` will
|
||||
be reported with full error message.
|
||||
|
||||
This breaking change is done to avoid information leak in production when unhandled
|
||||
exceptions were reported to clients (e.g. database connection errors, file access errors, etc).
|
||||
|
||||
Also every error reported to client now has new `category` key which is either `graphql` or `internal`.
|
||||
Exceptions implementing `ClientAware` interface may define their own custom categories.
|
||||
|
||||
During development or debugging use `$executionResult->toArray(true)`. It will add `debugMessage` key to
|
||||
each error entry in result. If you also want to add `trace` for each error - pass flags instead:
|
||||
|
||||
```
|
||||
use GraphQL\Error\FormattedError;
|
||||
$debug = FormattedError::INCLUDE_DEBUG_MESSAGE | FormattedError::INCLUDE_TRACE;
|
||||
$result = GraphQL::executeAndReturnResult(/*args*/)->toArray($debug);
|
||||
```
|
||||
|
||||
To change default `"Internal server error"` message to something else, use:
|
||||
```
|
||||
GraphQL\Error\FormattedError::setInternalErrorMessage("Unexpected error");
|
||||
```
|
||||
|
||||
**This change only affects default error reporting mechanism. If you set your own error formatter using
|
||||
`$executionResult->setErrorFormatter($myFormatter)` you won't be affected by this change.**
|
||||
|
||||
If you need to revert to old behavior temporary, use:
|
||||
|
||||
```php
|
||||
GraphQL::executeAndReturnResult(/**/)
|
||||
->setErrorFormatter('\GraphQL\Error\Error::formatError')
|
||||
->toArray();
|
||||
```
|
||||
But note that this is deprecated format and will be removed in future versions.
|
||||
|
||||
In general, if new default formatting doesn't work for you - just set [your own error
|
||||
formatter](http://webonyx.github.io/graphql-php/error-handling/#custom-error-handling-and-formatting).
|
||||
|
||||
### Breaking: Validation rules now have abstract base class
|
||||
Previously any callable was accepted by DocumentValidator as validation rule. Now only instances of
|
||||
`GraphQL\Validator\Rules\AbstractValidationRule` are allowed.
|
||||
|
||||
If you were using custom validation rules, just wrap them with
|
||||
`GraphQL\Validator\Rules\CustomValidationRule` (created for backwards compatibility).
|
||||
|
||||
Before:
|
||||
```php
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
$myRule = function(ValidationContext $context) {};
|
||||
DocumentValidator::validate($schema, $ast, [$myRule]);
|
||||
```
|
||||
|
||||
After:
|
||||
```php
|
||||
use GraphQL\Validator\Rules\CustomValidationRule;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
$myRule = new CustomValidationRule('MyRule', function(ValidationContext $context) {});
|
||||
DocumentValidator::validate($schema, $ast, [$myRule]);
|
||||
```
|
||||
|
||||
Also `DocumentValidator::addRule()` signature changed.
|
||||
|
||||
Before the change:
|
||||
```php
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
$myRule = function(ValidationContext $context) {};
|
||||
DocumentValidator::addRule('MyRuleName', $myRule);
|
||||
```
|
||||
|
||||
After the change:
|
||||
```php
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
$myRule = new CustomValidationRulefunction('MyRule', ValidationContext $context) {});
|
||||
DocumentValidator::addRule($myRule);
|
||||
```
|
||||
|
||||
|
||||
### Breaking: AST now uses `NodeList` vs array for lists of nodes
|
||||
It helps us unserialize AST from array lazily. This change affects you only if you use `array_`
|
||||
functions with AST or mutate AST directly.
|
||||
|
||||
Before the change:
|
||||
```php
|
||||
new GraphQL\Language\AST\DocumentNode([
|
||||
'definitions' => array(/*...*/)
|
||||
]);
|
||||
```
|
||||
After the change:
|
||||
```
|
||||
new GraphQL\Language\AST\DocumentNode([
|
||||
'definitions' => new NodeList([/*...*/])
|
||||
]);
|
||||
```
|
||||
|
||||
|
||||
### Breaking: scalar types now throw different exceptions when parsing and serializing
|
||||
On invalid client input (`parseValue` and `parseLiteral`) they throw standard `GraphQL\Error\Error`
|
||||
but when they encounter invalid output (in `serialize`) they throw `GraphQL\Error\InvariantViolation`.
|
||||
|
||||
Previously they were throwing `GraphQL\Error\UserError`. This exception is no longer used so make sure
|
||||
to adjust if you were checking for this error in your custom error formatters.
|
||||
|
||||
### Breaking: removed previously deprecated ability to define type as callable
|
||||
See https://github.com/webonyx/graphql-php/issues/35
|
||||
|
||||
### Deprecated: `GraphQL\GraphQL::executeAndReturnResult`
|
||||
Method is renamed to `GraphQL\GraphQL::executeQuery`. Old method name is still available,
|
||||
but will trigger deprecation warning in the next version.
|
||||
|
||||
### Deprecated: `GraphQL\GraphQL::execute`
|
||||
Use `GraphQL\GraphQL::executeQuery()->toArray()` instead.
|
||||
Old method still exists, but will trigger deprecation warning in next version.
|
||||
|
||||
### Deprecated: `GraphQL\Schema` moved to `GraphQL\Type\Schema`
|
||||
Old class still exists, but will trigger deprecation warning in next version.
|
||||
|
||||
### Deprecated: `GraphQL\Utils` moved to `GraphQL\Utils\Utils`
|
||||
Old class still exists, but triggers deprecation warning when referenced.
|
||||
|
||||
### Deprecated: `GraphQL\Type\Definition\Config`
|
||||
If you were using config validation in previous versions, replace:
|
||||
```php
|
||||
GraphQL\Type\Definition\Config::enableValidation();
|
||||
```
|
||||
with:
|
||||
```php
|
||||
$schema->assertValid();
|
||||
```
|
||||
See https://github.com/webonyx/graphql-php/issues/148
|
||||
|
||||
### Deprecated: experimental `GraphQL\Server`
|
||||
Use [new PSR-7 compliant implementation](docs/executing-queries.md#using-server) instead.
|
||||
|
||||
### Deprecated: experimental `GraphQL\Type\Resolution` interface and implementations
|
||||
Use schema [**typeLoader** option](docs/type-system/schema.md#lazy-loading-of-types) instead.
|
||||
|
||||
### Non-breaking: usage on async platforms
|
||||
When using the library on async platforms use separate method `GraphQL::promiseToExecute()`.
|
||||
It requires promise adapter in it's first argument and always returns a `Promise`.
|
||||
|
||||
Old methods `GraphQL::execute` and `GraphQL::executeAndReturnResult` still work in backwards-compatible manner,
|
||||
but they are deprecated and will be removed eventually.
|
||||
|
||||
Same applies to Executor: use `Executor::promiseToExecute()` vs `Executor::execute()`.
|
||||
|
||||
## Upgrade v0.7.x > v0.8.x
|
||||
All of those changes apply to those who extends various parts of this library.
|
||||
If you only use the library and don't try to extend it - everything should work without breaks.
|
||||
|
||||
|
||||
### Breaking: Custom directives handling
|
||||
When passing custom directives to schema, default directives (like `@skip` and `@include`)
|
||||
are not added to schema automatically anymore. If you need them - add them explicitly with
|
||||
your other directives.
|
||||
|
||||
Before the change:
|
||||
```php
|
||||
$schema = new Schema([
|
||||
// ...
|
||||
'directives' => [$myDirective]
|
||||
]);
|
||||
```
|
||||
|
||||
After the change:
|
||||
```php
|
||||
$schema = new Schema([
|
||||
// ...
|
||||
'directives' => array_merge(GraphQL::getInternalDirectives(), [$myDirective])
|
||||
]);
|
||||
```
|
||||
|
||||
### Breaking: Schema protected property and methods visibility
|
||||
Most of the `protected` properties and methods of `GraphQL\Schema` were changed to `private`.
|
||||
Please use public interface instead.
|
||||
|
||||
### Breaking: Node kind constants
|
||||
Node kind constants were extracted from `GraphQL\Language\AST\Node` to
|
||||
separate class `GraphQL\Language\AST\NodeKind`
|
||||
|
||||
### Non-breaking: AST node classes renamed
|
||||
AST node classes were renamed to disambiguate with types. e.g.:
|
||||
|
||||
```
|
||||
GraphQL\Language\AST\Field -> GraphQL\Language\AST\FieldNode
|
||||
GraphQL\Language\AST\OjbectValue -> GraphQL\Language\AST\OjbectValueNode
|
||||
```
|
||||
etc.
|
||||
|
||||
Old names are still available via `class_alias` defined in `src/deprecated.php`.
|
||||
This file is included automatically when using composer autoloading.
|
||||
|
||||
### Deprecations
|
||||
There are several deprecations which still work, but trigger `E_USER_DEPRECATED` when used.
|
||||
|
||||
For example `GraphQL\Executor\Executor::setDefaultResolveFn()` is renamed to `setDefaultResolver()`
|
||||
but still works with old name.
|
||||
|
||||
## Upgrade v0.6.x > v0.7.x
|
||||
|
||||
There are a few new breaking changes in v0.7.0 that were added to the graphql-js reference implementation
|
||||
with the spec of April2016
|
||||
|
||||
### 1. Context for resolver
|
||||
|
||||
You can now pass a custom context to the `GraphQL::execute` function that is available in all resolvers as 3rd argument.
|
||||
This can for example be used to pass the current user etc.
|
||||
|
||||
Make sure to update all calls to `GraphQL::execute`, `GraphQL::executeAndReturnResult`, `Executor::execute` and all
|
||||
`'resolve'` callbacks in your app.
|
||||
|
||||
Before v0.7.0 `GraphQL::execute` signature looked this way:
|
||||
```php
|
||||
GraphQL::execute(
|
||||
$schema,
|
||||
$query,
|
||||
$rootValue,
|
||||
$variables,
|
||||
$operationName
|
||||
);
|
||||
```
|
||||
|
||||
Starting from v0.7.0 the signature looks this way (note the new `$context` argument):
|
||||
```php
|
||||
GraphQL::execute(
|
||||
$schema,
|
||||
$query,
|
||||
$rootValue,
|
||||
$context,
|
||||
$variables,
|
||||
$operationName
|
||||
);
|
||||
```
|
||||
|
||||
Before v.0.7.0 resolve callbacks had following signature:
|
||||
```php
|
||||
/**
|
||||
* @param mixed $object The parent resolved object
|
||||
* @param array $args Input arguments
|
||||
* @param ResolveInfo $info ResolveInfo object
|
||||
* @return mixed
|
||||
*/
|
||||
function resolveMyField($object, array $args, ResolveInfo $info) {
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
Starting from v0.7.0 the signature has changed to (note the new `$context` argument):
|
||||
```php
|
||||
/**
|
||||
* @param mixed $object The parent resolved object
|
||||
* @param array $args Input arguments
|
||||
* @param mixed $context The context object hat was passed to GraphQL::execute
|
||||
* @param ResolveInfo $info ResolveInfo object
|
||||
* @return mixed
|
||||
*/
|
||||
function resolveMyField($object, array $args, $context, ResolveInfo $info){
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Schema constructor signature
|
||||
|
||||
The signature of the Schema constructor now accepts an associative config array instead of positional arguments:
|
||||
|
||||
Before v0.7.0:
|
||||
```php
|
||||
$schema = new Schema($queryType, $mutationType);
|
||||
```
|
||||
|
||||
Starting from v0.7.0:
|
||||
```php
|
||||
$schema = new Schema([
|
||||
'query' => $queryType,
|
||||
'mutation' => $mutationType,
|
||||
'types' => $arrayOfTypesWithInterfaces // See 3.
|
||||
]);
|
||||
```
|
||||
|
||||
### 3. Types can be directly passed to schema
|
||||
|
||||
There are edge cases when GraphQL cannot infer some types from your schema.
|
||||
One example is when you define a field of interface type and object types implementing
|
||||
this interface are not referenced anywhere else.
|
||||
|
||||
In such case object types might not be available when an interface is queried and query
|
||||
validation will fail. In that case, you need to pass the types that implement the
|
||||
interfaces directly to the schema, so that GraphQL knows of their existence during query validation.
|
||||
|
||||
For example:
|
||||
```php
|
||||
$schema = new Schema([
|
||||
'query' => $queryType,
|
||||
'mutation' => $mutationType,
|
||||
'types' => $arrayOfTypesWithInterfaces
|
||||
]);
|
||||
```
|
||||
|
||||
Note that you don't need to pass all types here - only those types that GraphQL "doesn't see"
|
||||
automatically. Before v7.0.0 the workaround for this was to create a dumb (non-used) field per
|
||||
each "invisible" object type.
|
||||
|
||||
Also see [webonyx/graphql-php#38](https://github.com/webonyx/graphql-php/issues/38)
|
||||
56
vendor/webonyx/graphql-php/composer.json
vendored
Normal file
56
vendor/webonyx/graphql-php/composer.json
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "webonyx/graphql-php",
|
||||
"description": "A PHP port of GraphQL reference implementation",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/webonyx/graphql-php",
|
||||
"keywords": [
|
||||
"graphql",
|
||||
"API"
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.1||^8.0",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^6.0",
|
||||
"phpbench/phpbench": "^0.14.0",
|
||||
"phpstan/phpstan": "^0.11.4",
|
||||
"phpstan/phpstan-phpunit": "^0.11.0",
|
||||
"phpstan/phpstan-strict-rules": "^0.11.0",
|
||||
"phpunit/phpcov": "^5.0",
|
||||
"phpunit/phpunit": "^7.2",
|
||||
"psr/http-message": "^1.0",
|
||||
"react/promise": "2.*"
|
||||
},
|
||||
"config": {
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GraphQL\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"GraphQL\\Tests\\": "tests/",
|
||||
"GraphQL\\Benchmarks\\": "benchmarks/",
|
||||
"GraphQL\\Examples\\Blog\\": "examples/01-blog/Blog/"
|
||||
}
|
||||
},
|
||||
"suggest": {
|
||||
"react/promise": "To leverage async resolving on React PHP platform",
|
||||
"psr/http-message": "To use standard GraphQL server"
|
||||
},
|
||||
"scripts": {
|
||||
"api-docs": "php tools/gendocs.php",
|
||||
"bench": "phpbench run .",
|
||||
"test": "phpunit",
|
||||
"lint" : "phpcs",
|
||||
"fix-style" : "phpcbf",
|
||||
"static-analysis": "phpstan analyse --ansi --memory-limit 256M",
|
||||
"check-all": "composer lint && composer static-analysis && composer test"
|
||||
}
|
||||
}
|
||||
19
vendor/webonyx/graphql-php/docs/best-practices.md
vendored
Normal file
19
vendor/webonyx/graphql-php/docs/best-practices.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Config Validation
|
||||
Defining types using arrays may be error-prone, but **graphql-php** provides config validation
|
||||
tool to report when config has unexpected structure.
|
||||
|
||||
This validation tool is **disabled by default** because it is time-consuming operation which only
|
||||
makes sense during development.
|
||||
|
||||
To enable validation - call: `GraphQL\Type\Definition\Config::enableValidation();` in your bootstrap
|
||||
but make sure to restrict it to debug/development mode only.
|
||||
|
||||
# Type Registry
|
||||
**graphql-php** expects that each type in Schema is presented by single instance. Therefore
|
||||
if you define your types as separate PHP classes you need to ensure that each type is referenced only once.
|
||||
|
||||
Technically you can create several instances of your type (for example for tests), but `GraphQL\Type\Schema`
|
||||
will throw on attempt to add different instances with the same name.
|
||||
|
||||
There are several ways to achieve this depending on your preferences. We provide reference
|
||||
implementation below that introduces TypeRegistry class:
|
||||
25
vendor/webonyx/graphql-php/docs/complementary-tools.md
vendored
Normal file
25
vendor/webonyx/graphql-php/docs/complementary-tools.md
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Integrations
|
||||
|
||||
* [Standard Server](executing-queries.md/#using-server) – Out of the box integration with any PSR-7 compatible framework (like [Slim](http://slimframework.com) or [Zend Expressive](http://zendframework.github.io/zend-expressive/)).
|
||||
* [Relay Library for graphql-php](https://github.com/ivome/graphql-relay-php) – Helps construct Relay related schema definitions.
|
||||
* [Lighthouse](https://github.com/nuwave/lighthouse) – Laravel based, uses Schema Definition Language
|
||||
* [OverblogGraphQLBundle](https://github.com/overblog/GraphQLBundle) – Bundle for Symfony
|
||||
* [WP-GraphQL](https://github.com/wp-graphql/wp-graphql) - GraphQL API for WordPress
|
||||
|
||||
# GraphQL PHP Tools
|
||||
|
||||
* [GraphQLite](https://graphqlite.thecodingmachine.io) – Define your complete schema with annotations
|
||||
* [GraphQL Doctrine](https://github.com/Ecodev/graphql-doctrine) – Define types with Doctrine ORM annotations
|
||||
* [DataLoaderPHP](https://github.com/overblog/dataloader-php) – as a ready implementation for [deferred resolvers](data-fetching.md#solving-n1-problem)
|
||||
* [GraphQL Uploads](https://github.com/Ecodev/graphql-upload) – A PSR-15 middleware to support file uploads in GraphQL.
|
||||
* [GraphQL Batch Processor](https://github.com/vasily-kartashov/graphql-batch-processing) – Provides a builder interface for defining collection, querying, filtering, and post-processing logic of batched data fetches.
|
||||
* [GraphQL Utils](https://github.com/simPod/GraphQL-Utils) – Objective schema definition builders (no need for arrays anymore) and `DateTime` scalar
|
||||
* [PSR 15 compliant middleware](https://github.com/phps-cans/psr7-middleware-graphql) for the Standard Server _(experimental)_
|
||||
|
||||
# General GraphQL Tools
|
||||
|
||||
* [GraphQL Playground](https://github.com/prismagraphql/graphql-playground) – GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).
|
||||
* [GraphiQL](https://github.com/graphql/graphiql) – An in-browser IDE for exploring GraphQL
|
||||
* [ChromeiQL](https://chrome.google.com/webstore/detail/chromeiql/fkkiamalmpiidkljmicmjfbieiclmeij)
|
||||
or [GraphiQL Feen](https://chrome.google.com/webstore/detail/graphiql-feen/mcbfdonlkfpbfdpimkjilhdneikhfklp) –
|
||||
GraphiQL as Google Chrome extension
|
||||
139
vendor/webonyx/graphql-php/docs/concepts.md
vendored
Normal file
139
vendor/webonyx/graphql-php/docs/concepts.md
vendored
Normal file
@ -0,0 +1,139 @@
|
||||
# Overview
|
||||
GraphQL is data-centric. On the very top level it is built around three major concepts:
|
||||
**Schema**, **Query** and **Mutation**.
|
||||
|
||||
You are expected to express your application as **Schema** (aka Type System) and expose it
|
||||
with single HTTP endpoint (e.g. using our [standard server](executing-queries.md#using-server)).
|
||||
Application clients (e.g. web or mobile clients) send **Queries**
|
||||
to this endpoint to request structured data and **Mutations** to perform changes (usually with HTTP POST method).
|
||||
|
||||
## Queries
|
||||
Queries are expressed in simple language that resembles JSON:
|
||||
|
||||
```graphql
|
||||
{
|
||||
hero {
|
||||
name
|
||||
friends {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It was designed to mirror the structure of expected response:
|
||||
```json
|
||||
{
|
||||
"hero": {
|
||||
"name": "R2-D2",
|
||||
"friends": [
|
||||
{"name": "Luke Skywalker"},
|
||||
{"name": "Han Solo"},
|
||||
{"name": "Leia Organa"}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
**graphql-php** runtime parses Queries, makes sure that they are valid for given Type System
|
||||
and executes using [data fetching tools](data-fetching.md) provided by you
|
||||
as a part of integration. Queries are supposed to be idempotent.
|
||||
|
||||
## Mutations
|
||||
Mutations use advanced features of the very same query language (like arguments and variables)
|
||||
and have only semantic difference from Queries:
|
||||
|
||||
```graphql
|
||||
mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
|
||||
createReview(episode: $ep, review: $review) {
|
||||
stars
|
||||
commentary
|
||||
}
|
||||
}
|
||||
```
|
||||
Variables `$ep` and `$review` are sent alongside with mutation. Full HTTP request might look like this:
|
||||
```json
|
||||
// POST /graphql-endpoint
|
||||
// Content-Type: application/javascript
|
||||
//
|
||||
{
|
||||
"query": "mutation CreateReviewForEpisode...",
|
||||
"variables": {
|
||||
"ep": "JEDI",
|
||||
"review": {
|
||||
"stars": 5,
|
||||
"commentary": "This is a great movie!"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
As you see variables may include complex objects and they will be correctly validated by
|
||||
**graphql-php** runtime.
|
||||
|
||||
Another nice feature of GraphQL mutations is that they also hold the query for data to be
|
||||
returned after mutation. In our example mutation will return:
|
||||
```
|
||||
{
|
||||
"createReview": {
|
||||
"stars": 5,
|
||||
"commentary": "This is a great movie!"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Type System
|
||||
Conceptually GraphQL type is a collection of fields. Each field in turn
|
||||
has it's own type which allows to build complex hierarchies.
|
||||
|
||||
Quick example on pseudo-language:
|
||||
```
|
||||
type BlogPost {
|
||||
title: String!
|
||||
author: User
|
||||
body: String
|
||||
}
|
||||
|
||||
type User {
|
||||
id: Id!
|
||||
firstName: String
|
||||
lastName: String
|
||||
}
|
||||
```
|
||||
|
||||
Type system is a heart of GraphQL integration. That's where **graphql-php** comes into play.
|
||||
|
||||
It provides following tools and primitives to describe your App as hierarchy of types:
|
||||
|
||||
* Primitives for defining **objects** and **interfaces**
|
||||
* Primitives for defining **enumerations** and **unions**
|
||||
* Primitives for defining custom **scalar types**
|
||||
* Built-in scalar types: `ID`, `String`, `Int`, `Float`, `Boolean`
|
||||
* Built-in type modifiers: `ListOf` and `NonNull`
|
||||
|
||||
Same example expressed in **graphql-php**:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$userType = new ObjectType([
|
||||
'name' => 'User',
|
||||
'fields' => [
|
||||
'id' => Type::nonNull(Type::id()),
|
||||
'firstName' => Type::string(),
|
||||
'lastName' => Type::string()
|
||||
]
|
||||
]);
|
||||
|
||||
$blogPostType = new ObjectType([
|
||||
'name' => 'BlogPost',
|
||||
'fields' => [
|
||||
'title' => Type::nonNull(Type::string()),
|
||||
'author' => $userType
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
# Further Reading
|
||||
To get deeper understanding of GraphQL concepts - [read the docs on official GraphQL website](http://graphql.org/learn/)
|
||||
|
||||
To get started with **graphql-php** - continue to next section ["Getting Started"](getting-started.md)
|
||||
273
vendor/webonyx/graphql-php/docs/data-fetching.md
vendored
Normal file
273
vendor/webonyx/graphql-php/docs/data-fetching.md
vendored
Normal file
@ -0,0 +1,273 @@
|
||||
# Overview
|
||||
GraphQL is data-storage agnostic. You can use any underlying data storage engine, including SQL or NoSQL database,
|
||||
plain files or in-memory data structures.
|
||||
|
||||
In order to convert the GraphQL query to PHP array, **graphql-php** traverses query fields (using depth-first algorithm) and
|
||||
runs special **resolve** function on each field. This **resolve** function is provided by you as a part of
|
||||
[field definition](type-system/object-types.md#field-configuration-options) or [query execution call](executing-queries.md#overview).
|
||||
|
||||
Result returned by **resolve** function is directly included in the response (for scalars and enums)
|
||||
or passed down to nested fields (for objects).
|
||||
|
||||
Let's walk through an example. Consider following GraphQL query:
|
||||
|
||||
```graphql
|
||||
{
|
||||
lastStory {
|
||||
title
|
||||
author {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We need a Schema that can fulfill it. On the very top level the Schema contains Query type:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$queryType = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
|
||||
'lastStory' => [
|
||||
'type' => $blogStoryType,
|
||||
'resolve' => function() {
|
||||
return [
|
||||
'id' => 1,
|
||||
'title' => 'Example blog post',
|
||||
'authorId' => 1
|
||||
];
|
||||
}
|
||||
]
|
||||
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
As we see field **lastStory** has **resolve** function that is responsible for fetching data.
|
||||
|
||||
In our example, we simply return array value, but in the real-world application you would query
|
||||
your database/cache/search index and return the result.
|
||||
|
||||
Since **lastStory** is of composite type **BlogStory** this result is passed down to fields of this type:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$blogStoryType = new ObjectType([
|
||||
'name' => 'BlogStory',
|
||||
'fields' => [
|
||||
|
||||
'author' => [
|
||||
'type' => $userType,
|
||||
'resolve' => function($blogStory) {
|
||||
$users = [
|
||||
1 => [
|
||||
'id' => 1,
|
||||
'name' => 'Smith'
|
||||
],
|
||||
2 => [
|
||||
'id' => 2,
|
||||
'name' => 'Anderson'
|
||||
]
|
||||
];
|
||||
return $users[$blogStory['authorId']];
|
||||
}
|
||||
],
|
||||
|
||||
'title' => [
|
||||
'type' => Type::string()
|
||||
]
|
||||
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
Here **$blogStory** is the array returned by **lastStory** field above.
|
||||
|
||||
Again: in the real-world applications you would fetch user data from data store by **authorId** and return it.
|
||||
Also, note that you don't have to return arrays. You can return any value, **graphql-php** will pass it untouched
|
||||
to nested resolvers.
|
||||
|
||||
But then the question appears - field **title** has no **resolve** option. How is it resolved?
|
||||
|
||||
There is a default resolver for all fields. When you define your own **resolve** function
|
||||
for a field you simply override this default resolver.
|
||||
|
||||
# Default Field Resolver
|
||||
**graphql-php** provides following default field resolver:
|
||||
```php
|
||||
<?php
|
||||
function defaultFieldResolver($source, $args, $context, \GraphQL\Type\Definition\ResolveInfo $info)
|
||||
{
|
||||
$fieldName = $info->fieldName;
|
||||
$property = null;
|
||||
|
||||
if (is_array($source) || $source instanceof \ArrayAccess) {
|
||||
if (isset($source[$fieldName])) {
|
||||
$property = $source[$fieldName];
|
||||
}
|
||||
} else if (is_object($source)) {
|
||||
if (isset($source->{$fieldName})) {
|
||||
$property = $source->{$fieldName};
|
||||
}
|
||||
}
|
||||
|
||||
return $property instanceof Closure ? $property($source, $args, $context, $info) : $property;
|
||||
}
|
||||
```
|
||||
|
||||
As you see it returns value by key (for arrays) or property (for objects).
|
||||
If the value is not set - it returns **null**.
|
||||
|
||||
To override the default resolver, pass it as an argument of [executeQuery](executing-queries.md) call.
|
||||
|
||||
# Default Field Resolver per Type
|
||||
Sometimes it might be convenient to set default field resolver per type. You can do so by providing
|
||||
[resolveField option in type config](type-system/object-types.md#configuration-options). For example:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
|
||||
$userType = new ObjectType([
|
||||
'name' => 'User',
|
||||
'fields' => [
|
||||
|
||||
'name' => Type::string(),
|
||||
'email' => Type::string()
|
||||
|
||||
],
|
||||
'resolveField' => function(User $user, $args, $context, ResolveInfo $info) {
|
||||
switch ($info->fieldName) {
|
||||
case 'name':
|
||||
return $user->getName();
|
||||
case 'email':
|
||||
return $user->getEmail();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
Keep in mind that **field resolver** has precedence over **default field resolver per type** which in turn
|
||||
has precedence over **default field resolver**.
|
||||
|
||||
|
||||
# Solving N+1 Problem
|
||||
Since: 0.9.0
|
||||
|
||||
One of the most annoying problems with data fetching is a so-called
|
||||
[N+1 problem](https://secure.phabricator.com/book/phabcontrib/article/n_plus_one/). <br>
|
||||
Consider following GraphQL query:
|
||||
```
|
||||
{
|
||||
topStories(limit: 10) {
|
||||
title
|
||||
author {
|
||||
name
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Naive field resolution process would require up to 10 calls to the underlying data store to fetch authors for all 10 stories.
|
||||
|
||||
**graphql-php** provides tools to mitigate this problem: it allows you to defer actual field resolution to a later stage
|
||||
when one batched query could be executed instead of 10 distinct queries.
|
||||
|
||||
Here is an example of **BlogStory** resolver for field **author** that uses deferring:
|
||||
```php
|
||||
<?php
|
||||
'resolve' => function($blogStory) {
|
||||
MyUserBuffer::add($blogStory['authorId']);
|
||||
|
||||
return new GraphQL\Deferred(function () use ($blogStory) {
|
||||
MyUserBuffer::loadBuffered();
|
||||
return MyUserBuffer::get($blogStory['authorId']);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
In this example, we fill up the buffer with 10 author ids first. Then **graphql-php** continues
|
||||
resolving other non-deferred fields until there are none of them left.
|
||||
|
||||
After that, it calls closures wrapped by `GraphQL\Deferred` which in turn load all buffered
|
||||
ids once (using SQL IN(?), Redis MGET or other similar tools) and returns final field value.
|
||||
|
||||
Originally this approach was advocated by Facebook in their [Dataloader](https://github.com/facebook/dataloader)
|
||||
project. This solution enables very interesting optimizations at no cost. Consider the following query:
|
||||
|
||||
```graphql
|
||||
{
|
||||
topStories(limit: 10) {
|
||||
author {
|
||||
email
|
||||
}
|
||||
}
|
||||
category {
|
||||
stories(limit: 10) {
|
||||
author {
|
||||
email
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Even though **author** field is located on different levels of the query - it can be buffered in the same buffer.
|
||||
In this example, only one query will be executed for all story authors comparing to 20 queries
|
||||
in a naive implementation.
|
||||
|
||||
# Async PHP
|
||||
Since: 0.10.0 (version 0.9.0 had slightly different API which still works, but is deprecated)
|
||||
|
||||
If your project runs in an environment that supports async operations
|
||||
(like HHVM, ReactPHP, Icicle.io, appserver.io, PHP threads, etc)
|
||||
you can leverage the power of your platform to resolve some fields asynchronously.
|
||||
|
||||
The only requirement: your platform must support the concept of Promises compatible with
|
||||
[Promises A+](https://promisesaplus.com/) specification.
|
||||
|
||||
To start using this feature, switch facade method for query execution from
|
||||
**executeQuery** to **promiseToExecute**:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Executor\ExecutionResult;
|
||||
|
||||
$promise = GraphQL::promiseToExecute(
|
||||
$promiseAdapter,
|
||||
$schema,
|
||||
$queryString,
|
||||
$rootValue = null,
|
||||
$contextValue = null,
|
||||
$variableValues = null,
|
||||
$operationName = null,
|
||||
$fieldResolver = null,
|
||||
$validationRules = null
|
||||
);
|
||||
$promise->then(function(ExecutionResult $result) {
|
||||
return $result->toArray();
|
||||
});
|
||||
```
|
||||
|
||||
Where **$promiseAdapter** is an instance of:
|
||||
|
||||
* For [ReactPHP](https://github.com/reactphp/react) (requires **react/promise** as composer dependency): <br>
|
||||
`GraphQL\Executor\Promise\Adapter\ReactPromiseAdapter`
|
||||
|
||||
* Other platforms: write your own class implementing interface: <br>
|
||||
[`GraphQL\Executor\Promise\PromiseAdapter`](reference.md#graphqlexecutorpromisepromiseadapter).
|
||||
|
||||
Then your **resolve** functions should return promises of your platform instead of `GraphQL\Deferred`s.
|
||||
193
vendor/webonyx/graphql-php/docs/error-handling.md
vendored
Normal file
193
vendor/webonyx/graphql-php/docs/error-handling.md
vendored
Normal file
@ -0,0 +1,193 @@
|
||||
# Errors in GraphQL
|
||||
|
||||
Query execution process never throws exceptions. Instead, all errors are caught and collected.
|
||||
After execution, they are available in **$errors** prop of
|
||||
[`GraphQL\Executor\ExecutionResult`](reference.md#graphqlexecutorexecutionresult).
|
||||
|
||||
When the result is converted to a serializable array using its **toArray()** method, all errors are
|
||||
converted to arrays as well using default error formatting (see below).
|
||||
|
||||
Alternatively, you can apply [custom error filtering and formatting](#custom-error-handling-and-formatting)
|
||||
for your specific requirements.
|
||||
|
||||
# Default Error formatting
|
||||
By default, each error entry is converted to an associative array with following structure:
|
||||
|
||||
```php
|
||||
<?php
|
||||
[
|
||||
'message' => 'Error message',
|
||||
'category' => 'graphql',
|
||||
'locations' => [
|
||||
['line' => 1, 'column' => 2]
|
||||
],
|
||||
'path' => [
|
||||
'listField',
|
||||
0,
|
||||
'fieldWithException'
|
||||
]
|
||||
];
|
||||
```
|
||||
Entry at key **locations** points to a character in query string which caused the error.
|
||||
In some cases (like deep fragment fields) locations will include several entries to track down
|
||||
the path to field with the error in query.
|
||||
|
||||
Entry at key **path** exists only for errors caused by exceptions thrown in resolvers.
|
||||
It contains a path from the very root field to actual field value producing an error
|
||||
(including indexes for list types and field names for composite types).
|
||||
|
||||
**Internal errors**
|
||||
|
||||
As of version **0.10.0**, all exceptions thrown in resolvers are reported with generic message **"Internal server error"**.
|
||||
This is done to avoid information leak in production environments (e.g. database connection errors, file access errors, etc).
|
||||
|
||||
Only exceptions implementing interface [`GraphQL\Error\ClientAware`](reference.md#graphqlerrorclientaware) and claiming themselves as **safe** will
|
||||
be reported with a full error message.
|
||||
|
||||
For example:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Error\ClientAware;
|
||||
|
||||
class MySafeException extends \Exception implements ClientAware
|
||||
{
|
||||
public function isClientSafe()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getCategory()
|
||||
{
|
||||
return 'businessLogic';
|
||||
}
|
||||
}
|
||||
```
|
||||
When such exception is thrown it will be reported with a full error message:
|
||||
```php
|
||||
<?php
|
||||
[
|
||||
'message' => 'My reported error',
|
||||
'category' => 'businessLogic',
|
||||
'locations' => [
|
||||
['line' => 10, 'column' => 2]
|
||||
],
|
||||
'path' => [
|
||||
'path',
|
||||
'to',
|
||||
'fieldWithException'
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
To change default **"Internal server error"** message to something else, use:
|
||||
```
|
||||
GraphQL\Error\FormattedError::setInternalErrorMessage("Unexpected error");
|
||||
```
|
||||
|
||||
# Debugging tools
|
||||
|
||||
During development or debugging use `$result->toArray(true)` to add **debugMessage** key to
|
||||
each formatted error entry. If you also want to add exception trace - pass flags instead:
|
||||
|
||||
```
|
||||
use GraphQL\Error\Debug;
|
||||
$debug = Debug::INCLUDE_DEBUG_MESSAGE | Debug::INCLUDE_TRACE;
|
||||
$result = GraphQL::executeQuery(/*args*/)->toArray($debug);
|
||||
```
|
||||
|
||||
This will make each error entry to look like this:
|
||||
```php
|
||||
<?php
|
||||
[
|
||||
'debugMessage' => 'Actual exception message',
|
||||
'message' => 'Internal server error',
|
||||
'category' => 'internal',
|
||||
'locations' => [
|
||||
['line' => 10, 'column' => 2]
|
||||
],
|
||||
'path' => [
|
||||
'listField',
|
||||
0,
|
||||
'fieldWithException'
|
||||
],
|
||||
'trace' => [
|
||||
/* Formatted original exception trace */
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
If you prefer the first resolver exception to be re-thrown, use following flags:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Error\Debug;
|
||||
$debug = Debug::INCLUDE_DEBUG_MESSAGE | Debug::RETHROW_INTERNAL_EXCEPTIONS;
|
||||
|
||||
// Following will throw if there was an exception in resolver during execution:
|
||||
$result = GraphQL::executeQuery(/*args*/)->toArray($debug);
|
||||
```
|
||||
|
||||
If you only want to re-throw Exceptions that are not marked as safe through the `ClientAware` interface, use
|
||||
the flag `Debug::RETHROW_UNSAFE_EXCEPTIONS`.
|
||||
|
||||
# Custom Error Handling and Formatting
|
||||
It is possible to define custom **formatter** and **handler** for result errors.
|
||||
|
||||
**Formatter** is responsible for converting instances of [`GraphQL\Error\Error`](reference.md#graphqlerrorerror)
|
||||
to an array. **Handler** is useful for error filtering and logging.
|
||||
|
||||
For example, these are default formatter and handler:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Error\FormattedError;
|
||||
|
||||
$myErrorFormatter = function(Error $error) {
|
||||
return FormattedError::createFromException($error);
|
||||
};
|
||||
|
||||
$myErrorHandler = function(array $errors, callable $formatter) {
|
||||
return array_map($formatter, $errors);
|
||||
};
|
||||
|
||||
$result = GraphQL::executeQuery(/* $args */)
|
||||
->setErrorFormatter($myErrorFormatter)
|
||||
->setErrorsHandler($myErrorHandler)
|
||||
->toArray();
|
||||
```
|
||||
|
||||
Note that when you pass [debug flags](#debugging-tools) to **toArray()** your custom formatter will still be
|
||||
decorated with same debugging information mentioned above.
|
||||
|
||||
# Schema Errors
|
||||
So far we only covered errors which occur during query execution process. But schema definition can
|
||||
also throw `GraphQL\Error\InvariantViolation` if there is an error in one of type definitions.
|
||||
|
||||
Usually such errors mean that there is some logical error in your schema and it is the only case
|
||||
when it makes sense to return `500` error code for GraphQL endpoint:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\Error\FormattedError;
|
||||
|
||||
try {
|
||||
$schema = new Schema([
|
||||
// ...
|
||||
]);
|
||||
|
||||
$body = GraphQL::executeQuery($schema, $query);
|
||||
$status = 200;
|
||||
} catch(\Exception $e) {
|
||||
$body = [
|
||||
'errors' => [FormattedError::createFromException($e)]
|
||||
];
|
||||
$status = 500;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json', true, $status);
|
||||
echo json_encode($body);
|
||||
```
|
||||
208
vendor/webonyx/graphql-php/docs/executing-queries.md
vendored
Normal file
208
vendor/webonyx/graphql-php/docs/executing-queries.md
vendored
Normal file
@ -0,0 +1,208 @@
|
||||
# Using Facade Method
|
||||
Query execution is a complex process involving multiple steps, including query **parsing**,
|
||||
**validating** and finally **executing** against your [schema](type-system/schema.md).
|
||||
|
||||
**graphql-php** provides a convenient facade for this process in class
|
||||
[`GraphQL\GraphQL`](reference.md#graphqlgraphql):
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
|
||||
$result = GraphQL::executeQuery(
|
||||
$schema,
|
||||
$queryString,
|
||||
$rootValue = null,
|
||||
$context = null,
|
||||
$variableValues = null,
|
||||
$operationName = null,
|
||||
$fieldResolver = null,
|
||||
$validationRules = null
|
||||
);
|
||||
```
|
||||
|
||||
It returns an instance of [`GraphQL\Executor\ExecutionResult`](reference.md#graphqlexecutorexecutionresult)
|
||||
which can be easily converted to array:
|
||||
|
||||
```php
|
||||
$serializableResult = $result->toArray();
|
||||
```
|
||||
|
||||
Returned array contains **data** and **errors** keys, as described by the
|
||||
[GraphQL spec](http://facebook.github.io/graphql/#sec-Response-Format).
|
||||
This array is suitable for further serialization (e.g. using **json_encode**).
|
||||
See also the section on [error handling and formatting](error-handling.md).
|
||||
|
||||
Description of **executeQuery** method arguments:
|
||||
|
||||
Argument | Type | Notes
|
||||
------------ | -------- | -----
|
||||
schema | [`GraphQL\Type\Schema`](#) | **Required.** Instance of your application [Schema](type-system/schema.md)
|
||||
queryString | `string` or `GraphQL\Language\AST\DocumentNode` | **Required.** Actual GraphQL query string to be parsed, validated and executed. If you parse query elsewhere before executing - pass corresponding AST document here to avoid new parsing.
|
||||
rootValue | `mixed` | Any value that represents a root of your data graph. It is passed as the 1st argument to field resolvers of [Query type](type-system/schema.md#query-and-mutation-types). Can be omitted or set to null if actual root values are fetched by Query type itself.
|
||||
context | `mixed` | Any value that holds information shared between all field resolvers. Most often they use it to pass currently logged in user, locale details, etc.<br><br>It will be available as the 3rd argument in all field resolvers. (see section on [Field Definitions](type-system/object-types.md#field-configuration-options) for reference) **graphql-php** never modifies this value and passes it *as is* to all underlying resolvers.
|
||||
variableValues | `array` | Map of variable values passed along with query string. See section on [query variables on official GraphQL website](http://graphql.org/learn/queries/#variables). Note that while variableValues must be an associative array, the values inside it can be nested using \stdClass if desired.
|
||||
operationName | `string` | Allows the caller to specify which operation in queryString will be run, in cases where queryString contains multiple top-level operations.
|
||||
fieldResolver | `callable` | A resolver function to use when one is not provided by the schema. If not provided, the [default field resolver is used](data-fetching.md#default-field-resolver).
|
||||
validationRules | `array` | A set of rules for query validation step. The default value is all available rules. Empty array would allow skipping query validation (may be convenient for persisted queries which are validated before persisting and assumed valid during execution)
|
||||
|
||||
# Using Server
|
||||
If you are building HTTP GraphQL API, you may prefer our Standard Server
|
||||
(compatible with [express-graphql](https://github.com/graphql/express-graphql)).
|
||||
It supports more features out of the box, including parsing HTTP requests, producing a spec-compliant response; [batched queries](#query-batching); persisted queries.
|
||||
|
||||
Usage example (with plain PHP):
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Server\StandardServer;
|
||||
|
||||
$server = new StandardServer([/* server options, see below */]);
|
||||
$server->handleRequest(); // parses PHP globals and emits response
|
||||
```
|
||||
|
||||
Server also supports [PSR-7 request/response interfaces](http://www.php-fig.org/psr/psr-7/):
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Server\StandardServer;
|
||||
use GraphQL\Executor\ExecutionResult;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\StreamInterface;
|
||||
|
||||
/** @var ServerRequestInterface $psrRequest */
|
||||
/** @var ResponseInterface $psrResponse */
|
||||
/** @var StreamInterface $psrBodyStream */
|
||||
$server = new StandardServer([/* server options, see below */]);
|
||||
$psrResponse = $server->processPsrRequest($psrRequest, $psrResponse, $psrBodyStream);
|
||||
|
||||
|
||||
// Alternatively create PSR-7 response yourself:
|
||||
|
||||
/** @var ExecutionResult|ExecutionResult[] $result */
|
||||
$result = $server->executePsrRequest($psrRequest);
|
||||
$psrResponse = new SomePsr7ResponseImplementation(json_encode($result));
|
||||
```
|
||||
|
||||
PSR-7 is useful when you want to integrate the server into existing framework:
|
||||
|
||||
- [PSR-7 for Laravel](https://laravel.com/docs/5.1/requests#psr7-requests)
|
||||
- [Symfony PSR-7 Bridge](https://symfony.com/doc/current/components/psr7.html)
|
||||
- [Slim](https://www.slimframework.com/docs/concepts/value-objects.html)
|
||||
- [Zend Expressive](http://zendframework.github.io/zend-expressive/)
|
||||
|
||||
## Server configuration options
|
||||
|
||||
Argument | Type | Notes
|
||||
------------ | -------- | -----
|
||||
schema | [`Schema`](reference.md#graphqltypeschema) | **Required.** Instance of your application [Schema](type-system/schema/)
|
||||
rootValue | `mixed` | Any value that represents a root of your data graph. It is passed as the 1st argument to field resolvers of [Query type](type-system/schema.md#query-and-mutation-types). Can be omitted or set to null if actual root values are fetched by Query type itself.
|
||||
context | `mixed` | Any value that holds information shared between all field resolvers. Most often they use it to pass currently logged in user, locale details, etc.<br><br>It will be available as the 3rd argument in all field resolvers. (see section on [Field Definitions](type-system/object-types.md#field-configuration-options) for reference) **graphql-php** never modifies this value and passes it *as is* to all underlying resolvers.
|
||||
fieldResolver | `callable` | A resolver function to use when one is not provided by the schema. If not provided, the [default field resolver is used](data-fetching.md#default-field-resolver).
|
||||
validationRules | `array` or `callable` | A set of rules for query validation step. The default value is all available rules. The empty array would allow skipping query validation (may be convenient for persisted queries which are validated before persisting and assumed valid during execution).<br><br>Pass `callable` to return different validation rules for different queries (e.g. empty array for persisted query and a full list of rules for regular queries). When passed, it is expected to have the following signature: <br><br> **function ([OperationParams](reference.md#graphqlserveroperationparams) $params, DocumentNode $node, $operationType): array**
|
||||
queryBatching | `bool` | Flag indicating whether this server supports query batching ([apollo-style](https://dev-blog.apollodata.com/query-batching-in-apollo-63acfd859862)).<br><br> Defaults to **false**
|
||||
debug | `int` | Debug flags. See [docs on error debugging](error-handling.md#debugging-tools) (flag values are the same).
|
||||
persistentQueryLoader | `callable` | A function which is called to fetch actual query when server encounters **queryId** in request vs **query**.<br><br> The server does not implement persistence part (which you will have to build on your own), but it allows you to execute queries which were persisted previously.<br><br> Expected function signature:<br> **function ($queryId, [OperationParams](reference.md#graphqlserveroperationparams) $params)** <br><br>Function is expected to return query **string** or parsed **DocumentNode** <br><br> [Read more about persisted queries](https://dev-blog.apollodata.com/persisted-graphql-queries-with-apollo-client-119fd7e6bba5).
|
||||
errorFormatter | `callable` | Custom error formatter. See [error handling docs](error-handling.md#custom-error-handling-and-formatting).
|
||||
errorsHandler | `callable` | Custom errors handler. See [error handling docs](error-handling.md#custom-error-handling-and-formatting).
|
||||
promiseAdapter | [`PromiseAdapter`](reference.md#graphqlexecutorpromisepromiseadapter) | Required for [Async PHP](data-fetching/#async-php) only.
|
||||
|
||||
**Server config instance**
|
||||
|
||||
If you prefer fluid interface for config with autocomplete in IDE and static time validation,
|
||||
use [`GraphQL\Server\ServerConfig`](reference.md#graphqlserverserverconfig) instead of an array:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Server\ServerConfig;
|
||||
use GraphQL\Server\StandardServer;
|
||||
|
||||
$config = ServerConfig::create()
|
||||
->setSchema($schema)
|
||||
->setErrorFormatter($myFormatter)
|
||||
->setDebug($debug)
|
||||
;
|
||||
|
||||
$server = new StandardServer($config);
|
||||
```
|
||||
|
||||
## Query batching
|
||||
Standard Server supports query batching ([apollo-style](https://dev-blog.apollodata.com/query-batching-in-apollo-63acfd859862)).
|
||||
|
||||
One of the major benefits of Server over a sequence of **executeQuery()** calls is that
|
||||
[Deferred resolvers](data-fetching.md#solving-n1-problem) won't be isolated in queries.
|
||||
So for example following batch will require single DB request (if user field is deferred):
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"query": "{user(id: 1) { id }}"
|
||||
},
|
||||
{
|
||||
"query": "{user(id: 2) { id }}"
|
||||
},
|
||||
{
|
||||
"query": "{user(id: 3) { id }}"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
To enable query batching, pass **queryBatching** option in server config:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Server\StandardServer;
|
||||
|
||||
$server = new StandardServer([
|
||||
'queryBatching' => true
|
||||
]);
|
||||
```
|
||||
|
||||
# Custom Validation Rules
|
||||
Before execution, a query is validated using a set of standard rules defined by the GraphQL spec.
|
||||
It is possible to override standard set of rules globally or per execution.
|
||||
|
||||
Add rules globally:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Validator\Rules;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
// Add to standard set of rules globally:
|
||||
DocumentValidator::addRule(new Rules\DisableIntrospection());
|
||||
```
|
||||
|
||||
Custom rules per execution:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Validator\Rules;
|
||||
|
||||
$myValiationRules = array_merge(
|
||||
GraphQL::getStandardValidationRules(),
|
||||
[
|
||||
new Rules\QueryComplexity(100),
|
||||
new Rules\DisableIntrospection()
|
||||
]
|
||||
);
|
||||
|
||||
$result = GraphQL::executeQuery(
|
||||
$schema,
|
||||
$queryString,
|
||||
$rootValue = null,
|
||||
$context = null,
|
||||
$variableValues = null,
|
||||
$operationName = null,
|
||||
$fieldResolver = null,
|
||||
$myValiationRules // <-- this will override global validation rules for this request
|
||||
);
|
||||
```
|
||||
|
||||
Or with a standard server:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Server\StandardServer;
|
||||
|
||||
$server = new StandardServer([
|
||||
'validationRules' => $myValiationRules
|
||||
]);
|
||||
```
|
||||
125
vendor/webonyx/graphql-php/docs/getting-started.md
vendored
Normal file
125
vendor/webonyx/graphql-php/docs/getting-started.md
vendored
Normal file
@ -0,0 +1,125 @@
|
||||
# Prerequisites
|
||||
This documentation assumes your familiarity with GraphQL concepts. If it is not the case -
|
||||
first learn about GraphQL on [the official website](http://graphql.org/learn/).
|
||||
|
||||
# Installation
|
||||
|
||||
Using [composer](https://getcomposer.org/doc/00-intro.md), run:
|
||||
|
||||
```sh
|
||||
composer require webonyx/graphql-php
|
||||
```
|
||||
|
||||
# Upgrading
|
||||
We try to keep library releases backwards compatible. But when breaking changes are inevitable
|
||||
they are explained in [upgrade instructions](https://github.com/webonyx/graphql-php/blob/master/UPGRADE.md).
|
||||
|
||||
# Install Tools (optional)
|
||||
While it is possible to communicate with GraphQL API using regular HTTP tools it is way
|
||||
more convenient for humans to use [GraphiQL](https://github.com/graphql/graphiql) - an in-browser
|
||||
IDE for exploring GraphQL APIs.
|
||||
|
||||
It provides syntax-highlighting, auto-completion and auto-generated documentation for
|
||||
GraphQL API.
|
||||
|
||||
The easiest way to use it is to install one of the existing Google Chrome extensions:
|
||||
|
||||
- [ChromeiQL](https://chrome.google.com/webstore/detail/chromeiql/fkkiamalmpiidkljmicmjfbieiclmeij)
|
||||
- [GraphiQL Feen](https://chrome.google.com/webstore/detail/graphiql-feen/mcbfdonlkfpbfdpimkjilhdneikhfklp)
|
||||
|
||||
Alternatively, you can follow instructions on [the GraphiQL](https://github.com/graphql/graphiql)
|
||||
page and install it locally.
|
||||
|
||||
|
||||
# Hello World
|
||||
Let's create a type system that will be capable to process following simple query:
|
||||
```
|
||||
query {
|
||||
echo(message: "Hello World")
|
||||
}
|
||||
```
|
||||
|
||||
To do so we need an object type with field `echo`:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
$queryType = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'echo' => [
|
||||
'type' => Type::string(),
|
||||
'args' => [
|
||||
'message' => Type::nonNull(Type::string()),
|
||||
],
|
||||
'resolve' => function ($root, $args) {
|
||||
return $root['prefix'] . $args['message'];
|
||||
}
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
```
|
||||
|
||||
(Note: type definition can be expressed in [different styles](type-system/index.md#type-definition-styles),
|
||||
but this example uses **inline** style for simplicity)
|
||||
|
||||
The interesting piece here is **resolve** option of field definition. It is responsible for returning
|
||||
a value of our field. Values of **scalar** fields will be directly included in response while values of
|
||||
**composite** fields (objects, interfaces, unions) will be passed down to nested field resolvers
|
||||
(not in this example though).
|
||||
|
||||
Now when our type is ready, let's create GraphQL endpoint file for it **graphql.php**:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Type\Schema;
|
||||
|
||||
$schema = new Schema([
|
||||
'query' => $queryType
|
||||
]);
|
||||
|
||||
$rawInput = file_get_contents('php://input');
|
||||
$input = json_decode($rawInput, true);
|
||||
$query = $input['query'];
|
||||
$variableValues = isset($input['variables']) ? $input['variables'] : null;
|
||||
|
||||
try {
|
||||
$rootValue = ['prefix' => 'You said: '];
|
||||
$result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
|
||||
$output = $result->toArray();
|
||||
} catch (\Exception $e) {
|
||||
$output = [
|
||||
'errors' => [
|
||||
[
|
||||
'message' => $e->getMessage()
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode($output);
|
||||
```
|
||||
|
||||
Our example is finished. Try it by running:
|
||||
```sh
|
||||
php -S localhost:8080 graphql.php
|
||||
curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
```
|
||||
|
||||
Check out the full [source code](https://github.com/webonyx/graphql-php/blob/master/examples/00-hello-world) of this example
|
||||
which also includes simple mutation.
|
||||
|
||||
Obviously hello world only scratches the surface of what is possible.
|
||||
So check out next example, which is closer to real-world apps.
|
||||
Or keep reading about [schema definition](type-system/index.md).
|
||||
|
||||
# Blog example
|
||||
It is often easier to start with a full-featured example and then get back to documentation
|
||||
for your own work.
|
||||
|
||||
Check out [Blog example of GraphQL API](https://github.com/webonyx/graphql-php/tree/master/examples/01-blog).
|
||||
It is quite close to real-world GraphQL hierarchies. Follow instructions and try it yourself in ~10 minutes.
|
||||
35
vendor/webonyx/graphql-php/docs/how-it-works.md
vendored
Normal file
35
vendor/webonyx/graphql-php/docs/how-it-works.md
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# Overview
|
||||
Following reading describes implementation details of query execution process. It may clarify some
|
||||
internals of GraphQL runtime but is not required to use it.
|
||||
|
||||
# Parsing
|
||||
|
||||
TODOC
|
||||
|
||||
# Validating
|
||||
TODOC
|
||||
|
||||
# Executing
|
||||
TODOC
|
||||
|
||||
# Errors explained
|
||||
There are 3 types of errors in GraphQL:
|
||||
|
||||
- **Syntax**: query has invalid syntax and could not be parsed;
|
||||
- **Validation**: query is incompatible with type system (e.g. unknown field is requested);
|
||||
- **Execution**: occurs when some field resolver throws (or returns unexpected value).
|
||||
|
||||
Obviously, when **Syntax** or **Validation** error is detected - the process is interrupted and
|
||||
the query is not executed.
|
||||
|
||||
Execution process never throws exceptions. Instead, all errors are caught and collected in
|
||||
execution result.
|
||||
|
||||
GraphQL is forgiving to **Execution** errors which occur in resolvers of nullable fields.
|
||||
If such field throws or returns unexpected value the value of the field in response will be simply
|
||||
replaced with **null** and error entry will be registered.
|
||||
|
||||
If an exception is thrown in the non-null field - error bubbles up to the first nullable field.
|
||||
This nullable field is replaced with **null** and error entry is added to the result.
|
||||
If all fields up to the root are non-null - **data** entry will be removed from the result
|
||||
and only **errors** key will be presented.
|
||||
55
vendor/webonyx/graphql-php/docs/index.md
vendored
Normal file
55
vendor/webonyx/graphql-php/docs/index.md
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
[](https://github.com/webonyx/graphql-php)
|
||||
[](https://travis-ci.org/webonyx/graphql-php)
|
||||
[](https://coveralls.io/github/webonyx/graphql-php)
|
||||
[](https://packagist.org/packages/webonyx/graphql-php)
|
||||
[](https://packagist.org/packages/webonyx/graphql-php)
|
||||
|
||||
# About GraphQL
|
||||
|
||||
GraphQL is a modern way to build HTTP APIs consumed by the web and mobile clients.
|
||||
It is intended to be an alternative to REST and SOAP APIs (even for **existing applications**).
|
||||
|
||||
GraphQL itself is a [specification](https://github.com/facebook/graphql) designed by Facebook
|
||||
engineers. Various implementations of this specification were written
|
||||
[in different languages and environments](http://graphql.org/code/).
|
||||
|
||||
Great overview of GraphQL features and benefits is presented on [the official website](http://graphql.org/).
|
||||
All of them equally apply to this PHP implementation.
|
||||
|
||||
|
||||
# About graphql-php
|
||||
|
||||
**graphql-php** is a feature-complete implementation of GraphQL specification in PHP (5.5+, 7.0+).
|
||||
It was originally inspired by [reference JavaScript implementation](https://github.com/graphql/graphql-js)
|
||||
published by Facebook.
|
||||
|
||||
This library is a thin wrapper around your existing data layer and business logic.
|
||||
It doesn't dictate how these layers are implemented or which storage engines
|
||||
are used. Instead, it provides tools for creating rich API for your existing app.
|
||||
|
||||
Library features include:
|
||||
|
||||
- Primitives to express your app as a [Type System](type-system/index.md)
|
||||
- Validation and introspection of this Type System (for compatibility with tools like [GraphiQL](complementary-tools.md#tools))
|
||||
- Parsing, validating and [executing GraphQL queries](executing-queries.md) against this Type System
|
||||
- Rich [error reporting](error-handling.md), including query validation and execution errors
|
||||
- Optional tools for [parsing GraphQL Type language](type-system/type-language.md)
|
||||
- Tools for [batching requests](data-fetching.md#solving-n1-problem) to backend storage
|
||||
- [Async PHP platforms support](data-fetching.md#async-php) via promises
|
||||
- [Standard HTTP server](executing-queries.md#using-server)
|
||||
|
||||
Also, several [complementary tools](complementary-tools.md) are available which provide integrations with
|
||||
existing PHP frameworks, add support for Relay, etc.
|
||||
|
||||
## Current Status
|
||||
The first version of this library (v0.1) was released on August 10th 2015.
|
||||
|
||||
The current version supports all features described by GraphQL specification
|
||||
as well as some experimental features like
|
||||
[Schema Language parser](type-system/type-language.md) and
|
||||
[Schema printer](reference.md#graphqlutilsschemaprinter).
|
||||
|
||||
Ready for real-world usage.
|
||||
|
||||
## GitHub
|
||||
Project source code is [hosted on GitHub](https://github.com/webonyx/graphql-php).
|
||||
2336
vendor/webonyx/graphql-php/docs/reference.md
vendored
Normal file
2336
vendor/webonyx/graphql-php/docs/reference.md
vendored
Normal file
File diff suppressed because it is too large
Load Diff
94
vendor/webonyx/graphql-php/docs/security.md
vendored
Normal file
94
vendor/webonyx/graphql-php/docs/security.md
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
# Query Complexity Analysis
|
||||
|
||||
This is a PHP port of [Query Complexity Analysis](http://sangria-graphql.org/learn/#query-complexity-analysis) in Sangria implementation.
|
||||
|
||||
Complexity analysis is a separate validation rule which calculates query complexity score before execution.
|
||||
Every field in the query gets a default score 1 (including ObjectType nodes). Total complexity of the
|
||||
query is the sum of all field scores. For example, the complexity of introspection query is **109**.
|
||||
|
||||
If this score exceeds a threshold, a query is not executed and an error is returned instead.
|
||||
|
||||
Complexity analysis is disabled by default. To enabled it, add validation rule:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Validator\Rules\QueryComplexity;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
$rule = new QueryComplexity($maxQueryComplexity = 100);
|
||||
DocumentValidator::addRule($rule);
|
||||
|
||||
GraphQL::executeQuery(/*...*/);
|
||||
```
|
||||
This will set the rule globally. Alternatively, you can provide validation rules [per execution](executing-queries.md#custom-validation-rules).
|
||||
|
||||
To customize field score add **complexity** function to field definition:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$type = new ObjectType([
|
||||
'name' => 'MyType',
|
||||
'fields' => [
|
||||
'someList' => [
|
||||
'type' => Type::listOf(Type::string()),
|
||||
'args' => [
|
||||
'limit' => [
|
||||
'type' => Type::int(),
|
||||
'defaultValue' => 10
|
||||
]
|
||||
],
|
||||
'complexity' => function($childrenComplexity, $args) {
|
||||
return $childrenComplexity * $args['limit'];
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
# Limiting Query Depth
|
||||
|
||||
This is a PHP port of [Limiting Query Depth](http://sangria-graphql.org/learn/#limiting-query-depth) in Sangria implementation.
|
||||
For example, max depth of the introspection query is **7**.
|
||||
|
||||
It is disabled by default. To enable it, add following validation rule:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Validator\Rules\QueryDepth;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
$rule = new QueryDepth($maxDepth = 10);
|
||||
DocumentValidator::addRule($rule);
|
||||
|
||||
GraphQL::executeQuery(/*...*/);
|
||||
```
|
||||
|
||||
This will set the rule globally. Alternatively, you can provide validation rules [per execution](executing-queries.md#custom-validation-rules).
|
||||
|
||||
# Disabling Introspection
|
||||
[Introspection](http://graphql.org/learn/introspection/) is a mechanism for fetching schema structure.
|
||||
It is used by tools like GraphiQL for auto-completion, query validation, etc.
|
||||
|
||||
Introspection is enabled by default. It means that anybody can get a full description of your schema by
|
||||
sending a special query containing meta fields **__type** and **__schema** .
|
||||
|
||||
If you are not planning to expose your API to the general public, it makes sense to disable this feature.
|
||||
|
||||
GraphQL PHP provides you separate validation rule which prohibits queries that contain
|
||||
**__type** or **__schema** fields. To disable introspection, add following rule:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Validator\Rules\DisableIntrospection;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
|
||||
DocumentValidator::addRule(new DisableIntrospection());
|
||||
|
||||
GraphQL::executeQuery(/*...*/);
|
||||
```
|
||||
This will set the rule globally. Alternatively, you can provide validation rules [per execution](executing-queries.md#custom-validation-rules).
|
||||
61
vendor/webonyx/graphql-php/docs/type-system/directives.md
vendored
Normal file
61
vendor/webonyx/graphql-php/docs/type-system/directives.md
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
# Built-in directives
|
||||
The directive is a way for a client to give GraphQL server additional context and hints on how to execute
|
||||
the query. The directive can be attached to a field or fragment and can affect the execution of the
|
||||
query in any way the server desires.
|
||||
|
||||
GraphQL specification includes two built-in directives:
|
||||
|
||||
* **@include(if: Boolean)** Only include this field or fragment in the result if the argument is **true**
|
||||
* **@skip(if: Boolean)** Skip this field or fragment if the argument is **true**
|
||||
|
||||
For example:
|
||||
```graphql
|
||||
query Hero($episode: Episode, $withFriends: Boolean!) {
|
||||
hero(episode: $episode) {
|
||||
name
|
||||
friends @include(if: $withFriends) {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
Here if **$withFriends** variable is set to **false** - friends section will be ignored and excluded
|
||||
from the response. Important implementation detail: those fields will never be executed
|
||||
(not just removed from response after execution).
|
||||
|
||||
# Custom directives
|
||||
**graphql-php** supports custom directives even though their presence does not affect the execution of fields.
|
||||
But you can use [`GraphQL\Type\Definition\ResolveInfo`](../reference.md#graphqltypedefinitionresolveinfo)
|
||||
in field resolvers to modify the output depending on those directives or perform statistics collection.
|
||||
|
||||
Other use case is your own query validation rules relying on custom directives.
|
||||
|
||||
In **graphql-php** custom directive is an instance of `GraphQL\Type\Definition\Directive`
|
||||
(or one of its subclasses) which accepts an array of following options:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Language\DirectiveLocation;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\Directive;
|
||||
use GraphQL\Type\Definition\FieldArgument;
|
||||
|
||||
$trackDirective = new Directive([
|
||||
'name' => 'track',
|
||||
'description' => 'Instruction to record usage of the field by client',
|
||||
'locations' => [
|
||||
DirectiveLocation::FIELD,
|
||||
],
|
||||
'args' => [
|
||||
new FieldArgument([
|
||||
'name' => 'details',
|
||||
'type' => Type::string(),
|
||||
'description' => 'String with additional details of field usage scenario',
|
||||
'defaultValue' => ''
|
||||
])
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
See possible directive locations in
|
||||
[`GraphQL\Language\DirectiveLocation`](../reference.md#graphqllanguagedirectivelocation).
|
||||
182
vendor/webonyx/graphql-php/docs/type-system/enum-types.md
vendored
Normal file
182
vendor/webonyx/graphql-php/docs/type-system/enum-types.md
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
# Enum Type Definition
|
||||
Enumeration types are a special kind of scalar that is restricted to a particular set
|
||||
of allowed values.
|
||||
|
||||
In **graphql-php** enum type is an instance of `GraphQL\Type\Definition\EnumType`
|
||||
which accepts configuration array in constructor:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
|
||||
$episodeEnum = new EnumType([
|
||||
'name' => 'Episode',
|
||||
'description' => 'One of the films in the Star Wars Trilogy',
|
||||
'values' => [
|
||||
'NEWHOPE' => [
|
||||
'value' => 4,
|
||||
'description' => 'Released in 1977.'
|
||||
],
|
||||
'EMPIRE' => [
|
||||
'value' => 5,
|
||||
'description' => 'Released in 1980.'
|
||||
],
|
||||
'JEDI' => [
|
||||
'value' => 6,
|
||||
'description' => 'Released in 1983.'
|
||||
],
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
This example uses an **inline** style for Enum Type definition, but you can also use
|
||||
[inheritance or type language](index.md#type-definition-styles).
|
||||
|
||||
# Configuration options
|
||||
Enum Type constructor accepts an array with following options:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Name of the type. When not set - inferred from array key (read about [shorthand field definition](#shorthand-definitions) below)
|
||||
description | `string` | Plain-text description of the type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
values | `array` | List of enumerated items, see below for expected structure of each entry
|
||||
|
||||
Each entry of **values** array in turn accepts following options:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Name of the item. When not set - inferred from array key (read about [shorthand field definition](#shorthand-definitions) below)
|
||||
value | `mixed` | Internal representation of enum item in your application (could be any value, including complex objects or callbacks)
|
||||
description | `string` | Plain-text description of enum value for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
deprecationReason | `string` | Text describing why this enum value is deprecated. When not empty - item will not be returned by introspection queries (unless forced)
|
||||
|
||||
|
||||
# Shorthand definitions
|
||||
If internal representation of enumerated item is the same as item name, then you can use
|
||||
following shorthand for definition:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
|
||||
$episodeEnum = new EnumType([
|
||||
'name' => 'Episode',
|
||||
'description' => 'One of the films in the Star Wars Trilogy',
|
||||
'values' => ['NEWHOPE', 'EMPIRE', 'JEDI']
|
||||
]);
|
||||
```
|
||||
|
||||
which is equivalent of:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
|
||||
$episodeEnum = new EnumType([
|
||||
'name' => 'Episode',
|
||||
'description' => 'One of the films in the Star Wars Trilogy',
|
||||
'values' => [
|
||||
'NEWHOPE' => ['value' => 'NEWHOPE'],
|
||||
'EMPIRE' => ['value' => 'EMPIRE'],
|
||||
'JEDI' => ['value' => 'JEDI']
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
which is in turn equivalent of the full form:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
|
||||
$episodeEnum = new EnumType([
|
||||
'name' => 'Episode',
|
||||
'description' => 'One of the films in the Star Wars Trilogy',
|
||||
'values' => [
|
||||
['name' => 'NEWHOPE', 'value' => 'NEWHOPE'],
|
||||
['name' => 'EMPIRE', 'value' => 'EMPIRE'],
|
||||
['name' => 'JEDI', 'value' => 'JEDI']
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
# Field Resolution
|
||||
When object field is of Enum Type, field resolver is expected to return an internal
|
||||
representation of corresponding Enum item (**value** in config). **graphql-php** will
|
||||
then serialize this **value** to **name** to include in response:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$episodeEnum = new EnumType([
|
||||
'name' => 'Episode',
|
||||
'description' => 'One of the films in the Star Wars Trilogy',
|
||||
'values' => [
|
||||
'NEWHOPE' => [
|
||||
'value' => 4,
|
||||
'description' => 'Released in 1977.'
|
||||
],
|
||||
'EMPIRE' => [
|
||||
'value' => 5,
|
||||
'description' => 'Released in 1980.'
|
||||
],
|
||||
'JEDI' => [
|
||||
'value' => 6,
|
||||
'description' => 'Released in 1983.'
|
||||
],
|
||||
]
|
||||
]);
|
||||
|
||||
$heroType = new ObjectType([
|
||||
'name' => 'Hero',
|
||||
'fields' => [
|
||||
'appearsIn' => [
|
||||
'type' => $episodeEnum,
|
||||
'resolve' => function() {
|
||||
return 5; // Actual entry in response will be 'appearsIn' => 'EMPIRE'
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
The Reverse is true when the enum is used as input type (e.g. as field argument).
|
||||
GraphQL will treat enum input as **name** and convert it into **value** before passing to your app.
|
||||
|
||||
For example, given object type definition:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$heroType = new ObjectType([
|
||||
'name' => 'Hero',
|
||||
'fields' => [
|
||||
'appearsIn' => [
|
||||
'type' => Type::boolean(),
|
||||
'args' => [
|
||||
'episode' => Type::nonNull($enumType)
|
||||
],
|
||||
'resolve' => function($_value, $args) {
|
||||
return $args['episode'] === 5 ? true : false;
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
Then following query:
|
||||
```graphql
|
||||
fragment on Hero {
|
||||
appearsInNewHope: appearsIn(NEWHOPE)
|
||||
appearsInEmpire: appearsIn(EMPIRE)
|
||||
}
|
||||
```
|
||||
will return:
|
||||
```php
|
||||
[
|
||||
'appearsInNewHope' => false,
|
||||
'appearsInEmpire' => true
|
||||
]
|
||||
```
|
||||
127
vendor/webonyx/graphql-php/docs/type-system/index.md
vendored
Normal file
127
vendor/webonyx/graphql-php/docs/type-system/index.md
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
# Type System
|
||||
To start using GraphQL you are expected to implement a type hierarchy and expose it as [Schema](schema.md).
|
||||
|
||||
In graphql-php **type** is an instance of internal class from
|
||||
`GraphQL\Type\Definition` namespace: [`ObjectType`](object-types.md),
|
||||
[`InterfaceType`](interfaces.md), [`UnionType`](unions.md), [`InputObjectType`](input-types.md),
|
||||
[`ScalarType`](scalar-types.md), [`EnumType`](enum-types.md) (or one of subclasses).
|
||||
|
||||
But most of the types in your schema will be [object types](object-types.md).
|
||||
|
||||
# Type Definition Styles
|
||||
Several styles of type definitions are supported depending on your preferences.
|
||||
|
||||
Inline definitions:
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
$myType = new ObjectType([
|
||||
'name' => 'MyType',
|
||||
'fields' => [
|
||||
'id' => Type::id()
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
Class per type:
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
class MyType extends ObjectType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
// Note: 'name' is not needed in this form:
|
||||
// it will be inferred from class name by omitting namespace and dropping "Type" suffix
|
||||
'fields' => [
|
||||
'id' => Type::id()
|
||||
]
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using [GraphQL Type language](http://graphql.org/learn/schema/#type-language):
|
||||
|
||||
```graphql
|
||||
schema {
|
||||
query: Query
|
||||
mutation: Mutation
|
||||
}
|
||||
|
||||
type Query {
|
||||
greetings(input: HelloInput!): String!
|
||||
}
|
||||
|
||||
input HelloInput {
|
||||
firstName: String!
|
||||
lastName: String
|
||||
}
|
||||
```
|
||||
|
||||
Read more about type language definitions in a [dedicated docs section](type-language.md).
|
||||
|
||||
# Type Registry
|
||||
Every type must be presented in Schema by a single instance (**graphql-php**
|
||||
throws when it discovers several instances with the same **name** in the schema).
|
||||
|
||||
Therefore if you define your type as separate PHP class you must ensure that only one
|
||||
instance of that class is added to the schema.
|
||||
|
||||
The typical way to do this is to create a registry of your types:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
class TypeRegistry
|
||||
{
|
||||
private $myAType;
|
||||
private $myBType;
|
||||
|
||||
public function myAType()
|
||||
{
|
||||
return $this->myAType ?: ($this->myAType = new MyAType($this));
|
||||
}
|
||||
|
||||
public function myBType()
|
||||
{
|
||||
return $this->myBType ?: ($this->myBType = new MyBType($this));
|
||||
}
|
||||
}
|
||||
```
|
||||
And use this registry in type definition:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
class MyAType extends ObjectType
|
||||
{
|
||||
public function __construct(TypeRegistry $types)
|
||||
{
|
||||
parent::__construct([
|
||||
'fields' => [
|
||||
'b' => $types->myBType()
|
||||
]
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
Obviously, you can automate this registry as you wish to reduce boilerplate or even
|
||||
introduce Dependency Injection Container if your types have other dependencies.
|
||||
|
||||
Alternatively, all methods of the registry could be static - then there is no need
|
||||
to pass it in constructor - instead just use use **TypeRegistry::myAType()** in your
|
||||
type definitions.
|
||||
172
vendor/webonyx/graphql-php/docs/type-system/input-types.md
vendored
Normal file
172
vendor/webonyx/graphql-php/docs/type-system/input-types.md
vendored
Normal file
@ -0,0 +1,172 @@
|
||||
# Mutations
|
||||
Mutation is just a field of a regular [Object Type](object-types.md) with arguments.
|
||||
For GraphQL PHP runtime there is no difference between query fields with arguments and mutations.
|
||||
They are executed [almost](http://facebook.github.io/graphql/#sec-Mutation) identically.
|
||||
To some extent, Mutation is just a convention described in the GraphQL spec.
|
||||
|
||||
Here is an example of a mutation operation:
|
||||
```graphql
|
||||
mutation CreateReviewForEpisode($ep: EpisodeInput!, $review: ReviewInput!) {
|
||||
createReview(episode: $ep, review: $review) {
|
||||
stars
|
||||
commentary
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To execute such a mutation, you need **Mutation** type [at the root of your schema](schema.md):
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$myMutationType = new ObjectType([
|
||||
'name' => 'Mutation',
|
||||
'fields' => [
|
||||
// List of mutations:
|
||||
'createReview' => [
|
||||
'args' => [
|
||||
'episode' => Type::nonNull($episodeInputType),
|
||||
'review' => Type::nonNull($reviewInputType)
|
||||
],
|
||||
'type' => new ObjectType([
|
||||
'name' => 'CreateReviewOutput',
|
||||
'fields' => [
|
||||
'stars' => ['type' => Type::int()],
|
||||
'commentary' => ['type' => Type::string()]
|
||||
]
|
||||
]),
|
||||
],
|
||||
// ... other mutations
|
||||
]
|
||||
]);
|
||||
```
|
||||
As you can see, the only difference from regular object type is the semantics of field names
|
||||
(verbs vs nouns).
|
||||
|
||||
Also as we see arguments can be of complex types. To leverage the full power of mutations
|
||||
(and field arguments in general) you must learn how to create complex input types.
|
||||
|
||||
|
||||
# About Input and Output Types
|
||||
All types in GraphQL are of two categories: **input** and **output**.
|
||||
|
||||
* **Output** types (or field types) are: [Scalar](scalar-types.md), [Enum](enum-types.md), [Object](object-types.md),
|
||||
[Interface](interfaces.md), [Union](unions.md)
|
||||
|
||||
* **Input** types (or argument types) are: [Scalar](scalar-types.md), [Enum](enum-types.md), InputObject
|
||||
|
||||
Obviously, [NonNull and List](lists-and-nonnulls.md) types belong to both categories depending on their
|
||||
inner type.
|
||||
|
||||
Until now all examples of field **arguments** in this documentation were of [Scalar](scalar-types.md) or
|
||||
[Enum](enum-types.md) types. But you can also pass complex objects.
|
||||
|
||||
This is particularly valuable in case of mutations, where input data might be rather complex.
|
||||
|
||||
# Input Object Type
|
||||
GraphQL specification defines Input Object Type for complex inputs. It is similar to ObjectType
|
||||
except that it's fields have no **args** or **resolve** options and their **type** must be input type.
|
||||
|
||||
In graphql-php **Input Object Type** is an instance of `GraphQL\Type\Definition\InputObjectType`
|
||||
(or one of it subclasses) which accepts configuration array in constructor:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\InputObjectType;
|
||||
|
||||
$filters = new InputObjectType([
|
||||
'name' => 'StoryFiltersInput',
|
||||
'fields' => [
|
||||
'author' => [
|
||||
'type' => Type::id(),
|
||||
'description' => 'Only show stories with this author id'
|
||||
],
|
||||
'popular' => [
|
||||
'type' => Type::boolean(),
|
||||
'description' => 'Only show popular stories (liked by several people)'
|
||||
],
|
||||
'tags' => [
|
||||
'type' => Type::listOf(Type::string()),
|
||||
'description' => 'Only show stories which contain all of those tags'
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
Every field may be of other InputObjectType (thus complex hierarchies of inputs are possible)
|
||||
|
||||
# Configuration options
|
||||
The constructor of InputObjectType accepts array with only 3 options:
|
||||
|
||||
Option | Type | Notes
|
||||
------------ | -------- | -----
|
||||
name | `string` | **Required.** Unique name of this object type within Schema
|
||||
fields | `array` or `callable` | **Required**. An array describing object fields or callable returning such an array (see below).
|
||||
description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
|
||||
Every field is an array with following entries:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Name of the input field. When not set - inferred from **fields** array key
|
||||
type | `Type` | **Required.** Instance of one of [Input Types](input-types.md) (**Scalar**, **Enum**, **InputObjectType** + any combination of those with **nonNull** and **listOf** modifiers)
|
||||
description | `string` | Plain-text description of this input field for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
defaultValue | `scalar` | Default value of this input field. Use the internal value if specifying a default for an **enum** type
|
||||
|
||||
# Using Input Object Type
|
||||
In the example above we defined our InputObjectType. Now let's use it in one of field arguments:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$queryType = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'stories' => [
|
||||
'type' => Type::listOf($storyType),
|
||||
'args' => [
|
||||
'filters' => [
|
||||
'type' => Type::nonNull($filters),
|
||||
'defaultValue' => [
|
||||
'popular' => true
|
||||
]
|
||||
]
|
||||
],
|
||||
'resolve' => function($rootValue, $args) {
|
||||
return DataSource::filterStories($args['filters']);
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
(note that you can define **defaultValue** for fields with complex inputs as associative array).
|
||||
|
||||
Then GraphQL query could include filters as literal value:
|
||||
```graphql
|
||||
{
|
||||
stories(filters: {author: "1", popular: false})
|
||||
}
|
||||
```
|
||||
|
||||
Or as query variable:
|
||||
```graphql
|
||||
query($filters: StoryFiltersInput!) {
|
||||
stories(filters: $filters)
|
||||
}
|
||||
```
|
||||
```php
|
||||
$variables = [
|
||||
'filters' => [
|
||||
"author" => "1",
|
||||
"popular" => false
|
||||
]
|
||||
];
|
||||
```
|
||||
|
||||
**graphql-php** will validate the input against your InputObjectType definition and pass it to your
|
||||
resolver as `$args['filters']`
|
||||
136
vendor/webonyx/graphql-php/docs/type-system/interfaces.md
vendored
Normal file
136
vendor/webonyx/graphql-php/docs/type-system/interfaces.md
vendored
Normal file
@ -0,0 +1,136 @@
|
||||
# Interface Type Definition
|
||||
An Interface is an abstract type that includes a certain set of fields that a
|
||||
type must include to implement the interface.
|
||||
|
||||
In **graphql-php** interface type is an instance of `GraphQL\Type\Definition\InterfaceType`
|
||||
(or one of its subclasses) which accepts configuration array in a constructor:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
$character = new InterfaceType([
|
||||
'name' => 'Character',
|
||||
'description' => 'A character in the Star Wars Trilogy',
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => Type::nonNull(Type::string()),
|
||||
'description' => 'The id of the character.',
|
||||
],
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'description' => 'The name of the character.'
|
||||
]
|
||||
],
|
||||
'resolveType' => function ($value) {
|
||||
if ($value->type === 'human') {
|
||||
return MyTypes::human();
|
||||
} else {
|
||||
return MyTypes::droid();
|
||||
}
|
||||
}
|
||||
]);
|
||||
```
|
||||
This example uses **inline** style for Interface definition, but you can also use
|
||||
[inheritance or type language](index.md#type-definition-styles).
|
||||
|
||||
# Configuration options
|
||||
The constructor of InterfaceType accepts an array. Below is a full list of allowed options:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Unique name of this interface type within Schema
|
||||
fields | `array` | **Required.** List of fields required to be defined by interface implementors. Same as [Fields for Object Type](object-types.md#field-configuration-options)
|
||||
description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
resolveType | `callback` | **function($value, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Receives **$value** from resolver of the parent field and returns concrete interface implementor for this **$value**.
|
||||
|
||||
# Implementing interface
|
||||
To implement the Interface simply add it to **interfaces** array of Object Type definition:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$humanType = new ObjectType([
|
||||
'name' => 'Human',
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => Type::nonNull(Type::string()),
|
||||
'description' => 'The id of the character.',
|
||||
],
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'description' => 'The name of the character.'
|
||||
]
|
||||
],
|
||||
'interfaces' => [
|
||||
$character
|
||||
]
|
||||
]);
|
||||
```
|
||||
Note that Object Type must include all fields of interface with exact same types
|
||||
(including **nonNull** specification) and arguments.
|
||||
|
||||
The only exception is when object's field type is more specific than the type of this field defined in interface
|
||||
(see [Covariant return types for interface fields](#covariant-return-types-for-interface-fields) below)
|
||||
|
||||
# Covariant return types for interface fields
|
||||
Object types implementing interface may change the field type to more specific.
|
||||
Example:
|
||||
|
||||
```
|
||||
interface A {
|
||||
field1: A
|
||||
}
|
||||
|
||||
type B implements A {
|
||||
field1: B
|
||||
}
|
||||
```
|
||||
|
||||
# Sharing Interface fields
|
||||
Since every Object Type implementing an Interface must have the same set of fields - it often makes
|
||||
sense to reuse field definitions of Interface in Object Types:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$humanType = new ObjectType([
|
||||
'name' => 'Human',
|
||||
'interfaces' => [
|
||||
$character
|
||||
],
|
||||
'fields' => [
|
||||
'height' => Type::float(),
|
||||
$character->getField('id'),
|
||||
$character->getField('name')
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
In this case, field definitions are created only once (as a part of Interface Type) and then
|
||||
reused by all interface implementors. It can save several microseconds and kilobytes + ensures that
|
||||
field definitions of Interface and implementors are always in sync.
|
||||
|
||||
Yet it creates a problem with the resolution of such fields. There are two ways how shared fields could
|
||||
be resolved:
|
||||
|
||||
1. If field resolution algorithm is the same for all Interface implementors - you can simply add
|
||||
**resolve** option to field definition in Interface itself.
|
||||
|
||||
2. If field resolution varies for different implementations - you can specify **resolveField**
|
||||
option in [Object Type config](object-types.md#configuration-options) and handle field
|
||||
resolutions there
|
||||
(Note: **resolve** option in field definition has precedence over **resolveField** option in object type definition)
|
||||
|
||||
# Interface role in data fetching
|
||||
The only responsibility of interface in Data Fetching process is to return concrete Object Type
|
||||
for given **$value** in **resolveType**. Then resolution of fields is delegated to resolvers of this
|
||||
concrete Object Type.
|
||||
|
||||
If a **resolveType** option is omitted, graphql-php will loop through all interface implementors and
|
||||
use their **isTypeOf** callback to pick the first suitable one. This is obviously less efficient
|
||||
than single **resolveType** call. So it is recommended to define **resolveType** whenever possible.
|
||||
62
vendor/webonyx/graphql-php/docs/type-system/lists-and-nonnulls.md
vendored
Normal file
62
vendor/webonyx/graphql-php/docs/type-system/lists-and-nonnulls.md
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
# Lists
|
||||
**graphql-php** provides built-in support for lists. In order to create list type - wrap
|
||||
existing type with `GraphQL\Type\Definition\Type::listOf()` modifier:
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$userType = new ObjectType([
|
||||
'name' => 'User',
|
||||
'fields' => [
|
||||
'emails' => [
|
||||
'type' => Type::listOf(Type::string()),
|
||||
'resolve' => function() {
|
||||
return ['jon@example.com', 'jonny@example.com'];
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
Resolvers for such fields are expected to return **array** or instance of PHP's built-in **Traversable**
|
||||
interface (**null** is allowed by default too).
|
||||
|
||||
If returned value is not of one of these types - **graphql-php** will add an error to result
|
||||
and set the field value to **null** (only if the field is nullable, see below for non-null fields).
|
||||
|
||||
# Non-Null fields
|
||||
By default in GraphQL, every field can have a **null** value. To indicate that some field always
|
||||
returns **non-null** value - use `GraphQL\Type\Definition\Type::nonNull()` modifier:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$humanType = new ObjectType([
|
||||
'name' => 'User',
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'type' => Type::nonNull(Type::id()),
|
||||
'resolve' => function() {
|
||||
return uniqid();
|
||||
}
|
||||
],
|
||||
'emails' => [
|
||||
'type' => Type::nonNull(Type::listOf(Type::string())),
|
||||
'resolve' => function() {
|
||||
return ['jon@example.com', 'jonny@example.com'];
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
If resolver of non-null field returns **null**, graphql-php will add an error to
|
||||
result and exclude the whole object from the output (an error will bubble to first
|
||||
nullable parent field which will be set to **null**).
|
||||
|
||||
Read the section on [Data Fetching](../data-fetching.md) for details.
|
||||
210
vendor/webonyx/graphql-php/docs/type-system/object-types.md
vendored
Normal file
210
vendor/webonyx/graphql-php/docs/type-system/object-types.md
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
# Object Type Definition
|
||||
Object Type is the most frequently used primitive in a typical GraphQL application.
|
||||
|
||||
Conceptually Object Type is a collection of Fields. Each field, in turn,
|
||||
has its own type which allows building complex hierarchies.
|
||||
|
||||
In **graphql-php** object type is an instance of `GraphQL\Type\Definition\ObjectType`
|
||||
(or one of it subclasses) which accepts configuration array in constructor:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Examples\Blog\Data\DataSource;
|
||||
use GraphQL\Examples\Blog\Data\Story;
|
||||
|
||||
$userType = new ObjectType([
|
||||
'name' => 'User',
|
||||
'description' => 'Our blog visitor',
|
||||
'fields' => [
|
||||
'firstName' => [
|
||||
'type' => Type::string(),
|
||||
'description' => 'User first name'
|
||||
],
|
||||
'email' => Type::string()
|
||||
]
|
||||
]);
|
||||
|
||||
$blogStory = new ObjectType([
|
||||
'name' => 'Story',
|
||||
'fields' => [
|
||||
'body' => Type::string(),
|
||||
'author' => [
|
||||
'type' => $userType,
|
||||
'description' => 'Story author',
|
||||
'resolve' => function(Story $blogStory) {
|
||||
return DataSource::findUser($blogStory->authorId);
|
||||
}
|
||||
],
|
||||
'likes' => [
|
||||
'type' => Type::listOf($userType),
|
||||
'description' => 'List of users who liked the story',
|
||||
'args' => [
|
||||
'limit' => [
|
||||
'type' => Type::int(),
|
||||
'description' => 'Limit the number of recent likes returned',
|
||||
'defaultValue' => 10
|
||||
]
|
||||
],
|
||||
'resolve' => function(Story $blogStory, $args) {
|
||||
return DataSource::findLikes($blogStory->id, $args['limit']);
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
This example uses **inline** style for Object Type definitions, but you can also use
|
||||
[inheritance or type language](index.md#type-definition-styles).
|
||||
|
||||
|
||||
# Configuration options
|
||||
Object type constructor expects configuration array. Below is a full list of available options:
|
||||
|
||||
Option | Type | Notes
|
||||
------------ | -------- | -----
|
||||
name | `string` | **Required.** Unique name of this object type within Schema
|
||||
fields | `array` or `callable` | **Required**. An array describing object fields or callable returning such an array. See [Fields](#field-definitions) section below for expected structure of each array entry. See also the section on [Circular types](#recurring-and-circular-types) for an explanation of when to use callable for this option.
|
||||
description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
interfaces | `array` or `callable` | List of interfaces implemented by this type or callable returning such a list. See [Interface Types](interfaces.md) for details. See also the section on [Circular types](#recurring-and-circular-types) for an explanation of when to use callable for this option.
|
||||
isTypeOf | `callable` | **function($value, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Expected to return **true** if **$value** qualifies for this type (see section about [Abstract Type Resolution](interfaces.md#interface-role-in-data-fetching) for explanation).
|
||||
resolveField | `callable` | **function($value, $args, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Given the **$value** of this type, it is expected to return value for a field defined in **$info->fieldName**. A good place to define a type-specific strategy for field resolution. See section on [Data Fetching](../data-fetching.md) for details.
|
||||
|
||||
# Field configuration options
|
||||
Below is a full list of available field configuration options:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Name of the field. When not set - inferred from **fields** array key (read about [shorthand field definition](#shorthand-field-definitions) below)
|
||||
type | `Type` | **Required.** An instance of internal or custom type. Note: type must be represented by a single instance within one schema (see also [Type Registry](index.md#type-registry))
|
||||
args | `array` | An array of possible type arguments. Each entry is expected to be an array with keys: **name**, **type**, **description**, **defaultValue**. See [Field Arguments](#field-arguments) section below.
|
||||
resolve | `callable` | **function($value, $args, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Given the **$value** of this type, it is expected to return actual value of the current field. See section on [Data Fetching](../data-fetching.md) for details
|
||||
complexity | `callable` | **function($childrenComplexity, $args)**<br> Used to restrict query complexity. The feature is disabled by default, read about [Security](../security.md#query-complexity-analysis) to use it.
|
||||
description | `string` | Plain-text description of this field for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
deprecationReason | `string` | Text describing why this field is deprecated. When not empty - field will not be returned by introspection queries (unless forced)
|
||||
|
||||
# Field arguments
|
||||
Every field on a GraphQL object type can have zero or more arguments, defined in **args** option of field definition.
|
||||
Each argument is an array with following options:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Name of the argument. When not set - inferred from **args** array key
|
||||
type | `Type` | **Required.** Instance of one of [Input Types](input-types.md) (**scalar**, **enum**, **InputObjectType** + any combination of those with **nonNull** and **listOf** modifiers)
|
||||
description | `string` | Plain-text description of this argument for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
defaultValue | `scalar` | Default value for this argument. Use the internal value if specifying a default for an **enum** type
|
||||
|
||||
# Shorthand field definitions
|
||||
Fields can be also defined in **shorthand** notation (with only **name** and **type** options):
|
||||
```php
|
||||
'fields' => [
|
||||
'id' => Type::id(),
|
||||
'fieldName' => $fieldType
|
||||
]
|
||||
```
|
||||
which is equivalent of:
|
||||
```php
|
||||
'fields' => [
|
||||
'id' => ['type' => Type::id()],
|
||||
'fieldName' => ['type' => $fieldName]
|
||||
]
|
||||
```
|
||||
which is in turn equivalent of the full form:
|
||||
```php
|
||||
'fields' => [
|
||||
['name' => 'id', 'type' => Type::id()],
|
||||
['name' => 'fieldName', 'type' => $fieldName]
|
||||
]
|
||||
```
|
||||
Same shorthand notation applies to field arguments as well.
|
||||
|
||||
# Recurring and circular types
|
||||
Almost all real-world applications contain recurring or circular types.
|
||||
Think user friends or nested comments for example.
|
||||
|
||||
**graphql-php** allows such types, but you have to use `callable` in
|
||||
option **fields** (and/or **interfaces**).
|
||||
|
||||
For example:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
$userType = null;
|
||||
|
||||
$userType = new ObjectType([
|
||||
'name' => 'User',
|
||||
'fields' => function() use (&$userType) {
|
||||
return [
|
||||
'email' => [
|
||||
'type' => Type::string()
|
||||
],
|
||||
'friends' => [
|
||||
'type' => Type::listOf($userType)
|
||||
]
|
||||
];
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
Same example for [inheritance style of type definitions](index.md#type-definition-styles) using [TypeRegistry](index.md#type-registry):
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
class UserType extends ObjectType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'fields' => function() {
|
||||
return [
|
||||
'email' => MyTypes::string(),
|
||||
'friends' => MyTypes::listOf(MyTypes::user())
|
||||
];
|
||||
}
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
|
||||
class MyTypes
|
||||
{
|
||||
private static $user;
|
||||
|
||||
public static function user()
|
||||
{
|
||||
return self::$user ?: (self::$user = new UserType());
|
||||
}
|
||||
|
||||
public static function string()
|
||||
{
|
||||
return Type::string();
|
||||
}
|
||||
|
||||
public static function listOf($type)
|
||||
{
|
||||
return Type::listOf($type);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Field Resolution
|
||||
Field resolution is the primary mechanism in **graphql-php** for returning actual data for your fields.
|
||||
It is implemented using **resolveField** callable in type definition or **resolve**
|
||||
callable in field definition (which has precedence).
|
||||
|
||||
Read the section on [Data Fetching](../data-fetching.md) for a complete description of this process.
|
||||
|
||||
# Custom Metadata
|
||||
All types in **graphql-php** accept configuration array. In some cases, you may be interested in
|
||||
passing your own metadata for type or field definition.
|
||||
|
||||
**graphql-php** preserves original configuration array in every type or field instance in
|
||||
public property **$config**. Use it to implement app-level mappings and definitions.
|
||||
130
vendor/webonyx/graphql-php/docs/type-system/scalar-types.md
vendored
Normal file
130
vendor/webonyx/graphql-php/docs/type-system/scalar-types.md
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
# Built-in Scalar Types
|
||||
GraphQL specification describes several built-in scalar types. In **graphql-php** they are
|
||||
exposed as static methods of [`GraphQL\Type\Definition\Type`](../reference.md#graphqltypedefinitiontype) class:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
// Built-in Scalar types:
|
||||
Type::string(); // String type
|
||||
Type::int(); // Int type
|
||||
Type::float(); // Float type
|
||||
Type::boolean(); // Boolean type
|
||||
Type::id(); // ID type
|
||||
```
|
||||
Those methods return instances of `GraphQL\Type\Definition\ScalarType` (actually one of subclasses).
|
||||
Use them directly in type definitions, or wrap in your [TypeRegistry](index.md#type-registry)
|
||||
(if you use one).
|
||||
|
||||
# Writing Custom Scalar Types
|
||||
In addition to built-in scalars, you can define your own scalar types with additional validation.
|
||||
Typical examples of such types are **Email**, **Date**, **Url**, etc.
|
||||
|
||||
In order to implement your own type, you must understand how scalars are presented in GraphQL.
|
||||
GraphQL deals with scalars in following cases:
|
||||
|
||||
1. When converting **internal representation** of value returned by your app (e.g. stored in a database
|
||||
or hardcoded in the source code) to **serialized** representation included in the response.
|
||||
|
||||
2. When converting **input value** passed by a client in variables along with GraphQL query to
|
||||
**internal representation** of your app.
|
||||
|
||||
3. When converting **input literal value** hardcoded in GraphQL query (e.g. field argument value) to
|
||||
the **internal representation** of your app.
|
||||
|
||||
Those cases are covered by methods `serialize`, `parseValue` and `parseLiteral` of abstract `ScalarType`
|
||||
class respectively.
|
||||
|
||||
Here is an example of a simple **Email** type:
|
||||
|
||||
```php
|
||||
<?php
|
||||
namespace MyApp;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Error\InvariantViolation;
|
||||
use GraphQL\Language\AST\StringValueNode;
|
||||
use GraphQL\Type\Definition\ScalarType;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class EmailType extends ScalarType
|
||||
{
|
||||
// Note: name can be omitted. In this case it will be inferred from class name
|
||||
// (suffix "Type" will be dropped)
|
||||
public $name = 'Email';
|
||||
|
||||
/**
|
||||
* Serializes an internal value to include in a response.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function serialize($value)
|
||||
{
|
||||
// Assuming internal representation of email is always correct:
|
||||
return $value;
|
||||
|
||||
// If it might be incorrect and you want to make sure that only correct values are included
|
||||
// in response - use following line instead:
|
||||
// if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
||||
// throw new InvariantViolation("Could not serialize following value as email: " . Utils::printSafe($value));
|
||||
// }
|
||||
// return $this->parseValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an externally provided value (query variable) to use as an input
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function parseValue($value)
|
||||
{
|
||||
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Error("Cannot represent following value as email: " . Utils::printSafeJson($value));
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input.
|
||||
*
|
||||
* E.g.
|
||||
* {
|
||||
* user(email: "user@example.com")
|
||||
* }
|
||||
*
|
||||
* @param \GraphQL\Language\AST\Node $valueNode
|
||||
* @param array|null $variables
|
||||
* @return string
|
||||
* @throws Error
|
||||
*/
|
||||
public function parseLiteral($valueNode, array $variables = null)
|
||||
{
|
||||
// Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
|
||||
// error location in query:
|
||||
if (!$valueNode instanceof StringValueNode) {
|
||||
throw new Error('Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode]);
|
||||
}
|
||||
if (!filter_var($valueNode->value, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Error("Not a valid email", [$valueNode]);
|
||||
}
|
||||
return $valueNode->value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or with inline style:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\CustomScalarType;
|
||||
|
||||
$emailType = new CustomScalarType([
|
||||
'name' => 'Email',
|
||||
'serialize' => function($value) {/* See function body above */},
|
||||
'parseValue' => function($value) {/* See function body above */},
|
||||
'parseLiteral' => function($valueNode, array $variables = null) {/* See function body above */},
|
||||
]);
|
||||
```
|
||||
194
vendor/webonyx/graphql-php/docs/type-system/schema.md
vendored
Normal file
194
vendor/webonyx/graphql-php/docs/type-system/schema.md
vendored
Normal file
@ -0,0 +1,194 @@
|
||||
# Schema Definition
|
||||
The schema is a container of your type hierarchy, which accepts root types in a constructor and provides
|
||||
methods for receiving information about your types to internal GrahpQL tools.
|
||||
|
||||
In **graphql-php** schema is an instance of [`GraphQL\Type\Schema`](../reference.md#graphqltypeschema)
|
||||
which accepts configuration array in a constructor:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Schema;
|
||||
|
||||
$schema = new Schema([
|
||||
'query' => $queryType,
|
||||
'mutation' => $mutationType,
|
||||
]);
|
||||
```
|
||||
See possible constructor options [below](#configuration-options).
|
||||
|
||||
# Query and Mutation types
|
||||
The schema consists of two root types:
|
||||
|
||||
* **Query** type is a surface of your read API
|
||||
* **Mutation** type (optional) exposes write API by declaring all possible mutations in your app.
|
||||
|
||||
Query and Mutation types are regular [object types](object-types.md) containing root-level fields
|
||||
of your API:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
$queryType = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'hello' => [
|
||||
'type' => Type::string(),
|
||||
'resolve' => function() {
|
||||
return 'Hello World!';
|
||||
}
|
||||
],
|
||||
'hero' => [
|
||||
'type' => $characterInterface,
|
||||
'args' => [
|
||||
'episode' => [
|
||||
'type' => $episodeEnum
|
||||
]
|
||||
],
|
||||
'resolve' => function ($rootValue, $args) {
|
||||
return StarWarsData::getHero(isset($args['episode']) ? $args['episode'] : null);
|
||||
},
|
||||
]
|
||||
]
|
||||
]);
|
||||
|
||||
$mutationType = new ObjectType([
|
||||
'name' => 'Mutation',
|
||||
'fields' => [
|
||||
'createReview' => [
|
||||
'type' => $createReviewOutput,
|
||||
'args' => [
|
||||
'episode' => $episodeEnum,
|
||||
'review' => $reviewInputObject
|
||||
],
|
||||
'resolve' => function($val, $args) {
|
||||
// TODOC
|
||||
}
|
||||
]
|
||||
]
|
||||
]);
|
||||
```
|
||||
|
||||
Keep in mind that other than the special meaning of declaring a surface area of your API,
|
||||
those types are the same as any other [object type](object-types.md), and their fields work
|
||||
exactly the same way.
|
||||
|
||||
**Mutation** type is also just a regular object type. The difference is in semantics.
|
||||
Field names of Mutation type are usually verbs and they almost always have arguments - quite often
|
||||
with complex input values (see [Mutations and Input Types](input-types.md) for details).
|
||||
|
||||
# Configuration Options
|
||||
Schema constructor expects an instance of [`GraphQL\Type\SchemaConfig`](../reference.md#graphqltypeschemaconfig)
|
||||
or an array with following options:
|
||||
|
||||
Option | Type | Notes
|
||||
------------ | -------- | -----
|
||||
query | `ObjectType` | **Required.** Object type (usually named "Query") containing root-level fields of your read API
|
||||
mutation | `ObjectType` | Object type (usually named "Mutation") containing root-level fields of your write API
|
||||
subscription | `ObjectType` | Reserved for future subscriptions implementation. Currently presented for compatibility with introspection query of **graphql-js**, used by various clients (like Relay or GraphiQL)
|
||||
directives | `Directive[]` | A full list of [directives](directives.md) supported by your schema. By default, contains built-in **@skip** and **@include** directives.<br><br> If you pass your own directives and still want to use built-in directives - add them explicitly. For example:<br><br> *array_merge(GraphQL::getStandardDirectives(), [$myCustomDirective]);*
|
||||
types | `ObjectType[]` | List of object types which cannot be detected by **graphql-php** during static schema analysis.<br><br>Most often it happens when the object type is never referenced in fields directly but is still a part of a schema because it implements an interface which resolves to this object type in its **resolveType** callable. <br><br> Note that you are not required to pass all of your types here - it is simply a workaround for concrete use-case.
|
||||
typeLoader | `callable` | **function($name)** Expected to return type instance given the name. Must always return the same instance if called multiple times. See section below on lazy type loading.
|
||||
|
||||
# Using config class
|
||||
If you prefer fluid interface for config with auto-completion in IDE and static time validation,
|
||||
use [`GraphQL\Type\SchemaConfig`](../reference.md#graphqltypeschemaconfig) instead of an array:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\SchemaConfig;
|
||||
use GraphQL\Type\Schema;
|
||||
|
||||
$config = SchemaConfig::create()
|
||||
->setQuery($myQueryType)
|
||||
->setTypeLoader($myTypeLoader);
|
||||
|
||||
$schema = new Schema($config);
|
||||
```
|
||||
|
||||
|
||||
# Lazy loading of types
|
||||
By default, the schema will scan all of your type, field and argument definitions to serve GraphQL queries.
|
||||
It may cause performance overhead when there are many types in the schema.
|
||||
|
||||
In this case, it is recommended to pass **typeLoader** option to schema constructor and define all
|
||||
of your object **fields** as callbacks.
|
||||
|
||||
Type loading concept is very similar to PHP class loading, but keep in mind that **typeLoader** must
|
||||
always return the same instance of a type.
|
||||
|
||||
Usage example:
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Schema;
|
||||
|
||||
class Types
|
||||
{
|
||||
private $types = [];
|
||||
|
||||
public function get($name)
|
||||
{
|
||||
if (!isset($this->types[$name])) {
|
||||
$this->types[$name] = $this->{$name}();
|
||||
}
|
||||
return $this->types[$name];
|
||||
}
|
||||
|
||||
private function MyTypeA()
|
||||
{
|
||||
return new ObjectType([
|
||||
'name' => 'MyTypeA',
|
||||
'fields' => function() {
|
||||
return [
|
||||
'b' => ['type' => $this->get('MyTypeB')]
|
||||
];
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
private function MyTypeB()
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
$registry = new Types();
|
||||
|
||||
$schema = new Schema([
|
||||
'query' => $registry->get('Query'),
|
||||
'typeLoader' => function($name) use ($registry) {
|
||||
return $registry->get($name);
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
|
||||
# Schema Validation
|
||||
By default, the schema is created with only shallow validation of type and field definitions
|
||||
(because validation requires full schema scan and is very costly on bigger schemas).
|
||||
|
||||
But there is a special method **assertValid()** on schema instance which throws
|
||||
`GraphQL\Error\InvariantViolation` exception when it encounters any error, like:
|
||||
|
||||
- Invalid types used for fields/arguments
|
||||
- Missing interface implementations
|
||||
- Invalid interface implementations
|
||||
- Other schema errors...
|
||||
|
||||
Schema validation is supposed to be used in CLI commands or during build step of your app.
|
||||
Don't call it in web requests in production.
|
||||
|
||||
Usage example:
|
||||
```php
|
||||
<?php
|
||||
try {
|
||||
$schema = new GraphQL\Type\Schema([
|
||||
'query' => $myQueryType
|
||||
]);
|
||||
$schema->assertValid();
|
||||
} catch (GraphQL\Error\InvariantViolation $e) {
|
||||
echo $e->getMessage();
|
||||
}
|
||||
```
|
||||
91
vendor/webonyx/graphql-php/docs/type-system/type-language.md
vendored
Normal file
91
vendor/webonyx/graphql-php/docs/type-system/type-language.md
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
# Defining your schema
|
||||
Since 0.9.0
|
||||
|
||||
[Type language](http://graphql.org/learn/schema/#type-language) is a convenient way to define your schema,
|
||||
especially with IDE autocompletion and syntax validation.
|
||||
|
||||
Here is a simple schema defined in GraphQL type language (e.g. in a separate **schema.graphql** file):
|
||||
|
||||
```graphql
|
||||
schema {
|
||||
query: Query
|
||||
mutation: Mutation
|
||||
}
|
||||
|
||||
type Query {
|
||||
greetings(input: HelloInput!): String!
|
||||
}
|
||||
|
||||
input HelloInput {
|
||||
firstName: String!
|
||||
lastName: String
|
||||
}
|
||||
```
|
||||
|
||||
In order to create schema instance out of this file, use
|
||||
[`GraphQL\Utils\BuildSchema`](../reference.md#graphqlutilsbuildschema):
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Utils\BuildSchema;
|
||||
|
||||
$contents = file_get_contents('schema.graphql');
|
||||
$schema = BuildSchema::build($contents);
|
||||
```
|
||||
|
||||
By default, such schema is created without any resolvers.
|
||||
|
||||
We have to rely on [default field resolver](../data-fetching.md#default-field-resolver) and **root value** in
|
||||
order to execute a query against this schema.
|
||||
|
||||
# Defining resolvers
|
||||
Since 0.10.0
|
||||
|
||||
In order to enable **Interfaces**, **Unions** and custom field resolvers you can pass the second argument:
|
||||
**type config decorator** to schema builder.
|
||||
|
||||
It accepts default type config produced by the builder and is expected to add missing options like
|
||||
[**resolveType**](interfaces.md#configuration-options) for interface types or
|
||||
[**resolveField**](object-types.md#configuration-options) for object types.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Utils\BuildSchema;
|
||||
|
||||
$typeConfigDecorator = function($typeConfig, $typeDefinitionNode) {
|
||||
$name = $typeConfig['name'];
|
||||
// ... add missing options to $typeConfig based on type $name
|
||||
return $typeConfig;
|
||||
};
|
||||
|
||||
$contents = file_get_contents('schema.graphql');
|
||||
$schema = BuildSchema::build($contents, $typeConfigDecorator);
|
||||
```
|
||||
|
||||
# Performance considerations
|
||||
Since 0.10.0
|
||||
|
||||
Method **build()** produces a [lazy schema](schema.md#lazy-loading-of-types)
|
||||
automatically, so it works efficiently even with very large schemas.
|
||||
|
||||
But parsing type definition file on each request is suboptimal, so it is recommended to cache
|
||||
intermediate parsed representation of the schema for the production environment:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Utils\BuildSchema;
|
||||
use GraphQL\Utils\AST;
|
||||
|
||||
$cacheFilename = 'cached_schema.php';
|
||||
|
||||
if (!file_exists($cacheFilename)) {
|
||||
$document = Parser::parse(file_get_contents('./schema.graphql'));
|
||||
file_put_contents($cacheFilename, "<?php\nreturn " . var_export(AST::toArray($document), true) . ";\n");
|
||||
} else {
|
||||
$document = AST::fromArray(require $cacheFilename); // fromArray() is a lazy operation as well
|
||||
}
|
||||
|
||||
$typeConfigDecorator = function () {};
|
||||
$schema = BuildSchema::build($document, $typeConfigDecorator);
|
||||
```
|
||||
39
vendor/webonyx/graphql-php/docs/type-system/unions.md
vendored
Normal file
39
vendor/webonyx/graphql-php/docs/type-system/unions.md
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Union Type Definition
|
||||
A Union is an abstract type that simply enumerates other Object Types.
|
||||
The value of Union Type is actually a value of one of included Object Types.
|
||||
|
||||
In **graphql-php** union type is an instance of `GraphQL\Type\Definition\UnionType`
|
||||
(or one of its subclasses) which accepts configuration array in a constructor:
|
||||
|
||||
```php
|
||||
<?php
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
|
||||
$searchResultType = new UnionType([
|
||||
'name' => 'SearchResult',
|
||||
'types' => [
|
||||
MyTypes::story(),
|
||||
MyTypes::user()
|
||||
],
|
||||
'resolveType' => function($value) {
|
||||
if ($value->type === 'story') {
|
||||
return MyTypes::story();
|
||||
} else {
|
||||
return MyTypes::user();
|
||||
}
|
||||
}
|
||||
]);
|
||||
```
|
||||
|
||||
This example uses **inline** style for Union definition, but you can also use
|
||||
[inheritance or type language](index.md#type-definition-styles).
|
||||
|
||||
# Configuration options
|
||||
The constructor of UnionType accepts an array. Below is a full list of allowed options:
|
||||
|
||||
Option | Type | Notes
|
||||
------ | ---- | -----
|
||||
name | `string` | **Required.** Unique name of this interface type within Schema
|
||||
types | `array` | **Required.** List of Object Types included in this Union. Note that you can't create a Union type out of Interfaces or other Unions.
|
||||
description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation)
|
||||
resolveType | `callback` | **function($value, $context, [ResolveInfo](../reference.md#graphqltypedefinitionresolveinfo) $info)**<br> Receives **$value** from resolver of the parent field and returns concrete Object Type for this **$value**.
|
||||
18
vendor/webonyx/graphql-php/examples/00-hello-world/README.md
vendored
Normal file
18
vendor/webonyx/graphql-php/examples/00-hello-world/README.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Hello world
|
||||
Clean and simple single-file example of main GraphQL concepts originally proposed and
|
||||
implemented by [Leo Cavalcante](https://github.com/leocavalcante)
|
||||
|
||||
### Run locally
|
||||
```
|
||||
php -S localhost:8080 ./graphql.php
|
||||
```
|
||||
|
||||
### Try query
|
||||
```
|
||||
curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
```
|
||||
|
||||
### Try mutation
|
||||
```
|
||||
curl http://localhost:8080 -d '{"query": "mutation { sum(x: 2, y: 2) }" }'
|
||||
```
|
||||
69
vendor/webonyx/graphql-php/examples/00-hello-world/graphql.php
vendored
Normal file
69
vendor/webonyx/graphql-php/examples/00-hello-world/graphql.php
vendored
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
// Test this using following command
|
||||
// php -S localhost:8080 ./graphql.php &
|
||||
// curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
// curl http://localhost:8080 -d '{"query": "mutation { sum(x: 2, y: 2) }" }'
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\GraphQL;
|
||||
|
||||
try {
|
||||
$queryType = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'echo' => [
|
||||
'type' => Type::string(),
|
||||
'args' => [
|
||||
'message' => ['type' => Type::string()],
|
||||
],
|
||||
'resolve' => function ($root, $args) {
|
||||
return $root['prefix'] . $args['message'];
|
||||
}
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$mutationType = new ObjectType([
|
||||
'name' => 'Calc',
|
||||
'fields' => [
|
||||
'sum' => [
|
||||
'type' => Type::int(),
|
||||
'args' => [
|
||||
'x' => ['type' => Type::int()],
|
||||
'y' => ['type' => Type::int()],
|
||||
],
|
||||
'resolve' => function ($root, $args) {
|
||||
return $args['x'] + $args['y'];
|
||||
},
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// See docs on schema options:
|
||||
// http://webonyx.github.io/graphql-php/type-system/schema/#configuration-options
|
||||
$schema = new Schema([
|
||||
'query' => $queryType,
|
||||
'mutation' => $mutationType,
|
||||
]);
|
||||
|
||||
$rawInput = file_get_contents('php://input');
|
||||
$input = json_decode($rawInput, true);
|
||||
$query = $input['query'];
|
||||
$variableValues = isset($input['variables']) ? $input['variables'] : null;
|
||||
|
||||
$rootValue = ['prefix' => 'You said: '];
|
||||
$result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
|
||||
$output = $result->toArray();
|
||||
} catch (\Exception $e) {
|
||||
$output = [
|
||||
'error' => [
|
||||
'message' => $e->getMessage()
|
||||
]
|
||||
];
|
||||
}
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
echo json_encode($output);
|
||||
|
||||
28
vendor/webonyx/graphql-php/examples/01-blog/Blog/AppContext.php
vendored
Normal file
28
vendor/webonyx/graphql-php/examples/01-blog/Blog/AppContext.php
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog;
|
||||
|
||||
use GraphQL\Examples\Blog\Data\User;
|
||||
|
||||
/**
|
||||
* Class AppContext
|
||||
* Instance available in all GraphQL resolvers as 3rd argument
|
||||
*
|
||||
* @package GraphQL\Examples\Blog
|
||||
*/
|
||||
class AppContext
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $rootUrl;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
public $viewer;
|
||||
|
||||
/**
|
||||
* @var \mixed
|
||||
*/
|
||||
public $request;
|
||||
}
|
||||
25
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/Comment.php
vendored
Normal file
25
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/Comment.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Data;
|
||||
|
||||
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class Comment
|
||||
{
|
||||
public $id;
|
||||
|
||||
public $authorId;
|
||||
|
||||
public $storyId;
|
||||
|
||||
public $parentId;
|
||||
|
||||
public $body;
|
||||
|
||||
public $isAnonymous;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
Utils::assign($this, $data);
|
||||
}
|
||||
}
|
||||
206
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/DataSource.php
vendored
Normal file
206
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/DataSource.php
vendored
Normal file
@ -0,0 +1,206 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Data;
|
||||
|
||||
/**
|
||||
* Class DataSource
|
||||
*
|
||||
* This is just a simple in-memory data holder for the sake of example.
|
||||
* Data layer for real app may use Doctrine or query the database directly (e.g. in CQRS style)
|
||||
*
|
||||
* @package GraphQL\Examples\Blog
|
||||
*/
|
||||
class DataSource
|
||||
{
|
||||
private static $users = [];
|
||||
private static $stories = [];
|
||||
private static $storyLikes = [];
|
||||
private static $comments = [];
|
||||
private static $storyComments = [];
|
||||
private static $commentReplies = [];
|
||||
private static $storyMentions = [];
|
||||
|
||||
public static function init()
|
||||
{
|
||||
self::$users = [
|
||||
'1' => new User([
|
||||
'id' => '1',
|
||||
'email' => 'john@example.com',
|
||||
'firstName' => 'John',
|
||||
'lastName' => 'Doe'
|
||||
]),
|
||||
'2' => new User([
|
||||
'id' => '2',
|
||||
'email' => 'jane@example.com',
|
||||
'firstName' => 'Jane',
|
||||
'lastName' => 'Doe'
|
||||
]),
|
||||
'3' => new User([
|
||||
'id' => '3',
|
||||
'email' => 'john@example.com',
|
||||
'firstName' => 'John',
|
||||
'lastName' => 'Doe'
|
||||
]),
|
||||
];
|
||||
|
||||
self::$stories = [
|
||||
'1' => new Story(['id' => '1', 'authorId' => '1', 'body' => '<h1>GraphQL is awesome!</h1>']),
|
||||
'2' => new Story(['id' => '2', 'authorId' => '1', 'body' => '<a>Test this</a>']),
|
||||
'3' => new Story(['id' => '3', 'authorId' => '3', 'body' => "This\n<br>story\n<br>spans\n<br>newlines"]),
|
||||
];
|
||||
|
||||
self::$storyLikes = [
|
||||
'1' => ['1', '2', '3'],
|
||||
'2' => [],
|
||||
'3' => ['1']
|
||||
];
|
||||
|
||||
self::$comments = [
|
||||
// thread #1:
|
||||
'100' => new Comment(['id' => '100', 'authorId' => '3', 'storyId' => '1', 'body' => 'Likes']),
|
||||
'110' => new Comment(['id' =>'110', 'authorId' =>'2', 'storyId' => '1', 'body' => 'Reply <b>#1</b>', 'parentId' => '100']),
|
||||
'111' => new Comment(['id' => '111', 'authorId' => '1', 'storyId' => '1', 'body' => 'Reply #1-1', 'parentId' => '110']),
|
||||
'112' => new Comment(['id' => '112', 'authorId' => '3', 'storyId' => '1', 'body' => 'Reply #1-2', 'parentId' => '110']),
|
||||
'113' => new Comment(['id' => '113', 'authorId' => '2', 'storyId' => '1', 'body' => 'Reply #1-3', 'parentId' => '110']),
|
||||
'114' => new Comment(['id' => '114', 'authorId' => '1', 'storyId' => '1', 'body' => 'Reply #1-4', 'parentId' => '110']),
|
||||
'115' => new Comment(['id' => '115', 'authorId' => '3', 'storyId' => '1', 'body' => 'Reply #1-5', 'parentId' => '110']),
|
||||
'116' => new Comment(['id' => '116', 'authorId' => '1', 'storyId' => '1', 'body' => 'Reply #1-6', 'parentId' => '110']),
|
||||
'117' => new Comment(['id' => '117', 'authorId' => '2', 'storyId' => '1', 'body' => 'Reply #1-7', 'parentId' => '110']),
|
||||
'120' => new Comment(['id' => '120', 'authorId' => '3', 'storyId' => '1', 'body' => 'Reply #2', 'parentId' => '100']),
|
||||
'130' => new Comment(['id' => '130', 'authorId' => '3', 'storyId' => '1', 'body' => 'Reply #3', 'parentId' => '100']),
|
||||
'200' => new Comment(['id' => '200', 'authorId' => '2', 'storyId' => '1', 'body' => 'Me2']),
|
||||
'300' => new Comment(['id' => '300', 'authorId' => '3', 'storyId' => '1', 'body' => 'U2']),
|
||||
|
||||
# thread #2:
|
||||
'400' => new Comment(['id' => '400', 'authorId' => '2', 'storyId' => '2', 'body' => 'Me too']),
|
||||
'500' => new Comment(['id' => '500', 'authorId' => '2', 'storyId' => '2', 'body' => 'Nice!']),
|
||||
];
|
||||
|
||||
self::$storyComments = [
|
||||
'1' => ['100', '200', '300'],
|
||||
'2' => ['400', '500']
|
||||
];
|
||||
|
||||
self::$commentReplies = [
|
||||
'100' => ['110', '120', '130'],
|
||||
'110' => ['111', '112', '113', '114', '115', '116', '117'],
|
||||
];
|
||||
|
||||
self::$storyMentions = [
|
||||
'1' => [
|
||||
self::$users['2']
|
||||
],
|
||||
'2' => [
|
||||
self::$stories['1'],
|
||||
self::$users['3']
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
public static function findUser($id)
|
||||
{
|
||||
return isset(self::$users[$id]) ? self::$users[$id] : null;
|
||||
}
|
||||
|
||||
public static function findStory($id)
|
||||
{
|
||||
return isset(self::$stories[$id]) ? self::$stories[$id] : null;
|
||||
}
|
||||
|
||||
public static function findComment($id)
|
||||
{
|
||||
return isset(self::$comments[$id]) ? self::$comments[$id] : null;
|
||||
}
|
||||
|
||||
public static function findLastStoryFor($authorId)
|
||||
{
|
||||
$storiesFound = array_filter(self::$stories, function(Story $story) use ($authorId) {
|
||||
return $story->authorId == $authorId;
|
||||
});
|
||||
return !empty($storiesFound) ? $storiesFound[count($storiesFound) - 1] : null;
|
||||
}
|
||||
|
||||
public static function findLikes($storyId, $limit)
|
||||
{
|
||||
$likes = isset(self::$storyLikes[$storyId]) ? self::$storyLikes[$storyId] : [];
|
||||
$result = array_map(
|
||||
function($userId) {
|
||||
return self::$users[$userId];
|
||||
},
|
||||
$likes
|
||||
);
|
||||
return array_slice($result, 0, $limit);
|
||||
}
|
||||
|
||||
public static function isLikedBy($storyId, $userId)
|
||||
{
|
||||
$subscribers = isset(self::$storyLikes[$storyId]) ? self::$storyLikes[$storyId] : [];
|
||||
return in_array($userId, $subscribers);
|
||||
}
|
||||
|
||||
public static function getUserPhoto($userId, $size)
|
||||
{
|
||||
return new Image([
|
||||
'id' => $userId,
|
||||
'type' => Image::TYPE_USERPIC,
|
||||
'size' => $size,
|
||||
'width' => rand(100, 200),
|
||||
'height' => rand(100, 200)
|
||||
]);
|
||||
}
|
||||
|
||||
public static function findLatestStory()
|
||||
{
|
||||
return array_pop(self::$stories);
|
||||
}
|
||||
|
||||
public static function findStories($limit, $afterId = null)
|
||||
{
|
||||
$start = $afterId ? (int) array_search($afterId, array_keys(self::$stories)) + 1 : 0;
|
||||
return array_slice(array_values(self::$stories), $start, $limit);
|
||||
}
|
||||
|
||||
public static function findComments($storyId, $limit = 5, $afterId = null)
|
||||
{
|
||||
$storyComments = isset(self::$storyComments[$storyId]) ? self::$storyComments[$storyId] : [];
|
||||
|
||||
$start = isset($after) ? (int) array_search($afterId, $storyComments) + 1 : 0;
|
||||
$storyComments = array_slice($storyComments, $start, $limit);
|
||||
|
||||
return array_map(
|
||||
function($commentId) {
|
||||
return self::$comments[$commentId];
|
||||
},
|
||||
$storyComments
|
||||
);
|
||||
}
|
||||
|
||||
public static function findReplies($commentId, $limit = 5, $afterId = null)
|
||||
{
|
||||
$commentReplies = isset(self::$commentReplies[$commentId]) ? self::$commentReplies[$commentId] : [];
|
||||
|
||||
$start = isset($after) ? (int) array_search($afterId, $commentReplies) + 1: 0;
|
||||
$commentReplies = array_slice($commentReplies, $start, $limit);
|
||||
|
||||
return array_map(
|
||||
function($replyId) {
|
||||
return self::$comments[$replyId];
|
||||
},
|
||||
$commentReplies
|
||||
);
|
||||
}
|
||||
|
||||
public static function countComments($storyId)
|
||||
{
|
||||
return isset(self::$storyComments[$storyId]) ? count(self::$storyComments[$storyId]) : 0;
|
||||
}
|
||||
|
||||
public static function countReplies($commentId)
|
||||
{
|
||||
return isset(self::$commentReplies[$commentId]) ? count(self::$commentReplies[$commentId]) : 0;
|
||||
}
|
||||
|
||||
public static function findStoryMentions($storyId)
|
||||
{
|
||||
return isset(self::$storyMentions[$storyId]) ? self::$storyMentions[$storyId] :[];
|
||||
}
|
||||
}
|
||||
29
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/Image.php
vendored
Normal file
29
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/Image.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Data;
|
||||
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class Image
|
||||
{
|
||||
const TYPE_USERPIC = 'userpic';
|
||||
|
||||
const SIZE_ICON = 'icon';
|
||||
const SIZE_SMALL = 'small';
|
||||
const SIZE_MEDIUM = 'medium';
|
||||
const SIZE_ORIGINAL = 'original';
|
||||
|
||||
public $id;
|
||||
|
||||
public $type;
|
||||
|
||||
public $size;
|
||||
|
||||
public $width;
|
||||
|
||||
public $height;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
Utils::assign($this, $data);
|
||||
}
|
||||
}
|
||||
22
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/Story.php
vendored
Normal file
22
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/Story.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Data;
|
||||
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class Story
|
||||
{
|
||||
public $id;
|
||||
|
||||
public $authorId;
|
||||
|
||||
public $title;
|
||||
|
||||
public $body;
|
||||
|
||||
public $isAnonymous = false;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
Utils::assign($this, $data);
|
||||
}
|
||||
}
|
||||
22
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/User.php
vendored
Normal file
22
vendor/webonyx/graphql-php/examples/01-blog/Blog/Data/User.php
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Data;
|
||||
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class User
|
||||
{
|
||||
public $id;
|
||||
|
||||
public $email;
|
||||
|
||||
public $firstName;
|
||||
|
||||
public $lastName;
|
||||
|
||||
public $hasPhoto;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
Utils::assign($this, $data);
|
||||
}
|
||||
}
|
||||
76
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/CommentType.php
vendored
Normal file
76
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/CommentType.php
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\AppContext;
|
||||
use GraphQL\Examples\Blog\Data\Comment;
|
||||
use GraphQL\Examples\Blog\Data\DataSource;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
|
||||
class CommentType extends ObjectType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'Comment',
|
||||
'fields' => function() {
|
||||
return [
|
||||
'id' => Types::id(),
|
||||
'author' => Types::user(),
|
||||
'parent' => Types::comment(),
|
||||
'isAnonymous' => Types::boolean(),
|
||||
'replies' => [
|
||||
'type' => Types::listOf(Types::comment()),
|
||||
'args' => [
|
||||
'after' => Types::int(),
|
||||
'limit' => [
|
||||
'type' => Types::int(),
|
||||
'defaultValue' => 5
|
||||
]
|
||||
]
|
||||
],
|
||||
'totalReplyCount' => Types::int(),
|
||||
|
||||
Types::htmlField('body')
|
||||
];
|
||||
},
|
||||
'resolveField' => function($value, $args, $context, ResolveInfo $info) {
|
||||
$method = 'resolve' . ucfirst($info->fieldName);
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}($value, $args, $context, $info);
|
||||
} else {
|
||||
return $value->{$info->fieldName};
|
||||
}
|
||||
}
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function resolveAuthor(Comment $comment)
|
||||
{
|
||||
if ($comment->isAnonymous) {
|
||||
return null;
|
||||
}
|
||||
return DataSource::findUser($comment->authorId);
|
||||
}
|
||||
|
||||
public function resolveParent(Comment $comment)
|
||||
{
|
||||
if ($comment->parentId) {
|
||||
return DataSource::findComment($comment->parentId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function resolveReplies(Comment $comment, $args)
|
||||
{
|
||||
$args += ['after' => null];
|
||||
return DataSource::findReplies($comment->id, $args['limit'], $args['after']);
|
||||
}
|
||||
|
||||
public function resolveTotalReplyCount(Comment $comment)
|
||||
{
|
||||
return DataSource::countReplies($comment->id);
|
||||
}
|
||||
}
|
||||
19
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Enum/ContentFormatEnum.php
vendored
Normal file
19
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Enum/ContentFormatEnum.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type\Enum;
|
||||
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
|
||||
class ContentFormatEnum extends EnumType
|
||||
{
|
||||
const FORMAT_TEXT = 'TEXT';
|
||||
const FORMAT_HTML = 'HTML';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'ContentFormatEnum',
|
||||
'values' => [self::FORMAT_TEXT, self::FORMAT_HTML]
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
23
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Enum/ImageSizeEnumType.php
vendored
Normal file
23
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Enum/ImageSizeEnumType.php
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type\Enum;
|
||||
|
||||
use GraphQL\Examples\Blog\Data\Image;
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
|
||||
class ImageSizeEnumType extends EnumType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
// Note: 'name' option is not needed in this form - it will be inferred from className
|
||||
'values' => [
|
||||
'ICON' => Image::SIZE_ICON,
|
||||
'SMALL' => Image::SIZE_SMALL,
|
||||
'MEDIUM' => Image::SIZE_MEDIUM,
|
||||
'ORIGINAL' => Image::SIZE_ORIGINAL
|
||||
]
|
||||
];
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
52
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Field/HtmlField.php
vendored
Normal file
52
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Field/HtmlField.php
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type\Field;
|
||||
|
||||
use GraphQL\Examples\Blog\Type\Enum\ContentFormatEnum;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
|
||||
class HtmlField
|
||||
{
|
||||
public static function build($name, $objectKey = null)
|
||||
{
|
||||
$objectKey = $objectKey ?: $name;
|
||||
|
||||
// Demonstrates how to organize re-usable fields
|
||||
// Usual example: when the same field with same args shows up in different types
|
||||
// (for example when it is a part of some interface)
|
||||
return [
|
||||
'name' => $name,
|
||||
'type' => Types::string(),
|
||||
'args' => [
|
||||
'format' => [
|
||||
'type' => Types::contentFormatEnum(),
|
||||
'defaultValue' => ContentFormatEnum::FORMAT_HTML
|
||||
],
|
||||
'maxLength' => Types::int()
|
||||
],
|
||||
'resolve' => function($object, $args) use ($objectKey) {
|
||||
$html = $object->{$objectKey};
|
||||
$text = strip_tags($html);
|
||||
|
||||
if (!empty($args['maxLength'])) {
|
||||
$safeText = mb_substr($text, 0, $args['maxLength']);
|
||||
} else {
|
||||
$safeText = $text;
|
||||
}
|
||||
|
||||
switch ($args['format']) {
|
||||
case ContentFormatEnum::FORMAT_HTML:
|
||||
if ($safeText !== $text) {
|
||||
// Text was truncated, so just show what's safe:
|
||||
return nl2br($safeText);
|
||||
} else {
|
||||
return $html;
|
||||
}
|
||||
|
||||
case ContentFormatEnum::FORMAT_TEXT:
|
||||
default:
|
||||
return $safeText;
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
62
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/ImageType.php
vendored
Normal file
62
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/ImageType.php
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\AppContext;
|
||||
use GraphQL\Examples\Blog\Data\Image;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
|
||||
class ImageType extends ObjectType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'ImageType',
|
||||
'fields' => [
|
||||
'id' => Types::id(),
|
||||
'type' => new EnumType([
|
||||
'name' => 'ImageTypeEnum',
|
||||
'values' => [
|
||||
'USERPIC' => Image::TYPE_USERPIC
|
||||
]
|
||||
]),
|
||||
'size' => Types::imageSizeEnum(),
|
||||
'width' => Types::int(),
|
||||
'height' => Types::int(),
|
||||
'url' => [
|
||||
'type' => Types::url(),
|
||||
'resolve' => [$this, 'resolveUrl']
|
||||
],
|
||||
|
||||
// Just for the sake of example
|
||||
'fieldWithError' => [
|
||||
'type' => Types::string(),
|
||||
'resolve' => function() {
|
||||
throw new \Exception("Field with exception");
|
||||
}
|
||||
],
|
||||
'nonNullFieldWithError' => [
|
||||
'type' => Types::nonNull(Types::string()),
|
||||
'resolve' => function() {
|
||||
throw new \Exception("Non-null field with exception");
|
||||
}
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function resolveUrl(Image $value, $args, AppContext $context)
|
||||
{
|
||||
switch ($value->type) {
|
||||
case Image::TYPE_USERPIC:
|
||||
$path = "/images/user/{$value->id}-{$value->size}.jpg";
|
||||
break;
|
||||
default:
|
||||
throw new \UnexpectedValueException("Unexpected image type: " . $value->type);
|
||||
}
|
||||
return $context->rootUrl . $path;
|
||||
}
|
||||
}
|
||||
34
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/NodeType.php
vendored
Normal file
34
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/NodeType.php
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\Data\Story;
|
||||
use GraphQL\Examples\Blog\Data\User;
|
||||
use GraphQL\Examples\Blog\Data\Image;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\InterfaceType;
|
||||
|
||||
class NodeType extends InterfaceType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'Node',
|
||||
'fields' => [
|
||||
'id' => Types::id()
|
||||
],
|
||||
'resolveType' => [$this, 'resolveNodeType']
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function resolveNodeType($object)
|
||||
{
|
||||
if ($object instanceof User) {
|
||||
return Types::user();
|
||||
} else if ($object instanceof Image) {
|
||||
return Types::image();
|
||||
} else if ($object instanceof Story) {
|
||||
return Types::story();
|
||||
}
|
||||
}
|
||||
}
|
||||
97
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/QueryType.php
vendored
Normal file
97
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/QueryType.php
vendored
Normal file
@ -0,0 +1,97 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\AppContext;
|
||||
use GraphQL\Examples\Blog\Data\DataSource;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
class QueryType extends ObjectType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'user' => [
|
||||
'type' => Types::user(),
|
||||
'description' => 'Returns user by id (in range of 1-5)',
|
||||
'args' => [
|
||||
'id' => Types::nonNull(Types::id())
|
||||
]
|
||||
],
|
||||
'viewer' => [
|
||||
'type' => Types::user(),
|
||||
'description' => 'Represents currently logged-in user (for the sake of example - simply returns user with id == 1)'
|
||||
],
|
||||
'stories' => [
|
||||
'type' => Types::listOf(Types::story()),
|
||||
'description' => 'Returns subset of stories posted for this blog',
|
||||
'args' => [
|
||||
'after' => [
|
||||
'type' => Types::id(),
|
||||
'description' => 'Fetch stories listed after the story with this ID'
|
||||
],
|
||||
'limit' => [
|
||||
'type' => Types::int(),
|
||||
'description' => 'Number of stories to be returned',
|
||||
'defaultValue' => 10
|
||||
]
|
||||
]
|
||||
],
|
||||
'lastStoryPosted' => [
|
||||
'type' => Types::story(),
|
||||
'description' => 'Returns last story posted for this blog'
|
||||
],
|
||||
'deprecatedField' => [
|
||||
'type' => Types::string(),
|
||||
'deprecationReason' => 'This field is deprecated!'
|
||||
],
|
||||
'fieldWithException' => [
|
||||
'type' => Types::string(),
|
||||
'resolve' => function() {
|
||||
throw new \Exception("Exception message thrown in field resolver");
|
||||
}
|
||||
],
|
||||
'hello' => Type::string()
|
||||
],
|
||||
'resolveField' => function($val, $args, $context, ResolveInfo $info) {
|
||||
return $this->{$info->fieldName}($val, $args, $context, $info);
|
||||
}
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function user($rootValue, $args)
|
||||
{
|
||||
return DataSource::findUser($args['id']);
|
||||
}
|
||||
|
||||
public function viewer($rootValue, $args, AppContext $context)
|
||||
{
|
||||
return $context->viewer;
|
||||
}
|
||||
|
||||
public function stories($rootValue, $args)
|
||||
{
|
||||
$args += ['after' => null];
|
||||
return DataSource::findStories($args['limit'], $args['after']);
|
||||
}
|
||||
|
||||
public function lastStoryPosted()
|
||||
{
|
||||
return DataSource::findLatestStory();
|
||||
}
|
||||
|
||||
public function hello()
|
||||
{
|
||||
return 'Your graphql-php endpoint is ready! Use GraphiQL to browse API';
|
||||
}
|
||||
|
||||
public function deprecatedField()
|
||||
{
|
||||
return 'You can request deprecated field, but it is not displayed in auto-generated documentation by default.';
|
||||
}
|
||||
}
|
||||
70
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Scalar/EmailType.php
vendored
Normal file
70
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Scalar/EmailType.php
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type\Scalar;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Language\AST\StringValueNode;
|
||||
use GraphQL\Type\Definition\CustomScalarType;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class EmailType
|
||||
{
|
||||
public static function create()
|
||||
{
|
||||
return new CustomScalarType([
|
||||
'name' => 'Email',
|
||||
'serialize' => [__CLASS__, 'serialize'],
|
||||
'parseValue' => [__CLASS__, 'parseValue'],
|
||||
'parseLiteral' => [__CLASS__, 'parseLiteral'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an internal value to include in a response.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function serialize($value)
|
||||
{
|
||||
// Assuming internal representation of email is always correct:
|
||||
return $value;
|
||||
|
||||
// If it might be incorrect and you want to make sure that only correct values are included in response -
|
||||
// use following line instead:
|
||||
// return $this->parseValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an externally provided value (query variable) to use as an input
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function parseValue($value)
|
||||
{
|
||||
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new \UnexpectedValueException("Cannot represent value as email: " . Utils::printSafe($value));
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an externally provided literal value (hardcoded in GraphQL query) to use as an input
|
||||
*
|
||||
* @param \GraphQL\Language\AST\Node $valueNode
|
||||
* @return string
|
||||
* @throws Error
|
||||
*/
|
||||
public static function parseLiteral($valueNode)
|
||||
{
|
||||
// Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
|
||||
// error location in query:
|
||||
if (!$valueNode instanceof StringValueNode) {
|
||||
throw new Error('Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode]);
|
||||
}
|
||||
if (!filter_var($valueNode->value, FILTER_VALIDATE_EMAIL)) {
|
||||
throw new Error("Not a valid email", [$valueNode]);
|
||||
}
|
||||
return $valueNode->value;
|
||||
}
|
||||
}
|
||||
63
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Scalar/UrlType.php
vendored
Normal file
63
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/Scalar/UrlType.php
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type\Scalar;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Language\AST\Node;
|
||||
use GraphQL\Language\AST\StringValueNode;
|
||||
use GraphQL\Type\Definition\ScalarType;
|
||||
use GraphQL\Utils\Utils;
|
||||
|
||||
class UrlType extends ScalarType
|
||||
{
|
||||
/**
|
||||
* Serializes an internal value to include in a response.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function serialize($value)
|
||||
{
|
||||
// Assuming internal representation of url is always correct:
|
||||
return $value;
|
||||
|
||||
// If it might be incorrect and you want to make sure that only correct values are included in response -
|
||||
// use following line instead:
|
||||
// return $this->parseValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an externally provided value (query variable) to use as an input
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
* @throws Error
|
||||
*/
|
||||
public function parseValue($value)
|
||||
{
|
||||
if (!is_string($value) || !filter_var($value, FILTER_VALIDATE_URL)) { // quite naive, but after all this is example
|
||||
throw new Error("Cannot represent value as URL: " . Utils::printSafe($value));
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an externally provided literal value to use as an input (e.g. in Query AST)
|
||||
*
|
||||
* @param Node $valueNode
|
||||
* @param array|null $variables
|
||||
* @return null|string
|
||||
* @throws Error
|
||||
*/
|
||||
public function parseLiteral($valueNode, array $variables = null)
|
||||
{
|
||||
// Note: throwing GraphQL\Error\Error vs \UnexpectedValueException to benefit from GraphQL
|
||||
// error location in query:
|
||||
if (!($valueNode instanceof StringValueNode)) {
|
||||
throw new Error('Query error: Can only parse strings got: ' . $valueNode->kind, [$valueNode]);
|
||||
}
|
||||
if (!is_string($valueNode->value) || !filter_var($valueNode->value, FILTER_VALIDATE_URL)) {
|
||||
throw new Error('Query error: Not a valid URL', [$valueNode]);
|
||||
}
|
||||
return $valueNode->value;
|
||||
}
|
||||
}
|
||||
31
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/SearchResultType.php
vendored
Normal file
31
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/SearchResultType.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\Data\Story;
|
||||
use GraphQL\Examples\Blog\Data\User;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
|
||||
class SearchResultType extends UnionType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'SearchResultType',
|
||||
'types' => function() {
|
||||
return [
|
||||
Types::story(),
|
||||
Types::user()
|
||||
];
|
||||
},
|
||||
'resolveType' => function($value) {
|
||||
if ($value instanceof Story) {
|
||||
return Types::story();
|
||||
} else if ($value instanceof User) {
|
||||
return Types::user();
|
||||
}
|
||||
}
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
}
|
||||
127
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/StoryType.php
vendored
Normal file
127
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/StoryType.php
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\AppContext;
|
||||
use GraphQL\Examples\Blog\Data\DataSource;
|
||||
use GraphQL\Examples\Blog\Data\Story;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
|
||||
/**
|
||||
* Class StoryType
|
||||
* @package GraphQL\Examples\Social\Type
|
||||
*/
|
||||
class StoryType extends ObjectType
|
||||
{
|
||||
const EDIT = 'EDIT';
|
||||
const DELETE = 'DELETE';
|
||||
const LIKE = 'LIKE';
|
||||
const UNLIKE = 'UNLIKE';
|
||||
const REPLY = 'REPLY';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'Story',
|
||||
'fields' => function() {
|
||||
return [
|
||||
'id' => Types::id(),
|
||||
'author' => Types::user(),
|
||||
'mentions' => Types::listOf(Types::mention()),
|
||||
'totalCommentCount' => Types::int(),
|
||||
'comments' => [
|
||||
'type' => Types::listOf(Types::comment()),
|
||||
'args' => [
|
||||
'after' => [
|
||||
'type' => Types::id(),
|
||||
'description' => 'Load all comments listed after given comment ID'
|
||||
],
|
||||
'limit' => [
|
||||
'type' => Types::int(),
|
||||
'defaultValue' => 5
|
||||
]
|
||||
]
|
||||
],
|
||||
'likes' => [
|
||||
'type' => Types::listOf(Types::user()),
|
||||
'args' => [
|
||||
'limit' => [
|
||||
'type' => Types::int(),
|
||||
'description' => 'Limit the number of recent likes returned',
|
||||
'defaultValue' => 5
|
||||
]
|
||||
]
|
||||
],
|
||||
'likedBy' => [
|
||||
'type' => Types::listOf(Types::user()),
|
||||
],
|
||||
'affordances' => Types::listOf(new EnumType([
|
||||
'name' => 'StoryAffordancesEnum',
|
||||
'values' => [
|
||||
self::EDIT,
|
||||
self::DELETE,
|
||||
self::LIKE,
|
||||
self::UNLIKE,
|
||||
self::REPLY
|
||||
]
|
||||
])),
|
||||
'hasViewerLiked' => Types::boolean(),
|
||||
|
||||
Types::htmlField('body'),
|
||||
];
|
||||
},
|
||||
'interfaces' => [
|
||||
Types::node()
|
||||
],
|
||||
'resolveField' => function($value, $args, $context, ResolveInfo $info) {
|
||||
$method = 'resolve' . ucfirst($info->fieldName);
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}($value, $args, $context, $info);
|
||||
} else {
|
||||
return $value->{$info->fieldName};
|
||||
}
|
||||
}
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function resolveAuthor(Story $story)
|
||||
{
|
||||
return DataSource::findUser($story->authorId);
|
||||
}
|
||||
|
||||
public function resolveAffordances(Story $story, $args, AppContext $context)
|
||||
{
|
||||
$isViewer = $context->viewer === DataSource::findUser($story->authorId);
|
||||
$isLiked = DataSource::isLikedBy($story->id, $context->viewer->id);
|
||||
|
||||
if ($isViewer) {
|
||||
$affordances[] = self::EDIT;
|
||||
$affordances[] = self::DELETE;
|
||||
}
|
||||
if ($isLiked) {
|
||||
$affordances[] = self::UNLIKE;
|
||||
} else {
|
||||
$affordances[] = self::LIKE;
|
||||
}
|
||||
return $affordances;
|
||||
}
|
||||
|
||||
public function resolveHasViewerLiked(Story $story, $args, AppContext $context)
|
||||
{
|
||||
return DataSource::isLikedBy($story->id, $context->viewer->id);
|
||||
}
|
||||
|
||||
public function resolveTotalCommentCount(Story $story)
|
||||
{
|
||||
return DataSource::countComments($story->id);
|
||||
}
|
||||
|
||||
public function resolveComments(Story $story, $args)
|
||||
{
|
||||
$args += ['after' => null];
|
||||
return DataSource::findComments($story->id, $args['limit'], $args['after']);
|
||||
}
|
||||
}
|
||||
68
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/UserType.php
vendored
Normal file
68
vendor/webonyx/graphql-php/examples/01-blog/Blog/Type/UserType.php
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog\Type;
|
||||
|
||||
use GraphQL\Examples\Blog\AppContext;
|
||||
use GraphQL\Examples\Blog\Data\DataSource;
|
||||
use GraphQL\Examples\Blog\Data\User;
|
||||
use GraphQL\Examples\Blog\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ResolveInfo;
|
||||
|
||||
class UserType extends ObjectType
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$config = [
|
||||
'name' => 'User',
|
||||
'description' => 'Our blog authors',
|
||||
'fields' => function() {
|
||||
return [
|
||||
'id' => Types::id(),
|
||||
'email' => Types::email(),
|
||||
'photo' => [
|
||||
'type' => Types::image(),
|
||||
'description' => 'User photo URL',
|
||||
'args' => [
|
||||
'size' => Types::nonNull(Types::imageSizeEnum()),
|
||||
]
|
||||
],
|
||||
'firstName' => [
|
||||
'type' => Types::string(),
|
||||
],
|
||||
'lastName' => [
|
||||
'type' => Types::string(),
|
||||
],
|
||||
'lastStoryPosted' => Types::story(),
|
||||
'fieldWithError' => [
|
||||
'type' => Types::string(),
|
||||
'resolve' => function() {
|
||||
throw new \Exception("This is error field");
|
||||
}
|
||||
]
|
||||
];
|
||||
},
|
||||
'interfaces' => [
|
||||
Types::node()
|
||||
],
|
||||
'resolveField' => function($value, $args, $context, ResolveInfo $info) {
|
||||
$method = 'resolve' . ucfirst($info->fieldName);
|
||||
if (method_exists($this, $method)) {
|
||||
return $this->{$method}($value, $args, $context, $info);
|
||||
} else {
|
||||
return $value->{$info->fieldName};
|
||||
}
|
||||
}
|
||||
];
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
public function resolvePhoto(User $user, $args)
|
||||
{
|
||||
return DataSource::getUserPhoto($user->id, $args['size']);
|
||||
}
|
||||
|
||||
public function resolveLastStoryPosted(User $user)
|
||||
{
|
||||
return DataSource::findLastStoryFor($user->id);
|
||||
}
|
||||
}
|
||||
209
vendor/webonyx/graphql-php/examples/01-blog/Blog/Types.php
vendored
Normal file
209
vendor/webonyx/graphql-php/examples/01-blog/Blog/Types.php
vendored
Normal file
@ -0,0 +1,209 @@
|
||||
<?php
|
||||
namespace GraphQL\Examples\Blog;
|
||||
|
||||
use GraphQL\Examples\Blog\Type\CommentType;
|
||||
use GraphQL\Examples\Blog\Type\Enum\ContentFormatEnum;
|
||||
use GraphQL\Examples\Blog\Type\Enum\ImageSizeEnumType;
|
||||
use GraphQL\Examples\Blog\Type\Field\HtmlField;
|
||||
use GraphQL\Examples\Blog\Type\SearchResultType;
|
||||
use GraphQL\Examples\Blog\Type\NodeType;
|
||||
use GraphQL\Examples\Blog\Type\QueryType;
|
||||
use GraphQL\Examples\Blog\Type\Scalar\EmailType;
|
||||
use GraphQL\Examples\Blog\Type\StoryType;
|
||||
use GraphQL\Examples\Blog\Type\Scalar\UrlType;
|
||||
use GraphQL\Examples\Blog\Type\UserType;
|
||||
use GraphQL\Examples\Blog\Type\ImageType;
|
||||
use GraphQL\Type\Definition\ListOfType;
|
||||
use GraphQL\Type\Definition\NonNull;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
|
||||
/**
|
||||
* Class Types
|
||||
*
|
||||
* Acts as a registry and factory for your types.
|
||||
*
|
||||
* As simplistic as possible for the sake of clarity of this example.
|
||||
* Your own may be more dynamic (or even code-generated).
|
||||
*
|
||||
* @package GraphQL\Examples\Blog
|
||||
*/
|
||||
class Types
|
||||
{
|
||||
// Object types:
|
||||
private static $user;
|
||||
private static $story;
|
||||
private static $comment;
|
||||
private static $image;
|
||||
private static $query;
|
||||
|
||||
/**
|
||||
* @return UserType
|
||||
*/
|
||||
public static function user()
|
||||
{
|
||||
return self::$user ?: (self::$user = new UserType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return StoryType
|
||||
*/
|
||||
public static function story()
|
||||
{
|
||||
return self::$story ?: (self::$story = new StoryType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CommentType
|
||||
*/
|
||||
public static function comment()
|
||||
{
|
||||
return self::$comment ?: (self::$comment = new CommentType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ImageType
|
||||
*/
|
||||
public static function image()
|
||||
{
|
||||
return self::$image ?: (self::$image = new ImageType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return QueryType
|
||||
*/
|
||||
public static function query()
|
||||
{
|
||||
return self::$query ?: (self::$query = new QueryType());
|
||||
}
|
||||
|
||||
|
||||
// Interface types
|
||||
private static $node;
|
||||
|
||||
/**
|
||||
* @return NodeType
|
||||
*/
|
||||
public static function node()
|
||||
{
|
||||
return self::$node ?: (self::$node = new NodeType());
|
||||
}
|
||||
|
||||
|
||||
// Unions types:
|
||||
private static $mention;
|
||||
|
||||
/**
|
||||
* @return SearchResultType
|
||||
*/
|
||||
public static function mention()
|
||||
{
|
||||
return self::$mention ?: (self::$mention = new SearchResultType());
|
||||
}
|
||||
|
||||
|
||||
// Enum types
|
||||
private static $imageSizeEnum;
|
||||
private static $contentFormatEnum;
|
||||
|
||||
/**
|
||||
* @return ImageSizeEnumType
|
||||
*/
|
||||
public static function imageSizeEnum()
|
||||
{
|
||||
return self::$imageSizeEnum ?: (self::$imageSizeEnum = new ImageSizeEnumType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ContentFormatEnum
|
||||
*/
|
||||
public static function contentFormatEnum()
|
||||
{
|
||||
return self::$contentFormatEnum ?: (self::$contentFormatEnum = new ContentFormatEnum());
|
||||
}
|
||||
|
||||
// Custom Scalar types:
|
||||
private static $urlType;
|
||||
private static $emailType;
|
||||
|
||||
public static function email()
|
||||
{
|
||||
return self::$emailType ?: (self::$emailType = EmailType::create());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return UrlType
|
||||
*/
|
||||
public static function url()
|
||||
{
|
||||
return self::$urlType ?: (self::$urlType = new UrlType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @param null $objectKey
|
||||
* @return array
|
||||
*/
|
||||
public static function htmlField($name, $objectKey = null)
|
||||
{
|
||||
return HtmlField::build($name, $objectKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Let's add internal types as well for consistent experience
|
||||
|
||||
public static function boolean()
|
||||
{
|
||||
return Type::boolean();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \GraphQL\Type\Definition\FloatType
|
||||
*/
|
||||
public static function float()
|
||||
{
|
||||
return Type::float();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \GraphQL\Type\Definition\IDType
|
||||
*/
|
||||
public static function id()
|
||||
{
|
||||
return Type::id();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \GraphQL\Type\Definition\IntType
|
||||
*/
|
||||
public static function int()
|
||||
{
|
||||
return Type::int();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \GraphQL\Type\Definition\StringType
|
||||
*/
|
||||
public static function string()
|
||||
{
|
||||
return Type::string();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type $type
|
||||
* @return ListOfType
|
||||
*/
|
||||
public static function listOf($type)
|
||||
{
|
||||
return new ListOfType($type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Type $type
|
||||
* @return NonNull
|
||||
*/
|
||||
public static function nonNull($type)
|
||||
{
|
||||
return new NonNull($type);
|
||||
}
|
||||
}
|
||||
120
vendor/webonyx/graphql-php/examples/01-blog/README.md
vendored
Normal file
120
vendor/webonyx/graphql-php/examples/01-blog/README.md
vendored
Normal file
@ -0,0 +1,120 @@
|
||||
## Blog Example
|
||||
Simple yet full-featured example of GraphQL API. Models blogging platform with Stories, Users
|
||||
and hierarchical comments.
|
||||
|
||||
### Run locally
|
||||
```
|
||||
php -S localhost:8080 ./graphql.php
|
||||
```
|
||||
|
||||
### Test if GraphQL is running
|
||||
If you open `http://localhost:8080` in browser you should see `json` response with
|
||||
following message:
|
||||
```
|
||||
{
|
||||
data: {
|
||||
hello: "Your GraphQL endpoint is ready! Install GraphiQL to browse API"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that some browsers may try to download JSON file instead of showing you the response.
|
||||
In this case try to install browser plugin that adds JSON support (like JSONView or similar)
|
||||
|
||||
### Debugging Mode
|
||||
By default GraphQL endpoint exposed at `http://localhost:8080` runs in production mode without
|
||||
additional debugging tools enabled.
|
||||
|
||||
In order to enable debugging mode with additional validation, error handling and reporting -
|
||||
use `http://localhost:8080?debug=1` as endpoint
|
||||
|
||||
### Browsing API
|
||||
The most convenient way to browse GraphQL API is by using [GraphiQL](https://github.com/graphql/graphiql)
|
||||
But setting it up from scratch may be inconvenient. An easy alternative is to use one of
|
||||
the existing Google Chrome extensions:
|
||||
- [ChromeiQL](https://chrome.google.com/webstore/detail/chromeiql/fkkiamalmpiidkljmicmjfbieiclmeij)
|
||||
- [GraphiQL Feen](https://chrome.google.com/webstore/detail/graphiql-feen/mcbfdonlkfpbfdpimkjilhdneikhfklp)
|
||||
|
||||
Set `http://localhost:8080?debug=1` as your GraphQL endpoint/server in one of these extensions
|
||||
and try clicking "Docs" button (usually in the top-right corner) to browse auto-generated
|
||||
documentation.
|
||||
|
||||
### Running GraphQL queries
|
||||
Copy following query to GraphiQL and execute (by clicking play button on top bar)
|
||||
|
||||
```
|
||||
{
|
||||
viewer {
|
||||
id
|
||||
email
|
||||
}
|
||||
user(id: "2") {
|
||||
id
|
||||
email
|
||||
}
|
||||
stories(after: "1") {
|
||||
id
|
||||
body
|
||||
comments {
|
||||
...CommentView
|
||||
}
|
||||
}
|
||||
lastStoryPosted {
|
||||
id
|
||||
hasViewerLiked
|
||||
|
||||
author {
|
||||
id
|
||||
photo(size: ICON) {
|
||||
id
|
||||
url
|
||||
type
|
||||
size
|
||||
width
|
||||
height
|
||||
# Uncomment following line to see validation error:
|
||||
# nonExistingField
|
||||
|
||||
# Uncomment to see error reporting for fields with exceptions thrown in resolvers
|
||||
# fieldWithError
|
||||
# nonNullFieldWithError
|
||||
}
|
||||
lastStoryPosted {
|
||||
id
|
||||
}
|
||||
}
|
||||
body(format: HTML, maxLength: 10)
|
||||
}
|
||||
}
|
||||
|
||||
fragment CommentView on Comment {
|
||||
id
|
||||
body
|
||||
totalReplyCount
|
||||
replies {
|
||||
id
|
||||
body
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Run your own query
|
||||
Use GraphiQL autocomplete (via CTRL+space) to easily create your own query.
|
||||
|
||||
Note: GraphQL query requires at least one field per object type (to prevent accidental overfetching).
|
||||
For example following query is invalid in GraphQL:
|
||||
|
||||
```
|
||||
{
|
||||
viewer
|
||||
}
|
||||
```
|
||||
|
||||
Try copying this query and see what happens
|
||||
|
||||
### Run mutation query
|
||||
TODOC
|
||||
|
||||
### Dig into source code
|
||||
Now when you tried GraphQL API as a consumer, see how it is implemented by browsing
|
||||
source code.
|
||||
71
vendor/webonyx/graphql-php/examples/01-blog/graphql.php
vendored
Normal file
71
vendor/webonyx/graphql-php/examples/01-blog/graphql.php
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
// Test this using following command
|
||||
// php -S localhost:8080 ./graphql.php
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use \GraphQL\Examples\Blog\Types;
|
||||
use \GraphQL\Examples\Blog\AppContext;
|
||||
use \GraphQL\Examples\Blog\Data\DataSource;
|
||||
use \GraphQL\Type\Schema;
|
||||
use \GraphQL\GraphQL;
|
||||
use \GraphQL\Error\FormattedError;
|
||||
use \GraphQL\Error\Debug;
|
||||
|
||||
// Disable default PHP error reporting - we have better one for debug mode (see bellow)
|
||||
ini_set('display_errors', 0);
|
||||
|
||||
$debug = false;
|
||||
if (!empty($_GET['debug'])) {
|
||||
set_error_handler(function($severity, $message, $file, $line) use (&$phpErrors) {
|
||||
throw new ErrorException($message, 0, $severity, $file, $line);
|
||||
});
|
||||
$debug = Debug::INCLUDE_DEBUG_MESSAGE | Debug::INCLUDE_TRACE;
|
||||
}
|
||||
|
||||
try {
|
||||
// Initialize our fake data source
|
||||
DataSource::init();
|
||||
|
||||
// Prepare context that will be available in all field resolvers (as 3rd argument):
|
||||
$appContext = new AppContext();
|
||||
$appContext->viewer = DataSource::findUser('1'); // simulated "currently logged-in user"
|
||||
$appContext->rootUrl = 'http://localhost:8080';
|
||||
$appContext->request = $_REQUEST;
|
||||
|
||||
// Parse incoming query and variables
|
||||
if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
|
||||
$raw = file_get_contents('php://input') ?: '';
|
||||
$data = json_decode($raw, true) ?: [];
|
||||
} else {
|
||||
$data = $_REQUEST;
|
||||
}
|
||||
|
||||
$data += ['query' => null, 'variables' => null];
|
||||
|
||||
if (null === $data['query']) {
|
||||
$data['query'] = '{hello}';
|
||||
}
|
||||
|
||||
// GraphQL schema to be passed to query executor:
|
||||
$schema = new Schema([
|
||||
'query' => Types::query()
|
||||
]);
|
||||
|
||||
$result = GraphQL::executeQuery(
|
||||
$schema,
|
||||
$data['query'],
|
||||
null,
|
||||
$appContext,
|
||||
(array) $data['variables']
|
||||
);
|
||||
$output = $result->toArray($debug);
|
||||
$httpStatus = 200;
|
||||
} catch (\Exception $error) {
|
||||
$httpStatus = 500;
|
||||
$output['errors'] = [
|
||||
FormattedError::createFromException($error, $debug)
|
||||
];
|
||||
}
|
||||
|
||||
header('Content-Type: application/json', true, $httpStatus);
|
||||
echo json_encode($output);
|
||||
19
vendor/webonyx/graphql-php/examples/02-shorthand/README.md
vendored
Normal file
19
vendor/webonyx/graphql-php/examples/02-shorthand/README.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Parsing GraphQL IDL shorthand
|
||||
|
||||
Same as the Hello world example but shows how to build GraphQL schema from shorthand
|
||||
and wire up some resolvers
|
||||
|
||||
### Run locally
|
||||
```
|
||||
php -S localhost:8080 ./graphql.php
|
||||
```
|
||||
|
||||
### Try query
|
||||
```
|
||||
curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
```
|
||||
|
||||
### Try mutation
|
||||
```
|
||||
curl http://localhost:8080 -d '{"query": "mutation { sum(x: 2, y: 2) }" }'
|
||||
```
|
||||
31
vendor/webonyx/graphql-php/examples/02-shorthand/graphql.php
vendored
Normal file
31
vendor/webonyx/graphql-php/examples/02-shorthand/graphql.php
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
// Test this using following command
|
||||
// php -S localhost:8080 ./graphql.php &
|
||||
// curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
// curl http://localhost:8080 -d '{"query": "mutation { sum(x: 2, y: 2) }" }'
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use GraphQL\GraphQL;
|
||||
use GraphQL\Utils\BuildSchema;
|
||||
|
||||
try {
|
||||
|
||||
$schema = BuildSchema::build(file_get_contents(__DIR__ . '/schema.graphqls'));
|
||||
$rootValue = include __DIR__ . '/rootvalue.php';
|
||||
|
||||
$rawInput = file_get_contents('php://input');
|
||||
$input = json_decode($rawInput, true);
|
||||
$query = $input['query'];
|
||||
$variableValues = isset($input['variables']) ? $input['variables'] : null;
|
||||
|
||||
$result = GraphQL::executeQuery($schema, $query, $rootValue, null, $variableValues);
|
||||
} catch (\Exception $e) {
|
||||
$result = [
|
||||
'error' => [
|
||||
'message' => $e->getMessage()
|
||||
]
|
||||
];
|
||||
}
|
||||
header('Content-Type: application/json; charset=UTF-8');
|
||||
echo json_encode($result);
|
||||
|
||||
35
vendor/webonyx/graphql-php/examples/02-shorthand/rootvalue.php
vendored
Normal file
35
vendor/webonyx/graphql-php/examples/02-shorthand/rootvalue.php
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
interface Resolver {
|
||||
public function resolve($root, $args, $context);
|
||||
}
|
||||
|
||||
class Addition implements Resolver
|
||||
{
|
||||
public function resolve($root, $args, $context)
|
||||
{
|
||||
return $args['x'] + $args['y'];
|
||||
}
|
||||
}
|
||||
|
||||
class Echoer implements Resolver
|
||||
{
|
||||
public function resolve($root, $args, $context)
|
||||
{
|
||||
return $root['prefix'].$args['message'];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'sum' => function($root, $args, $context) {
|
||||
$sum = new Addition();
|
||||
|
||||
return $sum->resolve($root, $args, $context);
|
||||
},
|
||||
'echo' => function($root, $args, $context) {
|
||||
$echo = new Echoer();
|
||||
|
||||
return $echo->resolve($root, $args, $context);
|
||||
},
|
||||
'prefix' => 'You said: ',
|
||||
];
|
||||
13
vendor/webonyx/graphql-php/examples/02-shorthand/schema.graphqls
vendored
Normal file
13
vendor/webonyx/graphql-php/examples/02-shorthand/schema.graphqls
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
schema {
|
||||
query: Query
|
||||
mutation: Calc
|
||||
}
|
||||
|
||||
type Calc {
|
||||
sum(x: Int, y: Int): Int
|
||||
}
|
||||
|
||||
type Query {
|
||||
echo(message: String): String
|
||||
}
|
||||
|
||||
19
vendor/webonyx/graphql-php/examples/03-server/README.md
vendored
Normal file
19
vendor/webonyx/graphql-php/examples/03-server/README.md
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
# Hello world
|
||||
Same example as 01-hello-world, but uses
|
||||
[Standard Http Server](http://webonyx.github.io/graphql-php/executing-queries/#using-server)
|
||||
instead of manual parsing of incoming data.
|
||||
|
||||
### Run locally
|
||||
```
|
||||
php -S localhost:8080 ./graphql.php
|
||||
```
|
||||
|
||||
### Try query
|
||||
```
|
||||
curl -d '{"query": "query { echo(message: \"Hello World\") }" }' -H "Content-Type: application/json" http://localhost:8080
|
||||
```
|
||||
|
||||
### Try mutation
|
||||
```
|
||||
curl -d '{"query": "mutation { sum(x: 2, y: 2) }" }' -H "Content-Type: application/json" http://localhost:8080
|
||||
```
|
||||
61
vendor/webonyx/graphql-php/examples/03-server/graphql.php
vendored
Normal file
61
vendor/webonyx/graphql-php/examples/03-server/graphql.php
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
<?php
|
||||
// Test this using following command
|
||||
// php -S localhost:8080 ./graphql.php &
|
||||
// curl http://localhost:8080 -d '{"query": "query { echo(message: \"Hello World\") }" }'
|
||||
// curl http://localhost:8080 -d '{"query": "mutation { sum(x: 2, y: 2) }" }'
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\Server\StandardServer;
|
||||
|
||||
try {
|
||||
$queryType = new ObjectType([
|
||||
'name' => 'Query',
|
||||
'fields' => [
|
||||
'echo' => [
|
||||
'type' => Type::string(),
|
||||
'args' => [
|
||||
'message' => ['type' => Type::string()],
|
||||
],
|
||||
'resolve' => function ($root, $args) {
|
||||
return $root['prefix'] . $args['message'];
|
||||
}
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$mutationType = new ObjectType([
|
||||
'name' => 'Calc',
|
||||
'fields' => [
|
||||
'sum' => [
|
||||
'type' => Type::int(),
|
||||
'args' => [
|
||||
'x' => ['type' => Type::int()],
|
||||
'y' => ['type' => Type::int()],
|
||||
],
|
||||
'resolve' => function ($root, $args) {
|
||||
return $args['x'] + $args['y'];
|
||||
},
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
// See docs on schema options:
|
||||
// http://webonyx.github.io/graphql-php/type-system/schema/#configuration-options
|
||||
$schema = new Schema([
|
||||
'query' => $queryType,
|
||||
'mutation' => $mutationType,
|
||||
]);
|
||||
|
||||
// See docs on server options:
|
||||
// http://webonyx.github.io/graphql-php/executing-queries/#server-configuration-options
|
||||
$server = new StandardServer([
|
||||
'schema' => $schema
|
||||
]);
|
||||
|
||||
$server->handleRequest();
|
||||
} catch (\Exception $e) {
|
||||
StandardServer::send500Error($e);
|
||||
}
|
||||
102
vendor/webonyx/graphql-php/phpcs.xml.dist
vendored
Normal file
102
vendor/webonyx/graphql-php/phpcs.xml.dist
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
<?xml version="1.0"?>
|
||||
<ruleset>
|
||||
<arg name="basepath" value="." />
|
||||
<arg name="extensions" value="php" />
|
||||
<arg name="parallel" value="80" />
|
||||
<arg name="cache" value=".phpcs-cache" />
|
||||
<arg name="colors" />
|
||||
|
||||
<!-- Ignore warnings, show progress of the run and show sniff names -->
|
||||
<arg value="nps" />
|
||||
|
||||
<file>src</file>
|
||||
<file>tests</file>
|
||||
|
||||
<rule ref="Doctrine">
|
||||
<!-- Disable PHP7+ features that might cause BC breaks for now -->
|
||||
<exclude name="SlevomatCodingStandard.Classes.ClassConstantVisibility.MissingConstantVisibility" />
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint" />
|
||||
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingReturnTypeHint" />
|
||||
<!-- Enable when Slevomat starts supporting variadics, see https://github.com/slevomat/coding-standard/issues/251 -->
|
||||
<exclude name="SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse" />
|
||||
</rule>
|
||||
|
||||
<!--@api annotation is required for now -->
|
||||
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration">
|
||||
<properties>
|
||||
<property
|
||||
name="usefulAnnotations"
|
||||
type="array"
|
||||
value="
|
||||
@after,
|
||||
@afterClass,
|
||||
@AfterMethods,
|
||||
@api,
|
||||
@Attribute,
|
||||
@Attributes,
|
||||
@before,
|
||||
@beforeClass,
|
||||
@BeforeMethods,
|
||||
@covers,
|
||||
@coversDefaultClass,
|
||||
@coversNothing,
|
||||
@dataProvider,
|
||||
@depends,
|
||||
@deprecated,
|
||||
@doesNotPerformAssertions,
|
||||
@Enum,
|
||||
@expectedDeprecation,
|
||||
@expectedException,
|
||||
@expectedExceptionCode,
|
||||
@expectedExceptionMessage,
|
||||
@expectedExceptionMessageRegExp,
|
||||
@group,
|
||||
@Groups,
|
||||
@IgnoreAnnotation,
|
||||
@internal,
|
||||
@Iterations,
|
||||
@link,
|
||||
@ODM\,
|
||||
@ORM\,
|
||||
@requires,
|
||||
@Required,
|
||||
@Revs,
|
||||
@runInSeparateProcess,
|
||||
@runTestsInSeparateProcesses,
|
||||
@see,
|
||||
@Target,
|
||||
@test,
|
||||
@throws,
|
||||
@uses
|
||||
"
|
||||
/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenAnnotations">
|
||||
<properties>
|
||||
<property
|
||||
name="forbiddenAnnotations"
|
||||
type="array"
|
||||
value="
|
||||
@author,
|
||||
@category,
|
||||
@copyright,
|
||||
@created,
|
||||
@license,
|
||||
@package,
|
||||
@since,
|
||||
@subpackage,
|
||||
@version
|
||||
"
|
||||
/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<!-- IDEs sort by PSR12, Slevomat coding standard uses old sorting for BC -->
|
||||
<rule ref="SlevomatCodingStandard.Namespaces.AlphabeticallySortedUses">
|
||||
<properties>
|
||||
<property name="psr12Compatible" type="bool" value="true" />
|
||||
</properties>
|
||||
</rule>
|
||||
</ruleset>
|
||||
17
vendor/webonyx/graphql-php/phpstan.neon.dist
vendored
Normal file
17
vendor/webonyx/graphql-php/phpstan.neon.dist
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
parameters:
|
||||
level: 1
|
||||
|
||||
paths:
|
||||
- %currentWorkingDirectory%/src
|
||||
- %currentWorkingDirectory%/tests
|
||||
|
||||
ignoreErrors:
|
||||
- "~Construct empty\\(\\) is not allowed\\. Use more strict comparison~"
|
||||
- "~(Method|Property) .+::.+(\\(\\))? (has parameter \\$\\w+ with no|has no return|has no) typehint specified~"
|
||||
- "~Variable property access on .+~"
|
||||
- "~Variable method call on static\\(GraphQL\\\\Server\\\\ServerConfig\\)~" # TODO get rid of
|
||||
|
||||
includes:
|
||||
- vendor/phpstan/phpstan-phpunit/extension.neon
|
||||
- vendor/phpstan/phpstan-phpunit/rules.neon
|
||||
- vendor/phpstan/phpstan-strict-rules/rules.neon
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user