Codeigniter and Pagination with Query Strings - codeigniter

I am trying to build a Search with Pagination in Codeigniter and would love some help with it.
So far, I've realized that I can not use BOTH url segments and query strings together. Using only query strings produces very ugly URLs.
I understand that Codeigniter destroys the GET and I'm trying to put it back in. Ergo... if I place this in the constructor of the search controller, will my problems be solved?
parse_str(substr(strrchr($_SERVER['REQUEST_URI'], "?"), 1), $_GET);
As in, if it works for me, is there anything I need to be aware of security wise?

So far, I've realized that I can not use BOTH url segments and query strings together.
Sure you can. Try this in your config:
$config['uri_protocol'] = "PATH_INFO";
That should get things started. Now, since CI abandons and empties the $_GET variable, you need to repopulate it like this:
parse_str($_SERVER['QUERY_STRING'],$_GET);
Now the only real concern here is that, if you have global XSS filtering on, you should know that you just manually parsed the query string into the global $_GET variable. This means you haven't passed it through any XSS filters. In CI 1.x you can access the filter through the input library like this:
$myvar = $this->input->xss_clean($_GET['myvar']);
In CI 2.x you do it through the security library like this:
$myvar = $this->security->xss_clean($_GET['myvar']);
Of course, it goes without saying that you can extend the Controller class to have a get() method that does all this automatically such that you can do this:
$myvar = $this->get('myvar');

Related

Pagination Conundrum

I used Codeigniter to build my site, and everything is going peachy, except when it comes to dealing with pagination. Because database queries are driven by data passed from my URL, this is screwing everything up. I'm SURE I'm overlooking something obvious, but this is my issue:
/events/town/venue/event-name
All fine and works as expected; the method takes the parameters from the URL to get the data and deliver it. But my question is - what do I do when I want to paginate my Events page? I.e.
/events/2
/events/3
...etc
As far as my controller, and my routes are concerned, the page number here is considered a town, which it isn't. How do I get around this?
Many thanks
"Test" your town or "page number" uri segment, if it is integer then
you sure know that you are looking for pagination thing, otherwise
"normal" behavior of your controller/method pattern.
using PHPs is_numeric.
A little pseudo code:
if (is_numeric($this->uri->segment(n))) {
//pagination stuff
} else {
//regular behavior
}
In case you are using aplication/config/routes.php consider using _remap() instead (for this certain controller).
or use routes as following:
$route['events/(:num)'] = "events/page/$1"; //pagination "behind the scene" with method "page" (that is not seen by user).
$route['events/town/venue/(:any)'] = "events/town/venue/$1";

Enable query string access only to select few Controller functions?

In few pages I need to make pagination. This of course can be achieved with URI segments, but in few cases in addition to pagination parameters, I need to pass some other GET parameters for filtering purposes.
So obviously in this case i need to be able access the controller via query string like so:
example.com/?c=controller&m=function
In order to achieve this I set the enable_query_strings to TRUE in main config file.
This seemed to work, but I discovered that it breaks a bunch of different stuff. For example if I use current_url() the URL returned has a ? at the end to accommodate the query string. So if I use it in form, it does not work.
So is there any way to enable the controller access to controller functions only to specified functions?
You can construct you url like this:
/param1/param2/pagination_parameters
So you will be able to send custom data (number of params), and pagination data using just URI segments.
For example if I use current_url() the URL returned has a ? at the end
to accommodate the query string. So if I use it in form, it does not
work.
Please note, that you can also left form 'action' blank, so result will be the same as if you had used current_url() (http request will go to the same script).
Instead of enabling enable_query_strings in main config, just enable in pagination config only. So it will apply to that particular page only.
Ex:
$config['page_query_string'] = TRUE;

Change CodeIgniter route for static pages and auth login [duplicate]

I have a problem with Codeigniter routes. I would like to all registered users on my site gets its own "directory", for example: www.example.com/username1, www.example.com/username2. This "directory" should map to the controller "polica", method "ogled", parameter "username1".
If I do like this, then each controller is mapped to this route: "polica/ogled/parameter". It's not OK:
$route["(:any)"] = "polica/ogled/$1";
This works, but I have always manually entered info in routes.php:
$route["username1"] = "polica/ogled/username1";
How do I do so that this will be automated?
UPDATE:
For example, I have controller with name ads. For example, if you go to www.example.com/ads/
there will be listed ads. If you are go to www.example.com/username1 there are listed ads by user username1. There is also controller user, profile, latest,...
My Current routes.php:
$route['oglasi'] = 'oglasi';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
I solved problem with this code:
$route['oglasi/(:any)'] = 'oglasi/$1';
$route['(:any)'] = "polica/ogled/$1"
$route['default_controller'] = 'domov';
$route['404_override'] = '';
Regards, Mario
The problem with your route is that by using :any you match, actually...ANY route, so you're pretty much stuck there.
I think you might have two solutions:
1)You can selectively re-route all your sites controller individually, like:
$route['aboutus'] = "aboutus";
$route['where-we-are'] = "whereweare";
//And do this for all your site's controllers
//Finally:
$route['(:any)'] = "polica/ogled/$1";
All these routes must come BEFORE the ANY, since they are read in the order they are presented, and if you place the :any at the beginning it will happily skip all the rest.
EDIT after comment:
What I mean is, if you're going to match against ANY segment, this means that you cannot use any controller at all (which is, by default, the first URI segment), since the router will always re-route you using your defined law.
In order to allow CI to execute other controllers (whatever they are, I just used some common web pages, but can be literally everything), you need to allow them by excluding them from the re-routing. And you can achieve this by placing them before your ANY rule, so that everytime CI passed through your routing rules it parses first the one you "escaped", and ONLY if they don't match anything it found on the URL, it passes on to the :ANY rule.
I know that this is a code verbosity nonetheless, but they'll surely be less than 6K as you said.
Since I don't know the actual structure of your URLs and of your web application, it's the only solution that comes to my mind. If you provide further information, such as how are shaped the regular urls of your app, then I can update my answer
/end edit
This is not much a pratical solution, because it will require a lot of code, but if you want a design like that it's the only way that comes to my mind.
Also, consider you can use regexes as the $route index, but I don't think it can work here, as your usernames are unlikely matchable in this fashion, but I just wanted to point out the possibility.
OR
2) You can change your design pattern slightly, and assign another route to usernames, something along the line of
$route['user/(:any)'] = "polica/ogled/$1";
This will generate quite pretty (and semantic) URLs nonetheless, and will avoid all the hassle of escaping the other routes.
view this:
http://www.web-and-development.com/codeigniter-minimize-url-and-remove-index-php/
which includes remove index.php/remove 1st url segment/remove 2st url sigment/routing automatically.it will very helpful for you.
I was struggling with this same problem very recently. I created something that worked for me this way:
Define a "redirect" controller with a remap method. This will allow you to gather the requests sent to the contoller with any proceeding variable string into one function. So if a request is made to http://yoursite/jeff/ or http://yoursite/jamie it won't hit those methods but instead hit http://yoursite/ remap function. (even if those methods/names don't exist and even if you have an index function, it supersedes it). In the _Remap method you could define a conditional switch which then works with the rest of your code re-directing the user any way you want.
You should then define this re-direct controller as the default one and set up your routes like so:
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
This is at first a bit of a problem because this will basically force everything to be re-directed to this controller no matter what and ultimately through this _remap switch.
But what you could do is define the rules/routes that you don't want to abide to this condition above those route statements.
i.e
$route['myroute'] = "myroute";
$route['(.*)'] = "redirect/index/$1";
$route['default_controller'] = "redirect";
I found that this produces a nice system where I can have as many variable users as are defined where I'm able to redirect them easily based on what they stand for through one controller.
Another way would be declaring an array with your intenal controllers and redirect everything else to the user controller like this in your routes.php file from codeigniter:
$controllers=array('admin', 'user', 'blog', 'api');
if(array_search($this->uri->segment(1), $controllers)){
$route['.*'] = "polica/ogled/$1";
}

Using and hiding default class

This is my first time getting my hands dirty with CI so I'm getting a little confused.
I'm wanting to accomplish a couple things with my question. First of all, I'd like to always use the default controller without having it to appear in the url. For example, I created a new class named after my site (Example.php) and that works fine. However, if I want to call the search function in my controller I then have to go to example.com/index.php/example/search/.
The second thing I want to accomplish is when I run a search I'll get a nice looking url like so: example.com/search/This+is+a+search (I haven't gotten to removing the index.php portion but I know to use a htaccess). I'm not worried about the actual mechanics of the search, just that I'd like to format the url in this way.
I originally experimented with using a Search class but that found that it doesn't allow me put the search in the url because the second parameter should be a function and not the extra stuff.
Thanks for any help.
In application/config/routes.php file add $route to redirect everything to your controller.
Something like this:
$route['([^\/]+)'] = 'content/index/$1';
$route['([^\/]+)\/([^\/]+)'] = 'content/index/$1/$2';
This will redirect urls like example.com/A and example.com/A/B to a controller named content. Parameters A and B will be passed to method index.

Trouble with Codeigniter Routes involving a query

I'm having a little trouble with a CodeIgniter route when there is a query (stuff after the ?) in the URI. I know it is good practice to replace queries with routes in CI, but I'm importing in a premade messageboard that already does everything with queries. This is my route:
$route['messageboard/:any'] = "messageboard/index";
Any in this case refers to a script name. So if it's messageboard/admin.php, I have it load a view that loads my premade messageboard's script "admin.php". It's working just fine if I do messageboard/admin.php. It does fine if I do messageboard/admin.php?. If I put a parameter into the query, however, the route won't correctly send the user to the messageboard controller, and instead sends them to a 404. Does anyone have any ideas on how to make this work? I would be eternally grateful. Thanks!
Okay guys, I solved it. I needed to change three things. The first was mtvee's suggestion, which lets it read query strings. The second one you're going to want to change the $config['permitted_uri_chars'] in the config file to include an equals sign, since it starts off disabled and all query strings will be of the for ?a=34 or something like that. The third is you need to go to $config['uri_protocol'] and change it from AUTO to PATH_INFO. Once I did those, it worked.
I'm sure the syntax is:
$route['messageboard/(:any)'] = "messageboard/index"; //<-- notice brackets
and not
$route['messageboard/:any'] = "messageboard/index";
I believe CI doesn't do GET out of the box. Check out Enabling Query Strings here http://ellislab.com/codeigniter/user-guide/general/urls.html

Resources