Codeigniter Controller URI routing problems - codeigniter

I encounter problems when I call the method of a controller. By the way, this controller is routed.
Routes
$route['admin/company'] ='company';
Controller
class Company extends CI_controller {
public function __construct() {
parent::__construct();
session_start();
/** Check if user is logged in */
if ($this->session->userdata('user') != "") {
$this->load->model('my_model');
if ( $this->uri->segment(1) != "admin" ) {
redirect('admin/company/'.$this->uri->segment(2));
}
} else redirect('/');
}
public function index() { Some coding here............ }
public function addnew() { Some coding here...........}
public function process() { Some coding here...... }
}
When I call "localhost/company", it works fine and redirects me to "localhost/admin/company which is great. But, when I try to call the method of it, it displays a 404 error message.
Example: When I go to link: localhost/admin/company/addnew
Did lack something in routes? or in controller? or anything else?
Thanks,
James

If appropriate for all use cases, use a simple catch-all rule in routes.php:
$route['admin/company/(.+)$'] = "company/$1";

You will have to add a route for each function in your controller.
$route['admin/company/addNew'] ='company/addNew';
$route['admin/company/process'] ='company/process';
It's very annoying. Better, create a folder "admin" inside your "controllers" folder. Put the controller on the folder. Thus you can access your controller with the URL "localhost/admin/company" and all the methods without rerouting.
If it doesn't work at first, create a controller inside "admin" folder with the same name you'll find in your routes file (default_controller).

create a admin directory and add $route["company"]="admin/company"

Related

Laravel Backpack - getting current record from crud controller

In my crud controller I am trying to get the name of the person who is currently being edited.
so
http://192.168.10.10/admin/people/93/edit
In the people crud controller
public function setup() {
dd(\App\Models\People::get()->first()->name)
}
This returns the first person not the person currently being edited.
How do I return the current person (with an id of 93 in this example)
Ok, So since you use backpack look into CrudController to see how the method looks:
public function edit($id)
{
$this->crud->hasAccessOrFail('update');
$this->data['entry'] = $this->crud->getEntry($id);
$this->data['crud'] = $this->crud;
$this->data['fields'] = $this->crud->getUpdateFields($id);
$this->data['id'] = $id;
return view('crud::edit', $this->data);
}
So now you can overwrite the edit function and change whatever you want. You can even create a custom edit page if you so wish.
Setup on the other hand is usually used to add things like
$this->crud->addClause(...);
Or you can even get the entire constructor and put it in the setup method because setup call looks like this:
public function __construct()
{
// call the setup function inside this closure to also have the request there
// this way, developers can use things stored in session (auth variables, etc)
$this->middleware(function ($request, $next) {
$this->setup();
return $next($request);
});
}
So you could do something like \Auth::user()->id;
Also it's normal to work like this. If you only use pure laravel you will only have access to the current id in the routes that you set accordingly.
Rahman said about find($id) method. If you want to abort 404 exception just use method findOrFail($id). In my opinion it's better way, because find($id)->name can throw
"Trying to get property of non-object error ..."
findOrFail($id) first fetch user with specified ID. If doesn't exists just throw 404, not 500.
The best answer is:
public function edit($id)
{
return \App\Models\People::findOrFail($id);
}
Good luck.
you need person against id, try below
public function setup($id) {
dd(\App\Models\People::find($id)->name);
}

How to get controller action by passing URL in laravel

I searched more time to find how to get the controller method name by passing the URL but not found my expected answer. I want to make a method where I will pass a URL and it will give the corresponding controller action like as below but I can't figure out.
I found a helper which just return the current URL's action which is Route::currentRouteAction()
If a route in my application like as Route::get('/abc', 'YourController#method') which will generate the url http://example.com/abc
then how can I get the YourController#method by passing http://example.com/abc
function getAction($url){
//what will be logic?
// return like App\Controllers\MyController#method
}
I have to make a custom permission system where I need it for show and hide the menu by checking the URL of each menu.
Within your controller you can do the following:
<?php
use Illuminate\Routing\Router;
use Illuminate\Http\Request;
public function index(Request $request, Router $route)
{
$action = $router->getRoutes()->match($request)->getActionName();
// action should be what you're looking for.
}
You can try this if you want to:
Route::get('/the/url', 'YourController#method');
Every time anything calls the URL in the route, your method will be called.
You don't need to navigate to that url to call your method, it could be called by a form action, or a buttons action and just execute your method.
Edit:
url is your url as parameter (plain route)
import this:
use Illuminate\Routing\Route;
this is your function:
public function method(Route $route, $url)
{
$routes = \Route::getRoutes()->getRoutes();
foreach($routes as $r){
if($r->getUri() == $url){
$youraction= $r->getActionName();
dd($youraction);
}
else{
dd('does not exist');
}
}
}
Tested.

How to catch any link that came from upload/ in laravel 5?

im new in laravel 5.2, I just want to ask how you can catch a link that came from uploads like: http://sitename.com/uploads/59128.txt? I want to redirect them to login page if they tried to access any of route or link that came from uploads/{any filename}.
Yes you can achieve by protecting your route with auth middleware,
make a small FileController
class FileController extends Controller {
public function __construct()
{
$this->middleware('auth');
}
public function getFile($filename)
{
return response()->download(storage_path($filename), null, [], null);
}
}
and then in routes.php
Route::get('file/{filename}', 'FileController#getFile')->where('filename', '^[^/]+$');
And that's it. Now, your authenticated users can download files from storage folder (but not its subfolders) by calling http://yoursite.com/file/secret.jpg. Add you can use this URL in src attribute of an image tag.
answer's original source!
#xerwudjohn simple you can't.
When this file is in the public folder, everyone can access it whitout being logged in.
One method I tried for some minutes, create a new route:
Route::group(['middleware' => ['web', 'auth']], function () {
Route::get('/download/{id}', 'DownloadController#showFile');
});
create the function showFile in the DonwloadController
public function showFile($id)
{
return redirect('/image/'.$id.'.txt');
}
or use a Model to read uniqueIds out of any table and get the realfile name.
Cheers

Controller method not called in laravel 4

I'm trying to learn laravel 4. I created a form(using view) and returned it via a controller(testController) using index method. I had created this controller using artisan command.
i created another method (dologin) in the controller which would process the form. In the form url parameter i gave the address of dologin method.
This is the route:
Route::resource('test', 'testController');
This is the controller
<?php
class testController extends \BaseController {
public function index()
{
return View::make('test.index');
}
public function dologin(){
echo "working";
}
and this is the index view file
{{ Form::open(array('url'=>'test/loginform')) }}
{{ Form::text('username', null, array('placeholder'=>'Username')) }}<br/>
{{ Form::password('password', array('placeholder'=>'Password')) }}<br/>
{{ Form::submit('Login') }}
{{ Form::close() }}
After submitting form, it should echo "working" in the browser. But after submitting the form, page is blank. The url changes though from
/laravel/public/index.php/test/
to
/laravel/public/index.php/test/loginform
umefarooq's answer is correct, however hopefully this answer should give you a bit more insight into getting a head-start in your Laravel development as well as a consistent best-practice programming style.
Firstly, class names should really start with a capital letter. Try to keep methods / function names starting with a lower case letter, and class names starting with a capital.
Secondly, you don't need the \ in front of BaseController. You only need the backslash if you are name-spacing your controller. e.g. if your controller is in the folder Admin\TestController.php, and you put your TestController in the Admin namespace by typing <?php namespace Admin at the beginning of the file. This is when you should use \BaseController because you are telling your TestController to extend BaseController from the Global Namespace. Alternatively, before you declare your class, you can type use BaseController; and you don't need to put a \ in every time.
Specifically related to your question:
When you use resource routes in your routes file, you are telling Laravel that the controller can have any or all of the following methods: index, show, create, store, edit, update and destroy.
As such, Route::resource('test', 'TestController'); will point to TestController.php inside your controllers folder.
Your TestController should be structured as follows, most restful controllers will use the below as some kind of boilerplate:
<?php
class TestController extends BaseController
{
public function __construct()
{
}
// Typically used for listing all or filtered subset of items
public function index()
{
$tests = Test::all();
return View::make('test.index', compact('tests'));
}
// Typically shows a specific item detail
public function show($id)
{
$test = Test::find($id);
return View::make('test.show', compact('test'));
}
// Typically used to show the form which creates a new resource.
public function create()
{
return View::make('test.create');
}
// Handles the post request from the create form
public function store()
{
$test = new Test;
$test->attribute1 = Input::get('attribute1');
$test->attribute2 = Input::get('attribute2');
$test->attribute3 = Input::get('attribute3');
$test->attribute4 = Input::get('attribute4');
if ($test->save())
{
return Redirect::route('test.show', $test->id);
}
}
// Shows the edit form
public function edit($id)
{
$test = Test::find($id);
return View::make('test.edit', compact('test'));
}
// Handles storing the submitted PUT request from the edit form.
public function update($id)
{
$test = Test::find($id);
$test->attribute1 = Input::get('attribute1');
$test->attribute2 = Input::get('attribute2');
$test->attribute3 = Input::get('attribute3');
$test->attribute4 = Input::get('attribute4');
if ($test->save())
{
return Redirect::route('test.show', [$id]);
}
}
// Used to delete a resource.
public function destroy($id)
{
$test = Test::find($id);
$test->delete();
return Redirect::route('test.index');
}
}
Also, the beauty of using Resource Controllers is that you can take advantage of named routes.
in the terminal window, type in php artisan routes.
You should see 7 named routes.
test.index
test.destroy
test.show
test.edit
test.destroy
test.create
test.update
So within your form, instead of doing
{{ Form::open(array('url'=>'test/loginform')) }} you can point the url to a named route instead:
{{ Form::open(array('route' => array('test.store')) }}
That way if you ever change the url, or need to move around your site structure, this will be easy, because the forms post url will auto bind to the named route within the routes file. You wont need to update every single one of your views to ensure that the url's are pointing to the correct location.
Finally, as a starting point, I would recommend using JefreyWay/Laravel-4-Generators package. https://github.com/JeffreyWay/Laravel-4-Generators . Use them to create your resources, controllers, views etc. and see how the generators scaffold your models, views and, controllers for you.
Here is another resource to help you get started:
https://laracasts.com/lessons/understanding-rest
Route::resource('test', 'testController');
will work for RESTful method of controller, like index, edit, destroy, create and now you are using custom method of controller for this you need to create another route
Route::post("test/loginform",'testController#dologin');
hope this will work for you. read route documentation http://laravel.com/docs/routing
In addition to what umefarooq said, which is 100% accurate. You need to look into flash messages as well.
public function dologin(){
//do login verification stuff
If login validated
Return redirect::to(logged/page)->with('message', 'You're logged in');
If login failed
Return redirect::to('test')->with('message', 'You login credentials fail');
}
For further research:
http://laravel.com/docs/responses

Codeigniter : calling a method of one controller from other

I have two controllers a and b.
I would like to call a method of controller a from a method of controller b.
Could anyone help explain how I can achieve this?
This is not supported behavior of the MVC System. If you want to execute an action of another controller you just redirect the user to the page you want (i.e. the controller function that consumes the url).
If you want common functionality, you should build a library to be used in the two different controllers.
I can only assume you want to build up your site a bit modular. (I.e. re-use the output of one controller method in other controller methods.) There's some plugins / extensions for CI that help you build like that. However, the simplest way is to use a library to build up common "controls" (i.e. load the model, render the view into a string). Then you can return that string and pass it along to the other controller's view.
You can load into a string by adding true at the end of the view call:
$string_view = $this->load->view('someview', array('data'=>'stuff'), true);
test.php Controller File :
Class Test {
function demo() {
echo "Hello";
}
}
test1.php Controller File :
Class Test1 {
function demo2() {
require('test.php');
$test = new Test();
$test->demo();
}
}
Very simple way in codeigniter to call a method of one controller to other controller
1. Controller A
class A extends CI_Controller {
public function __construct()
{
parent::__construct();
}
function custom_a()
{
}
}
2. Controller B
class B extends CI_Controller {
public function __construct()
{
parent::__construct();
}
function custom_b()
{
require_once(APPPATH.'controllers/a.php'); //include controller
$aObj = new a(); //create object
$aObj->custom_a(); //call function
}
}
I agree that the way to do is to redirect to the new controller in usual cases.
I came across a use case where I needed to display the same page to 2 different kind of users (backend user previewing the page of a frontend user) so in my opinion what I needed was genuinely to call the frontend controller from the backend controller.
I solved the problem by making the frontend method static and wrapping it in another method.
Hope it helps!
//==========
// Frontend
//==========
function profile()
{
//Access check
//Get profile id
$id = get_user_id();
return self::_profile($id);
}
static function _profile($id)
{
$CI = &get_instance();
//Prepare page
//Load view
}
//==========
// Backend
//==========
function preview_profile($id)
{
$this->load->file('controllers/frontend.php', false);
Frontend::_profile($id);
}
I posted a somewhat similar question a while back, but regarding a model on CI.
Returning two separate query results within a model function
Although your question is not exactly the same, I believe the solution follows the same principle: if you're proposing to do what you mention in your question, there may be something wrong in the way you're coding and some refactoring could be in order.
The take home message is that what you're asking is not the way to go when working with MVC.
The best practice is to either use a Model to place reusable functions and call them in a controller that outputs the data through a view -- or even better use helpers or libraries (for functions that may be needed repeatedly).
You can do like
$result= file_get_contents(site_url('[ADDRESS TO CONTROLLER FUNCTION]'));
Replace [ADDRESS TO CONTROLLER FUNCTION] by the way we use in site_url();
You need to echo output in controller function instead of return.
You can use the redirect() function.
Like this
class ControllerA extends CI_Controller{
public function MethodA(){
redirect("ControllerB/MethodB");
}
}
Controller to be extended
require_once(PHYSICAL_BASE_URL . 'system/application/controllers/abc.php');
$report= new onlineAssessmentReport();
echo ($report->detailView());
You can use the redirect URL to controller:
Class Ctrlr1 extends CI_Controller{
public void my_fct1(){
redirect('Ctrlr2 /my_fct2', 'refresh');
}
}
Class Ctrlr2 extends CI_Controller{
public void my_fct2(){
$this->load->view('view1');
}
}
very simple
in first controllr call
$this->load->model('MyController');
$this->MyController->test();
place file MyController.php to /model patch
MyController.php should be contain
class MyController extends CI_Model {
function __construct() {
parent::__construct();
}
function test()
{
echo 'OK';
}
}

Resources