Spatie Laravel-activitylog causedBy, performedOn with Logging model - php

I am using this package for activity logging in laravel
I am able to do logging from controller but, I want to do it using Model.
I read this useful information from the official documentation
but, it doesnt store subject id, type and causer id, type. I can store it from controller as
activity()
->causedBy($userModel)
->performedOn($someContentModel)
->log('edited');
How to do this from model? Suggestions are appreciated.

Alright. Now I got your question. If you want to performance in Modal.
Below is my sample code in my Business model class.
protected static function boot()
{
//to log what field update
static::updating(function ($business) {
$changes = $business->isDirty() ? $business->getDirty() : false;
if($changes)
{
foreach($changes as $attr => $value)
{
activity()
->performedOn($business)
->causedBy(auth()->user())
->withProperties(['business_name' => $business->name, 'which field updated' => $business->getDirty()])
->log('Business Field <span class="text-green">Updated</span> - '.$business->name);
}
}
});
}
For the Subject's info you have to manually add in, below is my sample code how I store it in controller. I hope you can get some reference.
activity()
->performedOn($business)
->causedBy(auth()->user())
->withProperties(['business_name' => $business->name)
->log('Business <span class="text-green">Updated</span> - '.$business->name);
DB Records as below:
+----+----------+-----------------------------------------------------------------+------------+--------------+-----------+-------------+-------------------------------------+---------------------+---------------------+
| id | log_name | description | subject_id | subject_type | causer_id | causer_type | properties | created_at | updated_at |
+----+----------+-----------------------------------------------------------------+------------+--------------+-----------+-------------+-------------------------------------+---------------------+---------------------+
| 1 | default | Business <span class="text-green">Updated</span> - Companies 10 | 10 | App\Business | 1 | App\User | {"business_name":"Best Restaurant"} | 2017-08-04 14:58:06 | 2017-08-04 14:58:06 |
+----+----------+-----------------------------------------------------------------+------------+--------------+-----------+-------------+-------------------------------------+---------------------+---------------------+

Related

How to authorization user in laravel?

I have user table :
| id | username | password | role_id |
|:--:|:--------:|:--------:|:-------:|
| 1 | user1 | password | 10 |
| 2 | user2 | password | 11 |
and the role table :
| id | name |
|:--:|:----:|
| 10 | admin|
| 11 | superadmin|
it is mean the user table should has relationship with role table.
I get confused how to make authorization with relation table, I have try to include this method in my user model, but is not working :
public function role()
{
return $this->belongsTo(Role::class, 'role_id', 'id');
}
and this is my Gate in authserviceprovider :
public function boot()
{
$this->registerPolicies();
Gate::define('isSuperadmin', function ($admin) {
return $admin->role == 'superadmin';
});
}
When you go $admin->role it will return a model instance of the role, which is not a string, you should have
$admin->role->name === 'superadmin'
And a side note it makes more sense to me to call the admin var $user since it might be a regular user
Use spatie/laravel-permission package instead for roles/permissions management.

laravel 5 - Eloquent Relationships (permissions table)

I think am struggling to get the relationships correctly in the scenario I have.
I have three tables
Table: users
| id | username |
----------------------
| 1 | pluto |
|------|-------------|
Table: permissions
| id | user_id | level_id | app_id |
--------------------------------------------------
| 1 | 1 | 2 | 9 |
|------|-------------|--------------|------------|
Table: levels
| id | level |
----------------------
| 1 | admin |
|------|-------------|
| 2 | manager |
|------|-------------|
| 3 | editor |
|------|-------------|
The result I am looking to get is
manager //through User:: model or Auth::
I would like to get a value from levels table in level column either through User model. This is the last version on what I have in my classes...
class User extends Authenticatable
{
public function permissions()
{
return $this->hasOne('App\Permissions');
}
}
class Permissions extends Model
{
public function user()
{
return $this->hasMany('App\User');
}
public function levels()
{
return $this->hasMany('App\Levels');
}
}
class Levels extends Model
{
public function permissions()
{
return $this->belongsTo('Modules\Ecosystem\Entities\permissions');
}
}
Using this in the controller I am able to retrieve values from permissions table. However I am unable to get values from levels table...
$user = User::with('permissions')->find(Auth::user()->id);
However I am unable to get values from levels table when I try this...
$user = User::with('permissions.levels')->find(Auth::user()->id);
That produces an error:
Column not found: 1054 Unknown column 'levels.permissions_id' in 'where clause' (SQL: select * from `levels` where `levels`.`permissions_id` in (1))
I understand that I am not understanding exactly how relationships would work in this instance but I don't want to just guess a solution. I'd like to understand it.
The thing is ,, Levels table serves only as a list of permission levels (roles). I recognize that I can define permission levels in some other way but for the moment this is how everything is set up.
If you are making a usual user permission system, where 'roles' is replaced by 'levels', then you need to reorganized your tables and relationships.
Table: users
| id | username | level_id |
---------------------------------------
| 1 | pluto | 2 |
|------|-------------|----------------|
Table: levels
| id | level |
----------------------
| 1 | admin |
|------|-------------|
| 2 | manager |
|------|-------------|
| 3 | editor |
|------|-------------|
Table: permissions
| id | level_id | app_id |
-----------------------------------
| 1 | 2 | 9 |
|------|-------------|------------|
So now User
hasOne('App\Levels', 'level_id');
Levels
hasMany('Modules\Ecosystem\Entities\permissions', 'level_id');
Permissions
belongsTo('App\Levels', 'level_id');
That is probably what you were trying to do, and it will works.
However, if many roles may have similar permissions, e.g: admin, manager & editor can all have access to a 'Page' or 'Content' or whatever that they all have access to, then you will need a 4th table to have many-to-many relationship between permissions and levels.
Table: permissions
| id | app_id |
---------------------
| 1 | 9 |
|------|------------|
Table: levels_permissions
| level_id | permission_id |
-----------------------------------
| 2 | 1 |
|-------------|-------------------|
With this, in Levels
belongsToMany('Modules\Ecosystem\Entities\permissions', 'levels_permissions', 'level_id', 'permission_id');
Inverse the relation in Permissions
belongsToMany('App\Levels', 'levels_permissions', 'permission_id', 'level_id');
In both approaches, you can now do
$user = User::with('levels.permissions')->find(Auth::user()->id);

Correct approach to handle similar but different types of objects like user accounts

I am starting a new web project. And I have some questions about handling user accounts. I have some basic OOP knowledge but new with PHP.
My scenario is very familiar. There will be two different type of accounts. Customers and Companies. They will have some shared and particular properties.
In database I will use three tables for storing user data. One for shared properties. Others will be for specific information on the type of user.
shared_data
+---------+-----------------------+---------------+----------+----------+--------+
| user_id | email | user_name | password | type | active |
+---------+-----------------------+---------------+----------+----------+--------+
| 1 | mail#supercompany.com | Super Company | secret | company | 1 |
| 2 | mail#boldcompany | Bold Company | cetres | company | 1 |
| 3 | johndoe#mail.com | John Doe | retsec | customer | 1 |
| 4 | janedoe#mail.com | Jane Doe | setrec | customer | 1 |
+---------+-----------------------+---------------+----------+----------+--------+
company_only_data
+---------+-----------------+------------------+
| user_id | company_address | person_in_charge |
+---------+-----------------+------------------+
| 1 | Berlin | Steven Seagal |
| 2 | Budapest | Chuck Norris |
+---------+-----------------+------------------+
user_only_data
+---------+--------+--------------+
| user_id | gender | last_shoping |
+---------+--------+--------------+
| 3 | male | never |
| 4 | female | yesterday |
+---------+--------+--------------+
I don't want to reinvent the whell. As user handling is one of the essential step of web programming I thought I'd find better resources about that subject. I read many articles including "abstract classes and interfaces" but none of them was clear.
My plan is construct something like below
class UserManager
{
private $user_id;
public function __construct($user_id)
{
$this->user_id = $user_id;
}
public function getData()
{
//Return joined data of shared_data table
//and second table (based on type of account)
}
public function deactivate()
{
//Update shared_data set active=0 WHERE user_id = $this->user_id
}
public function login()
{
//...
}
public function logout()
{
//...
}
}
class CustomerManager extends UserManager
{
public function getShoppingData()
{
//Return results of shopping_data table for $this->user_id
}
//...some other customer related methods
}
class CompanyManager extends UserManager
{
public function getSalesReport()
{
//Work with results of sales_data table for $this->user_id
}
//...some other company related methods
}
Am I on the right track or doing something wrong?
Can you suggest me some well documented links to start with or suggest me an approach?
You should use an interface to set the common methods and attributes. by using interfaces, you make sure that all your classes have the minimum set of methods and attributes your app logic requires (like login, logout, commonDetails, etc)

Laravel sum() method on collection returning results for all items in table

Given the following table
gallery
+----+---------------+--------------+---------+
| id | gallery_title | viewcount | user_id |
+----+---------------+--------------+---------+
| 1 | Animals | 10 | 1 |
| 2 | Cars | 5 | 1 |
| 3 | Houses | 2 | 2 |
+----+---------------+--------------+---------+
user
+----+----------+
| id | username |
+----+----------+
| 1 | Bob |
| 2 | James |
+----+----------+
and the following classes
class Gallery extends Model
....
public function user()
{
return $this->belongsTo('App\User');
}
and
class User extends Model
....
public function galleries()
{
return $this->hasMany('App\Gallery');
}
calling $galleryCollections= Auth::user()->galleries; returns an array of collections in which I can iterate through
foreach ($galleryCollections as $galleryCollection)
{
$viewcount += $galleryCollection->viewcount;
}
print $viewcount; #returns 15
and so far everything works as expected, correctly up until this point.
However if I accidentally called $galleryCollection->sum('viewcount'), which is the last value from the iteration, the returned value is 17, as it's simply running the following SQL select sum('viewcount') as aggregate from 'gallery'.
I'm struggling to understand what exactly what is happening here. It's almost as if it's calling the 'sum()' method on the gallery class itself without passing in any 'where' values. I'd at least expect it to call the sum() method on the Collection, but instead it's going back to the database.
Is it because my Gallery class does not implement a 'sum()' method, and therefore it uses the Parent Model class and ignores the Gallery class?
If you want to count through sql, then:
Auth::user()->galleries()->sum('viewCount');
But, Auth::user()->galleries->sum('viewCount'); will sum on the collection Auth::user()->galleries.
Auth::user()->galleries() is a queryBuilder whereas Auth::user()->galleries is a collection of galleries of that user.

Laravel getting results from model belongsToMany relationship back to controller

I'm using Laravel 5 and Eloquent, I have 3 tables setup:
photos
+----+---------------+------------------+
| id | photo_name | photo_location |
+----+---------------+------------------+
| 1 | kittens.jpg | C:\kittens.jpg |
| 2 | puppies.jpg | C:\puppies.jpg |
| 3 | airplanes.jpg | C:\airplanes.jpg |
| 4 | trains.jpg | C:\trains.jpg |
+----+---------------+------------------+
photo_set (pivot table)
+------------+----------+
| set_id | photo_id |
+------------+----------+
| 1 | 1 |
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
+------------+----------+
sets
+----+----------------+
| id | description |
+----+----------------+
| 1 | cute animals |
| 2 | transportation |
+----+----------------+
I created a belongsToMany relationship in my photos and sets models to link these two together.
class Photo extends Model {
public function sets()
{
return $this->belongsToMany('App\Set');
}
}
and
class Set extends Model {
public function photos()
{
return $this->belongsToMany('App\Photo');
}
}
However I'm trying to reference the $Sets->photos() model function in my controller, so that given a set of id=1, I can return the photo_location value for each row [C:\kittens.jpg,C:\puppies.jpg], but I don't know how to access it..
Also, I can "sort of" access this information in the view with:
#foreach($sets as $set)
{{$set->images}}
#endforeach
but it looks like it only iterates through once and returns a json (?) of the necessary information, though I'm not sure how to parse that to regular HTML either.
So in short, I'm having trouble accessing this data (photo_location) from both the controller and the view
Use Collection::lists()
$locations = Set::find(1)->photos->lists('photo_location');
It will return an array ['C:\kittens.jpg', 'C:\puppies.jpg']
http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Collection.html#method_lists
In your controller try this :
$result = PhotoSet::where('set_id', $set_id)
->with('sets')
->with('photos')
->get();
$photo_location = $result->photos->photo_location;
here PhotoSet is the model for photo_set table, because it is a pivot table we will be able to access both sets and photos table from it.

Categories