How to configure URL token in yii2 rest UrlRule - yii2

I just created a yii2 rest API but some of the endpoint created are not working as expected.
when i do http://localhost/v1/countries I get a response but when i do http://localhost/v1/countries/AU i get a 404 error. I think the problem is with the token but i don't know how to fix this. Any help would be appreciated
<?php
namespace api\modules\v1\controllers;
class CountryController extends \yii\rest\ActiveController
{
public $modelClass = 'api\modules\v1\models\Country';
}
<?php
namespace api\modules\v1\models;
/**
* This is the model class for table "country".
*
* #property string $code
* #property string $name
* #property int $population
*/
class Country extends \yii\db\ActiveRecord
{
/**
* {#inheritdoc}
*/
public static function tableName()
{
return 'country';
}
public static function primaryKey() {
return ['code'];
}
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['code', 'name'], 'required'],
[['population'], 'integer'],
[['code'], 'string', 'max' => 2],
[['name'], 'string', 'max' => 52],
[['code'], 'unique'],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'code' => 'Code',
'name' => 'Name',
'population' => 'Population',
];
}
}
config file
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'rules' => [
['class' => 'yii\rest\UrlRule',
'controller' => ['v1/default', 'v1/country'],
'tokens' => [ '{id}' => 'id:\\w+' ],
//'pluralize'=>false,
'extraPatterns' => [
'GET,POST,PUT index' => 'index',
],
],
],
],
GET /countries: working
HEAD /countries: return status 200 empty message
POST /countries: working
GET /countries/AU: not working 404 error
HEAD /countries/AU: not working 404 error
PATCH /countries/AU: not working 404 error
PUT /countries/AU: not working 404 error
DELETE /countries/AU: not working 404 error
OPTIONS /countries: return status 200 (null)
OPTIONS /countries/AU: not working 404 error

Related

How to use relations using joinWith in yii2 search model

I have two models with related data fbl_leagues and fbl_country tables. fbl_leagues have a column country_id which is related to fbl_country, now in yii2 gridView i was able to do something like [
'attribute' => 'country_id',
'value' => 'country.name',
], which gives the name of the country rather than the countries id, then i also want to enable searching by country name rather than country_id but i get the below error
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'country.name' in 'where clause'
The SQL being executed was: SELECT COUNT(*) FROM `fbl_leagues` LEFT JOIN `fbl_country` ON `fbl_leagues`.`country_id` = `fbl_country`.`id` WHERE `country`.`name` LIKE '%s%'
Below is my LeagueSearch model
class LeagueSearch extends League
{
/**
* {#inheritdoc}
*/
public function rules()
{
return [
[['id', 'created_at', 'updated_at'], 'integer'],
[['name','country_id'], 'safe'],
];
}
/**
* {#inheritdoc}
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = League::find();
$query->joinWith('country');
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'country.name',$this->country_id]);
return $dataProvider;
}
}
and my league model
{
return [
[['country_id', 'created_at', 'updated_at'], 'integer'],
[['name','country_id'], 'required'],
[['name'], 'string', 'max' => 100],
[['country_id'], 'exist', 'skipOnError' => true, 'targetClass' => Country::className(), 'targetAttribute' => ['country_id' => 'id']],
];
}
/**
* {#inheritdoc}
*/
public function attributeLabels()
{
return [
'id' => Yii::t('app', 'ID'),
'country_id' => Yii::t('app', 'Country Name'),
'name' => Yii::t('app', 'Name'),
'created_at' => Yii::t('app', 'Created At'),
'updated_at' => Yii::t('app', 'Updated At'),
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getCountry()
{
return $this->hasOne(Country::className(), ['id' => 'country_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getPerfectSelections()
{
return $this->hasMany(PerfectSelection::className(), ['league_id' => 'id']);
}
Now i noticed that when i comment out $query->joinWith('country'); then there will be no error but searching not working as expected
Hmm silly me i guess i later figure out the problem the table name is fbl_country so i suppose write fbl_country.name but wrote country.name in my search model, it's being a long day though, thanks for all

yii2 custom validation addError message doesn't show

when i use custom validations on yii2 dynamic forms it doesn't show any error messages below the input field.Below I have posted my model.
It doesn't show any error messges when qty field gets validated
namespace frontend\models;
use Yii;
class OrderD extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'order_d';
}
public function rules()
{
return [
[['item_id', 'qty', 'price', 'value'], 'required'],
[['item_id'], 'integer'],
[['price', 'value'], 'number'],
[['order_code'], 'string', 'max' => 10],
[['item_id'], 'exist', 'skipOnError' => true, 'targetClass' => Item::className(), 'targetAttribute' => ['item_id' => 'id']],
[['order_code'], 'exist', 'skipOnError' => true, 'targetClass' => OrderH::className(), 'targetAttribute' => ['order_code' => 'code']],
['qty', 'validateQty']
];
}
public function validateQty($attribute)
{
$qty = $this->$attribute;
if ($qty >= 5)
{
$this->addError('qty', "qty validation successful");
}
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
'id' => 'ID',
'item_id' => 'Item ID',
'order_code' => 'Order Code',
'qty' => 'Qty',
'price' => 'Price',
'value' => 'Value',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getItem()
{
return $this->hasOne(Item::className(), ['id' => 'item_id']);
}
/**
* #return \yii\db\ActiveQuery
*/
public function getOrderCode()
{
return $this->hasOne(OrderH::className(), ['code' => 'order_code']);
}
}
Be sure to know custom validations are php functions and not convert as javascript to validate in runtime .. those will work after the page has submit and send to controller ..
here is simple sample you want :
['qty','custom_function_validation'],
];
}
public function custom_function_validation($attribute, $params){
if($this->$attribute>5){
$this->addError($attribute,'it\'s more than 5');
}
}
To create a validator that supports client-side validation, you should implement the yii\validators\Validator::clientValidateAttribute() method which returns a piece of JavaScript code that performs the validation on the client-side.
public function clientValidateAttribute($model, $attribute, $view)
{
return <<<JS
// your validation
JS;
}
See the documentation here: http://www.yiiframework.com/doc-2.0/guide-input-validation.html#implementing-client-side-validation
Use method addError() in a controller and then just render your view file
Example
if ($promo_code) {
if ($promo_code->status == '1') {
$message = 'This combination is incorrect.';
$model->addError('promo_code', $message);
return $this->render('index', compact('model'));
}
$promo_code->status = '1';
$promo_code->save();
$model->save();
}

Yii2 Yii::$app->user->identity->id returns an error instead of redirecting to login page

in my behaviours I have specified that actionList can only be viewed by authenticated users.
$behaviors [ 'access' ] = [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => [ 'list' ],
'allow' => ['#'],
]
],
];
In actionList I'm getting the user_id:
public function actionList() {
$user_id = \Yii::$app->user->identity->id;
return $this->render( 'list' );
}
All good, but if you go to this action when not logged in, you get an error:
PHP Notice – yii\base\ErrorException
Trying to get property of non-object
Makes sense, I'm not logged in so I don't have a user id, but why does the code go that far? If I comment the $user_id = \Yii::$app->user->identity->id; out, I get redirected to the login page, which is the expected behaviour. I don't think I should have to do yet another check to see if someone is logged in in the action itself, shouldn't that be handled by the behaviours['access'] beforehand?
Try this changing the allow and roles attributes:
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'actions' => ['list'],
'allow' => true,
'roles' => ['#'],
],
], // rules
], // access
];
}
More info here.
Here is my cent to the already good answers above
Add following code to the main controller file in your project (not the base controller) but some controller above this which is base for every other controller
/**
* Check if user is logged in and not logged out
*
* #param type $action
* #return type
*/
public function beforeAction($action) {
$this->enableCsrfValidation = false;
if(!empty($action) && $action->actionMethod == 'actionLogin') {
return true;
}
/* Check User's Login Status */
if (is_null(Yii::$app->user->identity)) {
$this->redirect(Url::to(['../site/login']));
Yii::$app->end();
}
return true;
}

Yii2: Returning an array of primary keys

Maybe I'm missing the essentials but why the following code will throw a Bad Request error (#400) complaining on "Missing parameter id" when rendering a view on a MySQL view?
In model:
public static function primaryKey()
{
return [
'vcostumbre_id',
'vbibliografia_id',
'vpagina_inicial',
];
}
In controller:
public function actionView($id)
{
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
But this will work:
public function actionView($vcostumbre_id, $vbibliografia_id, $vpagina_inicial)
{
$id = [
'vcostumbre_id' => $vcostumbre_id,
'vbibliografia_id' => $vbibliografia_id,
'vpagina_inicial' => $vpagina_inicial,
];
return $this->render('view', [
'model' => $this->findModel($id),
]);
}
Because in the URL you have not the parameter "id".
It should be /mycontroller/view?id=42".
Check the view file where the link is. It should be :
Url::to(['/controller/view', 'id' => 42])

Yii2: Method not allowed arror while logout action from different controller

When i am executing logging out action from
....index.php?r=teams/dashboard
it is throwing me #405 method not allowed error. DO i have to implement logout method other than site controller.. i.e in teams controller????
/**
* #inheritdoc
*/
public function behaviors()
{
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'logout' => ['post'],
],
],
];
}
this action does not accept Get method, you should send it as Post OR remove it from VerbFilter.
<?= Html::a('Logout', ['/user/logout'], ['data-method'=>'post']) ?>