mobileka / scope-applicator-yii2
Scope Applicator bindings for Yii2 Framework
Requires
- php: >=5.4.0
- mobileka/scope-applicator: 1.1.*
- yiisoft/yii2: 2.0.*
Requires (Dev)
- mockery/mockery: 0.9.3
- phpunit/phpunit: 4.1.*
- satooshi/php-coveralls: 0.6.1
This package is not auto-updated.
Last update: 2024-11-09 18:48:45 UTC
README
ScopeApplicator brings an elegant way of sorting and filtering data to your Yii2 projects.
Overview
ScopeApplicator is an easy and logical way to achieve something like this:
/posts
– returns a list of all posts
/posts?recent
– returns only recent posts
/posts?author_id=5
– returns posts belonging to an author with an id=5
/posts?author_id=5&order_by_title=desc&status=active
– returns only active posts belonging to an author with an id=5
and sorts them by a title in a descending order
Requirements
– PHP 5.4 or newer
– Yii 2.0.x
Installation
composer require mobileka/scope-applicator-yii2 1.0.*
Usage
Let's learn by example. First of all, we'll implement an author_id
filter for post
table.
These are steps required to achieve this:
- Create a
PostQuery
class which extendsMobileka\ScopeApplicator\Yii2\ActiveQuery
and define auserId
method - Create a
Post
model which extendsMobileka\ScopeApplicator\Yii2\Model
and make it use thePostQuery
instead of a regularActiveQuery
- Create a basic
PostController
which outputs a list of posts when/posts
route is hit - Tell ScopeApplicator that
userId
scope is available and give it an alias - Visit
/posts?author_id=1
and enjoy the result
Ok, let's cover these step by step.
— Create a PostQuery
class in app/models/queries
directory with the following content:
<?php namespace app\models\queries; use Mobileka\ScopeApplicator\Yii2\ActiveQuery; class PostQuery extends ActiveQuery { public function userId($id = 0) { if ($id) { return $this->andWhere(['user_id' => $id]); } return $this; } }
I'll refer the userId()
method as a userId
scope in the future.
Make sure that this class extends Mobileka\ScopeApplicator\Yii2\ActiveQuery
.
– Create a Post
model and override the find
method like follows:
<?php namespace app\models; use app\models\queries\PostQuery; use Mobileka\ScopeApplicator\Yii2\Model; use Yii; class Post extends Model { public static function find() { return Yii::createObject(PostQuery::className(), [get_called_class()]); } }
This makes sure that our userId
scope will be available to the Post
model.
– Next, create a PostController
:
<?php namespace app\controllers; use Yii; use yii\web\Response; use yii\rest\Controller; use app\models\Post; class PostController extends Controller { public function actionIndex() { return Post::find()->all(); } public function behaviors() { $behaviors = parent::behaviors(); $behaviors['contentNegotiator']['formats'] = [ 'application/json' => Response::FORMAT_JSON ]; return $behaviors; } }
In this case I extend the yii\rest\Controller
and make sure that its output format is set to JSON.
– Now let's modify this controller to make it use ScopeApplicator:
<?php namespace app\controllers; use Yii; use yii\web\Response; use yii\rest\Controller; use app\models\Post; class PostController extends Controller { /** * Scope configuration array */ protected $scopes = ['userId']; public function actionIndex() { return Post::applyScopes($this->scopes)->all(); } public function behaviors() { $behaviors = parent::behaviors(); $behaviors['contentNegotiator']['formats'] = [ 'application/json' => Response::FORMAT_JSON ]; return $behaviors; } }
Note that I added a new protected property which describes available scopes. Right now we have only userId
.
Also note that I have replaced Post::find()
with Post::applyScopes($this->scopes)
.
If you have done all the above steps, you should be able to populate your post
table and try to filter data like follows:
/posts?userId=x
.
But we wanted it to be author_id
instead of userId
, so we have to configure our scope and add an alias:
<?php namespace app\controllers; use Yii; use yii\web\Response; use yii\rest\Controller; use app\models\Post; class PostController extends Controller { /** * Scope configuration array */ protected $scopes = [ 'userId' => [ // here it is! 'alias' => 'author_id' ] ]; public function actionIndex() { return Post::applyScopes($this->scopes)->all(); } public function behaviors() { $behaviors = parent::behaviors(); $behaviors['contentNegotiator']['formats'] = [ 'application/json' => Response::FORMAT_JSON ]; return $behaviors; } }
— That's it! Now you can visit /posts?author_id=x
and check the result.
alias
is only one of the many available scope configuration options. These are described in ScopeApplicator's documentation.
Contributing
If you have noticed a bug or have suggestions, you can always create an issue or a pull request (use PSR-2). We will discuss the problem or a suggestion and plan the implementation together.
License
ScopeApplicator is an open-source software and licensed under the MIT License.