PHP 8.5 compatibility - closes #5114

This commit is contained in:
FreeScout
2025-12-17 09:23:05 -08:00
parent 061eabfadd
commit 43576f53ca
8 changed files with 736 additions and 7 deletions

View File

@@ -1785,11 +1785,15 @@ class Helper
if ($contents == '') {
$https_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (PHP_VERSION_ID < 80000) {
\curl_close($ch);
}
throw new \Exception('Empty Response. Curl Error Number: '.$curl_errno.'. Response Status Code: '.$https_status, 1);
//return false;
} else {
curl_close($ch);
if (PHP_VERSION_ID < 80000) {
\curl_close($ch);
}
}
return $contents;

View File

@@ -281,6 +281,7 @@
"vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasGlobalScopes.php",
"vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php",
"vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php",
"vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php",
"vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php",
"vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php",
"vendor/laravel/framework/src/Illuminate/Pagination/AbstractPaginator.php",
@@ -467,6 +468,7 @@
"vendor/laravel/framework/src/Illuminate/Mail/Mailer.php",
"vendor/filp/whoops/src/Whoops/Run.php",
"vendor/filp/whoops/src/Whoops/Handler/PrettyPageHandler.php",
"vendor/filp/whoops/src/Whoops/Handler/PlainTextHandler.php",
"vendor/filp/whoops/src/Whoops/Util/TemplateHelper.php",
"vendor/laravel/framework/src/Illuminate/Validation/Factory.php",
"vendor/laravel/framework/src/Illuminate/Validation/ValidationRuleParser.php",

View File

@@ -0,0 +1,359 @@
<?php
/**
* Whoops - php errors for cool kids
* @author Filipe Dobreira <http://github.com/filp>
* Plaintext handler for command line and logs.
* @author Pierre-Yves Landuré <https://howto.biapy.com/>
*/
namespace Whoops\Handler;
use InvalidArgumentException;
use Psr\Log\LoggerInterface;
use Whoops\Exception\Frame;
/**
* Handler outputing plaintext error messages. Can be used
* directly, or will be instantiated automagically by Whoops\Run
* if passed to Run::pushHandler
*/
class PlainTextHandler extends Handler
{
const VAR_DUMP_PREFIX = ' | ';
/**
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* @var callable
*/
protected $dumper;
/**
* @var bool
*/
private $addTraceToOutput = true;
/**
* @var bool|integer
*/
private $addTraceFunctionArgsToOutput = false;
/**
* @var integer
*/
private $traceFunctionArgsOutputLimit = 1024;
/**
* @var bool
*/
private $addPreviousToOutput = true;
/**
* @var bool
*/
private $loggerOnly = false;
/**
* Constructor.
* @throws InvalidArgumentException If argument is not null or a LoggerInterface
* @param \Psr\Log\LoggerInterface|null $logger
*/
public function __construct($logger = null)
{
$this->setLogger($logger);
}
/**
* Set the output logger interface.
* @throws InvalidArgumentException If argument is not null or a LoggerInterface
* @param \Psr\Log\LoggerInterface|null $logger
*/
public function setLogger($logger = null)
{
if (! (is_null($logger)
|| $logger instanceof LoggerInterface)) {
throw new InvalidArgumentException(
'Argument to ' . __METHOD__ .
" must be a valid Logger Interface (aka. Monolog), " .
get_class($logger) . ' given.'
);
}
$this->logger = $logger;
}
/**
* @return \Psr\Log\LoggerInterface|null
*/
public function getLogger()
{
return $this->logger;
}
/**
* Set var dumper callback function.
*
* @param callable $dumper
* @return static
*/
public function setDumper(callable $dumper)
{
$this->dumper = $dumper;
return $this;
}
/**
* Add error trace to output.
* @param bool|null $addTraceToOutput
* @return bool|static
*/
public function addTraceToOutput($addTraceToOutput = null)
{
if (func_num_args() == 0) {
return $this->addTraceToOutput;
}
$this->addTraceToOutput = (bool) $addTraceToOutput;
return $this;
}
/**
* Add previous exceptions to output.
* @param bool|null $addPreviousToOutput
* @return bool|static
*/
public function addPreviousToOutput($addPreviousToOutput = null)
{
if (func_num_args() == 0) {
return $this->addPreviousToOutput;
}
$this->addPreviousToOutput = (bool) $addPreviousToOutput;
return $this;
}
/**
* Add error trace function arguments to output.
* Set to True for all frame args, or integer for the n first frame args.
* @param bool|integer|null $addTraceFunctionArgsToOutput
* @return static|bool|integer
*/
public function addTraceFunctionArgsToOutput($addTraceFunctionArgsToOutput = null)
{
if (func_num_args() == 0) {
return $this->addTraceFunctionArgsToOutput;
}
if (! is_integer($addTraceFunctionArgsToOutput)) {
$this->addTraceFunctionArgsToOutput = (bool) $addTraceFunctionArgsToOutput;
} else {
$this->addTraceFunctionArgsToOutput = $addTraceFunctionArgsToOutput;
}
return $this;
}
/**
* Set the size limit in bytes of frame arguments var_dump output.
* If the limit is reached, the var_dump output is discarded.
* Prevent memory limit errors.
* @var integer
* @return static
*/
public function setTraceFunctionArgsOutputLimit($traceFunctionArgsOutputLimit)
{
$this->traceFunctionArgsOutputLimit = (int) $traceFunctionArgsOutputLimit;
return $this;
}
/**
* Create plain text response and return it as a string
* @return string
*/
public function generateResponse()
{
$exception = $this->getException();
$message = $this->getExceptionOutput($exception);
if ($this->addPreviousToOutput) {
$previous = $exception->getPrevious();
while ($previous) {
$message .= "\n\nCaused by\n" . $this->getExceptionOutput($previous);
$previous = $previous->getPrevious();
}
}
return $message . $this->getTraceOutput() . "\n";
}
/**
* Get the size limit in bytes of frame arguments var_dump output.
* If the limit is reached, the var_dump output is discarded.
* Prevent memory limit errors.
* @return integer
*/
public function getTraceFunctionArgsOutputLimit()
{
return $this->traceFunctionArgsOutputLimit;
}
/**
* Only output to logger.
* @param bool|null $loggerOnly
* @return static|bool
*/
public function loggerOnly($loggerOnly = null)
{
if (func_num_args() == 0) {
return $this->loggerOnly;
}
$this->loggerOnly = (bool) $loggerOnly;
return $this;
}
/**
* Test if handler can output to stdout.
* @return bool
*/
private function canOutput()
{
return !$this->loggerOnly();
}
/**
* Get the frame args var_dump.
* @param \Whoops\Exception\Frame $frame [description]
* @param integer $line [description]
* @return string
*/
private function getFrameArgsOutput(Frame $frame, $line)
{
if ($this->addTraceFunctionArgsToOutput() === false
|| $this->addTraceFunctionArgsToOutput() < $line) {
return '';
}
// Dump the arguments:
ob_start();
$this->dump($frame->getArgs());
if (ob_get_length() > $this->getTraceFunctionArgsOutputLimit()) {
// The argument var_dump is to big.
// Discarded to limit memory usage.
ob_clean();
return sprintf(
"\n%sArguments dump length greater than %d Bytes. Discarded.",
self::VAR_DUMP_PREFIX,
$this->getTraceFunctionArgsOutputLimit()
);
}
return sprintf(
"\n%s",
preg_replace('/^/m', self::VAR_DUMP_PREFIX, ob_get_clean())
);
}
/**
* Dump variable.
*
* @param mixed $var
* @return void
*/
protected function dump($var)
{
if ($this->dumper) {
call_user_func($this->dumper, $var);
} else {
var_dump($var);
}
}
/**
* Get the exception trace as plain text.
* @return string
*/
private function getTraceOutput()
{
if (! $this->addTraceToOutput()) {
return '';
}
$inspector = $this->getInspector();
$frames = $inspector->getFrames();
$response = "\nStack trace:";
$line = 1;
foreach ($frames as $frame) {
/** @var Frame $frame */
$class = $frame->getClass();
$template = "\n%3d. %s->%s() %s:%d%s";
if (! $class) {
// Remove method arrow (->) from output.
$template = "\n%3d. %s%s() %s:%d%s";
}
$response .= sprintf(
$template,
$line,
$class,
$frame->getFunction(),
$frame->getFile(),
$frame->getLine(),
$this->getFrameArgsOutput($frame, $line)
);
$line++;
}
return $response;
}
/**
* Get the exception as plain text.
* @param \Throwable $exception
* @return string
*/
private function getExceptionOutput($exception)
{
return sprintf(
"%s: %s in file %s on line %d",
get_class($exception),
$exception->getMessage(),
$exception->getFile(),
$exception->getLine()
);
}
/**
* @return int
*/
public function handle()
{
$response = $this->generateResponse();
if ($this->getLogger()) {
$this->getLogger()->error($response);
}
if (! $this->canOutput()) {
return Handler::DONE;
}
echo $response;
return Handler::QUIT;
}
/**
* @return string
*/
public function contentType()
{
return 'text/plain';
}
}

View File

@@ -175,7 +175,9 @@ class CurlMultiHandler
$handle = $this->handles[$id]['easy']->handle;
unset($this->delays[$id], $this->handles[$id]);
curl_multi_remove_handle($this->_mh, $handle);
curl_close($handle);
if (PHP_VERSION_ID < 80000) {
\curl_close($handle);
}
return true;
}

View File

@@ -320,9 +320,9 @@ class StreamHandler
);
return $this->createResource(
function () use ($uri, &$http_response_header, $context, $options) {
function () use ($uri, &$http_response_header_local, $context, $options) {
$resource = fopen((string) $uri, 'r', null, $context);
$this->lastHeaders = $http_response_header;
$this->lastHeaders = $http_response_header_local;
if (isset($options['read_timeout'])) {
$readTimeout = $options['read_timeout'];

View File

@@ -0,0 +1,362 @@
<?php
namespace Illuminate\Database\Eloquent\Relations;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\Concerns\SupportsDefaultModels;
/**
* @mixin \Illuminate\Database\Eloquent\Builder
*/
class BelongsTo extends Relation
{
use SupportsDefaultModels;
/**
* The child model instance of the relation.
*/
protected $child;
/**
* The foreign key of the parent model.
*
* @var string
*/
protected $foreignKey;
/**
* The associated key on the parent model.
*
* @var string
*/
protected $ownerKey;
/**
* The name of the relationship.
*
* @var string
*/
protected $relation;
/**
* The count of self joins.
*
* @var int
*/
protected static $selfJoinCount = 0;
/**
* Create a new belongs to relationship instance.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Model $child
* @param string $foreignKey
* @param string $ownerKey
* @param string $relation
* @return void
*/
public function __construct(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
{
$this->ownerKey = $ownerKey;
$this->relation = $relation;
$this->foreignKey = $foreignKey;
// In the underlying base relationship class, this variable is referred to as
// the "parent" since most relationships are not inversed. But, since this
// one is we will create a "child" variable for much better readability.
$this->child = $child;
parent::__construct($query, $child);
}
/**
* Get the results of the relationship.
*
* @return mixed
*/
public function getResults()
{
return $this->query->first() ?: $this->getDefaultFor($this->parent);
}
/**
* Set the base constraints on the relation query.
*
* @return void
*/
public function addConstraints()
{
if (static::$constraints) {
// For belongs to relationships, which are essentially the inverse of has one
// or has many relationships, we need to actually query on the primary key
// of the related models matching on the foreign key that's on a parent.
$table = $this->related->getTable();
$this->query->where($table.'.'.$this->ownerKey, '=', $this->child->{$this->foreignKey});
}
}
/**
* Set the constraints for an eager load of the relation.
*
* @param array $models
* @return void
*/
public function addEagerConstraints(array $models)
{
// We'll grab the primary key name of the related models since it could be set to
// a non-standard name and not "id". We will then construct the constraint for
// our eagerly loading query so it returns the proper models from execution.
$key = $this->related->getTable().'.'.$this->ownerKey;
$this->query->whereIn($key, $this->getEagerModelKeys($models));
}
/**
* Gather the keys from an array of related models.
*
* @param array $models
* @return array
*/
protected function getEagerModelKeys(array $models)
{
$keys = [];
// First we need to gather all of the keys from the parent models so we know what
// to query for via the eager loading query. We will add them to an array then
// execute a "where in" statement to gather up all of those related records.
foreach ($models as $model) {
if (! is_null($value = $model->{$this->foreignKey})) {
$keys[] = $value;
}
}
// If there are no keys that were not null we will just return an array with null
// so this query wont fail plus returns zero results, which should be what the
// developer expects to happen in this situation. Otherwise we'll sort them.
if (count($keys) === 0) {
return [null];
}
sort($keys);
return array_values(array_unique($keys));
}
/**
* Initialize the relation on a set of models.
*
* @param array $models
* @param string $relation
* @return array
*/
public function initRelation(array $models, $relation)
{
foreach ($models as $model) {
$model->setRelation($relation, $this->getDefaultFor($model));
}
return $models;
}
/**
* Match the eagerly loaded results to their parents.
*
* @param array $models
* @param \Illuminate\Database\Eloquent\Collection $results
* @param string $relation
* @return array
*/
public function match(array $models, Collection $results, $relation)
{
$foreign = $this->foreignKey;
$owner = $this->ownerKey;
// First we will get to build a dictionary of the child models by their primary
// key of the relationship, then we can easily match the children back onto
// the parents using that dictionary and the primary key of the children.
$dictionary = [];
foreach ($results as $result) {
$dictionary[$result->getAttribute($owner)] = $result;
}
// Once we have the dictionary constructed, we can loop through all the parents
// and match back onto their children using these keys of the dictionary and
// the primary key of the children to map them onto the correct instances.
foreach ($models as $model) {
if (isset($dictionary[$model->{$foreign} ?? ''])) {
$model->setRelation($relation, $dictionary[$model->{$foreign}]);
}
}
return $models;
}
/**
* Update the parent model on the relationship.
*
* @param array $attributes
* @return mixed
*/
public function update(array $attributes)
{
return $this->getResults()->fill($attributes)->save();
}
/**
* Associate the model instance to the given parent.
*
* @param \Illuminate\Database\Eloquent\Model|int|string $model
* @return \Illuminate\Database\Eloquent\Model
*/
public function associate($model)
{
$ownerKey = $model instanceof Model ? $model->getAttribute($this->ownerKey) : $model;
$this->child->setAttribute($this->foreignKey, $ownerKey);
if ($model instanceof Model) {
$this->child->setRelation($this->relation, $model);
}
return $this->child;
}
/**
* Dissociate previously associated model from the given parent.
*
* @return \Illuminate\Database\Eloquent\Model
*/
public function dissociate()
{
$this->child->setAttribute($this->foreignKey, null);
return $this->child->setRelation($this->relation, null);
}
/**
* Add the constraints for a relationship query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Builder $parentQuery
* @param array|mixed $columns
* @return \Illuminate\Database\Eloquent\Builder
*/
public function getRelationExistenceQuery(Builder $query, Builder $parentQuery, $columns = ['*'])
{
if ($parentQuery->getQuery()->from == $query->getQuery()->from) {
return $this->getRelationExistenceQueryForSelfRelation($query, $parentQuery, $columns);
}
return $query->select($columns)->whereColumn(
$this->getQualifiedForeignKey(), '=', $query->qualifyColumn($this->ownerKey)
);
}
/**
* Add the constraints for a relationship query on the same table.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @param \Illuminate\Database\Eloquent\Builder $parentQuery
* @param array|mixed $columns
* @return \Illuminate\Database\Eloquent\Builder
*/
public function getRelationExistenceQueryForSelfRelation(Builder $query, Builder $parentQuery, $columns = ['*'])
{
$query->select($columns)->from(
$query->getModel()->getTable().' as '.$hash = $this->getRelationCountHash()
);
$query->getModel()->setTable($hash);
return $query->whereColumn(
$hash.'.'.$query->getModel()->getKeyName(), '=', $this->getQualifiedForeignKey()
);
}
/**
* Get a relationship join table hash.
*
* @return string
*/
public function getRelationCountHash()
{
return 'laravel_reserved_'.static::$selfJoinCount++;
}
/**
* Determine if the related model has an auto-incrementing ID.
*
* @return bool
*/
protected function relationHasIncrementingId()
{
return $this->related->getIncrementing() &&
$this->related->getKeyType() === 'int';
}
/**
* Make a new related instance for the given model.
*
* @param \Illuminate\Database\Eloquent\Model $parent
* @return \Illuminate\Database\Eloquent\Model
*/
protected function newRelatedInstanceFor(Model $parent)
{
return $this->related->newInstance();
}
/**
* Get the foreign key of the relationship.
*
* @return string
*/
public function getForeignKey()
{
return $this->foreignKey;
}
/**
* Get the fully qualified foreign key of the relationship.
*
* @return string
*/
public function getQualifiedForeignKey()
{
return $this->child->qualifyColumn($this->foreignKey);
}
/**
* Get the associated key of the relationship.
*
* @return string
*/
public function getOwnerKey()
{
return $this->ownerKey;
}
/**
* Get the fully qualified associated key of the relationship.
*
* @return string
*/
public function getQualifiedOwnerKeyName()
{
return $this->related->qualifyColumn($this->ownerKey);
}
/**
* Get the name of the relationship.
*
* @return string
*/
public function getRelation()
{
return $this->relation;
}
}

View File

@@ -2318,7 +2318,7 @@ class CssMin
*/
public static function setVerbose($to)
{
self::$isVerbose = (boolean) $to;
self::$isVerbose = (bool) $to;
return self::$isVerbose;
}
/**

View File

@@ -298,7 +298,7 @@ class PopProtocol extends Protocol {
* @return bool
*/
public function connected(): bool {
return (boolean) $this->stream;
return (bool) $this->stream;
}
/**