I'm looking at checking the Group id of a user then comparing it to the user's Group name. The code I have so far is in the login function (which is still work in progress):
$this->User->data = $this->data;
//find the user based on the data from the login form
$results = $this->User->findByemail ($this->data['User']['email']);
$this->User->id = $results['User']['id'];
$name = 'admin';
$admin['Group']['name'] = $this->User->Group->find('list', array('conditions' => array('Group.name' => $name)));
$str1 = $admin;
$str2 = 'admin';
if (strcmp($admin, 'admin'))
{
debug ('Yes, admin matches'); die();
}
So far I have the find for the group id but I'm struggling to compare the name with the string 'admin'. Any ideas?
First of all, your $admin seems to be an array, while strcmp() takes two strings as an argument. The result of this comparison is probably not what you might expect it to be.
Second, find('list') will return the field specified by $displayField which can be defined for each model. You either need to specify the displayField or the fields in your find()-call.
First You need to add relation of Group with User in User Model like as :
public $belongsTo = array(
'Group'
);
and add a group_id in user table Than you will get the role name in controller like as :
$results = $this->User->findByemail ($this->data['User']['email']);
$group = $results['Group']['name'];
After that you match the string.
Related
I wanted to let the system to show error message when detect duplicated entry of full_name column without applying unique in the full_name column from public function rules() in model.
My code is like this :
if ($model->load(Yii::$app->request->post()) ) {
$model->full_name = $model->first_name .'' . $model->last_name ;
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name]);
if($name == $model->full_name ){
echo "<script type='text/javascript'>alert('Same student name is detected');</script>";
}
else{
$model->status ="Active";
$model->call_format = Countries::find()->select('phonecode')->where(['name'=> $model->country]);
$model->date_created = new Expression('NOW()');
$user->user_type ='student';
$user->user_name = $model->full_name;
$user->user_status = $model->status;
$user->authKey = Yii::$app->security->generateRandomString(10);
$user->accessToken = Yii::$app->security->generateRandomString(10);
$user->save();
$model->save();
return $this->redirect(['view', 'id' => $model->id]);
}
}
But it shows error like :missing required parameters: id. When i apply model->save(false) ,it seems that the sql statement wont run because of duplicate entry in full_name column. How do i fix it?
Well, there is a construct exists() for such a purposes (see Yii2: check exist ActiveRecord model in database ).
if(StudentInfo::find()->where(['full_name'=> $model->full_name])->exists()){
echo "<script type='text/javascript'>alert('Same student name is detected');</script>";
}
else{...}
it generates the EXISTS query, which is faster and you don't have to load all the data from DB.
If you don't have such a column in your table, then check it by the first/last name.
change it:
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name]);
To:
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name])->one();
Also, if you use the select() method, to use the update() and save() or updateCounters() ... methods, you need the row ID in the same query.
Example:
->select('id') or ->select(['id', 'full_name'])
info: Multi-parameter is an array in select()
:missing required parameters: id
could mean that it couldn't find id, not by duplicate entry in full_name column. please check again
There are two problems with your code.
$name = StudentInfo::find()->select('full_name')->where(['full_name'=> $model->full_name]);
When this line is executed the $name variable will contain instance of yii\db\ActiveQuery. You want to call some method, that will actually execute your query and return result.
You can use scalar() to get the selected value. In that case the $name will contain the content of full_name column from result.
$name = StudentInfo::find()
->select('full_name')
->where(['full_name'=> $model->full_name])
->scalar();
Or you can use count() to get the number of rows that match condition. In that case you may leave out the select() method call but you will need to modify your condition
$count = StudentInfo::find()
->where(['full_name'=> $model->full_name])
->count();
if ($count > 0) {
echo "<script type='text/javascript'>alert('Same student name is detected');</script>";
} else {
// ...
}
The other problem is that you are not checking whether your $model->save() was successful. If your $model is new instance and the id attribute is auto-generated then when $model->save fails the $model->id is empty and then you are trying to redirect user to view with empty id.
Your code should look like this:
if ($user->save() && $model->save()) {
return $this->redirect(['view', 'id' => $model->id]);
}
If the save fails because of validation the validation errors will be stored in models and if you are using ActiveForm widget the errors will be displayed. If you are not using ActiveForm you should do something to tell user that operation failed.
Since you are saving two different models you might want to consider use of transactions to prevent a situations where $user model is saved but save of $model fails.
I have in my database many ads , I want to select one from theme by name I try but I get a null return
public function index()
{
# code...
// $Ads = ads::all();
// return $this->sendResponse($Ads->toArray(), 'Ads read succesfully');
$column = 'name'; // This is the name of the column you wish to search
$Ads = ads::where($column)->first();
return response()->json(['success'=> true,'ads'=>$Ads, 'message'=> 'Ads read succesfully']);
}
and this what I get in post man:
{
"success": true,
"ads": null,
"message": "Ads read succesfully" }
There are some things to note before you dig in:
You need to have Request variable so that you can fetch the user input or if its static then just provide it static. However, static doesnt make sense so I am providing a code that will take input variable.
You need to compare the value with column name in order to fetch it.
Name of the models should be singular form and start with capital as its same as class name so you should use Ad instead of ads, ads is proper for table name, not for model name.
Considering above notes, here is the code which will work for you:
public function index(\Illuminate\Http\Request $request)
{
# code...
$column = 'name'; // This is the name of the column you wish to search
$columnValue = $request->input('name');// This is the value of the column you wish to search
$Ads = Ad::where($column, $columnValue)->first();
return response()->json(['success'=> true,'ads'=>$Ads, 'message'=> 'Ads read succesfully']);
}
Description: I have a site. I just want to keep track of a suspicious request and possible barn them only if needed. I just started to implement that feature. I have all the records of IP Addresses, but I'm not sure how to increment their visit count each time - they visit.
Goal: To increment visit_count attribute each time user visit a site
In my visitors table, I have an ip attribute
I want to check for an existing first before, I perform the saving, and other logics, but I'm just a little stuck here.
How do I check if the value already exists in the database using Laravel ?
Any hints on this will be much appreciated !
I've tried
Model : Visitor.php
class Visitor extends Model {
protected $table = 'visitors';
//Validation Rules and Validator Function
public static function validator($input, $id = ''){
$rules = array(
'ip' =>'unique:visitors,ip,'.$id,
);
return Validator::make($input,$rules);
}
}
Controller : Visitor.php
// Check for existing
$validator = Visitor::validator($ip);
if ($validator->fails()) {
$ip = Visitor::where('ip', '=', $ip)->firstOrFail();
$id = $ip['attributes']['id']; //<------ Not sure if this is a proper way
if($ip){
$visitor = Visitor::findOrFail($id);
$visitor->visit_count = $visitor->visit_count + 1 ;
$visitor->save();
}
} else {
$visitor = new Visitor;
$visitor->ip = $ip;
$visitor->visit_count = $visitor->visit_count + 1 ;
$visitor->save();
}
Result
I keep getting
Argument 1 passed to Illuminate\Validation\Factory::make() must be of the type array, string given
I believe, it from this line here $validator = Visitor::validator($ip);
The error message kind of gives it away. The Validator expects the values and the rules to be two separate arrays, each with keys denoting the columns name that needs to be validated. You have that for the rules, but not for the values being checked. This will fix your error:
return Validator::make(['ip' => $input], $rules);
I have a function that takes user id as an argument, and returns array of user data:
function user_get_data( $user_id ) {
$query = "SELECT * FROM users WHERE id = '$user_id'";
...
return $user_data; // associative array
}
Usage:
$user_data = user_get_data( 123 );
var_dump( $user_data );
// Outputs:
// array (size=2)
// 'id' => int 123
// 'name' => string 'Juan Vitelli' (length=12)
And I have a function that takes user id, and returns count of posts of that user:
function user_get_post_count( $user_id ) {
$query = "SELECT COUNT(*) FROM posts WHERE user_id = '$user_id'";
...
return $post_count;
}
Now I want to rewrite user_get_post_count() function so it can take as an argument either user id directly, or user data array returned by user_get_data() function, which contains that id. Something like this...
function user_get_post_count( $user_data_or_id ) {
// get user id
if( is_array( $user_data_or_id ) ) {
$user_id = $user_data_or_id[ "id" ];
} else {
$user_id = $user_data_or_id;
}
// get post count
$query = "SELECT COUNT(*) FROM posts WHERE user_id = '$user_id'";
...
return $post_count;
}
I just want to know if something like this is considered as good practice or if there is better way. If it is good practice my next question is if $user_data_or_id is suitable variable name for what I am doing.
There are different approaches to this. You may want to read a bit about ORM, Active Record, Data Mapper, Query Object.
In your context, I don't see a point of passing an array just to extract the "user_id" from it. If you are passing an array, i would say that this is indicating that you're looking for "posts" by more than one "user_id", or according to a specific criteria. That is, in another more general context, you are building your query based on the input parameter. And in that case, it would indeed be better to pass a filter array.
For example, your array might look like this:
array('user_id' => 7, 'title'=>'abc','ts_created'=>1234567, 'published'=>1, ...)
And using some SQL syntax builder, you would end up with a query like this:
SELECT
*
FROM
`posts`
WHERE
`user_id` = 7 AND
`title` LIKE '%abc%' AND
`ts_created` >= 1234567 AND
`published` = 1
.
.
.
As you can see, this would return a resultset that matches your search criteria. If you criteria specifies a "userID", then you would get back "posts" only by this user in the results.
To do this in OOP, there's also several approaches. If you want to map the above to a simple "User" class, you could do:
class User{
public function getByID($userID){
//sql query
$query = "SELECT FROM users where user_id = $userID"
//execute query and return results
}
}
But as you can see, this is not very flexible if you want to specify more filter criteria for the SQL query. To make it more flexible, taking "Posts" as an example, you can create a "Post" class:
class Post{
/*
* This is not a working code, just an example to give you an idea.
*/
protected $mSQLBuilder;
protected $mTable = 'posts';
public function __construct(){
$this->mSQLBuilder = new SQLBuilder($this->mTable);
}
public function search($filter = array()){
//
$criteria = array('fields'=>array('*'),'filters'=>$filter);
//
$query = $sqlBuilder->build($criteria);
//
return $query->execute()->fetchAll();
}
public function count($filter){
//
$criteria = array('fields'=>array('count(*)'),'filters'=>$filter);
//
$query = $sqlBuilder->build($criteria);
//
return $query->execute()->fetch();
}
public function setSQLBuilder($builder){
$this->sqlBuilder = $builder;
}
}
Make sure you do a bit of reading about ORM and design patterns.
I'm trying to get a logged in users type (eg super admin, registered). I've tried this code:
$user =& JFactory::getUser();
$curref = $user->usertype();
Which gives a function not found error. What is the correct way to get the user type name, without a db query if possible.
You just need to treat usertype as a member, not a method.
$type = $user->usertype;
Documentation: http://docs.joomla.org/Accessing_the_current_user_object
You can take a look at the $user object structure by doing a var_dump. Try this, and inspect the output:
var_dump( $user );
So if you want to iterate over the groups array, you could do the following:
$groupIDs = array();
foreach( $user->groups as $groupID ){
$groupIDs[] = $groupID;
}
var_dump( $groupIDs );
You can also use some joomla methods to return the groups in different ways. You may want to check out this forum thread: http://forum.joomla.org/viewtopic.php?t=530721