pbmedia / laravel-specifications
指定您的 Eloquent 模型
Requires
- php: ~7.0
- pbmedia/specifications: ^1.0.0
Requires (Dev)
- orchestra/testbench: ^3.3
- phpunit/phpunit: ~5.0
- scrutinizer/ocular: ^1.3
- squizlabs/php_codesniffer: ^2.3
README
此 Laravel 包提供了指定 Eloquent 模型的能力。它包含一个 'matcher' 服务,可以根据您提供的 'criteria' 对模型集合进行排序。困惑?看看例子,几乎可以自我解释。底层使用的是框架无关版本的此包。
要求
- 兼容 Laravel 5.3 及以上版本。
- PHP 7.0 和 7.1。
安装
通过 Composer
$ composer require pbmedia/laravel-specifications
将服务提供者和外观添加到您的 app.php
配置文件中
'providers' => [ ... Pbmedia\Specifications\Laravel\SpecificationsServiceProvider::class, ... ]; 'aliases' => [ ... 'SpecificationsMatcher' => Pbmedia\Specifications\Laravel\SpecificationsFacade::class ... ];
使用 artisan CLI 工具发布迁移文件
php artisan vendor:publish --provider="Pbmedia\Specifications\Laravel\SpecificationsServiceProvider"
php artisan migrate
用法
假设您有一个 Eloquent 模型,代表您出售的产品。使用 HasSpecificationsTrait
和 CanBeSpecified
接口,您可以为产品添加规范。将接口和特性添加到 Eloquent 模型中
use Illuminate\Database\Eloquent\Model; use Pbmedia\Specifications\Interfaces\CanBeSpecified; use Pbmedia\Specifications\Laravel\Models\HasSpecificationsTrait; class Product extends Model implements CanBeSpecified { use HasSpecificationsTrait; }
让我们考虑如何指定您的产品,例如 '磁盘容量' 和 '内部内存'。让我们使用 AttributeModel
将这些存储到数据库中。
use Pbmedia\Specifications\Laravel\Models\AttributeModel; $diskCapacity = AttributeModel::create(['name' => 'Disk Capacity in GB']); // or use the 'createWithName' helper method: $internalMemory = AttributeModel::createWithName('Internal Memory in MB');
使用 ScoreModel
,您可以绑定一个值到 AttributeModel
并将其添加到产品的规范中
use Pbmedia\Specifications\Laravel\Models\ScoreModel; $macbookAir = Product::whereName('MacBook Air')->first(); $macbookPro = Product::whereName('MacBook Pro')->first(); $macbookAir->specifications()->set( $internalMemory, new ScoreModel(['value' => 4096]) ); // or use the 'withValue' helper method: $macbookPro->specifications()->set( $internalMemory, ScoreModel::withValue(8192) ); // don't forget to save the products! $macbookAir->save(); $macbookPro->save();
specifications()
方法返回一个具有以下方法的 Specifications
类
// add a AttributeScore object to the specifications public function add(AttributeScore $attributeScore): Specifications; // helper method to add multiple AttributeScore objects at once public function addMany(array $attributeScores = []): Specifications; // does the same as the 'add' method, but generates the AttributeScore object // automatically based on the given Attribute and Score objects public function set(Attribute $attribute, Score $score): Specifications; // returns a boolean wether the given Attribute is present public function has(Attribute $attribute): bool; // returns the AttributeScore object based on the given Attribute object public function get(Attribute $attribute): AttributeScore; // forgets the AttributeScore object based on the given Attribute object public function forget(Attribute $attribute): Specifications; // returns a Collection object containing all AttributeScore objects public function all(): Collection; // count the number of AttributeScore objects public function count(): int;
AttributeScore
对象结合了属性对象和分数对象,并且只有三个方法可用
$diskCapacity = new AttributeModel(['name' => 'Disk Capacity in GB']); $size = new ScoreModel(['value' => 256]); $attributeScore = new AttributeScore($diskCapacity, $size); // returns the AttributeModel $attributeScore->getAttribute(); // returns the ScoreModel $attributeScore->getScore(); // returns 256 $attributeScore->getScoreValue();
现在让我们关注 Matcher
服务。您必须向服务提供两种类型的数据。首先,您必须将产品添加到服务中(或实现 CanBeSpecified
接口的其他模型)。其次,您必须添加 'criteria',就像您添加到产品中一样。由于服务本身也实现了 CanBeSpecified
接口,因此通过使用 specifications()
方法,这完全相同。
在这个例子中,我们将再次使用 MacBook 产品。记住我们指定了这些产品的内部内存。假设您正在寻找具有 16 GB 内部内存的笔记本电脑,但不幸的是,这些笔记本电脑在我们的数据库中不存在。匹配器服务将根据产品与规范最接近的程度对产品进行排序。
// the MacBook Air has 4096 MB of Internal Memory $macbookAir = Product::whereName('MacBook Air')->first(); // the MacBook Pro has 8196 MB of Internal Memory $macbookPro = Product::whereName('MacBook Pro')->first(); $matcher = new Matcher(); $matcher->addCandidate($macbookAir); $matcher->addCandidate($macbookPro); // you can also use the 'addCandidates' helper method: $matcher->addCandidates($macbookAir, $macbookPro); $matcher->addCandidates([$macbookAir, $macbookPro]); // now provide some criteria. $memoryAttribute = AttributeModel::whereName('Internal Memory in MB')->first(); $sixteenGigabytesScore = ScoreModel::withValue(16384); $matcher->specifications()->set( $memoryAttribute, $sixteenGigabytesScore ); // now let the service do its magic! $products = $matcher->get(); // returns a Collection instance // prints the MacBook Pro var_dump($products[0]); // print the MacBook Air var_dump($products[1]);
MacBook Pro 是数组中的第一个元素,因为它与给定规范的接近程度比 MacBook Air 更高。您可以添加任意多的规范,每个在比较中都被视为同等重要。Matcher
服务也通过 Laravel 外观提供
$matcher = SpecificationsMatcher::addCandidates([$macbookAir, $macbookPro]);
变更日志
有关最近更改的更多信息,请参阅CHANGELOG。
测试
$ composer test
贡献
有关详细信息,请参阅CONTRIBUTING 和 CONDUCT。
安全
如果您发现任何与安全相关的问题,请通过电子邮件pascal@pascalbaljetmedia.com联系,而不是使用问题跟踪器。
鸣谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。