Pre-info: Laravel 5 is my first framework I've used besides our custom framework that we've created over the years. I'm still wrapping my head around the concepts but its mostly all there. I have page calls, authorization checks, form submission and db queries all working.
The issue: In the past I would create a new class "Access" and I'd call the function desired wherever I'd need to:
$access = Access::getAccessByAccount($accountID);
My hope is to do the same in laravel somehow and be able to call this public function from within a controller.. I just don't know how to call it and where to actually store the function.
Here is a sample of the function I'd like to call:
public function getAccessByAccount($accountID){
//Grab all access rights set to given account ID
$accessList = DB::table('element_access')
->join('element', 'element.id', '=', 'element_access.element_id')
->select('element.name as element', 'element_access.permission as permission')
->where('element_access.account_id', $accountID)
->get();
//Return $access[element] = permission list or false if no access rights are assigned to account ID
if(is_array($accessList)){
$access = array();
foreach($accessList as $item){
$access[$item->element] = $item->permission;
}
return $access;
}else{
return false;
}
}
Here is how I'd like to somehow be able to call it in a controller:
<?php namespace App\Http\Controllers\Portal\Admin;
use App\Http\Controllers\Controller;
class AdminController extends Controller {
public function showAdminDashboard(){
$access = Access::getAccessByAccount(Auth::id());
if($access['admin-dashboard'] == 'r'){
return view('portal.admin.dashboard');
}
}
}
EDITS:
Here is the solution I came up with with the help of the checked solution.
Created new file: app\Library\Access.php
<?php namespace App\Library;
use DB;
class Access{
public function getElementAccessByAccount($accountID){
//Grab all access rights set to given account ID
return DB::table('element_access')
->join('element', 'element.id', '=', 'element_access.element_id')
->select('element.name as element', 'element_access.permission as permission')
->where('element_access.account_id', $accountID)
->get();
}
}
To call the function:
$access = new \App\Library\Access;
$accessList = $access->getElementAccessByAccount(Auth::id());
If I was in your shoes, I would store all classes of custom functionalities to the app/services directory.
Access class
<?php namespace App\Services;
class Access
{
public static function getAccessByAccount($accountID) {
//Grab all access rights set to given account ID
$accessList = \DB::table('element_access')
->join('element', 'element.id', '=', 'element_access.element_id')
->select('element.name as element', 'element_access.permission as permission')
->where('element_access.account_id', $accountID)
->get();
//Return $access[element] = permission list or false if no access rights are assigned to account ID
if (is_array($accessList)) {
$access = array();
foreach($accessList as $item){
$access[$item['element']] = $item['permission'];
}
return $access;
} else{
return false;
}
}
}
Controller
<?php namespace App\Http\Controllers\Portal\Admin;
use App\Http\Controllers\Controller;
class AdminController extends Controller
{
public function showAdminDashboard() {
$access = \App\Services\Access::getAccessByAccount(\Auth::id());
if($access['admin-dashboard'] == 'r') {
return view('portal.admin.dashboard');
}
}
}
Related
I need to save the model id that is being saved and avoid another save while it's saving it, but I don't know how to persist data between requests and access it later.
JAVASCRIPT
Works perfectly well, but I can't do the same in LARAVEL 9.
// MODELS THAT ARE BEING UPDATED.
const models = {}
function handleRequest(req) {
if (models[req.model_id]) {
return
}
models[req.model_id] = true
// UPDATE MODEL.
models[req.model_id] = false
}
LARAVEL 9
Doesn't work as expected.
<?php
use App\Http\Controllers\Controller;
// MODELS THAT ARE BEING UPDATED.
$models = [];
class MyController extends Controller
{
public function index(Request $request)
{
if ($models[$model_id]) {
return;
}
$models[$model_id] = true;
// UPDATE MODEL.
$models[$model_id] = false;
}
}
Your problem is that you are trying to compare different entities in JS, you use a Function, and in Laravel you have a Class, these are different concepts and mechanics of work
You can make a property inside a class
<?php
use App\Http\Controllers\Controller;
class MyController extends Controller
{
// MODELS THAT ARE BEING UPDATED.
public $models = [];
public function index(Request $request)
{
if ($this->models[$model_id]) {
return;
}
$this->models[$model_id] = true;
// UPDATE MODEL.
$this->models[$model_id] = false;
}
}
You might consider using sessions:
session(['model_id' => 123]); // save data to session
$model_id = session('model_id'); // get data from session
Here we go again, everytime I write a new policy it doesn't work for unknown reasons.
I have a voting system where I have a pivot table for votes that references the model and the user along with extra columns ('up_voted', 'down_voted').
My relations are working and if I write this code to test I get it all ok. I set in the DB an example vote for model id = 1 by the user so this code will return 'user voted' while modifying the id to 2,3, 4 whatever it will return 'user didn't vote'.
$model_id = 1;
if($user->model_votes->contains('model_id', $model_id)){
dd('user voted');
}else{
dd("user didn't vote");
}
so I thought ok I will make a policy for this and this is my policy which I correctly registered in AuthServiceProvider:
namespace App\Policies;
use App\Model;
use App\User;
class ModelPolicy
{
public function voteModel(User $user, Model $model)
{
if($user->model_votes->contains('model_id', $model->id)){
return false;
}else{
return true;
}
}
}
so in the controller I have this:
$model = Model::findOrFail($id);
$this->authorize('voteModel', $model);
and of course it doesn't work and always returns an exception no matter what
The working code you put contains this condition:
$user->model_votes->contains('model_id', $model_id)
So I assume that you just have to put the very same condition in your Policy:
public function voteModel(User $user, Model $model)
{
return $user->model_votes->contains('model_id', $model->id);
}
I passed parameter from view to controller via URL. Now I want to send it from controller to model so that I can use it to pick data from tables. Here is my code:
controller:
function view(){
if(isset($_GET['r'])) {
$rank = $_GET['r'];
}
$rank=$this->uri->segment($rank);
$this->load->model('names_rank');
$data=$this->names_rank->get_names($rank);
print_r($rank);
}
model:
function get_names($rank){
$this->db->select('u.*,v.*');
$this->db->from('unit_member u, Vyeo v');
$this->db->where('v.fno = u.fno');
$this->db->where('u.present = ""');
$this->db->where('v.rank', $rank);
$this->db->where('v.date_of_end="0000-00-00"');
$query = $this->db->get();
return $query->result_array();
}
this is the result:
A PHP Error was encountered Severity: Warning Message: Missing
argument 1 for Names_rank::get_names(), called in
C:\xampp\htdocs\unit\application\controllers\names.php on line 32 and
defined
This will work to send to model but your code isn't understandable for me, you re-declare the variable after setting it in the IF? are you trying to print_r() the output from the model?
I think you are trying to achieve this maybe?
function view() {
if(isset($_GET['r'])) {
$rank = $_GET['r'];
}else{
$rank = $this->uri->segment($rank);
}
$this->load->model('names_rank');
$data = $this->names_rank->get_names($rank);
print_r($data);
}
You can pass a Parameter to your model. First you have to call your model within your controller if you not enable it on autoload.
Your Model:
<?php
class AwesomeModel extends CI_Model
{
publif function do_work($param, $anotherParam)
{
//code here
}
}
Then your controller:
<?php
class AwesomeController extends CI_Controller
{
public function __construct()
{
/*
* load in constructor so not need to recall every time you want use it
* second parameter is model renaming (optional)
*/
$this->load->model('AwesomeModel', 'awe');
}
public function pass_data()
{
$this->awe->do_work($param1, $param2);
}
?>
Thats all.
I have a Model that looks something like this:
Rewards Earned Model:
class RewardsEarnedModel extends BaseModel{
protected $appends = ['readable_date'];
public function getReadableDateAttribute(){
// How do I access the User Service?
return $this->userService->dateTime($this->attributes['created_at'])->readableDate;
}
public function scopeSums($query, User $user, $offset = 0, $limit = 50){
return $query-> /* add items here (snipped) */;
}
}
I then run the model like this from my controller:
Rewards Controller:
public function getRewards(Request $request, User $user, $date = null){
$rewards = new RewardsEarnedModel;
$rewards = $rewards->Sums($user);
$sums = $rewards->get()->toArray();
}
My User service class has a Time trait attached to it. In that trait there is the function dateTime, and I would like to access it from my getReadableDateAttribute method, but I can not seem to do so. What can I do to access it from my User service?
User Service:
namespace App\Services;
class User {
use Time;
}
Time trait:
namespace App\Traits;
trait Time{
public function dateTime($datetime = null){
/* Snipped code */
}
}
I was able access the User service by doing app()->User here is the final result:
public function getReadableDateAttribute(){
return app()->User->dateTime($this->attributes['created_at'])->readableDate;
}
My Zend Framework 2 Application has a view whereby I display a log of events, in a simple table format. I use several basic View Helpers to manipulate the presentation of the data in the table, but on these existing View Helpers all of the logic is contained to the View Helper itself, e.g:
namespace Application\View\Helper;
use Zend\View\Helper\AbstractHelper;
class GetSystemName extends AbstractHelper
{
public function __invoke($val)
{
if ($val == 0){
return 'Something';
}
if ($val == 1){
return 'Something else';
}
}
}
My requirement is to build a function GetUserName to accept user_id and perform a check on the database to display the User's name, as the ID is of no value to the person using the system.
The way I see it I can either:
A) Start a new query from within the View Helper to return what I need or
B) Use a function called getUser() from within the 'User' Module / UserTable class.
The code for B is:
namespace User\Model;
use Zend\Db\TableGateway\TableGateway;
class UserTable
{
protected $tableGateway;
public function __construct(TableGateway $tableGateway)
{
$this->tableGateway = $tableGateway;
}
//..other functions
public function getUser($id)
{
$id = (int) $id;
$rowset = $this->tableGateway->select(array('id' => $id));
$row = $rowset->current();
if (!$row) {
throw new \Exception("Could not find row $id");
}
return $row;
}
What is the best option? And how would I implement it?
Apologies if this is a basic questions I am quite new to MVC and Zend.
In the model-view-controller pattern, the view should not be aware of the model layer. Information from the models are injected into the view through the controller.
Having your view helper call the getUser() method in your model breaks this pattern.
So, what do you do?
Have your controller get the user information into the view:
// controller
$userId = $this->params()->fromQuery("userID");
// or from session ID if this is a private profile page
// You might want some validation, too...
$userTable = $this->getServiceLocator()->get("UserTable");
// or whatever you've configured in the service config for this
$user = $userTable->getUser($userId);
// if this is a public profile page, you might want to
// exclude some fields like "password" so they don't
// accidentally get into the view
$view = new ViewModel();
$view->setVariable("user", $user);
return $view;
Then in the view.phtml you just do:
<?php $this->GetSystemName($user->whateverField); ?>