I'm trying to create a default page controller for a site with urls like http://www.example.com/about. So, if there isn't an 'about' controller, then go looking for a page with that url string in the database.
I've set the 404_override to my 'page' controller and am using the _remap() function to determine where to go next, either load the homepage (the page controller's index() method) or load a page.
However, as it stands right now if I use a different controller (product, in this case) with a method in the path (http://www.example.com/product/widget, which doesn't exist) I am being served the index() method of the page controller.
I thought the problem comes from the way I'm checking if the requested page is the homepage in my _remap() so I added an echo to the beginning of my remap to see if it mattered. The _remap() doesn't appear to be called. Instead, in attempting to handle the 404_override CI just shows the index method.
Any ideas how I can accomplish this more effectively?
public function _remap($method)
{
echo 'Method '.$method;
if($this->uri->segment(1) == null)
{
// $this->index();
} else {
$this->view();
};
}
I seem to have found a workable solution in this blog post: http://pinoytech.org/blog/post/codeigniter-route-everything-except-these-controllers
Using a regular expression in the route definition allows for other controllers (product, order, etc.) to be ignored while still sending everything else to the page controller.
$route['^(?!product|order|misc_controller)\S*'] = "page/$1";
Haven't tested it out just yet, but as far as I can tell it should work swimmingly.
Related
In laravel 5.8, I have have 2 type of url.
/news/{category} - > send to news controller index action, if have category bind
/news/{news} - > send to news controller details action, if have news bind
Another case abort with 404.
How can i solve this problem?
In Laravel and almost all frameworks and routing systems I'm aware of, the Route and Controller/Action relationship is 1:1. Each route can only have one controller or action to handle it.
If I understand your question correctly, you have a single route pattern of /news/{parameter}, and you want one of three things to happen:
{parameter} contains a valid Category slug. Retrieve the category and display the appropriate view.
{parameter} contains a valid Article (details) slug. Retrieve the article and display the appropriate view.
{parameter} does not contain a valid category or article slug, and thus is not found. Return a 404 error.
You'll still need only a single controller action, but you can separate the logic to make it easy to understand:
routes/web.php:
Route::get('/news/{param}', 'NewsController#index');
app/Http/Controllers/NewsController (with pseudo code):
class NewsController extends Controller
{
public function index(string $param)
{
if ($category = Category::whereSlug($param)->first()) {
// Return your category view.
}
if ($article = Article::whereSlug($param)->first()) {
// Return your article view.
}
\abort(404);
}
}
I would personally recommend against sharing a common URL structure for two different entity types like this. It opens the possibility for name conflicts (a Category and Article have the same slug) and can make the user experience confusing. (It might hurt search engine optimizations or results, also, but that's just speculation - I don't have anything to confirm or deny that.)
I am new in Codeigniter and it's one of the good frameworks of php. But on some conditions I'm confused. Like this one. If any of you have any clarification about my dough, it's a great help for me.
Offcouse redirects refresh the page and $this not but apart from this I want to know - anyhow both of them used to go to somewhere else on view pages or like in other controller or in same controller to other methods.
But we don't use these side by side because when getting any of them it will go to that page or method without checking the next lines.
In case of a normal difference then have lot's of but I just want to know about the condition of going to next page or method when we use redirect or $this like this -
$this->Function($value); //It's method of same controller.
redirect('Controller/function'); //It's also doing same with page reload.
Thank for looking my problem.
Redirect()
When you will call any function of helper in codeigniter then you can call function directly without using any object. Helper in Codeigniter is collection of functions.
Redirect() method is a part of URL helper in Codeigniter.
For your ref. https://www.codeigniter.com/user_guide/helpers/url_helper.html
So, just load helper using $this->load->helper('url'); or you can also mention in autoload.php file.
$this->Function(); used to call a function from same controller
$this->Function(); used to call a function from same controller
redirect()
While building a web application, we often need to redirect the user from one page to another page. CodeIgniter makes this job easy for us. The redirect() function is used for this purpose.
redirect($uri = '', $method = 'auto', $code = NULL)
The first argument can have two types of URI. We can pass full site URL or URI segments to the controller you want to direct.
The second optional parameter can have any of the three values from auto, location or refresh. The default is auto.
The third optional parameter is only available with location redirects and it allows you to send specific HTTP response code.
Redirect means jumping to another function mentioned in the redirect method.
$this->Function($value); => jumping to another function and you can execute the code of the same function as well as pass the value back by returning value.
When you send request to codeigniter generally CI controller gets called and then function which is mentioned in uri segment. like below... So this will be another request.
redirect('Controller/function'); //It's also doing same with page reload.
But when you have to call another function within the same request then you can use below approach
$this->Function($value); //It's method of same controller.
This will execute the given function and return the value within same request.
I tried to understand how the routing in CodeIgniter work.
I want to use normal access to sides which are not a kind of user area or something special - only normals links in the main root of the website.
So I try this.
I've set in the routes.php
$route['/'] = "index";
I've created controller names Frontend.php and a model named Frontend_modell.php
The Controller (nothing to do)
public function index()
{
redirect(site_url('index'));
}
The Modell
public function __construct()
{
parent::__construct();
}
I've added an index.php inside the view-folder Frontend and I add the index.php (for test) in the main folder from appilation and in the view folder.
If I try to access www.domain.com I see the URL will change to www.domain.com/index, but no side will come up. "the page you requested was not found."
What I do wrong ? I hope somebody can explain to me how it works correctly and why.
First of all routes uses controller_name/method_name and here you tried to use method_name directly.
Secondly, most of cases you don't need to play with routes unless you need a special handler or rerouting, so mostly keep it to default.
Btw the url rerouted to www.domain.com/index cause it looked for a controller named index as you specified and there in no controller found with that name it should be frontend if that's your controller.
The reason for the problem was from another point.
The Controller i've create had some bugs, after checking the function of the CR Controller, the routing works fine :-))
I defined a login check in my controller constructor method like following code:
if($this->session->userdata('log_in')== false){
redirect(); //function for redirect to login page
}
But I dont want to call this login check for a specific action
(say public function viewProduct())
of the same controller. How can I do that?
You can specify your method name in constructor in if condition like
$method = $this->router->fetch_method();
if($this->session->userdata('log_in')== false && $method !== 'viewProduct'){
redirect(); //function for redirect to login page
}
Now it will be not checked in viewProduct method.
You cannot. You can either run the login check within the individual controller methods or put the view product into it's own controller that does not do the login check in the constructor.
Thinking about this, I suppose you could check the segments within the constructor like this:
if ( ($this->session->userdata('log_in')== false) AND ($this->uri->segment(2, '') != 'view_product') )
redirect(); //function for redirect to login page
}
The uri_segment is explained here: http://www.codeigniter.com/user_guide/general/urls.html#uri-segments
Not sure this is a great idea though. I would do one of the first two suggestions myself. But that is just a matter of preference.
Hope that helps,
Paul.
I think the best way is to pass through method in controller rather do it on constructor. Constructor first run while loading the controller so handling through that is not a good practice. But certain hooks can work for you but you should really follow the standard practice for future coding.
Say I have a controller, "Articles" but I want it to appear as a sub-folder (e.g. "blog/articles"), I can add a route like this:
$route['blog/articles'] = 'articles';
$route['blog/articles/(:any)'] = 'articles/$1';
This works fine, the only problem now is that example.com/articles and example.com/blog/articles both use the Articles controller and thus resolve to the same content. Is there a way to prevent this?
To add a little more clarity in case people aren't understanding:
In this example, I don't have a 'blog' controller, but I want 'articles' etc to appear to be in that subfolder (it's an organization thing).
I could have a blog controller with an 'articles' function, but I'm likely to have a bunch of 'subcontrollers' and want to separate the functionality (otherwise I could end up with 30+ functions for separate entities in the blog controller).
I want example.com/articles to return a 404 since that is not the correct URL, example.com/blog/articles is.
Shove this in your controller:
function __construct()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR show_404();
}
You can use subfolders in Codeigniter controllers, so in CI, the following directory structure works:
application/controllers/blog/articles.php and is then accessed at
http://example.com/blog/articles/*.
If, for some reason, you're set on routing instead of accessing the controllers in folders (you want to have a blog controller, for example, and don't want to route to it), you can do as suggested above and add the test for 'blog' to the constructor.
If you're in PHP5, you can use the constructor function like this:
function __construct()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR redirect('/blog/articles');
}
or, in PHP4, like this:
function Articles()
{
parent::Controller();
$this->uri->uri_segment(1) == 'blog' OR redirect('/blog/articles');
}
I would suggest using redirect('blog/articles') instead of show_404(), though, so that you're directing users who hit /articles to the correct location, instead of just showing them a 404 page.
Routing there does not mean it will use a different controller, it just creates alias url segment to same controller. The way will be to create another controller if you are looking to use a different controller for those url segments.
If both /blog/ and /articles/ use the same controller, you can reroute one of them to a different one by just adding a new rule in your routes file.