Yii2 Rbac (DbManager)- return null - yii2

Yii::$app->user->can('do_all') return null when i enter by my user (in db only 1 user).
What i did wrong.
1)- I created 4 tables.
auth_asignment: item_name => do_all, user_id => 1
auth_item: name => do_all, type => 1
auth_item_child: empty
auth_rule: empty
2)- I added in config/web.php
'components' => [
'authManager' => [
'class' => 'yii\rbac\DbManager',
'defaultRoles' => ['guest'],
]
]
3)- In controller i added
public function actionIndex()
{
if(Yii::$app->user->can('do_all')){
return $this->render('index');
}
else{
throw new ForbiddenHttpException('The requested page is not exist.');
}
}

I think you shuld add value in auth_item_child and organize the value this way
try adding a role ind this way
auth_item: name => do_all_role, type => 1
auth_item_child parent: do_all_role, child : do_all
auth_asignment: item_name => do_all_role, user_id => 1
and use (attention at the class name normally the User class name start with an Uppercase char)
Yii::$app->User->can('do_all');

Related

Custom filter in Gridview (Regular or Overdue)

I have a registration_date column where I store the date that the customer was registered in the company (example: 2015-06-12). You'll need to filter if the customer has a failed or overdue registration (if registration_date is longer than 365 days).
In the preview screen I can display this condition, but I need to display as a filter in Gridview with 2 options (Regular or Overdue).
[
'attribute' => 'registration_date',
'format' => 'raw',
'value' => function ($model) {
return $model->getRegistration($model->registration_date);
},
'filter' => [Regular or Overdue], ????
'contentOptions' => $contentOptions,
'headerOptions' => $headerOptions,
],
How do I make this check in model ClientSearch?
What I understand is that you want to add a filter on the column registration_date which is as a Date type column, which should have 2 options Regular and Overdue and should filter the records based on
Regular
The option should filter out all the records that have the registration_date difference smaller than or equal to 365 days.
Overdue
The option should filter out all the records that have the registration_date difference from the current date greater than 365 days.
Your gridview column will look like below
GridView Changes
If the above is correct then, first of all, add the following configuration in your gridview column configuration. we will provide an active-dropdown in the filter option and assign it a name registration_status.
Note: I have used select2 for the dropdown you can use the default if you do not want, and change the $searchModel to the exact name for the client search model that you are passing to the filterModel option in your gridview.
[
'filter' => \kartik\widgets\Select2::widget ( [
'data' => $searchModel->statusOptions(),
'model' => $searchModel ,
'attribute' => 'registration_status' ,
'options' => [
'placeholder' => 'Registration Status' ,
'class' => 'form-control' ,
'id' => 'registration_status' ,
] ,
'theme' => \kartik\widgets\Select2::THEME_BOOTSTRAP ,
'pluginOptions' => [
'allowClear' => true ,
] ,
] ) ,
'attribute' => 'created_at' ,
'label' => Yii::t ( 'app' , 'Registration Date' ) ,
] ,
Without Select2
[
'filter' => Html::activeDropDownList ( $searchModel , 'registration_status' , $searchModel->statusOptions () , [ 'prompt' => 'Select Registration status' ] ) ,
'attribute' => 'created_at' ,
'label' => Yii::t ( 'app' , 'Registration Date' ) ,
] ,
ClientSearch Changes
Add the constants on top of your ClientSearch model.
const STATUS_OVERDUE = 'overdue';
const STATUS_REGULAR = 'regular';
Add the function statusOptions() inside the ClientSearch model.
public function statusOptions() {
return [
self::STATUS_OVERDUE => 'Overdue' ,
self::STATUS_REGULAR => 'Regular'
];
}
Add a public property registration_status inside the search model.
public $registration_status
Add this field we created to the safe list inside the rules()
function.
function rules(){
return [
//other rules
[ [.... , 'registration_status' ] , 'safe' ] ,
];
}
Then the next thing is to accomplish the SQL condition which would filter out the records, you can use MySQL functions, DATEDIFF() and CURDATE(), like DATEDIFF(CURDATE(),registration_date)>365.
So add the following inside the search() function of the search model before the last line return $dataProvider.
if ( $this->registration_status === self::STATUS_OVERDUE ) {
$query->andFilterWhere ( [ '>' , 'DATEDIFF(NOW(),registration_date)' , 365 ] );
} else if ( $this->registration_status === self::STATUS_REGULAR ) {
$query->andFilterWhere ( [ '<=' , 'DATEDIFF(NOW(),registration_date)' , 365 ] );
}
Now you can filter the records based on the selected option and if you clear out the options in the drop-down it will show all of the records.

Checking 2 unique codes against the table and then registering the form

I've 2 different tables with 2 columns [code,status] each and the column 'code' contains unique code in integers (392,21,2981,2743,..etc) and they are about 100 in each table while the status tells if these codes were used or not.
I want the form to be only submitted when both of the provided codes from the user match the codes in those 2 tables and have the status '0'
I could create a very simple validation in the controller but that dosen't make much sense to what i just explained
public function formValidationPost(Request $request)
{
$this->validate($request,[
'name' => 'required|min:5|max:35',
'email' => 'required|email|unique:users',
'mobile' => 'required|numeric',
'code_a' => 'bail|required|exists:code_a,code',
'code_b' => 'bail|required|exists:code_b,code'
],[
'name.required' => ' The name field is required.',
'name.min' => ' The name must be at least 5 characters.',
'name.max' => ' The name may not be greater than 35 characters.',
]);
dd('You successfully added all fields.');
}
So with my validation rules I want to be able to make sure that:
Form doesn't submit unless both the provided codes are matched in the database ( code_a[table] and code_b[table] ) and their status to be '0'
I hope this makes sense.
Thanks
Reference
use Illuminate\Validation\Rule;
$this->validate($request,
[...
'mobile' => 'required|numeric',
'code_a' => [
'bail',
'required',
Rule::exists('code_a', 'code')->where(function($query) {
$query->where('status', 0);
})
],
'code_b' => [
'bail',
'required',
Rule::exists('code_b', 'code')->where(function($query) {
$query->where('status', 0);
})
]
],
[...]);

Multiple categories in Url

I want to create links something like that:
http://example.com/cat1/itemname-1
http://example.com/cat1/cat2/itemname-2
http://example.com/cat1/cat2/cat3/itemname-3
http://example.com/cat1/cat2/cat3/[..]/cat9/itemname-9
How rule looks like in yii2 UrlManager and how to create links for this?
Url::to([
'param1' => 'cat1',
'param2' => 'cat2',
'param3' => 'cat3',
'slug' => 'itemname',
'id' => 3
]);
Above code is really bad for multiple category params.
I add that important is only last param it means ID.
Controller looks like that:
public function actionProduct($id)
{
echo $id;
}
The below url rule would to this trick but you have to build the "slug" with the categories within your controller:
'rules' => [
['route' => 'module/controller/product', 'pattern' => '<slug:(.*)+>/<id:\d+>', 'encodeParams' => false],
]
Generate the Url:
yii\helpers\Url::toRoute(['/module/controller/product', 'slug' => 'cat1/cat2/cat3', 'id' => 1])
The output would be:
example.com/cat1/cat2/cat3/1

CakePHP 3.0 cannot get 2 items from 1 table

In a football match i have 2 clubs "Home-Club" and "Away-Club" . I have created table "match" and "club" in MySQL. In "match" table has 2 foreign key "home_id" and "away_id". I'm using cakePHP to show list matches, match information contain names of "Home-Club" and "Away-Club". How to get name of "Home-Club" and "Away-Club" in template file ( .ctp file ).
For now I using this code in the template file:
$match->club->name
Code in Controller:
public function index()
{
$this->paginate = [
'contain' => ['Club']
];
$this->set('match', $this->paginate($this->Match));
$this->set('_serialize', ['match']);
}
It always show name of "Away-Club". I don't known how to get name of "Home-Club"
Please tell me how to do it
Thanks very much!
Problem is in definition of belongsTo associations. Try to redefine it this way:
$this->belongsTo('HomeClub', [
'className' => 'Club',
'foreignKey' => 'home_id',
'propertyName' => 'home_club'
]);
$this->belongsTo('AwayClub', [
'className' => 'Club',
'foreignKey' => 'away_id',
'propertyName' => 'away_club'
]);
Names of belongsTo associations have to be unique. Now contain them in the controller
// ...
$this->paginate = [
'contain' => ['HomeClub', 'AwayClub']
];
$this->set('matches', $this->paginate($this->Match));
And then in the template use
<?= $match->home_club->name ?>
<?= $match->away_club->name ?>

Retrieve value from new column

I am trying to learn opencart structure, and trying to create a new column under the table product. The new column is "test"
Then I try to retrieve the data under this page index.php?route=checkout/cart (replace price with test column)
catalog\controller\checkout\cart.php
...
$this->data['products'][] = array(
'key' => $product['key'],
'thumb' => $image,
'name' => $product['name'],
'model' => $product['model'],
'option' => $option_data,
'quantity' => $product['quantity'],
'stock' => $product['stock'] ? true : !(!$this->config->get('config_stock_checkout') || $this->config->get('config_stock_warning')),
'reward' => ($product['reward'] ? sprintf($this->language->get('text_points'), $product['reward']) : ''),
'price' => $product['test'], //<-- new column
'total' => $total,
'href' => $this->url->link('product/product', 'product_id=' . $product['product_id']),
'remove' => $this->url->link('checkout/cart', 'remove=' . $product['key'])
);
The problem is I'm not getting any output, and I'm not sure how to work with the model. Which query/function is related with this page ?
The problem is that the $products that are available at cart.php controller are retrieved from the session where they have been stored in previously set structure, so there is no test index and You should get a Notice: undefined index 'test' in .... The $products are retrieved by
foreach ($this->cart->getProducts() as $product) {
//...
}
See /system/library/cart.php and method getProducts() to understand what I am speaking about.
If You would like to use this at catalog/controller/product/category.php or catalog/controller/product/product.php controllers, the code You are trying will work.
If You replace the price within all product lists and product detail, these controllers:
product/
category.php
manufacturer_info.php
product.php
search.php
special.php
module/
bestseller.php
featured.php
latest.php
special.php
with Your value, the final price within cart would be Your test value.