Yii2 enablePrettyUrl fail and frontend post request fail - yii2

i was trying to make
this url
http://localhost/advanced/frontend/web/index.php?r=test
into
htttp://localhost/advanced/frontend/web/tests in yii2
also to receive post request
this in my codding in common/config/main.php
<?php
return [
'vendorPath' => dirname(dirname(__DIR__)) . '/vendor',
'components' => [
'cache' => [
'class' => 'yii\caching\FileCache',
],
'urlManager' => [
],
'urlManagerFrontEnd' => [
'enablePrettyUrl' => true,
'rules' => [
[
'class' => 'yii\rest\UrlRule',
'controller' => ['test'],
'only' => ['index', 'create'],
],
],
'showScriptName' => false,
],
],
];
this in my frontend testController
namespace frontend\controllers;
use Yii;
use yii\rest\ActiveController;
use common\models\Test;
use yii\data\ActiveDataProvider;
class TestController extends ActiveController {
public $modelClass = 'common\models\Test';
public function actions(){
$actions = parent::actions();
unset($actions['create']);
return $actions;
}
public function actionCreate(){
$model = new Test();
$model->load(Yii::$app->request->post(),'');
$model->save();
return $model;
}
}
i have a problem in the post request when i tried
Postman result jpg
so i have 2 problem the first is the prettyUrl and the post request
if u have a solution please make it easy because i just learn php yii2 html css etc for 1 month

Related

Yii2 all controllers and actions require login, need to add some exceptions. How can I do it?

I've found a lot of answers on how to create Access Control that requires login to all controllers and actions.
The following post shows how I did all controllers require login:
Yii2 require all Controller and Action to login
I've used the code below under my components:
'as beforeRequest' => [
'class' => 'yii\filters\AccessControl',
'rules' => [
[
'allow' => true,
'actions' => ['login', 'error'],
],
[
'allow' => true,
'roles' => ['#'],
],
]
],
But, I want to add some exceptions to it. Some controllers need to have some actions visible to Guest.
I've tried to use this code inside my behaviors on ReportsController:
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'actions' => ['share'],
'roles' => ['?'],
],
],
]
Still get redirected to login.
I'm trying to to make actionShare($param) {} public to guests.
What am I missing?
Thanks for all your help!
First execute
yii migrate --migrationPath=#yii/rbac/migrations
from command prompt to create RBAC table in data base.
Then create RbacController in component folder
namespace app\components;
use yii;
use yii\web\Controller;
use yii\filters\AccessControl;
class RbacController extends Controller
{
public function RbacRule($modules = false)
{
$rules = false;
if ($modules){
$rules = [
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
$module = Yii::$app->controller->module->id;
$action = Yii::$app->controller->action->id;
$controller = Yii::$app->controller->id;
$route = "/$module/$controller/$action";
$post = Yii::$app->request->post();
if (\Yii::$app->user->can($route)) {
return true;
}
}
];
}else{
$rules = [
'allow' => true,
'roles' => ['#'],
'matchCallback' => function ($rule, $action) {
//$module = Yii::$app->controller->module->id;
$action = Yii::$app->controller->action->id;
$controller = Yii::$app->controller->id;
$route = "/$controller/$action";
$post = Yii::$app->request->post();
if (\Yii::$app->user->can($route)) {
return true;
}
}
];
}
return $rules;
// return true;
}
}
then extend to your controller using this RbacController instead of controller.
use app\components\RbacController;
class AdminController extends RbacController
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
// [
// 'actions' => ['login', 'logout'],
// 'allow' => true,
// 'roles' => ['?'],
// ],
parent::RbacRule(),
],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
'bulk-delete' => ['post'],
],
],
];
}
.......
}
If your controller is inside Modules folder then you have to use
parent::RbacRule(TRUE) instead of parent::RbacRule(),

Yii2 restricting access to RBAC Module itself

How I can restrict access to RBAC Module itself?
I'm using yii\rbac\DbManager and I have created a module(Authorization) in backend for permission assignment,create auth items, now I want to make sure only admin can access this module!
In controller I have used something this and it's working fine.
use yii\filters\AccessControl;
class MyController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'only' => ['index', 'view', 'create', 'update', 'delete'], //only be applied to
'rules' => [
[
'allow' => true,
'actions' => ['index', 'view', 'create', 'update','delete'],
'roles' => ['admin'],
],
],
],
.........
I have put this in Authorization.php init function but nothing happen, all auth controllers are accessable.
public function init()
{
if(\Yii::$app->user->can('admin'))
parent::init();
// custom initialization code goes here
}
Update
backend/config/main.php
'modules' => [
'authorization' => [
'class' => 'backend\modules\authorization\Authorization',
],
],
In your module class you can add this method
public function beforeAction($action)
{
if (!parent::beforeAction($action)) {
return false;
}
if (!\Yii::$app->user->can('admin')) {
throw new \yii\web\ForbiddenHttpException('You are not allowed to access this page.');
}
return true;
}

How to set a Yii2 module to return JSON response using config/main.php

I am currently using the following lines of code on every controller in the API module in order to return JSON response/data.
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['contentNegotiator']['formats']['text/html'] = Response::FORMAT_JSON;
return $behaviors;
}
It works well. But how can i achieve the same using main configuration file?
I tried the following on my frontend/config/main.php
'api' => [
'class' => 'app\modules\api\Module',
'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'common\models\User',
'enableSession' => false,
'loginUrl' => null,
],
'response' => [
'class' => \yii\filters\ContentNegotiator::className(),
'formats' => [
'application/json' => \yii\web\Response::FORMAT_JSON,
],
]
],// Module component
],
above configuration still returns XML response only. What is the correct configuration to set all the controllers in the API module to return JSON data.Thanks
Configure your response component as follows:
'response' => [
'format' => yii\web\Response::FORMAT_JSON,
// ...
]
formats is an array containing the available formats. format is the actual output format.
Add this is your config/main-local.php
use yii\web\Response;
$config['bootstrap'][]=
[
'class' => '\yii\filters\ContentNegotiator',
'formats' => [
'text/html' => Response::FORMAT_JSON,
]
];

Invalid JSON data in request body: Syntax error POST Call Rest API YII2

When I try to post using Postman,I get this error {"name":"Bad Request","message":"Invalid JSON data in request body: Syntax error.","code":0,"status":400,"type":"yii\\web\\BadRequestHttpException"}
My controller is
`class CountryController extends ActiveController
{
public $modelClass = 'app\models\Country';
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['index', 'view','create'],
'formats' => ['application/json' => Response::FORMAT_JSON,],
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index'=>['get'],
'view'=>['get'],
'create'=>['post'],
'update'=>['put'],
'delete' => ['delete'],
'deleteall'=>['post'],
],
],
];
}
}`
added
'parsers' => [
'application/json' => 'yii\web\JsonParser',
]
in api/config.php file.
Where I am wrong??
Try this
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['index', 'view','create'],
'formats' => ['application/json' => Response::FORMAT_JSON]
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'index'=>['get'],
'view'=>['get'],
'create'=>['post'],
'update'=>['post'],
'delete' => ['delete'],
'deleteall'=>['post'],
]
]
];
}
I am using wordpress 4.7 on php 7, also getting problems with the empty request body.
My Controller :
add_action('rest_api_init', function()
{
register_rest_route('v0', '/accounts/(?P<slug>[a-z0-9_\-]+)/accounts', array(
'methods' => 'GET',
'callback' => function($request)
{
try {
return 'hello';
}
catch (Exception $e) {
$error = json_decode($e->getMessage(), true);
return new WP_Error($error['status_code'], $error['message'], "");
}
}
));
});
Response Error :
{"code":"rest_invalid_json","message":"Invalid JSON body passed.","data":{"status":400,"json_error_code":4,"json_error_message":"Syntax error"}}
I did not found any solution rather than changing in WP core : wp-includes/rest-api/class-wp-rest-request.php and chaning line 672 for conditional check for empty body or not.
$params = json_decode( $this->get_body(), true );

Yii2 Apply a function to all requests

Is there any way to apply a function to all requests and queries in Yii2?
I want to replace specific characters for all of them.
I am using Yii2 advanced app
Thanks.
This is the config file:
$config = [
'language' => 'en',
'components' => [
'request' => [
'cookieValidationKey' => 'something',
],
'authManager' => [
'class' => 'yii\rbac\DbManager',
'defaultRoles' => ['guest'],
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
],
],
];
return $config;
Without extending custom code on each request can be exexuted like so (add this to your application config):
return [
'on beforeRequest' => function () {
if (!Yii::$app->get('user', false)) {
return;
}
$user = User::getCurrent();
if ($user) {
Yii::$app->setTimeZone($user->time_zone);
}
},
'on afterRequest' => function () {
...
},
];
Depending on when you need to execute code (before or after the request) use 'on beforeRequest' or 'on afterRequest' accordingly.
yii2 have a request component. You can extend yii\web\request and define your custom implementation.
[
...
'components' =>
'request' => [
'class' => '\common\MyRequest',
'addGeoLocationForExample' => true,
]
...