bumpcore/panorama 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

bumpcore/panorama

Composer 安装命令:

composer require bumpcore/panorama

包简介

Query-backed Eloquent models for Laravel.

README 文档

README

Bumpcore Panorama is a Laravel package for building Eloquent models from query sources. It lets a model behave like a normal read model while its rows come from a subquery, aggregate, CTE, or custom query builder source.

Use it when you need query-backed models for reports, projections, aggregate tables, read-only relation targets, or custom database features without giving up Eloquent relations and builder chaining.

Table Of Contents

Version Table

Bumpcore Panorama Laravel PHP
0.x ^12.0 ^8.2
0.x ^13.0 ^8.3

Installation

Install the package with Composer:

composer require bumpcore/panorama

Quick Start

Add the HasSource trait to an Eloquent model and define newSource().

use Bumpcore\Panorama\HasSource;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;

class CustomerBalance extends Model
{
    use HasSource;

    protected $primaryKey = 'customer_id';

    public function newSource(int $customer_id): Builder
    {
        return DB::table('invoices')
            ->selectRaw('customer_id, sum(amount) as balance')
            ->where('customer_id', $customer_id)
            ->groupBy('customer_id');
    }
}

$balances = CustomerBalance::query()
    ->where('balance', '>', 0)
    ->withParams(customer_id: $customer->getKey())
    ->get();

The model is still queried through Eloquent. Panorama only replaces the model's from clause with the source query when the builder is executed.

HasSource

HasSource registers a global scope and a local withParams() scope on the model. The global scope wraps the model query in the source returned by newSource().

Defining a Source

newSource() may return an Eloquent builder or a base query builder.

use Bumpcore\Panorama\HasSource;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class OpenInvoiceTotal extends Model
{
    use HasSource;

    public function newSource(): Builder
    {
        return Invoice::query()
            ->selectRaw('customer_id, sum(amount) as open_total')
            ->where('status', 'open')
            ->groupBy('customer_id');
    }
}

The source is not expected to hit a real table with the model name. It becomes the derived table Panorama queries from.

Passing Source Params

Use withParams() to pass named arguments to newSource().

$balance = CustomerBalance::query()
    ->withParams(customer_id: 1, status: 'open')
    ->first();

Array params are also supported:

$balance = CustomerBalance::query()
    ->withParams([
        'customer_id' => 1,
        'status' => 'open',
    ])
    ->first();

Params must use string keys because they are passed as named arguments. Later calls replace earlier values, just like normal builder state.

Changing the Source Alias

By default, Panorama uses the model table name as the SQL alias for the wrapped source. Override querySourceAlias() when the source should use a different alias.

class CustomerBalance extends Model
{
    use HasSource;

    public function querySourceAlias(): string
    {
        return 'customer_balances';
    }
}

The alias must not be an empty string.

Eloquent Compatibility

Panorama keeps the consumer-facing Eloquent builder intact. You can still use:

  • normal Eloquent builder methods;
  • local scopes;
  • relations and eager loading;
  • whereHas() against query-backed relation models;
  • custom Eloquent builders;
  • external query builder extensions.

The test suite includes compatibility coverage for:

  • staudenmeir/laravel-cte
  • tpetry/laravel-postgresql-enhanced
  • consumer-defined custom Eloquent builders

Exceptions

All package-specific failures extend:

Bumpcore\Panorama\Exceptions\PanoramaException

More specific exceptions are available:

  • InvalidQuerySourceException
  • MissingQuerySourceException

InvalidQuerySourceException is thrown when a model does not use the required trait, when newSource() returns an unsupported value, or when the source alias is empty.

MissingQuerySourceException is thrown when a model uses HasSource without overriding newSource().

Testing

Install development dependencies:

composer install

Run the test suite:

composer test

Run static analysis:

composer analyse

Check code style:

composer cs:check

Run the 100% coverage gate:

composer test:coverage

Coverage requires PCOV, Xdebug, or phpdbg.

Contribution

Contributions are welcome. If you find a bug or have a suggestion for improvement, please open an issue or create a pull request.

Please include tests for behavioral changes and run the quality checks before submitting a pull request:

composer cs:check
composer analyse
composer test

Changelog

See CHANGELOG.md for version history.

Credits

License

The MIT License (MIT). Please see License File for more information.

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-06-01

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固