Laravel trait function not found - laravel

I have look all over stackoverflow and google and I cannot seem to solve my trait function not found. I have tried composer dump-autoload, my composer.json have the app directory connected and even checked my namespace and trait names. Here is my user controller.
<?php
namespace App\Http\Controllers;
use App\User;
use App\Traits\ControllerTrait;
use App\Http\Requests\UpdateUser;
use Illuminate\Http\Request;
use App\Http\Requests\IndexUser;
class UserController extends Controller
{
use ControllerTrait;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show multiple users.
*
* #return \Illuminate\Http\Response
*/
public function index(IndexUser $request)
{
$per_page = 50;
$order_by = 'id';
$sort_by = 'ASC';
if($request->has('per_page')) {
$per_page = $request->input('per_page');
}
if($request->has('order_by')) {
$order_by = $request->input('order_by');
}
if($request->has('sort_by')) {
$sort_by = $request->input('sort_by');
}
$users = User::when($request->has('select'), function ($query) use ($request) {
selectPrepare($query, $request->input('select'));
})->when($request->has('include'), function ($query) use ($request) {
if(!empty($request->input('include'))) {
$includedTables = explode(',', $request->input('include'));
$tables = array_map('trim', $includedTables);
return $query->with($tables);
}
return $query;
})->orderBy("{$order_by}", "{$sort_by}")
->paginate($per_page);
return response()->json($users);
}
}
}
Here is my Trait
<?php
namespace App\Traits;
trait ControllerTrait
{
/**
* Function: scopeSelectPrepare
public function selectPrepare($query, $select) {
if(!empty($select)) {
$selectedColumns = explode(',', $select);
$columns = array_map('trim', $selectedColumns);
return $query->select($columns);
}
return $query;
}
}
As you can see my name space for the Trait is App\Traits and call the use App\Traits\ControllerTrait in my controller then can the use ControllerTrait to get the functions from the trait. When I try to get the function to use in my query it says: Call to undefined function App\Http\Controllers\selectPrepare()
Is there something I am missing? I am new to the traits functionality of laravel but I thought I was following all of the examples and naming conventions. Can anyone see what I am doing wrong.

You need to use $this when accessing trait methods, just like you would for any other method:
$users = User::when($request->has('select'), function ($query) use ($request) {
$this->selectPrepare($query, $request->input('select'));

Related

How Can I Integrate Shippo API With Laravel 8

I'm building an ecommerce website with Laravel 8, and I'm trying to incorporate real time shipping rates with Shippo API. I was able to install Shippo via composer, but I get an error saying too few arguements or undefined variable. I'm borrowing some code from article regarding Shippo, but I keep getting the errors. Are you having a similar problem? Did you solve it? Any help is appreciated. Here is my controller code,
<?php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\ShipDivision;
use App\Models\ShipDistrict;
use App\Models\ShipState;
use App\Models\Product;
use App\Services\Shipping_New;
use App\Models\User;
use Auth;
use\App\Http\Controllers\Frontend\CartController;
use Gloudemans\Shoppingcart\Facades\Cart;
use Carbon\Carbon;
class CheckoutController extends Controller
{
/**
* #var Shipping
*/
private $shipping;
/**
* #var UserRepository
*/
private $user;
/**
* CheckoutController constructor.
* #param UserRepository $user
* #param Shipping $shipping
*/
public function __construct(User $user, Shipping_New $shipping)
{
$this->middleware('auth');
$this->shipping = $shipping;
$this->user = $user;
}
public function DistrictGetAjax($division_id) {
$ship = ShipDistrict::where('division_id',$division_id)->orderBy('district_name', 'ASC')->get();
return json_encode($ship);
}
public function StateGetAjax($district_id) {
$ship = ShipState::where('district_id',$district_id)->orderBy('state_name', 'ASC')->get();
return json_encode($ship);
}
public function CheckoutStore(Request $request) {
$data = array();
$data['name'] = $request->name;
$data['shipping_last_name'] = $request->shipping_last_name;
$data['email'] = $request->email;
$data['phone'] = $request->phone;
$data['zip'] = $request->zip;
$data['street1'] = $request->street1;
$data['company'] = $request->company;
$data['city'] = $request->city;
$data['country'] = $request->country;
$data['notes'] = $request->notes;
$data['state_id'] = $request->state_id;
$data['district_id'] = $request->district_id;
$data['division_id'] = $request->division_id;
$cartTotal = Cart::total();
// The rates is a complete object but for this we
// only need the rates_list items and will pass that.
if ($request->payment_method == 'stripe') {
return view('online-boutique-stores.payment.stripe', compact('data','cartTotal'));
}
elseif ($request->payment_method == 'paypal') {
$carts = Cart::content();
$cartQty = Cart::count();
$cartTotal = Cart::total();
return view('online-boutique-stores.payment.paypal', compact('data', 'cartTotal'));
}
else {
return 'cash';
}
}
}
Remove this your construct arguments. Because you don't see any use in these arguments. You can use this way ?
public function __construct()
{
$this->middleware('auth');
}

Run an extra where clause in the model

Is it possible to specify a where clause for the model to run with each select?
Example:
I have a query $var = TestModal::where('date', '2021-06-08')->get(); and I want my TestModal to run ->where('type', 'r') for every query so I don't have to write it multiple times
You could use an Anonymous Global Scope to define the query for each Query running on the Model
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class TestModal extends Model
{
/**
* The "booted" method of the model.
*
* #return void
*/
protected static function booted()
{
static::addGlobalScope('type', function (Builder $builder) {
$builder->where('type', 'r');
});
}
}
yes you can use multiple where like this
var = TestModal->where(['date' => '2021-06-08', 'type' => '' ])->get();
or
var = TestModal->where('date' , '2021-06-08' )->where('type' , '')->get();
or can your addGlobalScope
protected static function booted()
{
static::addGlobalScope('table_name', function (Builder $builder) {
$builder->where('type', ');
});
}

Adding key-value to Laravel result object/collection

New to Laravel. Have what seems like should be a non-issue, but is causing a headache.
I'm trying to insert a key-value pair (bookingRef) within the result object/collection returned, such that the result would be:
[{"class_id":7,"class_name":"beginner","class_slots_avail":100,"class_slots_booked":53,"class_date":"2020-12-07 21:47:23","class_time":"09:25:00","class_reg_price":350, bookingRef: 127}]
I've tried methods such as push, put and merge that will insert the key-value after the object returned, but this is not what I require.
Here is my controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Booking;
use App\Http\Controllers\Auth;
use Illuminate\Support\Facades\Mail;
use DB;
class BookingsController extends Controller
{
//
function store(Request $request) {
$id = $request->input('class');
if(DB::table('classes')->where('class_id', '=', $id)->exists()) {
if(DB::table('classes')->where('class_id', '=', $id)->value('class_slots_booked')
< DB::table('classes')->where('class_id', '=', $id)->value('class_slots_avail')) {
$booking = new Booking();
$booking->class_id = $id;
$booking->user_id = \Auth::id();
$booking->save();
DB::table('classes')->where('class_id', '=', $id)->increment('class_slots_booked', 1);
if($booking) {
$confBook = DB::table('classes')->where('class_id', '=', $id)->get();
$confBook->bookingRef = $booking->id;
\error_log($confBook);
}
}
else return('CLASS FULLY BOOOOKED');
}
else return('CLASS NOT Available');
}
}
You can cut down on your queries and put this extra data in place with some adjustments:
function store(Request $request)
{
$id = $rquest->input('class');
$class = DB::table('classes')->where('class_id', $id)->first();
if ($class) {
if ($class->class_slots_booked < $class->class_slots_avail) {
$booking = new Booking();
$booking->class_id = $id;
$booking->user_id = $request->auth()->id;
if ($booking->save()) {
// adding the extra data
$class->bookingRef = $booking->id;
DB::table('classes')->where('class_id', $id)
->increment('class_slots_booked', 1);
$class->class_slots_booked++;
return view('view-booking', [
'bookings' => collect($class),
]);
}
// booking did not save
}
// unavailable
}
// class not found
}
This would be a little more convenient with a Model for the classes table and a relationship setup to Booking would be a plus as well.
I managed to resolve it, thanks to Lagbox's suggestion of using a model:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Booking;
use App\Models\Classes;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
class BookingsController extends Controller
{
//
function store(Request $request) {
$id = $request->input('class');
$class = Classes::where('class_id', $id)->first();
if($class) {
if($class->class_slots_booked < $class->class_slots_avail) {
$booking = new Booking();
$booking->class_id = $id;
$booking->user_id = Auth::id();
if($booking->save()){
$class->where('class_id', $id)->increment('class_slots_booked');
$class->bookingRef = $booking->id;
return view('view-booking', ['bookings' => $class]);
}
}
else return('Class Fully Booked');
}
else return('Class Not Available');
}
};
From what I can see, the get() method returns an array with object(s), which is why object->new_property = value would not work. The first() method, however, seems to return a single object, which is why it would.
Seems I've got some reading up on models and collections to do.

Laravel Import Issue

I have this issue when I import excel sheet to Laravel, I'm trying to create table instantly when I import it and creating fields dynamically:
Symfony\Component\Debug\Exception\FatalThrowableError
syntax error, unexpected 'if' (T_IF), expecting ']'
this is the import model for importing files
<?php
namespace App\Imports;
use DB;
use App\People;
use Maatwebsite\Excel\Concerns\ToModel;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
class PeopleImport implements ToModel
{
// importing excel sheet or creating new schema
public function model(array $row)
{
return new People([
if (!Schema::hasTable($table_name))
{
Schema::connection('mysql')->create($table_name, function (Blueprint $table) use
($ff, $table_name) {
if (count($ff) > 0) {
foreach ($ff as $field) {
$table->longText($field)->nullable();
$array[] = $field;
}
}
});
foreach($data->toArray() as $row2) {
$insert = DB::table($table_name)->insert($row2);
}
}
]);
}
}
and this is the controller for the file import
<?php
namespace App\Http\Controllers;
use App\People;
use DB;
use Illuminate\Http\Request;
use App\Exports\PeopleExport;
use App\Imports\PeopleImport;
use Maatwebsite\Excel\Facades\Excel;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
class PeopleController extends Controller
{
/**
* #return \Illuminate\Support\Collection
*/
public function view()
{
$tables = DB::select('SHOW TABLES');
return view('view', [ 'tables' => $tables ]);
}
/**
* #return \Illuminate\Support\Collection
*/
public function export()
{
return Excel::download(new PeopleExport, 'people.xlsx');
}
/**
* #return \Illuminate\Support\Collection
*/
public function import()
{
$data = Excel::import(new PeopleImport,request()->file('file'));
foreach($data->toArray() as $row) {
$value[] = $row;
foreach($row as $key => $val) {
$fields[] = $key;
}
}
$ff = array_unique($fields);
return back()->withStatus(['تم الرفع']);
}
}
by the way I'm using laravel 6 and maatwebsite 3.1
return new People([
if (!Schema::hasTable($table_name))
You can't put if inside an array return new People([if hasTable($table_name))...,
place it elsewhere before.

Get onlyTrashed() does not exist in query builder

I am trying to get trashed rows from table messages:
public function trash() {
return $this->onlyTrashed()
->where('user_id', '=', $this->_u)
->orWhere('receiver', '=', $this->_u)
->orderBy('deleted_at', 'desc')->get();
}
I get this error:
Method Illuminate\Database\Query\Builder::onlyTrashed does not exist.
I checked up Builder and SoftDeletes files for onlyTrashed method and it does not exist, how can I look up to trashed messages from message table?
The only way I think about is to create method that doesn't return messages where delete_at is not null and for trashed to return only those where it is not null. But I am still wondering why this doesn't work since it is in documentation at this url:
https://laravel.com/docs/5.6/eloquent#soft-deleting
MORE INFO
Yes it is inside model and yes I added use SoftDeletes:
use Illuminate\Database\Eloquent\SoftDeletes; - on top
use SoftDeletes; after opening the class
Let me paste entire model here:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\DB;
class Messages extends Model
{
use SoftDeletes;
protected $fillable = [
'user_id', 'subject', 'text', 'receiver'
];
public $_u;
protected $dates = ['deleted_at'];
public function __construct() {
$this->_u = auth()->user()->user_id; //or some id as string
}
public function trash() {
return $this->onlyTrashed()
->where('user_id', '=', $this->_u)
->orWhere('receiver', '=', $this->_u)
->orderBy('deleted_at', 'desc')->get();
}
public static function trashed() {
return self::onlyTrashed();
}
}
And controller has:
public function __construct() {
$this->middleware('auth');
}
public function index($field = 'trash') {
if ($field !== "new") {
$messages = (new Msg)->$field();
$user = auth()->user();
return view('pages.messages', compact('messages', 'user'));
}
return view('pages.messages.new', compact('messages', 'user'));
}
I tried calling static as well and I tried doing it from tinker and still keep getting:
onlyTrashed() doesn not exist
You have to call the parent constructor:
public function __construct() {
parent::__construct();
$this->_u = auth()->user()->user_id;
}
I think what you want is to define the trash method static:
public static function trash() {
return self::onlyTrashed()
->where('user_id', '=', $this->_u)
->orWhere('receiver', '=', $this->_u)
->orderBy('deleted_at', 'desc')->get();
}
Then call this function by:
$messages = Messages::trash();
This should work
# YourModelController.php
/**
* Show only trashed
*
* #return \Illuminate\Http\Response
*/
public function trashed()
{
...
$trashed = YourModel::onlyTrashed()->get();
...
}
I have researched a little further and I got this:
From https://laravel.com/api/5.6/Illuminate/Database/Eloquent.html
I should have
SoftDeletesTrait
but I have
SoftDeletes
. In softdeletestrait we have onlyTrashed method but in SoftDeletes we do not.
So I copied that method from this page:
https://github.com/laravel/framework/blob/7d9e7068c49f945385673014d4cba4de28accd5e/src/Illuminate/Database/Eloquent/SoftDeletingTrait.php#L119
And added it to SoftDeletes class, now it works like it should. I haven't find why it doesn't exist inside SoftDeletes class so if anyone find out let us know!

Resources