diff --git a/.gitignore b/.gitignore
index 4e3728b..6586246 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
-.idea/
composer.phar
composer.lock
+phpcs.xml
vendor/
-bin/
diff --git a/.travis.yml b/.travis.yml
index 648e187..45e4636 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,6 @@ dist: trusty
language: php
php:
- - 5.6
- - 7.0
- 7.1
- 7.2
- nightly
@@ -47,3 +45,21 @@ jobs:
after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover clover.xml
+ - stage: Pull request coding standard
+ if: type = pull_request
+ install: travis_retry composer install --prefer-dist
+ script:
+ - |
+ if [ $TRAVIS_BRANCH != "master" ]; then
+ git remote set-branches --add origin $TRAVIS_BRANCH;
+ git fetch origin $TRAVIS_BRANCH;
+ fi
+ - git merge-base origin/$TRAVIS_BRANCH $TRAVIS_PULL_REQUEST_SHA || git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge --unshallow
+ - wget https://github.com/diff-sniffer/git/releases/download/0.1.0/git-phpcs.phar
+ - php git-phpcs.phar origin/$TRAVIS_BRANCH...$TRAVIS_PULL_REQUEST_SHA
+ - stage: Coding standard
+ if: NOT type = pull_request
+ php: 7.1
+ install: travis_retry composer install --prefer-dist
+ script:
+ - ./vendor/bin/phpcs
diff --git a/composer.json b/composer.json
index 27bfc82..dc8e02f 100644
--- a/composer.json
+++ b/composer.json
@@ -9,10 +9,11 @@
"API"
],
"require": {
- "php": ">=5.6",
+ "php": "^7.1",
"ext-mbstring": "*"
},
"require-dev": {
+ "doctrine/coding-standard": "^4.0",
"phpunit/phpunit": "^4.8",
"psr/http-message": "^1.0"
},
@@ -35,5 +36,8 @@
"suggest": {
"react/promise": "To leverage async resolving on React PHP platform",
"psr/http-message": "To use standard GraphQL server"
+ },
+ "scripts": {
+ "lint" : "vendor/bin/phpcs"
}
}
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
new file mode 100644
index 0000000..4be54dd
--- /dev/null
+++ b/phpcs.xml.dist
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+ src
+ tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Error/ClientAware.php b/src/Error/ClientAware.php
index 70c6987..c347004 100644
--- a/src/Error/ClientAware.php
+++ b/src/Error/ClientAware.php
@@ -1,4 +1,7 @@
nodes = $nodes;
+ $this->source = $source;
+ $this->positions = $positions;
+ $this->path = $path;
+ $this->extensions = $extensions ?: (
+ $previous && $previous instanceof self
+ ? $previous->extensions
+ : []
+ );
+
+ if ($previous instanceof ClientAware) {
+ $this->isClientSafe = $previous->isClientSafe();
+ $this->category = $previous->getCategory() ?: static::CATEGORY_INTERNAL;
+ } elseif ($previous) {
+ $this->isClientSafe = false;
+ $this->category = static::CATEGORY_INTERNAL;
+ } else {
+ $this->isClientSafe = true;
+ $this->category = static::CATEGORY_GRAPHQL;
+ }
+ }
+
/**
* Given an arbitrary Error, presumably thrown while attempting to execute a
* GraphQL operation, produce a new GraphQLError aware of the location in the
* document responsible for the original Error.
*
- * @param $error
- * @param array|null $nodes
- * @param array|null $path
+ * @param mixed $error
+ * @param Node[]|null $nodes
+ * @param mixed[]|null $path
* @return Error
*/
public static function createLocatedError($error, $nodes = null, $path = null)
@@ -99,22 +145,22 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
return $error;
} else {
$nodes = $nodes ?: $error->nodes;
- $path = $path ?: $error->path;
+ $path = $path ?: $error->path;
}
}
- $source = $positions = $originalError = null;
+ $source = $positions = $originalError = null;
$extensions = [];
if ($error instanceof self) {
- $message = $error->getMessage();
+ $message = $error->getMessage();
$originalError = $error;
- $nodes = $error->nodes ?: $nodes;
- $source = $error->source;
- $positions = $error->positions;
- $extensions = $error->extensions;
- } else if ($error instanceof \Exception || $error instanceof \Throwable) {
- $message = $error->getMessage();
+ $nodes = $error->nodes ?: $nodes;
+ $source = $error->source;
+ $positions = $error->positions;
+ $extensions = $error->extensions;
+ } elseif ($error instanceof \Exception || $error instanceof \Throwable) {
+ $message = $error->getMessage();
$originalError = $error;
} else {
$message = (string) $error;
@@ -131,66 +177,14 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
);
}
-
/**
- * @param Error $error
- * @return array
+ * @return mixed[]
*/
public static function formatError(Error $error)
{
return $error->toSerializableArray();
}
- /**
- * @param string $message
- * @param array|Node|null $nodes
- * @param Source $source
- * @param array|null $positions
- * @param array|null $path
- * @param \Throwable $previous
- * @param array $extensions
- */
- public function __construct(
- $message,
- $nodes = null,
- Source $source = null,
- $positions = null,
- $path = null,
- $previous = null,
- array $extensions = []
- )
- {
- parent::__construct($message, 0, $previous);
-
- // Compute list of blame nodes.
- if ($nodes instanceof \Traversable) {
- $nodes = iterator_to_array($nodes);
- } else if ($nodes && !is_array($nodes)) {
- $nodes = [$nodes];
- }
-
- $this->nodes = $nodes;
- $this->source = $source;
- $this->positions = $positions;
- $this->path = $path;
- $this->extensions = $extensions ?: (
- $previous && $previous instanceof self
- ? $previous->extensions
- : []
- );
-
- if ($previous instanceof ClientAware) {
- $this->isClientSafe = $previous->isClientSafe();
- $this->category = $previous->getCategory() ?: static::CATEGORY_INTERNAL;
- } else if ($previous) {
- $this->isClientSafe = false;
- $this->category = static::CATEGORY_INTERNAL;
- } else {
- $this->isClientSafe = true;
- $this->category = static::CATEGORY_GRAPHQL;
- }
- }
-
/**
* @inheritdoc
*/
@@ -212,29 +206,36 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
*/
public function getSource()
{
- if (null === $this->source) {
- if (!empty($this->nodes[0]) && !empty($this->nodes[0]->loc)) {
+ if ($this->source === null) {
+ if (! empty($this->nodes[0]) && ! empty($this->nodes[0]->loc)) {
$this->source = $this->nodes[0]->loc->source;
}
}
+
return $this->source;
}
/**
- * @return array
+ * @return int[]
*/
public function getPositions()
{
- if (null === $this->positions) {
- if (!empty($this->nodes)) {
- $positions = array_map(function($node) {
+ if ($this->positions === null && ! empty($this->nodes)) {
+ $positions = array_map(
+ function ($node) {
return isset($node->loc) ? $node->loc->start : null;
- }, $this->nodes);
- $this->positions = array_filter($positions, function($p) {
+ },
+ $this->nodes
+ );
+
+ $this->positions = array_filter(
+ $positions,
+ function ($p) {
return $p !== null;
- });
- }
+ }
+ );
}
+
return $this->positions;
}
@@ -254,21 +255,29 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
*/
public function getLocations()
{
- if (null === $this->locations) {
+ if ($this->locations === null) {
$positions = $this->getPositions();
- $source = $this->getSource();
- $nodes = $this->nodes;
+ $source = $this->getSource();
+ $nodes = $this->nodes;
if ($positions && $source) {
- $this->locations = array_map(function ($pos) use ($source) {
- return $source->getLocation($pos);
- }, $positions);
- } else if ($nodes) {
- $this->locations = array_filter(array_map(function ($node) {
- if ($node->loc) {
- return $node->loc->source->getLocation($node->loc->start);
- }
- }, $nodes));
+ $this->locations = array_map(
+ function ($pos) use ($source) {
+ return $source->getLocation($pos);
+ },
+ $positions
+ );
+ } elseif ($nodes) {
+ $this->locations = array_filter(
+ array_map(
+ function ($node) {
+ if ($node->loc) {
+ return $node->loc->source->getLocation($node->loc->start);
+ }
+ },
+ $nodes
+ )
+ );
} else {
$this->locations = [];
}
@@ -278,7 +287,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
}
/**
- * @return array|Node[]|null
+ * @return Node[]|null
*/
public function getNodes()
{
@@ -290,7 +299,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
* Only included for execution errors.
*
* @api
- * @return array|null
+ * @return mixed[]|null
*/
public function getPath()
{
@@ -298,7 +307,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
}
/**
- * @return array
+ * @return mixed[]
*/
public function getExtensions()
{
@@ -309,26 +318,29 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
* Returns array representation of error suitable for serialization
*
* @deprecated Use FormattedError::createFromException() instead
- * @return array
+ * @return mixed[]
*/
public function toSerializableArray()
{
$arr = [
- 'message' => $this->getMessage()
+ 'message' => $this->getMessage(),
];
if ($this->getExtensions()) {
$arr = array_merge($this->getExtensions(), $arr);
}
- $locations = Utils::map($this->getLocations(), function(SourceLocation $loc) {
- return $loc->toSerializableArray();
- });
+ $locations = Utils::map(
+ $this->getLocations(),
+ function (SourceLocation $loc) {
+ return $loc->toSerializableArray();
+ }
+ );
- if (!empty($locations)) {
+ if (! empty($locations)) {
$arr['locations'] = $locations;
}
- if (!empty($this->path)) {
+ if (! empty($this->path)) {
$arr['path'] = $this->path;
}
@@ -340,9 +352,8 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
* @return mixed data which can be serialized by json_encode,
* which is a value of any type other than a resource.
- * @since 5.4.0
*/
- function jsonSerialize()
+ public function jsonSerialize()
{
return $this->toSerializableArray();
}
diff --git a/src/Error/FormattedError.php b/src/Error/FormattedError.php
index 82bb0cb..b73e641 100644
--- a/src/Error/FormattedError.php
+++ b/src/Error/FormattedError.php
@@ -1,4 +1,7 @@
nodes) {
/** @var Node $node */
- foreach($error->nodes as $node) {
- if ($node->loc) {
- $printedLocations[] = self::highlightSourceAtLocation(
- $node->loc->source,
- $node->loc->source->getLocation($node->loc->start)
- );
+ foreach ($error->nodes as $node) {
+ if (! $node->loc) {
+ continue;
}
+
+ if ($node->loc->source === null) {
+ continue;
+ }
+
+ $printedLocations[] = self::highlightSourceAtLocation(
+ $node->loc->source,
+ $node->loc->source->getLocation($node->loc->start)
+ );
}
- } else if ($error->getSource() && $error->getLocations()) {
+ } elseif ($error->getSource() && $error->getLocations()) {
$source = $error->getSource();
- foreach($error->getLocations() as $location) {
+ foreach ($error->getLocations() as $location) {
$printedLocations[] = self::highlightSourceAtLocation($source, $location);
}
}
- return !$printedLocations
+ return ! $printedLocations
? $error->getMessage()
- : join("\n\n", array_merge([$error->getMessage()], $printedLocations)) . "\n";
+ : implode("\n\n", array_merge([$error->getMessage()], $printedLocations)) . "\n";
}
/**
* Render a helpful description of the location of the error in the GraphQL
* Source document.
*
- * @param Source $source
- * @param SourceLocation $location
* @return string
*/
private static function highlightSourceAtLocation(Source $source, SourceLocation $location)
{
- $line = $location->line;
- $lineOffset = $source->locationOffset->line - 1;
- $columnOffset = self::getColumnOffset($source, $location);
- $contextLine = $line + $lineOffset;
+ $line = $location->line;
+ $lineOffset = $source->locationOffset->line - 1;
+ $columnOffset = self::getColumnOffset($source, $location);
+ $contextLine = $line + $lineOffset;
$contextColumn = $location->column + $columnOffset;
- $prevLineNum = (string) ($contextLine - 1);
- $lineNum = (string) $contextLine;
- $nextLineNum = (string) ($contextLine + 1);
- $padLen = strlen($nextLineNum);
- $lines = preg_split('/\r\n|[\n\r]/', $source->body);
+ $prevLineNum = (string) ($contextLine - 1);
+ $lineNum = (string) $contextLine;
+ $nextLineNum = (string) ($contextLine + 1);
+ $padLen = strlen($nextLineNum);
+ $lines = preg_split('/\r\n|[\n\r]/', $source->body);
$lines[0] = self::whitespace($source->locationOffset->column - 1) . $lines[0];
$outputLines = [
- "{$source->name} ($contextLine:$contextColumn)",
+ sprintf('%s (%s:%s)', $source->name, $contextLine, $contextColumn),
$line >= 2 ? (self::lpad($padLen, $prevLineNum) . ': ' . $lines[$line - 2]) : null,
self::lpad($padLen, $lineNum) . ': ' . $lines[$line - 1],
self::whitespace(2 + $padLen + $contextColumn - 1) . '^',
- $line < count($lines)? self::lpad($padLen, $nextLineNum) . ': ' . $lines[$line] : null
+ $line < count($lines) ? self::lpad($padLen, $nextLineNum) . ': ' . $lines[$line] : null,
];
- return join("\n", array_filter($outputLines));
+ return implode("\n", array_filter($outputLines));
}
/**
- * @param Source $source
- * @param SourceLocation $location
* @return int
*/
private static function getColumnOffset(Source $source, SourceLocation $location)
@@ -109,7 +134,8 @@ class FormattedError
* @param int $len
* @return string
*/
- private static function whitespace($len) {
+ private static function whitespace($len)
+ {
return str_repeat(' ', $len);
}
@@ -117,7 +143,8 @@ class FormattedError
* @param int $len
* @return string
*/
- private static function lpad($len, $str) {
+ private static function lpad($len, $str)
+ {
return self::whitespace($len - mb_strlen($str)) . $str;
}
@@ -132,16 +159,16 @@ class FormattedError
*
* @api
* @param \Throwable $e
- * @param bool|int $debug
- * @param string $internalErrorMessage
- * @return array
+ * @param bool|int $debug
+ * @param string $internalErrorMessage
+ * @return mixed[]
* @throws \Throwable
*/
public static function createFromException($e, $debug = false, $internalErrorMessage = null)
{
Utils::invariant(
$e instanceof \Exception || $e instanceof \Throwable,
- "Expected exception, got %s",
+ 'Expected exception, got %s',
Utils::getVariableType($e)
);
@@ -149,13 +176,13 @@ class FormattedError
if ($e instanceof ClientAware) {
$formattedError = [
- 'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
- 'category' => $e->getCategory()
+ 'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
+ 'category' => $e->getCategory(),
];
} else {
$formattedError = [
- 'message' => $internalErrorMessage,
- 'category' => Error::CATEGORY_INTERNAL
+ 'message' => $internalErrorMessage,
+ 'category' => Error::CATEGORY_INTERNAL,
];
}
@@ -164,14 +191,17 @@ class FormattedError
$formattedError = array_merge($e->getExtensions(), $formattedError);
}
- $locations = Utils::map($e->getLocations(), function(SourceLocation $loc) {
- return $loc->toSerializableArray();
- });
+ $locations = Utils::map(
+ $e->getLocations(),
+ function (SourceLocation $loc) {
+ return $loc->toSerializableArray();
+ }
+ );
- if (!empty($locations)) {
+ if (! empty($locations)) {
$formattedError['locations'] = $locations;
}
- if (!empty($e->path)) {
+ if (! empty($e->path)) {
$formattedError['path'] = $e->path;
}
}
@@ -187,35 +217,37 @@ class FormattedError
* Decorates spec-compliant $formattedError with debug entries according to $debug flags
* (see GraphQL\Error\Debug for available flags)
*
- * @param array $formattedError
+ * @param mixed[] $formattedError
* @param \Throwable $e
- * @param bool $debug
- * @return array
+ * @param bool $debug
+ * @return mixed[]
* @throws \Throwable
*/
public static function addDebugEntries(array $formattedError, $e, $debug)
{
- if (!$debug) {
+ if (! $debug) {
return $formattedError;
}
Utils::invariant(
$e instanceof \Exception || $e instanceof \Throwable,
- "Expected exception, got %s",
+ 'Expected exception, got %s',
Utils::getVariableType($e)
);
$debug = (int) $debug;
if ($debug & Debug::RETHROW_INTERNAL_EXCEPTIONS) {
- if (!$e instanceof Error) {
+ if (! $e instanceof Error) {
throw $e;
- } else if ($e->getPrevious()) {
+ }
+
+ if ($e->getPrevious()) {
throw $e->getPrevious();
}
}
- $isInternal = !$e instanceof ClientAware || !$e->isClientSafe();
+ $isInternal = ! $e instanceof ClientAware || ! $e->isClientSafe();
if (($debug & Debug::INCLUDE_DEBUG_MESSAGE) && $isInternal) {
// Displaying debugMessage as a first entry:
@@ -230,13 +262,14 @@ class FormattedError
];
}
- $isTrivial = $e instanceof Error && !$e->getPrevious();
+ $isTrivial = $e instanceof Error && ! $e->getPrevious();
- if (!$isTrivial) {
- $debugging = $e->getPrevious() ?: $e;
+ if (! $isTrivial) {
+ $debugging = $e->getPrevious() ?: $e;
$formattedError['trace'] = static::toSafeTrace($debugging);
}
}
+
return $formattedError;
}
@@ -244,20 +277,20 @@ class FormattedError
* Prepares final error formatter taking in account $debug flags.
* If initial formatter is not set, FormattedError::createFromException is used
*
- * @param callable|null $formatter
- * @param $debug
+ * @param bool $debug
* @return callable|\Closure
*/
- public static function prepareFormatter(callable $formatter = null, $debug)
+ public static function prepareFormatter(?callable $formatter = null, $debug)
{
- $formatter = $formatter ?: function($e) {
+ $formatter = $formatter ?: function ($e) {
return FormattedError::createFromException($e);
};
if ($debug) {
- $formatter = function($e) use ($formatter, $debug) {
+ $formatter = function ($e) use ($formatter, $debug) {
return FormattedError::addDebugEntries($formatter($e), $e, $debug);
};
}
+
return $formatter;
}
@@ -266,45 +299,45 @@ class FormattedError
*
* @api
* @param \Throwable $error
- * @return array
+ * @return mixed[]
*/
public static function toSafeTrace($error)
{
$trace = $error->getTrace();
- // Remove invariant entries as they don't provide much value:
- if (
- isset($trace[0]['function']) && isset($trace[0]['class']) &&
- ('GraphQL\Utils\Utils::invariant' === $trace[0]['class'].'::'.$trace[0]['function'])) {
+ if (isset($trace[0]['function']) && isset($trace[0]['class']) &&
+ // Remove invariant entries as they don't provide much value:
+ ($trace[0]['class'] . '::' . $trace[0]['function'] === 'GraphQL\Utils\Utils::invariant')) {
+ array_shift($trace);
+ } elseif (! isset($trace[0]['file'])) {
+ // Remove root call as it's likely error handler trace:
array_shift($trace);
}
- // Remove root call as it's likely error handler trace:
- else if (!isset($trace[0]['file'])) {
- array_shift($trace);
- }
+ return array_map(
+ function ($err) {
+ $safeErr = array_intersect_key($err, ['file' => true, 'line' => true]);
- return array_map(function($err) {
- $safeErr = array_intersect_key($err, ['file' => true, 'line' => true]);
+ if (isset($err['function'])) {
+ $func = $err['function'];
+ $args = ! empty($err['args']) ? array_map([__CLASS__, 'printVar'], $err['args']) : [];
+ $funcStr = $func . '(' . implode(', ', $args) . ')';
- if (isset($err['function'])) {
- $func = $err['function'];
- $args = !empty($err['args']) ? array_map([__CLASS__, 'printVar'], $err['args']) : [];
- $funcStr = $func . '(' . implode(", ", $args) . ')';
-
- if (isset($err['class'])) {
- $safeErr['call'] = $err['class'] . '::' . $funcStr;
- } else {
- $safeErr['function'] = $funcStr;
+ if (isset($err['class'])) {
+ $safeErr['call'] = $err['class'] . '::' . $funcStr;
+ } else {
+ $safeErr['function'] = $funcStr;
+ }
}
- }
- return $safeErr;
- }, $trace);
+ return $safeErr;
+ },
+ $trace
+ );
}
/**
- * @param $var
+ * @param mixed $var
* @return string
*/
public static function printVar($var)
@@ -314,6 +347,7 @@ class FormattedError
if ($var instanceof WrappingType) {
$var = $var->getWrappedType(true);
}
+
return 'GraphQLType: ' . $var->name;
}
@@ -323,7 +357,7 @@ class FormattedError
if (is_array($var)) {
return 'array(' . count($var) . ')';
}
- if ('' === $var) {
+ if ($var === '') {
return '(empty string)';
}
if (is_string($var)) {
@@ -335,42 +369,45 @@ class FormattedError
if (is_scalar($var)) {
return $var;
}
- if (null === $var) {
+ if ($var === null) {
return 'null';
}
+
return gettype($var);
}
/**
* @deprecated as of v0.8.0
- * @param $error
+ * @param string $error
* @param SourceLocation[] $locations
- * @return array
+ * @return mixed[]
*/
public static function create($error, array $locations = [])
{
- $formatted = [
- 'message' => $error
- ];
+ $formatted = ['message' => $error];
- if (!empty($locations)) {
- $formatted['locations'] = array_map(function($loc) { return $loc->toArray();}, $locations);
+ if (! empty($locations)) {
+ $formatted['locations'] = array_map(
+ function ($loc) {
+ return $loc->toArray();
+ },
+ $locations
+ );
}
return $formatted;
}
/**
- * @param \ErrorException $e
* @deprecated as of v0.10.0, use general purpose method createFromException() instead
- * @return array
+ * @return mixed[]
*/
public static function createFromPHPError(\ErrorException $e)
{
return [
- 'message' => $e->getMessage(),
+ 'message' => $e->getMessage(),
'severity' => $e->getSeverity(),
- 'trace' => self::toSafeTrace($e)
+ 'trace' => self::toSafeTrace($e),
];
}
}
diff --git a/src/Error/InvariantViolation.php b/src/Error/InvariantViolation.php
index f52793f..f108109 100644
--- a/src/Error/InvariantViolation.php
+++ b/src/Error/InvariantViolation.php
@@ -1,4 +1,7 @@
0 && !isset(self::$warned[$warningId])) {
+ } elseif ((self::$enableWarnings & $warningId) > 0 && ! isset(self::$warned[$warningId])) {
self::$warned[$warningId] = true;
trigger_error($errorMessage, $messageLevel ?: E_USER_WARNING);
}
}
- static function warn($errorMessage, $warningId, $messageLevel = null)
+ public static function warn($errorMessage, $warningId, $messageLevel = null)
{
if (self::$warningHandler) {
$fn = self::$warningHandler;
$fn($errorMessage, $warningId);
- } else if ((self::$enableWarnings & $warningId) > 0) {
+ } elseif ((self::$enableWarnings & $warningId) > 0) {
trigger_error($errorMessage, $messageLevel ?: E_USER_WARNING);
}
}