Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
23debff
Fix relationship expression counts and nested morph queries
binaryfire Sep 8, 2026
262b542
Fix expression and callback types and document relationship queries
binaryfire Sep 8, 2026
2c75297
Complete expression-contract support across database query paths
binaryfire Sep 8, 2026
ff76fba
Port Laravel queue, helper, context and full-text updates
binaryfire Sep 8, 2026
fa993e4
Port HTTP retry callback parity and response throwUnless coverage
binaryfire Sep 8, 2026
aac3f00
Port HTTP fake stream bodies and correct response sequence input types
binaryfire Sep 8, 2026
3844c8a
Complete queue idle-stop coverage and align command descriptions
binaryfire Sep 8, 2026
a9c66b0
Complete event and batch callback type contracts
binaryfire Sep 8, 2026
8552a86
Complete upstream string-trimming tests and document wildcard exclusions
binaryfire Sep 8, 2026
26f0fa4
Fix reload command exclusion coverage and package guidance
binaryfire Sep 8, 2026
6c71de8
Port Markdown mail theme, layout slots and language metadata
binaryfire Sep 8, 2026
4e83234
Complete queue identity coverage and batch callback types
binaryfire Sep 8, 2026
f270463
Preserve unique job lock ownership across retries and child dispatches
binaryfire Sep 8, 2026
b6a1e99
Tighten queue worker interruption polling coverage
binaryfire Sep 8, 2026
648e4d3
Port command prohibitions and clearing multiple queues
binaryfire Sep 8, 2026
6da8f26
Document conditional schema column and index changes
binaryfire Sep 8, 2026
82fd2e9
Preserve expression column names for Eloquent plucks
binaryfire Sep 8, 2026
f8a2c8a
Keep HTTP retry policies tied to the current outgoing request
binaryfire Sep 8, 2026
f7d264a
Correct database portability and bulk job count assertions
binaryfire Sep 8, 2026
9a625fb
Improve default mail footer and success button contrast
binaryfire Sep 8, 2026
d41c2f6
Synchronize the serializable closure dependency floor across packages
binaryfire Sep 8, 2026
9d7c100
Regenerate Event and Http facade annotations after upstream type updates
binaryfire Sep 8, 2026
cdcab0e
Keep worker limit and polling tests independent of suite memory usage
binaryfire Sep 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
"guzzlehttp/psr7": "^2.13",
"guzzlehttp/uri-template": "^1.0",
"hypervel/laminas-mime": "^0.1.0",
"laravel/serializable-closure": "^2.0.10",
"laravel/serializable-closure": "^2.0.11",
"lcobucci/jwt": "^5.0",
"league/commonmark": "^2.10",
"league/flysystem": "^3.25.1",
Expand Down
2 changes: 1 addition & 1 deletion src/bus/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
],
"require": {
"php": "^8.4",
"laravel/serializable-closure": "^2.0.10",
"laravel/serializable-closure": "^2.0.11",
"nesbot/carbon": "^3.13.1",
"hypervel/cache": "^0.4",
"hypervel/collections": "^0.4",
Expand Down
4 changes: 2 additions & 2 deletions src/bus/src/PendingBatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,11 @@ public function finallyCallbacks(): array
}

/**
* Indicate that the batch should not be cancelled when a job within the batch fails.
* Indicate that the batch should not be canceled when a job within the batch fails.
*
* Optionally, add callbacks to be executed upon each job failure.
*
* @param array<array-key, callable>|bool|callable $param
* @param array<array-key, callable(Batch, ?Throwable): mixed>|bool|(callable(Batch, ?Throwable): mixed) $param
*/
public function allowFailures(mixed $param = true): static
{
Expand Down
6 changes: 4 additions & 2 deletions src/bus/src/UniqueLock.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,16 +122,18 @@ protected function acquireResolvedLock(

/**
* Release the lock for the given job.
*
* @param string $owner the captured lock owner for a job without Queueable state
*/
public function release(mixed $job): void
public function release(mixed $job, string $owner = ''): void
{
$cache = method_exists($job, 'uniqueVia')
? ($job->uniqueVia() ?? $this->cache)
: $this->cache;

$owner = isset(class_uses_recursive($job)[Queueable::class])
? $job->uniqueLockOwner
: '';
: $owner;

static::releaseOwned($cache, static::getKey($job), $owner);
}
Expand Down
2 changes: 1 addition & 1 deletion src/cache/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"hypervel/macroable": "^0.4",
"hypervel/redis": "^0.4",
"hypervel/support": "^0.4",
"laravel/serializable-closure": "^2.0.10",
"laravel/serializable-closure": "^2.0.11",
"psr/simple-cache": "^3.0",
"symfony/console": "^8.1"
},
Expand Down
7 changes: 7 additions & 0 deletions src/cache/src/Console/ClearCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use BadMethodCallException;
use Hypervel\Cache\CacheManager;
use Hypervel\Console\Command;
use Hypervel\Console\Prohibitable;
use Hypervel\Contracts\Cache\Repository;
use Hypervel\Filesystem\Filesystem;
use Symfony\Component\Console\Attribute\AsCommand;
Expand All @@ -16,6 +17,8 @@
#[AsCommand(name: 'cache:clear')]
class ClearCommand extends Command
{
use Prohibitable;

/**
* The console command name.
*/
Expand All @@ -41,6 +44,10 @@ public function __construct(
*/
public function handle(): int
{
if ($this->isProhibited()) {
return self::FAILURE;
}

if ($this->option('locks')) {
return $this->clearLocks();
}
Expand Down
2 changes: 1 addition & 1 deletion src/concurrency/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
},
"require": {
"php": "^8.4",
"laravel/serializable-closure": "^2.0.10",
"laravel/serializable-closure": "^2.0.11",
"hypervel/console": "^0.4",
"hypervel/container": "^0.4",
"hypervel/context": "^0.4",
Expand Down
2 changes: 1 addition & 1 deletion src/data/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"hypervel/reflection": "^0.4",
"hypervel/support": "^0.4",
"hypervel/validation": "^0.4",
"laravel/serializable-closure": "^2.0.10",
"laravel/serializable-closure": "^2.0.11",
"nesbot/carbon": "^3.13.1",
"phpstan/phpdoc-parser": "^2.3",
"symfony/console": "^8.1",
Expand Down
1 change: 1 addition & 0 deletions src/database/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ Documentation: https://hypervel.org/docs/database
- `make:migration` omits Laravel's deprecated `--fullpath` option and obsolete Composer constructor dependency because migration creation no longer dumps autoload files.
- `Blueprint::dropForeign()` widens Laravel's method signature with an optional constraint name when columns are supplied, allowing explicitly named foreign keys to be dropped portably across SQLite and the server databases. Custom `Blueprint` subclasses that override this method must accept the optional second argument.
- Eloquent models that override `CREATED_AT` or `UPDATED_AT` must declare the compatible `?string` constant type, such as `public const ?string UPDATED_AT = null;`. Laravel's constants are untyped, but omitting the type from an override in Hypervel causes a fatal error.
- Eloquent expression plucks use `Query\Builder::pluckWithColumn()` to retain the returned field name for casts and accessors. Custom query builders overriding `pluck()` must also override `pluckWithColumn()` to customize this path. String-based Eloquent plucks still call `pluck()`.

Ported from: https://github.com/laravel/framework
9 changes: 7 additions & 2 deletions src/database/src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
use Exception;
use Generator;
use Hypervel\Context\NonCopyableContext;
use Hypervel\Contracts\Database\Query\Expression as ExpressionContract;
use Hypervel\Contracts\Events\Dispatcher;
use Hypervel\Database\Eloquent\Builder as EloquentBuilder;
use Hypervel\Database\Eloquent\Relations\Relation;
use Hypervel\Database\Events\QueryExecuted;
use Hypervel\Database\Events\QueryFailed;
use Hypervel\Database\Events\TransactionBeginning;
Expand Down Expand Up @@ -295,8 +298,10 @@ public function getSchemaState(?Filesystem $files = null, ?callable $processFact

/**
* Begin a fluent query against a database table.
*
* @param Closure|QueryBuilder|EloquentBuilder<*>|Relation<*, *, *>|ExpressionContract|UnitEnum|string $table
*/
public function table(Closure|QueryBuilder|UnitEnum|string $table, ?string $as = null): QueryBuilder
public function table(Closure|QueryBuilder|EloquentBuilder|Relation|ExpressionContract|UnitEnum|string $table, ?string $as = null): QueryBuilder
{
if ($table instanceof UnitEnum) {
$table = (string) enum_value($table);
Expand Down Expand Up @@ -1078,7 +1083,7 @@ protected function event(object $event): void
/**
* Get a new raw query expression.
*/
public function raw(mixed $value): Expression
public function raw(mixed $value): ExpressionContract
{
return new Expression($value);
}
Expand Down
8 changes: 6 additions & 2 deletions src/database/src/ConnectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

use Closure;
use Generator;
use Hypervel\Contracts\Database\Query\Expression;
use Hypervel\Database\Eloquent\Builder as EloquentBuilder;
use Hypervel\Database\Eloquent\Relations\Relation;
use Hypervel\Database\Query\Builder;
use Hypervel\Database\Query\Expression;
use Hypervel\Database\Query\Grammars\Grammar as QueryGrammar;
use Hypervel\Database\Query\Processors\Processor;
use Hypervel\Database\Schema\Builder as SchemaBuilder;
Expand All @@ -18,8 +20,10 @@ interface ConnectionInterface
{
/**
* Begin a fluent query against a database table.
*
* @param Closure|Builder|EloquentBuilder<*>|Relation<*, *, *>|Expression|UnitEnum|string $table
*/
public function table(Closure|Builder|UnitEnum|string $table, ?string $as = null): Builder;
public function table(Closure|Builder|EloquentBuilder|Relation|Expression|UnitEnum|string $table, ?string $as = null): Builder;

/**
* Get a new raw query expression.
Expand Down
42 changes: 27 additions & 15 deletions src/database/src/Eloquent/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -756,9 +756,7 @@ public function sole(array|string $columns = ['*']): Model
public function value(Expression|string $column): mixed
{
if ($result = $this->first([$column])) {
$column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;

return $result->{Str::afterLast($column, '.')};
return $this->getValueFromModel($result, $column);
}

return null;
Expand All @@ -772,9 +770,7 @@ public function value(Expression|string $column): mixed
*/
public function soleValue(Expression|string $column): mixed
{
$column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;

return $this->sole([$column])->{Str::afterLast($column, '.')};
return $this->getValueFromModel($this->sole([$column]), $column);
}

/**
Expand All @@ -784,9 +780,21 @@ public function soleValue(Expression|string $column): mixed
*/
public function valueOrFail(Expression|string $column): mixed
{
$column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;
return $this->getValueFromModel($this->firstOrFail([$column]), $column);
}

return $this->firstOrFail([$column])->{Str::afterLast($column, '.')};
/**
* Get the selected value through the model's attribute accessors.
*/
protected function getValueFromModel(Model $model, Expression|string $column): mixed
{
// The returned field name accounts for aliases and driver-specific names
// for unaliased expressions without interpreting their SQL.
$column = $column instanceof Expression
? (string) array_key_first($model->getAttributes())
: Str::afterLast($column, '.');

return $model->{$column};
}

/**
Expand Down Expand Up @@ -983,18 +991,22 @@ protected function enforceOrderBy(): void
*/
public function pluck(Expression|string $column, ?string $key = null): BaseCollection
{
$results = $this->toBase()->pluck($column, $key);

$column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column;
if ($column instanceof Expression) {
// Casts and accessors use the returned field name, which cannot be
// recovered from the values alone or reliably inferred from raw SQL.
[$results, $column] = $this->toBase()->pluckWithColumn($column, $key);
} else {
$results = $this->toBase()->pluck($column, $key);

$column = Str::after($column, "{$this->model->getTable()}.");
$column = Str::after($column, "{$this->model->getTable()}.");
}

// If the model has a mutator for the requested column, we will spin through
// the results and mutate the values so that the mutated version of these
// columns are returned as you would expect from these Eloquent models.
if (! $this->model->hasAnyGetMutator($column)
if (is_null($column) || (! $this->model->hasAnyGetMutator($column)
&& ! $this->model->hasCast($column)
&& ! in_array($column, $this->model->getDates())) {
&& ! in_array($column, $this->model->getDates()))) {
return $this->applyAfterQueryCallbacks($results);
}

Expand Down Expand Up @@ -1924,7 +1936,7 @@ public function qualifyColumn(Expression|string $column): string
/**
* Qualify the given columns with the model's table.
*/
public function qualifyColumns(Expression|array $columns): array
public function qualifyColumns(array $columns): array
{
return $this->model->qualifyColumns($columns);
}
Expand Down
11 changes: 6 additions & 5 deletions src/database/src/Eloquent/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Hypervel\Database\Eloquent;

use Closure;
use Hypervel\Contracts\Database\Query\Expression;
use Hypervel\Contracts\Queue\QueueableCollection;
use Hypervel\Contracts\Support\Arrayable;
use Hypervel\Database\Eloquent\Relations\Concerns\InteractsWithDictionary;
Expand Down Expand Up @@ -123,7 +124,7 @@ public function load(array|string $relations): static
*
* @throws MissingAttributeException
*/
public function loadAggregate(array|string $relations, string $column, ?string $function = null): static
public function loadAggregate(array|string $relations, Expression|string $column, ?string $function = null): static
{
if ($this->isEmpty()) {
return $this;
Expand Down Expand Up @@ -193,7 +194,7 @@ public function loadCount(array|string $relations): static
*
* @param array<array-key, array|(callable(\Hypervel\Database\Eloquent\Relations\Relation<*, *, *>): mixed)|string>|string $relations
*/
public function loadMax(array|string $relations, string $column): static
public function loadMax(array|string $relations, Expression|string $column): static
{
return $this->loadAggregate($relations, $column, 'max');
}
Expand All @@ -203,7 +204,7 @@ public function loadMax(array|string $relations, string $column): static
*
* @param array<array-key, array|(callable(\Hypervel\Database\Eloquent\Relations\Relation<*, *, *>): mixed)|string>|string $relations
*/
public function loadMin(array|string $relations, string $column): static
public function loadMin(array|string $relations, Expression|string $column): static
{
return $this->loadAggregate($relations, $column, 'min');
}
Expand All @@ -213,7 +214,7 @@ public function loadMin(array|string $relations, string $column): static
*
* @param array<array-key, array|(callable(\Hypervel\Database\Eloquent\Relations\Relation<*, *, *>): mixed)|string>|string $relations
*/
public function loadSum(array|string $relations, string $column): static
public function loadSum(array|string $relations, Expression|string $column): static
{
return $this->loadAggregate($relations, $column, 'sum');
}
Expand All @@ -223,7 +224,7 @@ public function loadSum(array|string $relations, string $column): static
*
* @param array<array-key, array|(callable(\Hypervel\Database\Eloquent\Relations\Relation<*, *, *>): mixed)|string>|string $relations
*/
public function loadAvg(array|string $relations, string $column): static
public function loadAvg(array|string $relations, Expression|string $column): static
{
return $this->loadAggregate($relations, $column, 'avg');
}
Expand Down
4 changes: 2 additions & 2 deletions src/database/src/Eloquent/Concerns/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ protected function getArrayableItems(array $values): array
*/
public function hasAttribute(string $key): bool
{
if (! $key) {
if ($key === '') {
return false;
}

Expand All @@ -488,7 +488,7 @@ public function hasAttribute(string $key): bool
*/
public function getAttribute(string $key): mixed
{
if (! $key) {
if ($key === '') {
return null;
}

Expand Down
Loading
Loading