I'm new to Laravel we are trying to add (https://github.com/TomLingham/Laravel-Searchy) to our project (https://github.com/wvulibraries/rockefeller-css/tree/trying-searchy) to allow the search of multiple fields in a table. I can see the package is in the vendor folder as tom-lingham for some reason I am not able to even use it. I get FatalThrowableError in DataViewController.php line 79: Class 'App\http\Controllers\Search' not Found. I followed the instructions in the github repo. Any suggestions would be appreciated.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
// Import the table and collection models
use App\Table;
use App\Collection;
use Illuminate\Support\Facades\Auth;
/**
* The controller is responsible for showing the cards data
*/
class DataViewController extends Controller {
/**
* Constructor that associates the middlewares
*
* #return void
*/
public function __construct(){
// Middleware to check for authenticated
$this->middleware('auth');
}
/**
* Show the data from the selected table
*/
public function index(Request $request, $curTable){
// Get the table entry in meta table "tables"
$curTable = Table::find($curTable);
if(!$curTable->hasAccess){
return redirect()->route('home')->withErrors(['Table is disabled']);
}
// Get and return of table doesn't have any records
$numOfRcrds = DB::table($curTable->tblNme)->count();
// check for the number of records
if ($numOfRcrds == 0){
return redirect()->route('home')->withErrors(['Table does not have any records.']);
}
// Get the records 30 at a time
$rcrds = DB::table($curTable->tblNme)->paginate(30);
// retrieve the column names
$clmnNmes = DB::getSchemaBuilder()->getColumnListing($curTable->tblNme);
// return the index page
return view('user.data')->with('rcrds',$rcrds)
->with('clmnNmes',$clmnNmes)
->with('tblNme',$curTable->tblNme)
->with('tblId',$curTable);
}
public function show(Request $request, $curTable, $curId){
// Get the table entry in meta table "tables"
$curTable = Table::find($curTable);
if(!$curTable->hasAccess){
return redirect()->route('home')->withErrors(['Table is disabled']);
}
// Check if search string and column were passed
if (strlen($curId) != 0) {
$numOfRcrds = DB::table($curTable->tblNme)
->where('id', '=', $curId)
->count();
// check for the number of records
if ($numOfRcrds == 0){
return redirect()->route('home')->withErrors(['Search Yeilded No Results']);
}
else {
// $rcrds = DB::table($curTable->tblNme)
// ->where('id', '=', $curId)
// ->get();
$rcrds = Searchy::search($curTable->tblNme)->fields('id')->query($curId)->get();
}
}
else {
return redirect()->route('home')->withErrors(['Invalid ID']);
}
// retrieve the column names
$clmnNmes = DB::getSchemaBuilder()->getColumnListing($curTable->tblNme);
// return the index page
return view('user.show')->with('rcrds',$rcrds)
->with('clmnNmes',$clmnNmes)
->with('tblNme',$curTable->tblNme)
->with('tblId',$curTable);
}
}
You're running into a namespacing issue.
Your controller is in the App\Http\Controllers namespace, so that's where it will look by default. At the top of your controller, adding a use Searchy; line alongside the existing use lines will make it work, or you can preface Searchy with a \ to tell PHP to start at the namespace root.
$rcrds = \Searchy::search(...);
Related
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'm having an issue with Eloquent. I am returning an object that contains data but when trying to access the id of the returned field it's blank.
Here's some example code:
public function activateMobile($token)
{
/*
* Get mobile activation row matching $token
*/
$activation = $this->ci->ActivationRepository->getMobileActivationByToken($token);
/*
* Does it exist?
*/
if(empty($activation)) {
return false;
}
die($activation);
}
And here's the model:
<?php
namespace MyApp\Models;
use Illuminate\Database\Eloquent\Model;
class MobileVerification extends Model
{
protected $table = 'mobile_verification';
public function user()
{
return $this->belongsTo('\MyApp\Models\User');
}
}
For examples sake I used die to print the value of the object in string form:
{"id":7,"user_id":24,"token":"68gb","is_used":0,"verified_at":null,"created_at":"2016-11-28 18:53:52","updated_at":"2016-11-28 18:53:52"}
As you can see the id is there.
But, if I replace the die with die($activation->id) its blank. Yet, if I do die($activation->token) that's visible.
Why is the id returning blank?
I have a Product model
class Product extends Model
{
...
public function prices()
{
return $this->hasMany('App\Price');
}
...
}
I want to add a function which will return the lowest price, and in controller I can get the value using:
Product::find(1)->lowest;
I added this in Product model:
public function lowest()
{
return $this->prices->min('price');
}
but I got an error saying:
Relationship method must return an object of type Illuminate\Database\Eloquent\Relations\Relation
And if I use Product::find(1)->lowest();, it will work. Is it possible to get Product::find(1)->lowest; to work?
Any help would be appreciated.
When you try to access a function in the model as a variable, laravel assumes you're trying to retrieve a related model. They call them dynamic properties. What you need instead is a custom attribute.
Before Laravel 9
Laravel 6 docs: https://laravel.com/docs/6.x/eloquent-mutators
add following method to your model:
public function getLowestAttribute()
{
//do whatever you want to do
return 'lowest price';
}
Now you should be able to access it like this:
Product::find(1)->lowest;
EDIT: New in Laravel 9
Laravel 9 offers a new way of dealing with attributes:
Docs: https://laravel.com/docs/9.x/eloquent-mutators#accessors-and-mutators
// use Illuminate\Database\Eloquent\Casts\Attribute;
public function lowest(): Attribute
{
return new Attribute(
get: function( $originalValue ){
//do whatever you want to do
//return $modifiedValue;
});
/**
* Or alternatively:-
*
* return Attribute::get( function( $originalValue ){
* // do whatever you want to do
* // return $modifiedValue;
* });
*/
}
Use Eloquent accessors
public function getLowestAttribute()
{
return $this->prices->min('price');
}
Then
$product->lowest;
you can use above methods or use following method to add a function direct into existing model:
class Company extends Model
{
protected $table = 'companies';
// get detail by id
static function detail($id)
{
return self::find($id)->toArray();
}
// get list by condition
static function list($name = '')
{
if ( !empty($name) ) return self::where('name', 'LIKE', $name)->get()->toArray();
else return self::all()->toArray();
}
}
Or use Illuminate\Support\Facades\DB; inside your function. Hope this help others.
why you just dont do this? i know , it's not what you asked for specificallyand it migh be a bad practice sometimes. but in your case i guess it's good.
$product = Product::with(['prices' => function ($query) {
$query->min('price');
}])->find($id);
change follow code
public function lowest()
{
return $this->prices->min('price');
}
to
// add get as prefix and add posfix Attribute and make camel case function
public function getLowestAttribute()
{
return $this->prices->min('price');
}
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');
}
}
}
I am trying to get distinct city names from a MySQL table called "city".
Here is how the controller code looks like:
public function getCityNames()
{
if(Auth::check())
{
$cities = DB::table('city')->distinct()->get();
var_dump($cities);
}
else
{
return Redirect::route('account-signin');
}
}
Here is the code for the model City:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class City extends Eloquent
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'city';
/**
* Using a different primary key name
*
*/
protected $primaryKey = 'geoname_id';
public $timestamps = false;
}
The Problem
I can output distinct values from other models using the exact code as in this controller above but when I run it for the city, I get a BLANK page.
I am using Laravel 4 with detailed error messages enabled.
Of course, there is data in the 'city' table
UPDATE:
When I write the following, I get data:
public function Test()
{
return City::where('country_name', '=', 'Canada')->get();
}
But when I write the following, I get the black page? Something with the data size?
public function Test()
{
return City::all()->get();
}
Not sure if this is problem, but are you trying to view the output of var_dump($cities)?
If so, shouldn't return var_dump($cities); give you the output, rather than the empty page?
Code looks like this:
public function getCityNames()
{
if(Auth::check()) // Tip: You can apply auth filters to controllers if you want.
{
$cities = DB::table('city')->distinct()->get();
return var_dump($cities); // Add return here.
}
else
{
return Redirect::route('account-signin');
}
// If the code doesn't go anywhere, it goes here.
return "TEST";
}
I am able to access the city table fine when I ran small queries (see my update in the question). Only explanation could be that I was exceeding the browser buffer size when I was trying to get all . This table has more than 70,000 rows.