set_exception_handler in codeigniter - how to use? - codeigniter

I have a code similar to the following which is not working.
class Abc extends CI_Controller {
static function exception_handler(Exception $ex)
{
var_dump($ex);
echo $ex->getMessage();
exit;
}
function __construct()
{
parent::__construct();
set_exception_handler('exception_handler');
}
function Index()
{
throw new Exception('hehe');
}
}
I get
A PHP Error was encountered
Severity: Warning
Message: set_exception_handler() expects the argument
(exception_handler) to be a valid callback
How to use set_exception_handler in codeigniter

Since exception_handler is a function inside a class, it should be:
set_exception_handler(array('self','exception_handler'));
Or
set_exception_handler(array('Abc','exception_handler'));

Set_exception_handler always expects full name class, including the namespace and omits the "use instruction" for use others namespaces.
In your case the fullname is: 'CI_Controller:exception_handler'
Therefore the correct call is: set_exception_handler('CI_Controller:exception_handler');
If you had one namespace e.g. namespace App;
The correct call is: set_exception_handler('App\CI_Controller:exception_handler');

function Index()
{
function ExceptionHandler($e) use($this)
{
$this->load->view('error', $this->sharedData);
}
set_exception_handler('ExceptionHandler');
throw new Exception('hehe');
}

You should use method of the instantiated Object with access level is public.
final class MyException
{
/**
* Constructor
* trigger getErrorTypesFromDefinedConstant method
*/
public function __construct()
{
// Set global exception handler
set_exception_handler(array($this, 'globalException'));
}
public function globalException($e)
{
// Your code to handle exception
}
}

Related

Laravel route model binding without global scope

I have following route group in my laravel 8.0 app:
Route::prefix('offline_transaction')->name('offline_transaction.')->group(function () {
Route::post('/approve/{transaction:uuid}', [OfflineTransactionController::class, 'approve'])
->name('approve');
Route::post('/reject/{transaction:uuid}', [OfflineTransactionController::class, 'reject'])
->name('reject');
});
And Transaction model is:
class Transaction extends Model implements CreditBlocker
{
//....
protected static function boot()
{
parent::boot();
static::addGlobalScope(new AuthUserScope());
}
//....
}
And this is my AuthUserScope:
class AuthUserScope implements Scope
{
private string $fieldName;
public function __construct($fieldName = 'user_id')
{
$this->fieldName = $fieldName;
}
public function apply(Builder $builder, Model $model)
{
$user = Auth::user();
if ($user) {
$builder->where($this->fieldName, $user->id);
}
}
}
Now the problem is when an admin wants to approve or reject a transaction, 404 Not found error will throws. How can I pass this?
Customizing The Resolution Logic
If you wish to define your own model binding resolution logic, you may
use the Route::bind method. The closure you pass to the bind
method will receive the value of the URI segment and should return the
instance of the class that should be injected into the route. Again,
this customization should take place in the boot method of your
application's RouteServiceProvider:
Solution
What you can do is change the parameter name(s) in your routes/web.php file for the specific route(s).
Route::prefix('offline_transaction')->name('offline_transaction.')->group(function () {
Route::post('/approve/{any_transaction}', [OfflineTransactionController::class, 'approve'])
->name('approve');
Route::post('/reject/{any_transaction}', [OfflineTransactionController::class, 'reject'])
->name('reject');
Note the any_transaction. Change that to whatever naming convention you find most convenient.
Then, in your app/Providers/RouteServiceProvider.php file, change your boot(...) method to something like this:
use App\Models\Transaction;
use Illuminate\Support\Facades\Route;
// ...
public function boot()
{
// ...
Route::bind('any_transaction', function($uuid) {
return Transaction::withoutGlobalScopes()->where('uuid', $uuid)->firstOrFail();
});
// ...
}
// ...
Then in your controller app/Http/Controllers/OfflineTransactionController.php file, access the injected model:
use App\Models\Transaction;
// ...
public function approve(Transaction $any_transaction) {
// ...
}
// ...
Credits: Using Route Model Binding without Global Scope #thomaskim
Addendum
If you would like to remove a specific global scope from the route model bound query, you may use
withoutGlobalScope(AuthUserScope::class) in the boot(...) method of the app/Providers/RouteServiceProvider.php file.
Another approach is that I can use Route::currentRouteNamed in AuthUserScope class as following, which I prefer to use instead of Route::bind:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
class AuthUserScope implements Scope
{
private string $fieldName;
public function __construct($fieldName = 'user_id')
{
$this->fieldName = $fieldName;
}
public function apply(Builder $builder, Model $model)
{
$user = Auth::user();
if ($user && !Route::currentRouteNamed('admin.*')) {
$builder->where($this->fieldName, $user->id);
}
}
}

How import data using controller to view in Laravel 8.*

I would like to go to specific object view from main page(index). Here is how I communicate with page which is about to be showed
{{ route('object',['id'=>$object->id]) }}
Error message:
Error message says that it should be something wrong with controller, but in previous case this code worked.
web.php(routes)
Route::get('/object/{id}','FrontendController#object')->name('object');
My FrontendController
use App\Interfaces\FrontendRepositoryInterface;
class FrontendController extends Controller
{
public function __construct(FrontendRepositoryInterface $frontendRepository)
{
$this->fR = $frontendRepository;
}
public function index()
{
$objects = $this->fR->getObjectsForMainPage();
//dd($objects);
return view('frontend.index',['objects'=>$objects]);
}
public function object($id)
{
$object = $this->fR->getObject($id);
//dd($objects);
return view('frontend.object',['object'=>$object]);
}
FrontendRepository
use App\Models\EventObject;
use App\Models\Photo;
use App\Interfaces\FrontendRepositoryInterface;
class FrontendRepository implements FrontendRepositoryInterface {
public function getObjectsForMainPage()
{
return EventObject::with(['photos','clubs'])->get();
}
public function getObject($id)
{
return EventObject::with(['photos','clubs'])->get();
}
}
Solution was to clear routes cache using php artisan route:cache and to add missing / in route
Route::get('/object/'.'{id}','FrontendController#object')->name('object');

Laravel handle error that only thrown by controller

I am creating a logic where a controller can call another controller depend on Auth::user() role, but not all of controller shared same method, so i want if controller calling a method that does not exist it will throw a 404 not found.
here is my controller
class LokalController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
Public $controller;
public function __construct()
{
//$this->middleware('adminakses');
$this->middleware(function ($request, $next) {
$this->setController();
return $next($request);
});
}
public function setController()
{
$role = Auth::user()->role;
switch ($role)
{
case 'admin':
$this->controller = new \SIA\Http\Controllers\Admin\LokalController;
break;
case 'guru':
$this->controller = new \SIA\Http\Controllers\Guru\LokalController;
break;
case 'siswa':
$this->controller = new \SIA\Http\Controllers\Guru\LokalController;
break;
}
}
public function index()
{
return $this->controller->index();
}
for example Admin\LokalController has method A(), but Guru\LokalController doesn't, and if user logged in as guru and trying to cal method A() it should returning not found exception or something user understandable message, but currently showing BadMethodCallException method A() does not exist
The approach you're trying to work is achievable but I think it will be overwhelming in time.
public function index()
{
try {
$action = $this->controller . '#' . __FUNCTION__;
action($action);
} catch (Exception $e) {
abort('401', "Your Message");
}
}
How I'd do it instead is, I'd create a redirect path for the User model.
public function getRedirectPathAttribute() {
switch ($this->role) {
case 'admin':
return '/admin';
case 'guru':
return '/guru';
case 'siswa':
return '/siswa';
}
}
And then create a middleware to make the check, and if redirect is needed, I'd redirect using auth()->user()->redirect_path.
What do you think?
One option is to have a controller all this controllers inherits from that implement all methods by calling App::abort(404), and in each of the child classes implement the methods they need, stopping the methods in the parent classes from being called
class BaseController extends Controller{
public function a() {
App::abort(404);
}
}
class AdminController extends BaseController{
public function a() {
// to stuff for admin
}
}
Controllers inheriting from BaseController that don't implement a() will get 404, admin controller will not

How to call BaseController public function from child classes in Laravel (4)?

I have a CustomController. For not to repeat myself, I defined getVars function in BaseController. I want to call getVars function from some functions in CustomController.
However, Laravel returns 404 error without any exception. What is wrong?
class BaseController extends Controller {
public function getVars($var1, $var2, $var3=Null, $var4=Null) {
return [];
}
}
class CustomController extends BaseController {
public function doBla1($var1, $var2) {
$vars = $this->getVars();
}
public function doBla2() {
$vars = $this->getVars();
}
public function doBla3() {
$vars = $this->getVars();
}
}
Sorry :( I found the reason of error. The names of doBla1 and getVars functions are same. This results in a 404 error. Sorry :(
$this is useful when you have method/function defined in same controller.
For functions inside parent controller you can use
Parent::getVars($var1, $var2)

On sorting and filtering showing "An error occured, please try again later" in magento

when I am clicking on any sort or filter option in category page it is showing an error occurred please try again please help.
<?php
class MageTracking_TicketSystem_Block_Ticketsystem_View extends Mage_Core_Block_Template
{
protected function _prepareLayout(){
$this->getLayout()->getBlock('head')->setTitle(Mage::helper('ticketsystem')->__('Ticket'));
return parent::_prepareLayout();
}
public function getTickets(){
return Mage::registry('ticketsystem_all');
}
public function getDepartments(){
return Mage::helper('ticketsystem')->getAllCategories(false);
}
public function getDepartment($id){
return Mage::helper('ticketsystem')->getCategory($id);
}
public function getPriority($priority){
$priorites= Mage::helper('ticketsystem')->getPriorities();
return $priorites[$priority];
}
public function getStatus($status){
$statuses = Mage::getSingleton('ticketsystem/status')->getOptionArray();
return $statuses[$status];
}
}
If I am not wrong you are using Tracking Ticketing System extension in your site.
Go to line number 35 in following file app\code\community\MageTracking\TicketSystem\Block\Ticketsystem\View.php
class MageTracking_TicketSystem_Block_Ticketsystem_View extends Mage_Core_Block_Template
{
protected function _prepareLayout(){
$this->getLayout()->getBlock('head')->setTitle(Mage::helper('ticketsystem')->__('Ticket'));
return parent::_prepareLayout();
}
Following line is creating the problem
$this->getLayout()->getBlock('head')->setTitle(Mage::helper('ticketsystem')->__('Ticket'));
You can check the error message in your browser console also.

Resources