store variables on user model laravel 4 - php

my user model has 3 fields: username, password and category_id
so when i auth the auth object will have all of the 3 variables, but i want to add the name of the category that is on other model
and i get like:
$category = Category::find(Auth::user()->category_id);
$category_name = $category->name;
so the question is who can i add $category_name to the Auth::user() object, in order to retrive it every time he is logged like this:
Auth::user()->category_name
i try Session::put("category_name","Category 1") when you loggin, but when i close the windows and open it by the last closed windows, it delete that variable.
i want to store the variable since the person login, untill the person logout, but if the person has logged in and close the window and then the person re open the page the variable must be filled

You can use Eloquent Accessors
In User model
public function setCategoryNameAttribute()
{
$categoryID = $this->category_id;
$category = Category::find($categoryID);
return $category->name;
}
You can access category name like
Auth::user()->category_name

try this
in your User model add the following function
EDIT try this
public function category_name()
{
return \Cache::remember('category_' . $this->id , 60, function()
{
return $this->belongsTo('App\Category')->get();
});
}
now everytime you use
Auth::user()->category_name
you will have the name
this will eco the name in your View
{{ Auth::user()->category_name }}
NOTE : this code is not the best solution even if it worked for you, this is open for changes, i just want you to get the point that if you want to access something via Auth::user()->getname you have to add the getname function in the User model
and by the way can you show us the relation you set in you model? because that would make it easier
an exemple
if you have something like this in ur model(hasone)
public function category() {
return $this->hasOne('category');
}
you can do this
Auth::user()->category->name

Related

Getting Model from within Collection

Something very basic but I'm having a hard time solving this.
I have a list of users in the database that show as online users. I am fetching these users by their user_id
Model
public function scopeloggedInUser($query){
return $query->select('user_id')->get();
}
when I var_dump or dd it shows that its a collection of a list of currently logged in users. (Said it was super simple).
I need to fetch those individual users. How do I dilute this to the individual user within the Online Model.
Within the Controller
public function index(Online $online)
{
$activeuser = $online->loggedInUser();
return view('user.user', compact('activeuser'));
}
In your online-model specify a relationship to the real user like this:
public function user()
{
return $this->hasOne('App\User');
}
In your view you can now access each user in your foreach-loop like this:
foreach ($activeusers as $user)
{
echo $user->user->username; // or whatever fields you need
}
But to be honest: in your case I wouldn't set up a new database table and new model if you need this functionality.
Move your logic to your User model and add a boolean field to your user table and change your query-scope to this (again: in your user model)
public function scopeOnline($query){
return $query->where('online', 1);
}
You also shouldn't do a get() within a scope because then you have no more access to the query builder. For example: you want all logged in users that are female.
With get: not pretty.
Without get:
User::online()->where('gender', '=', 'female')->get();

Laravel PHP, getting clicked link class

I have a html5 table which is dynamically made from database items and it contains links, e.g. delete icon, which is in link tags . I want to be able to click the delete icon and know, which item I want to delete. I have set class of the link the same as the relevant database items ID, but I cant read the class from the controller, after I click the link. Is there a method of doing that in PHP Laravel? Or maybe you could suggest a way better way to accomplish that? This seems a way off tactic for this.
If each row on the table represents a row on database, so your link could contain the id from database.
For example, a user table.
Row 1 => Link /users/delete/1
Row 2 => Link /users/delete/2
Row 3 => Link /users/delete/3
By doing it this way, you can know for sure which one is called.
On your routes file, if you are not using Route::resource(), you should have something like this:
Route::get('users/delete/{id}', 'UsersController#destroy');
And in your destroy method:
public function destroy($id)
{
// your logic here
}
Format your links as:
If for example you are listing all items using foreach:
#foreach( $items as $item )
{{$item->name}}
#endforeach
Inside routes.php
Route::get('item/delete/{id}', 'ItemsController#deleteItem');
inside ItemsController.php define the following function
public function deleteItem($id) {
$item = Item::get($id);
if( !$item ) App::abort(404);
$item->delete();
return Redirect::to('/');
}
and I am assuming you have your model in Item.php
class Item extends Eloquent {
protected $table = 'items';
}
and your items table has id and name columns

getting data from database in laravel using the username

I have a table in database called 'User'. All I want is to get the basic information of the user. I've tried to get data from database but the thing that keep me bugging is that I get all the data inside the table.
UserTable
|id|username|firstname|lasttname|middlename|gender|age|birthdate|address|contact_number|designation|
1 admin lee chiu kim male 47 07-22-87 cebu 0977452445 admin
2 lrose rose loo mar female 27 04-02-88 cebu 0977452445 manager
3 mgray gray men try male 37 01-22-89 cebu 0977452445 employee
UserProfile.php --> Model
<?php
class UserProfile extends Eloquent {
public $timestamps=false;
protected $table = 'users';
protected $fillable=array('firstname','lastname', 'middlename', 'gender', 'age', 'birthdate', 'address', 'contact_number', 'designation');
}
This is the model of my site.
UserProfileContoller.php --> Controller
<?php
class UserProfileController extends \BaseController {
public function index($id)
{
$userprofile = User::find($id);
return View::make('userprofile.index', array('userprofile' => $userprofile));
//return View::make('userprofile.index')->with('UserProfiles',UserProfile::get());
}
For example I am currently log in to username admin and I want to edit and view my profile. How can I get the data just for admin only. Please Help.
The situation hers is that. let say they have 3 employees. So in the table 3 username. lets assume that I'm not the admin. I will log in using lrose. and the other one log in as admin and so.on. If the three of us will go to our profiles the only thing to display there is their own profile and can edit it.
Assuming you property set-up your database why not just use the DB object?
// In the User table find the item with the username 'admin'
DB::table('User')->where('username', '=', 'admin')->get();
To get the information of some user that is logged in (given you have their username), called something like $userprofile. Then all we need to do is find by id then get the username:
// $id is the ID of the logged in user
$userprofile = User::find($id)->username; // get username of logged in user
$userprofile::find($id) will get you the information for admin only, if $id = 1.
find() only returns 1 tuple from the database.
After you call find(), you can access the data as such:
$userprofile->firstname
you mean when you pass $id to index method of User Controller all the data of other users are returned?
That's kinda weird.
$userprofile = User::find($id); change that line to $userprofile = User::find(1); and see if you can only get the data of admin.
If not, probably you are calling other method. Probably you iterate over the index method somewhere else for multiple times so that you get all the data in the database. To confirm both possibilities, just add echo 'I am in' at the entry point of your index method. If no echo message is shown, the first possibility is true. If multiple echo messages occur, the second possibility is true.
Hope this helps.
first of all, you need to use Session after login and store the id of the username in the Session.
e.g.
Step 1:
if($login) //successfull login
{
Session::put('userid', $userid);
//this id, you have to retreive it from the database after successful login
}
Step 2:
Setup the route
Route::get('profile',['uses' => 'UserProfileContoller#index']);
Step 3:
Controller
public function index()
{
if(is_null(Session::get('userid'))) return Redirect::to('login');
return View::make('userprofile.index', ['userprofile' => $this->model->index()]);
// Above code uses dependency injection to retrieve the information from db.
}
Step 4:
UserProfileModel
public function index()
{
return DB::table('user')->where('id','=', Session::get('userid'))->first();
}
p.s. i find it easier to use query builder than eloquent orm. if you want to use orm, change the code where needed.

Laravel belongsToMany function

I'm using Laravel to create a basic site with the following function: A user can follow certain topics. I have a 'users' table, a 'topics' table, and as a pivot table, I have a 'following' table.
users
----
user_id (primary)
user_first_name
etc..
following
---------
follow_id
user_id (foreign)
topic_id (foreign)
topics
------
topic_id (primary)
topic_name
etc...
I'm trying to create a page that displays all of the topics, but for the topics that the current user is following, I need to show an overlay on the box.
I have a User Model with the following function:
public function follows() {
return $this->belongsToMany('Topic', 'following', 'user_id', 'user_id');
}
However, I'm not too sure where to go from here (or whether this is right!)
Would be hugely grateful for any help.
First of all, you made a mistake on your follows method.
You have the same variable name on local and foreign id 'user_id'.
Then,
Did you already add a topic to an user ?
If yes, it would be great if you do the same as in your User model on the Topic model
public function followedBy()
{
return $this->belongsToMany('User', 'following', 'topic_id', 'user_'id');
}
From here, you can add a following topic to users by doing
$user->following()->attach($topic_id);
Or
$user->following()->attach([$first_topic, $second, $third, ...]);
You can use the sync method too, but that will delete all previous relationship between user and the topics which are not in the array.
To retrieve all information you can simply do the following:
foreach ($user->following as $topic) {};
/!\ Do not add parentheses to following otherwise you will get a QueryBuilder instead of a collection of the topics. /!\
If you want to add more filters (for example only active topics)
foreach ($user->following()->active()->get() as $topic) {}
Notice that here I added the parentheses which are necessaries because I do not directly want the topics but a QueryBuilder to filter the results.
Call the ->get() method when you are done filtering.
(This suppose you have a method called scopeActive() in your model)
See Laravel scope to do so : http://laravel.com/docs/eloquent#query-scopes
You can do the opposite on the topic side by doing :
foreach ($topic->followedBy as $user) {}
PS: sorry for my English, If you misunderstood something. Not my native language.
You sustain the following function in User Model
public function follows() {
return $this->belongsToMany('Topic', 'following');
}
and use below statement to retrieve the all topics of any user
$topics = User::find(1)->follows;
Where 1 is the user id for particular user.
1 In your setup you use non-default primary keys (topic_id / user_id / follow_id instead of id) so be sure to set:
protected $primaryKey = 'topic_id';
on each of your models accordingly.
2 I would suggest renaming the relation - follows is ambiguous, unless you have literally 3 models there.
3 Your relation for your current setup, like already suggested by #ChainList:
public function follows()
{
return $this->belongsToMany('Topic', 'following', 'user_id', 'topic_id');
}
4 In order to check if a user already follows given topic, do this:
// I Assume logged in user
$user = Auth::user();
$topics = Topic::all();
// somewhere in your view
#foreach ($topics as $topic)
{{ $topic->name }}
#if ($user->follows->contains($topic->id))
Already following this topic
#else
Follow this topic (put a link here or whatever)
#endif
#endforeach
With this you run just a single query for user's topics, when you call $user->follows for the first time.
My suggestion would be:
// leave id as primary key, it will make your life easier
// rename relation to
public function topics()
{
// rename table name to something meaningful
return $this->belongsToMany('Topic', 'topic_user'); // laravel convention
// or if you like topics_followers
}
Almost there, the follows() relationship needs to be like this:
public function follows() {
return $this->belongsToMany('Topic', 'following', 'user_id', 'topic_id');
}
Then you should be able to grab the topics associated to the current user by doing this:
$topicsUserIsFollowing = Auth::user()->follows;
To start following a topic, you can do this (assuming you have the topic's ID):
Auth::user()->follows()->attach($topic_id);
Edit
If you want to see if a topic is followed by someone, then in your Topic model put a function like this:
public function isFollowedBy($user)
{
return $user->follows->contains($this->topic_id);
}
So then you can do something like this:
$currentUser = Auth::user();
$topics = Topics::all();
foreach($topics as $topic) {
echo $topic->topic_name;
if( $topic->isFollowedBy($currentUser) ){
echo ' - [Already following this topic]';
} else {
echo ' - [Follow this topic]';
}
}
You'd want to put the loop in your view, this is just for illustration

Dynamically populating the dropdown menus in PHP Cake. Access Model from another Model?

I am building a Cake PHP application. Different users have different properties so I use two objects to store a user for example
User hasOne Student / Student belongs to User
User hasOne Lecturer / Lecturer belongs to User
The profile edit page will allow the User to edit all their details for both objects. I've set up the form and used saveAll so save both objects. My problem is dynamically populating the dropdown menus depending on which role the user has.
For example the counties field. Admin does not have an address whereas Student and Lecturer do. I have setup my Country model to find all my counties and put them into opt-groups in the select box (sorting them by country as shown here Dropdown list with dyanmic optgroup)
I can do this fine inside the Students/LecturersController as they allow me to access the Country model as I set $uses variable. I do not want to do this inside the UsersController as not all user roles have an address and an address is never stored inside the User object. I tried putting the code in the model but then I don't know how to access other Models inside a Model. Up to now I've had no problem building the app and I feel that I may have made a bad design decision somewhere or there's something I'm not understanding properly.
Essentially I'm asking how do I implement the setForForm() function below.
public function edit() {
//get user
$user = $this->Auth->user();
//get role
$role = $user['User']['role'];
if ($this->request->is('post') || $this->request->is('put')) {
//get IDs
$userID = $user['User']['id'];
$roleID = $user[$role]['id'];
//set IDs
$this->request->data[$role]['user_id'] = $userID;
$this->request->data[$role]['id'] = $roleID;
$this->request->data['User']['id'] = $userID;
//delete data for role that is not theirs
foreach ($this->request->data as $key => $value) {
if($key !== 'User' && $key !== $role) {
unset($this->request->data[$key]);
}
}
if ($this->User->saveAll($this->request->data)) {
//update logged in user
$this->Auth->login($this->User->$role->findByUserId($userID));
$this->Session->setFlash('Changes saved successfully.');
} else {
$this->Session->setFlash(__('Please try again.'));
}
}
//set role for easy access
$this->set(compact('role'));
//sets required variables for role form
$this->User->$role->setForForm();
//fills in form on first request
if (!$this->request->data) {
$this->request->data = $user;
}
//render form depending on role
$this->render(strtolower('edit_' . $role));
}
//this is the method I would like to implement in the Student/Lecturer model somehow
public function setForForm() {
$counties = $this->Country->getCountiesByCountry();
$homeCounties = $counties;
$termCounties = $counties;
$this->set(compact('homeCounties', 'termCounties'));
}
Not sure if I get your question correct, but I think what you want is the following:
User hasOne Student / Student belongs to User
and
Student hasOne Country / Country belongsTo Student
(and the same for Lectureres)
then from your UsersController you can do:
$this->User->Student->Country->findCountiesByCountry();
hope that helps
--
EDIT:
if you want to want to use $role instead of Student/Lecturer you would have to do it like this:
$this->User->{$role}->Country->findCountiesByCountry();
In the end I decided to just load counties in the user controller regardless of whether the form will need them or not since Admin is the only user that doesn't need them.
Try something like this:
public function setForForm() {
App::import('model', 'Country');
$Country = New Country();
$counties = $Country->getCountiesByCountry();
$homeCounties = $counties;
$termCounties = $counties;
$this->set(compact('homeCounties', 'termCounties'));
}
I don't know is this the best solution or not but it is working at least :)
Edited
Here is another mistake. Its not recommended to set variable from model to view , you can return data that will be set then in edit function normally set it to the view , but anyways if you need to set from model to the view you can load controller class to your model using App::import(); and use set function.

Categories