<?php namespace app\controllers; use Yii; use yii\web\Controller; class SiteController extends Controller { public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], 'captcha' => [ 'class' => 'yii\captcha\CaptchaAction', 'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null, ], ]; } }
<?php namespace app\modules\shop\actions; use Yii; use yii\base; use yii\web\Response; use app\modules\shop\components\FilterModelBase; use yii\widgets\LinkPager; class ListAction extends base\Action { /** * * @var FilterModelBase */ protected $_filterModel; /** * - * @var callable */ protected $_validationFailedCallback; /** * , * true, - eg $_GET/$_POST[SearchModel][attribute] * @var bool */ public $directPopulating = true; /** * , true, html , * AJAX * @var bool */ public $paginationAsHTML = false; /** * * @var string */ public $requestType = 'get'; /** * * @var string */ public $view = '@app/modules/shop/views/list/index'; public function run() { if (!$this->_filterModel) { throw new base\ErrorException(' '); } $request = Yii::$app->request; if ($request->isAjax) { Yii::$app->response->format = Response::FORMAT_JSON; } // $data = (strtolower($this->requestType) === 'post' && $request->isPost) ? $_POST : $_GET; $this->_filterModel->load(($this->directPopulating) ? $data : [$this->_filterModel->formName() => $data]); // $this->_filterModel->search(); // if ($this->_filterModel->hasErrors()) { /** * , * ajax , , */ if ($request->isAjax){ return (is_callable($this->_validationFailedCallback)) ? call_user_func($this->_validationFailedCallback, $this->_filterModel) : [ 'error' => current($this->_filterModel->getErrors()) ]; } if (empty($data)) { $this->_filterModel->clearErrors(); } } if (!($dataProvider = $this->_filterModel->getDataProvider())) { throw new base\ErrorException(' DataProvider'); } if ($request->isAjax) { // return [ 'list' => $this->_filterModel->buildModels(), 'pagination' => ($this->paginationAsHTML) ? LinkPager::widget([ 'pagination' => $dataProvider->getPagination() ]) : $dataProvider->getPagination() ]; } return $this->controller->render($this->view ?: $this->id, [ 'filterModel' => $this->_filterModel, 'dataProvider' => $dataProvider, 'requestType' => $this->requestType, 'directPopulating' => $this->directPopulating ]); } public function setFilterModel(FilterModelBase $model) { $this->_filterModel = $model; } public function setValidationFailedCallback(callable $callback) { $this->_validationFailedCallback = $callback; } }
<?php use yii\widgets\ActiveForm; use yii\helpers\Html; /** * @var \yii\web\View $this * @var \yii\data\DataProviderInterface $dataProvider * @var \app\modules\shop\components\FilterModelBase $filterModel * @var ActiveForm: $form * @var string $requestType * @var bool $directPopulating */ // safe if (($safeAttributes = $filterModel->safeAttributes())) { echo Html::beginTag('div', ['class' => 'well']); $form = ActiveForm::begin([ 'method' => $requestType ]); foreach ($safeAttributes as $attribute) { echo $form->field($filterModel, $attribute)->textInput([ 'name' => (!$directPopulating) ? $attribute : null ]); } echo Html::submitInput('search', ['class' => 'btn btn-default']). Html::endTag('div'); ActiveForm::end(); } echo \yii\grid\GridView::widget([ 'dataProvider' => $dataProvider, 'filterModel' => $filterModel ]);
<?php namespace app\modules\shop\components; use yii\base\Model; use yii\data\DataProviderInterface; abstract class FilterModelBase extends Model { /** * @var DataProviderInterface */ protected $_dataProvider; /** * @return DataProviderInterface */ abstract public function search(); /** * * , - .. * @return mixed */ public function buildModels() { return $this->_dataProvider->getModels(); } public function getDataProvider() { return $this->_dataProvider; } }
<?php namespace app\modules\shop\models\search; use app\modules\shop; use yii\data\ActiveDataProvider; use yii\data\Pagination; class ProductSearch extends shop\components\FilterModelBase { /** * */ public $price; public $page_size = 20; /** * * @return array */ public function rules() { return [ // ['price', 'required'], // , ['page_size', 'integer', 'integerOnly' => true, 'min' => 1] ]; } /** * * @return ActiveDataProvider|\yii\data\DataProviderInterface */ public function search() { // $query = shop\models\Product::find() ->with('categories'); /** * DataProvider, , */ $this->_dataProvider = new ActiveDataProvider([ 'query' => $query, 'pagination' => new Pagination([ 'pageSize' => $this->page_size ]) ]); // , if ($this->validate()) { $query->where('price <= :price', [':price' => $this->price]); } return $this->_dataProvider; } /** * , * * . * @return array|mixed */ public function buildModels() { $result = []; /** * @var shop\models\Product $product */ foreach ($this->_dataProvider->getModels() as $product) { $result[] = array_merge($product->getAttributes(), [ 'categories' => $product->categories ]); } return $result; } }
<?php namespace app\modules\shop\controllers; use yii\web\Controller; use app\modules\shop\actions\ListAction; use app\modules\shop\models\search\ProductSearch; class ProductController extends Controller { public function actions() { return [ 'index' => [ 'class' => ListAction::className(), 'filterModel' => new ProductSearch(), 'directPopulating' => false, ] ]; } }
{ "list": [ { "id": "7", "price": "50", "title": "product title #7", "description": "product description #7", "create_time": "0", "update_time": "0", "categories": [ { "id": "1", "title": "category title #1", "description": "category description #1", "create_time": "0", "update_time": "0" } ] } ], "pagination": { "pageVar": "page", "forcePageVar": true, "route": null, "params": null, "urlManager": null, "validatePage": true, "pageSize": 20, "totalCount": 1 } }
php yii migrate --migrationPath=modules/shop/migrations
Source: https://habr.com/ru/post/208556/
All Articles