Lease
module, it will be located along the modules/lease/controllers/frontend
file of the ApiController.php
file and write the following in it: <?php namespace modules\lease\controllers\frontend; use yii\rest\ActiveController; class ApiController extends ActiveController { public $modelClass = 'modules\lease\models\frontend\Lease'; }
modelClass
specifying modelClass
as modules\lease\models\frontend\Lease
, the controller knows which model can be used to extract and manipulate data.cors
behavior to the controller, if necessary: ... public function behaviors() { $behaviors = parent::behaviors(); $behaviors['corsFilter' ] = [ 'class' => \yii\filters\Cors::className(), ]; // ( ) return $behaviors; } ...
$behaviors = parent::behaviors();
and continue to add behaviors to it. ... $behaviors['contentNegotiator'] = [ 'class' => \yii\filters\ContentNegotiator::className(), 'formats' => [ 'application/json' => \yii\web\Response::FORMAT_JSON, ], ]; ...
... $behaviors['access'] = [ 'class' => \yii\filters\AccessControl::className(), 'only' => ['create', 'update', 'delete'], 'rules' => [ [ 'actions' => ['create', 'update', 'delete'], 'allow' => true, 'roles' => ['@'], ], ], ]; ...
CheckAccess()
method to check whether the current user has the privilege to perform a specific action on the specified data model. For example, let's write a check so that a user can edit or delete only his listings: … public function checkAccess($action, $model = null, $params = []) { // // ForbiddenHttpException if ($action === 'update' || $action === 'delete') { if ($model->user_id !== \Yii::$app->user->id) throw new \yii\web\ForbiddenHttpException(sprintf('You can only %s lease that you\'ve created.', $action)); } } ...
urlManager
component in the bootstrapping module class in the modules/lease/Bootstrap.php
file ... $app->getUrlManager()->addRules( [ [ 'class' => 'yii\rest\UrlRule', 'controller' => ['leases' => 'lease/api'], 'prefix' => 'api' ] ] ); …
prefix
so that all links for accessing API services start with /api/*
, so this pattern can be easily hidden from search engines in the robots.txt file. In the future, in each module that will participate in the RESTful API, we will add the controller for the API in the same way.Lease
model. We have created APIs that include:“require”
section of the composer.json
file. ... "bower-asset/angular": "^1.5", "bower-asset/angular-animate": "^1.5", "bower-asset/angular-bootstrap": "^2.2" …
php composer.phar update
command line php composer.phar update
.AssetBundle
in the file so that we can easily pick up AngularJS files to the layout. This is what the \frontend\assets\AngularAsset.php
file will look like <?php namespace frontend\assets; use yii\web\AssetBundle; use yii\web\View; class AngularAsset extends AssetBundle { public $sourcePath = '@bower'; public $js = [ 'angular/angular.js', 'angular-animate/angular-animate.min.js', 'angular-bootstrap/ui-bootstrap.min.js', 'angular-bootstrap/ui-bootstrap-tpls.min.js' ]; public $jsOptions = [ 'position' => View::POS_HEAD, ]; }
public $jsOptions = [ 'position' => View::POS_HEAD, ];
Tells Yii that you need to attach JavaScript files in the head section of our layout instead of placing them at the very end of the body section, so the AngularJS core will load as quickly as possible. We also have to add this Bundle in the dependencies of the main asset bundle
application and in the same place connect another 'js/app.js'
file, which will contain an instance of the AngularJS application. <?php namespace frontend\assets; use yii\web\AssetBundle; /** * Main frontend application asset bundle. */ class AppAsset extends AssetBundle { public $basePath = '@webroot'; public $baseUrl = '@web'; public $css = [ 'css/site.css', ]; public $js = [ 'js/app.js', 'js/controllers.js', 'js/directives.js', 'js/services.js', ]; public $depends = [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', 'frontend\assets\AngularAsset' ]; }
controllers.js
to the same bundle at the same time. In the future, we will write in it our front-end controllers, directives.js
and services.js
to describe the directives and services, respectively.ng-app
directive to the html element - this will launch our AngularJS application, which we will call “app”
. ... <html lang="<?= Yii::$app->language ?>" data-ng-app="app" > ...
data-ng-app
directive exactly this way; otherwise, our html markup will not pass W3C validation. This does not have any effect on the work of the directives, and the layout should be validated in accordance with the project specification. Therefore, for all non-standard directives we will add the data-
prefix.frontend/web/js/app.js
There we will define the application and connect to it the modules that we are going to use. 'use strict'; var app = angular.module('app', [ 'ngAnimate', 'ui.bootstrap', 'controllers' // frontend/web/js/controllers.js ]);
frontend/web/js/services.js
LeaseService
, we will write the LeaseService
service, which will perform CRUD operations for listings through communication with the REST API of the backend: 'use strict'; var app = angular.module('app'); app.service('LeaseService', function($http) { this.get = function() { return $http.get('/api/leases'); }; this.post = function (data) { return $http.post('/api/leases', data); }; this.put = function (id, data) { return $http.put('/api/leases/' + id, data); }; this.delete = function (id) { return $http.delete('/api/leases/' + id); }; });
controllers
module will contain a very simple LeaseController
controller. It will request data from /api/leases
and pass the data to the display. 'use strict'; var controllers = angular.module('controllers', []); controllers.controller('LeaseController', ['$scope', 'LeaseService', function ($scope, LeaseService) { $scope.leases = []; LeaseService.get().then(function (data) { if (data.status == 200) $scope.leases = data.data; }, function (err) { console.log(err); }) } ]);
\modules\lease\views\frontend\default\index.php
file using the ng-controller
directive and output the data provided by the API to the table: <div class="lease-default-index" data-ng-controller="LeaseController"> <div> <h1>All Leases</h1> <div data-ng-show="leases.length > 0"> <table class="table table-striped table-hover"> <thead> <th>Year</th> <th>Make</th> <th>Model</th> <th>Trim</th> </thead> <tbody> <tr data-ng-repeat="lease in leases"> <td>{{lease.year}}</td> <td>{{lease.make}}</td> <td>{{lease.model}}</td> <td>{{lease.trim}}</td> </tr> </tbody> </table> </div> <div data-ng-show="leases.length == 0"> No results </div> </div> </div>
/lease/default/index
, we will see a list of all listings recorded in the database.Source: https://habr.com/ru/post/318242/
All Articles