Your project must not contain invalid function or method calls 43
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.invalid_call
- 'message',
- $self->filterTrace(
- sprintf(
- '%s: %s',
- $class,
- $exception->getMessage()
- )
- )
- );
- $error->tag(
- 'backtrace',
- $notice->tag(
- 'user-attributes',
- '',
- [],
- function (XmlBuilder $user) use ($options) {
- Notice::xmlVarsFor($user, $options['user']);
- }
- );
- }
- $notice->tag(
- if (is_array($this->options['params_filters'])) {
- foreach ($this->options['params_filters'] as $pattern) {
- foreach ($this->options[$name] as $key => $value) {
- if (preg_match($pattern, (string)$key)) {
- $this->options[$name][$key] = '[FILTERED]';
- }
- }
- }
- }
- [],
- function (XmlBuilder $cgiData) use ($options
- ) {
- Notice::xmlVarsFor(
- $cgiData,
- $options['cgi_data']
- );
- }
- );
- }
- }
- ['key' => $key]
- );
- }
- } else {
- $builder->tag('var', $value, ['key' => $key]);
- }
- }
- }
- }
- $exception,
- $self
- ) {
- $trace = $exception->getTrace();
- $file1 = $exception->getFile();
- $backtrace->tag(
- 'line',
- '',
- [
- 'number' => $exception->getLine(),
- 'url',
- !empty($options['url']) ? $options['url'] : ''
- );
- $request->tag(
- 'component',
- !empty($options['controller']) ? $options['controller'] : ''
- );
- $request->tag(
- 'action',
- !empty($options['action']) ? $options['action'] : ''
- );
- $builder->tag(
- 'var',
- '',
- ['key' => $key],
- function ($var) use ($value) {
- Notice::xmlVarsFor($var, $value);
- },
- true
- );
- } else {
- $builder->tag(
- return sprintf(
- '%s://%s%s%s',
- $this->guessProtocol(),
- $this->guessHost(),
- $this->guessPort(),
- $_SERVER['REQUEST_URI']
- );
- }
- return null;
- }
- 'message',
- $self->filterTrace(
- sprintf(
- '%s: %s',
- $class,
- $exception->getMessage()
- )
- )
- );
- $error->tag(
- 'backtrace',
- return $builder->tag(
- 'notice',
- '',
- ['version' => Errbit::API_VERSION],
- function (XmlBuilder $notice) use ($exception, $options, $self) {
- $notice->tag('api-key', $options['api_key']);
- $notice->tag(
- 'notifier',
- '',
- [],
- function (XmlBuilder $notifier) {
- $notice->tag(
- 'error',
- '',
- [],
- function (XmlBuilder $error) use ($exception, $self) {
- $class = Notice::className($exception);
- $error->tag('class', $self->filterTrace($class));
- $error->tag(
- 'message',
- $self->filterTrace(
- sprintf(
- 'component',
- !empty($options['controller']) ? $options['controller'] : ''
- );
- $request->tag(
- 'action',
- !empty($options['action']) ? $options['action'] : ''
- );
- if (!empty($options['parameters'])) {
- $request->tag(
- 'params',
- '',
- 'file' => isset($frame['file']) ?
- $self->filterTrace(
- $frame['file']
- ) : '<unknown>',
- 'method' => $self->filterTrace(
- $self->formatMethod($frame)
- ),
- ]
- );
- }
- }
- {
- if (!empty($_SERVER['SERVER_PORT']) && !in_array(
- $_SERVER['SERVER_PORT'],
- [80, 443]
- )) {
- return sprintf(':%d', $_SERVER['SERVER_PORT']);
- }
- return '80';
- }
- $file1 = $exception->getFile();
- $backtrace->tag(
- 'line',
- '',
- [
- 'number' => $exception->getLine(),
- 'file' => !empty($file1) ? $self->filterTrace(
- $file1
- ) : '<unknown>',
- 'method' => "<unknown>",
- ]
- 'line',
- '',
- [
- 'number' => $exception->getLine(),
- 'file' => !empty($file1) ? $self->filterTrace(
- $file1
- ) : '<unknown>',
- 'method' => "<unknown>",
- ]
- );
- if (!empty($frame['class']) && !empty($frame['type']) && !empty($frame['function'])) {
- return sprintf(
- '%s%s%s()',
- $frame['class'],
- $frame['type'],
- $frame['function']
- );
- } else {
- return sprintf(
- '%s()',
- !empty($frame['function']) ? $frame['function'] : '<unknown>'
- )) {
- return $str;
- }
- foreach ($this->options['backtrace_filters'] as $pattern => $replacement) {
- $str = preg_replace($pattern, (string)$replacement, $str);
- }
- return $str;
- }
- public static function formatMethod(array $frame): string
- {
- if (!empty($frame['class']) && !empty($frame['type']) && !empty($frame['function'])) {
- return sprintf(
- '%s%s%s()',
- $frame['class'],
- $frame['type'],
- $frame['function']
- );
- } else {
- return sprintf(
- [],
- function (XmlBuilder $env) use ($options) {
- $env->tag('project-root', $options['project_root']);
- $env->tag(
- 'environment-name',
- $options['environment_name']
- );
- }
- );
- }
- )->asXml();
- [],
- function (XmlBuilder $session) use ($options
- ) {
- Notice::xmlVarsFor(
- $session,
- $options['session_data']
- );
- }
- );
- }
- $notice->tag(
- 'server-environment',
- '',
- [],
- function (XmlBuilder $env) use ($options) {
- $env->tag('project-root', $options['project_root']);
- $env->tag(
- 'environment-name',
- $options['environment_name']
- );
- }
- [],
- function (XmlBuilder $backtrace) use (
- $exception,
- $self
- ) {
- $trace = $exception->getTrace();
- $file1 = $exception->getFile();
- $backtrace->tag(
- 'line',
- '',
- '',
- [
- 'number' => $frame['line'] ?? 0,
- 'file' => isset($frame['file']) ?
- $self->filterTrace(
- $frame['file']
- ) : '<unknown>',
- 'method' => $self->filterTrace(
- $self->formatMethod($frame)
- ),
- ]
- '',
- [],
- function (XmlBuilder $request) use ($options) {
- $request->tag(
- 'url',
- !empty($options['url']) ? $options['url'] : ''
- );
- $request->tag(
- 'component',
- !empty($options['controller']) ? $options['controller'] : ''
- );
- [],
- function (XmlBuilder $params) use ($options
- ) {
- Notice::xmlVarsFor(
- $params,
- $options['parameters']
- );
- }
- );
- }
- $frame['function']
- );
- } else {
- return sprintf(
- '%s()',
- !empty($frame['function']) ? $frame['function'] : '<unknown>'
- );
- }
- }
- /**
- {
- if (!empty($frame['class']) && !empty($frame['type']) && !empty($frame['function'])) {
- return sprintf(
- '%s%s%s()',
- $frame['class'],
- $frame['type'],
- $frame['function']
- );
- } else {
- return sprintf(
- '%s()',
- $this->_xml->{$name}[$idx][$attr] = $v;
- }
- $node = new self($this->_xml->$name);
- if ($getLastChild) {
- $array = $this->_xml->xpath($name."[last()]");
- $xml = array_shift($array);
- $node = new self($xml);
- }
- if ($callback) {
- $callback($node);
- *
- * @return string the XML of the document
- */
- public function asXml(): string
- {
- return self::utf8ForXML($this->_xml->asXML());
- }
- /**
- * Util to converts special chars to be valid with xml
- *
- * @param array $handlers
- */
- private function install(array $handlers): void
- {
- if (in_array('error', $handlers, true)) {
- set_error_handler([$this, 'onError'], error_reporting());
- }
- if (in_array('exception', $handlers, true)) {
- set_exception_handler([$this, 'onException']);
- }
- if (in_array('error', $handlers, true)) {
- set_error_handler([$this, 'onError'], error_reporting());
- }
- if (in_array('exception', $handlers, true)) {
- set_exception_handler([$this, 'onException']);
- }
- if (in_array('fatal', $handlers, true)) {
- register_shutdown_function([$this, 'onShutdown']);
- }
- public function notify(\Throwable $exception, array $options = []): static
- {
- $this->checkConfig();
- $config = array_merge($this->config, $options);
- if ($this->shouldNotify($exception, $config['skipped_exceptions'])) {
- $this->getWriter()->write($exception, $config);
- $this->notifyObservers($exception, $config);
- }
- return $this;
- return false;
- }
- }
- $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
- foreach ($this->config['ignore_user_agent'] as $ua) {
- if ($userAgent !== '' && str_contains($userAgent, $ua)) {
- return false;
- }
- }
- return true;
- $socket = fsockopen(
- $this->buildConnectionScheme($config),
- (int) $config['port'],
- $errno,
- $errstr,
- $config['connect_timeout']
- );
- if ($socket) {
- stream_set_timeout($socket, $config['write_timeout']);
- $payLoad = $this->buildPayload($exception, $config);
- * Proxies usually do not make request to endpoints if client quits connection before
- * proxy even gets the chance to create connection to endpoint
- */
- if ($this->charactersToRead !== false) {
- while (!feof($socket)) {
- $character = fread($socket, $this->charactersToRead);
- break;
- }
- }
- }
- $errstr,
- $config['connect_timeout']
- );
- if ($socket) {
- stream_set_timeout($socket, $config['write_timeout']);
- $payLoad = $this->buildPayload($exception, $config);
- if (strlen((string) $payLoad) > 7000 && $config['async']) {
- $messageId = uniqid('', true);
- $chunks = str_split((string) $payLoad, 7000);
- foreach ($chunks as $idx => $chunk) {
- } else {
- return sprintf(
- "%s\r\n\r\n%s",
- implode(
- "\r\n",
- [sprintf('POST %s HTTP/1.1', self::NOTICES_PATH), sprintf('Host: %s', $config['host']), sprintf('User-Agent: %s', $config['agent']), sprintf('Content-Type: %s', 'text/xml'), sprintf('Accept: %s', 'text/xml, application/xml'), sprintf('Content-Length: %d', strlen((string) $body)), sprintf('Connection: %s', 'close')]
- ),
- $body
- );
- }
- }
- }
- public function asyncWrite(\Throwable $exception, array $config): PromiseInterface
- {
- $uri = $this->buildConnectionScheme($config);
- $promise = $this->client->postAsync(
- $uri.self::NOTICES_PATH,
- [
- 'body' =>$this->buildNoticeFor($exception, $config),
- 'connect_timout' => $config['connect_timeout'],
- 'headers'=>[
- if ($config['secure']) {
- $proto = "https";
- } else {
- $proto = 'http';
- }
- return sprintf('%s://%s%s', $proto, $config['host'], (isset($config['port']) ? ':' . $config['port'] : ''));
- }
- public function __construct(private readonly ClientInterface $client)
- {
- }
- public function synchronousWrite(\Throwable $exception, array $config): ResponseInterface
- {
- $uri = $this->buildConnectionScheme($config);
- $body = $this->buildNoticeFor($exception, $config);
- return $this->client->post(
- uri: $uri.self::NOTICES_PATH,
- options: [
- 'body' =>$body,
- 'connect_timout' => $config['connect_timeout'],
- 'headers'=>[
- $proto = "ssl";
- } else {
- $proto = 'tcp';
- }
- return sprintf('%s://%s', $proto, $config['host']);
- }
- /**
- * @param \Throwable $exception
- * @param array $options
Your project should only use iterable types in foreach loops 3
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.invalid_foreach_iterable
- return;
- }
- if (is_array($this->options['params_filters'])) {
- foreach ($this->options['params_filters'] as $pattern) {
- foreach ($this->options[$name] as $key => $value) {
- if (preg_match($pattern, (string)$key)) {
- $this->options[$name][$key] = '[FILTERED]';
- }
- }
- 'file' => '',
- 'method' => '',
- ]
- );
- } else {
- foreach ($trace as $frame) {
- $backtrace->tag(
- 'line',
- '',
- [
- 'number' => $frame['line'] ?? 0,
- if ($exception instanceof $skippedException) {
- return false;
- }
- }
- $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? '';
- foreach ($this->config['ignore_user_agent'] as $ua) {
- if ($userAgent !== '' && str_contains($userAgent, $ua)) {
- return false;
- }
- }
Your project should not use invalid parameter and return typehints 24
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.invalid_typehint
- * Create a new notice for the given Exception with the given $options.
- *
- * @param mixed $exception - the exception that occurred
- * @param array $options - full configuration + options
- */
- public function __construct(
- private mixed $exception,
- array $options = []
- ) {
- $this->options = array_merge(
- [
- *
- * @param array $frame - a single entry for the backtrace
- *
- * @return string - the name of the method/function
- */
- public static function formatMethod(array $frame): string
- {
- if (!empty($frame['class']) && !empty($frame['type']) && !empty($frame['function'])) {
- return sprintf(
- '%s%s%s()',
- $frame['class'],
- * @param mixed $exception - Exception
- * @param array $options - array of options
- *
- * @return Notice
- */
- public static function forException(
- mixed $exception,
- array $options = []
- ): Notice {
- return new self($exception, $options);
- }
- * data into
- * @param array $array the stack frame entry
- *
- * @return void
- */
- public static function xmlVarsFor(XmlBuilder $builder, array $array): void
- {
- foreach ($array as $key => $value) {
- if (is_object($value)) {
- * @param array $attributes an array of attributes for the tag, optional
- * @param Callable $callback a callback to receive an XmlBuilder for the new tag, optional
- *
- * @return XmlBuilder a builder for the inserted tag
- */
- public function tag($name, $value = '', $attributes = [], $callback = null, bool $getLastChild = false)
- {
- $idx = is_countable($this->_xml->$name) ? count($this->_xml->$name) : 0;
- if (is_object($value)) {
- * @param \Errbit\Errbit $errbit
- * @param array $handlers
- *
- * @return void
- */
- public static function register(Errbit $errbit, array $handlers = ['exception', 'error', 'fatal']): void
- {
- new self($errbit, $handlers);
- }
- /**
- /**
- * Installer
- *
- * @param array $handlers
- */
- private function install(array $handlers): void
- {
- if (in_array('error', $handlers, true)) {
- set_error_handler([$this, 'onError'], error_reporting());
- }
- /**
- * @param \Errbit\Errbit $errbit
- * @param array $handlers
- */
- public function __construct(private Errbit $errbit, array $handlers=[])
- {
- $this->install($handlers);
- $this->converter = Converter::createDefault();
- }
- * @param \Throwable $exception
- * @param array $skippedExceptions
- *
- * @return bool
- */
- protected function shouldNotify(\Throwable $exception, array $skippedExceptions): bool
- {
- foreach ($skippedExceptions as $skippedException) {
- if ($exception instanceof $skippedException) {
- return false;
- }
- * @param array $config
- *
- * @return static the current instance of the client
- * @throws \Errbit\Exception\ConfigurationException
- */
- public function configure(array $config = []): static
- {
- $this->config = array_merge($this->config, $config);
- $this->checkConfig();
- return $this;
- * @param array $options
- *
- * @return static [Errbit] the current instance
- * @throws \Errbit\Exception\ConfigurationException
- */
- public function notify(\Throwable $exception, array $options = []): static
- {
- $this->checkConfig();
- $config = array_merge($this->config, $options);
- if ($this->shouldNotify($exception, $config['skipped_exceptions'])) {
- * @param array $handlers
- *
- * @return $this
- * @throws \Errbit\Exception\Exception
- */
- public function start(array $handlers = ['exception', 'error', 'fatal']): static
- {
- $this->checkConfig();
- ErrorHandlers::register($this, $handlers);
- return $this;
- * @param \Throwable $exception
- * @param array $config
- *
- * @return void
- */
- protected function notifyObservers(\Throwable $exception, array $config): void
- {
- foreach ($this->observers as $observer) {
- $observer($exception, $config);
- }
- }
- * This is made public for flexibility, though it is not expected you
- * should use it.
- *
- * @param array $config the configuration for the API
- */
- public function __construct(private array $config = [])
- {
- }
- public function setWriter(WriterInterface $writer): void
- {
- * @param \Throwable $exception
- * @param array $config
- *
- * @return string
- */
- protected function buildPayload(\Throwable $exception, array $config): string
- {
- return $this->addHttpHeadersIfNeeded(
- $this->buildNoticeFor($exception, $config),
- $config
- );
- * @param array $config
- *
- * @return mixed
- * @throws \JsonException
- */
- public function write(\Throwable $exception, array $config): mixed
- {
- $socket = fsockopen(
- $this->buildConnectionScheme($config),
- (int) $config['port'],
- $errno,
- * @param string $body
- * @param array $config
- *
- * @return string
- */
- protected function addHttpHeadersIfNeeded(string $body, array $config): string
- {
- if ($config['async'] ?? false) {
- return $body;
- } else {
- return sprintf(
- * @param array $config
- *
- * @return ResponseInterface|PromiseInterface
- * @throws \GuzzleHttp\Exception\GuzzleException
- */
- public function write(\Throwable $exception, array $config): mixed
- {
- if($config['async']) {
- return $this->asyncWrite($exception, $config);
- }
- return $this->synchronousWrite($exception, $config);
- ]
- ]
- );
- }
- public function asyncWrite(\Throwable $exception, array $config): PromiseInterface
- {
- $uri = $this->buildConnectionScheme($config);
- $promise = $this->client->postAsync(
- $uri.self::NOTICES_PATH,
- [
- /**
- *
- * @throws \GuzzleHttp\Exception\GuzzleException
- */
- public function synchronousWrite(\Throwable $exception, array $config): ResponseInterface
- {
- $uri = $this->buildConnectionScheme($config);
- $body = $this->buildNoticeFor($exception, $config);
- return $this->client->post(
- /**
- * @param array $config
- *
- * @return string
- */
- protected function buildConnectionScheme(array $config): string
- {
- if ($config['secure']) {
- $proto = "https";
- } else {
- $proto = 'http';
- */
- public const NOTICES_PATH = '/notifier_api/v2/notices/';
- /**
- * @return string
- */
- protected function buildConnectionScheme(array $config): string
- {
- $proto = "";
- if ($config['async']) {
- $proto = "udp";
- } elseif ($config['secure']) {
- * @param \Throwable $exception
- * @param array $options
- *
- * @return string
- */
- protected function buildNoticeFor(\Throwable $exception, array $options): string
- {
- return Notice::forException($exception, $options)->asXml();
- }
- }
- * @param \Throwable $exception
- * @param array $config
- *
- * @return mixed
- */
- public function write(\Throwable $exception, array $config): mixed;
- }
Your project should not use invalid return types 6
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.invalid_return_typehint
- * @return string servername
- */
- private function guessHost(): string
- {
- if (!empty($_SERVER['HTTP_HOST'])) {
- return $_SERVER['HTTP_HOST'];
- } elseif (!empty($_SERVER['SERVER_NAME'])) {
- return $_SERVER['SERVER_NAME'];
- } else {
- return '127.0.0.1';
- }
- private function guessHost(): string
- {
- if (!empty($_SERVER['HTTP_HOST'])) {
- return $_SERVER['HTTP_HOST'];
- } elseif (!empty($_SERVER['SERVER_NAME'])) {
- return $_SERVER['SERVER_NAME'];
- } else {
- return '127.0.0.1';
- }
- }
- * @return string http or https protocol
- */
- private function guessProtocol(): string
- {
- if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
- return $_SERVER['HTTP_X_FORWARDED_PROTO'];
- } elseif (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) {
- return 'https';
- } else {
- return 'http';
- }
- foreach ($this->options['backtrace_filters'] as $pattern => $replacement) {
- $str = preg_replace($pattern, (string)$replacement, $str);
- }
- return $str;
- }
- /**
- * Extract a human-readable method/function name from the given stack frame.
- *
- 'Content-Type'=>'text/xml',
- 'Accept'=>'text/xml, application/xml'
- ]
- ]
- );
- return $promise;
- }
- }
- public function synchronousWrite(\Throwable $exception, array $config): ResponseInterface
- {
- $uri = $this->buildConnectionScheme($config);
- $body = $this->buildNoticeFor($exception, $config);
- return $this->client->post(
- uri: $uri.self::NOTICES_PATH,
- options: [
- 'body' =>$body,
- 'connect_timout' => $config['connect_timeout'],
- 'headers'=>[
Your project should not use invalid offsets
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.invalid_offset
- *
- * @return static the current builder
- */
- public function attribute($name, $value): static
- {
- $this->_xml[$name] = $value;
- return $this;
- }
- /**
Your project must not contain invalid instantiations
- Read doc
- Reliability
- Major
More information: https://insight.symfony.com/what-we-analyse/php.invalid_instantiation
- }
- $node = new self($this->_xml->$name);
- if ($getLastChild) {
- $array = $this->_xml->xpath($name."[last()]");
- $xml = array_shift($array);
- $node = new self($xml);
- }
- if ($callback) {
- $callback($node);
- }