Best practice in handling invalid parameter CodeIgniter - codeigniter

Let's say I have a method at Controller named
book($chapter,$page);
where $chapter and $page must be integer. To access the method, the URI will look like
book/chapter/page
For example,
book/1/1
If user try to access the URI without passing all parameter, or wrong parameter, like
book/1/
or
book/abcxyz/1
I can do some if else statements to handle, like
if(!empty($page)){
//process
}else{
//redirect
}
My question is, is there any best practice to handle those invalid parameters passed by user? My ultimate goal is to redirect to the main page whenever there is an invalid parameter? How can I achieve this?

Using the CodeIgniter routing in config/routes.php is pretty useful here, something like this:
$route['book/(:num)/(:num)'] = "book/$1/$2";
$route['book/(:any)'] = "error";
$route['book'] = "error";
Should catch everything. You can have pretty much any regular expressions in the routes, so can validate that the parameters are numeric, start with a lowercase letter, etc..

The best logic here seems to be adding the default values:
book($chapter = 1, $page = 1);
and then checking if they are numeric
So it automatically opens the 1st page of the 1st chapter if there are parameter missing or non-numeric.

Related

Construct routes(urls) with slugs separated by dash in laravel

I am about to make more SEO-friendly URLs on my page and want a pattern looking like this for my products:
www.example.com/product-category/a-pretty-long-seo-friendly-product-name-12
So what are we looking at here?
www.example.com/{slug1}/{slug2}-{id}
The only thing I will care about from the URL in my controller is the {id}. The rest two slugs are just of SEO purpose. So to my question. How can I get the 12 from a-pretty-long-seo-friendly-product-name-12?
I have tried www.mydomain.com/{slug}/{slug}-{id} and in my controller to try and get $id. Id does not work. I am not able to able to separate it from from a-pretty-long-seo-friendly-product-name. So in my controller no matter how I do I get {slug2} and {id} concatenated.
Coming from rails it is a piece of cake there but can't seem to figure out how to do that here in laravel.
EDIT:
I am sorry I formulated my question very unclear. I am looking for a way to do this in the routes file. Like in rails.
You're on the right track, but you can't really logically separate /{slug}-{id} if you're using dash-separated strings. To handle this, you can simply explode the chunks and select the last one:
// routes/web.php
Route::get('/{primarySlug}/{secondarySlugAndId}', [ExampleController::class, 'example']);
// ExampleController.php
public function example($primarySlug, $secondarySlugAndId){
$parts = collect(explode('-', $secondarySlugAndId));
$id = $parts->last();
$secondarySlug = $parts->slice(0, -1)->implode('-');
... // Do anything else you need to do
}
Given the URL example.com/primary-slug/secondary-slug-99, you would have the following variables:
dd($primarySlug, $secondarySlug, $id);
// "primary-slug"
// "secondary-slug"
// "99"
The only case this wouldn't work for is if your id had a dash in it, but that's another layer of complexity that I hope you don't have to handle.
Route::get('/test/{slug1}/{slug2}','IndexController#index');
public function index($slug1, $slug2)
{
$id_slug = last(explode('-',$slug2));
$second_slug = str_replace('-'.$id_slug,'',$slug2);
dd($slug1, $second_slug,$id_slug);
}

Laravel pass parameters to route/action

If I want to construct this url: /categories/5/update/?hidden=1 how could I pass both {id} param and hidden param (as GET) ?
My route is:
Route::get('categories/{id}/update', 'CategoryController#update');
I don't want to make a form and put it as POST because I have a number of buttons which simply hides/shows/removes a category and dont want to make a lot of forms for simple actions, although it has nothing to do with the question
I'm just a little bit confused, because it seems like action('CategoryController#update', [$id, 'hidden' => 1]) constructs the right URL but I got no idea how it's distinguished that the first one ($id) must be in URL and the second is a GET param
You may also try this to generate the URL:
$action = action('CategoryController#update', [id => $id]) . '?hidden=1';
Also, query string could be passed with any route even without mentioning about that in Route declaration.

Codeigniter Route to accept dynamic values

I am trying to create a router which will take a dynamic value and forward it to the actual route. In normal case it would be like
$route['login'] = 'auth/login';
It is possible to catch a parameter before the login in the above parameter and pass it to as the first parameter to the actual route ? like
$route['^(.+)/login$'] = "$1/user/login";
Check out the documentation[docs]. There is a very easy way to do this.
$route['(:any)/login'] = '$1/auth/login';
Starx answer is correct but I wouldn't do that, as your first param will be your controller, and if you don't know what's in the dynamic value that's impossible to manage.
I would do :
$route['(:any)/login'] = 'user/login/$1';
This way, 'anything/login' would be redirected to your User controller, to the Login function with the parameter 'anything'.

magento _redirect with parameters that have + or /

seems like a call to
$this->_redirect('*/*/myaction',$myargs);
does not properly escape the arguments
so if
$myargs=array(p1=>'string that has + or / within it')
the created URL will be something like:
..../myaction/?p1/string%20that%20has%20+%20or%20/%20within%20it
causing the getParams collection on the action to have
p1 with value 'string that has or ' <- plus sign missing and value broken and
' within it' with no value or something similar.
is there any standard way I should handle the arguments before passing them to _redirect ?
Eyal
Yes, there are two standard ways.
Pass all your params as route params, but encode them with php urlencode() func:
foreach ($myargs as $key => $val) {
$myargs[$key] = urlencode($val);
}
$this->_redirect('*/*/myaction', $myargs);
Pass your params as query params
$this->_redirect('*/*/myaction', array('_query', $myargs));
You'd better take second approach, because your params logically are not route but query parameters. Magento is made with a lot of architecture thinking, so it usually points better ways to do stuff - that's why in your case it's easier to send params using second way.
Notice: _redirect() internally uses Mage_Core_Model_Url, so everything said in this answer is true for all other url-forming routines and all usages of Url model.
refer to http://www.blooberry.com/indexdot/html/topics/urlencoding.htm#whatwhy and read the section "Reserved characters"

Mutliple URL Segments to Index Function With CodeIgniter

Please excuse me if this is an incredibly stupid question, as I'm new to CodeIgniter.
I have a controller for my verification system called Verify. I'd like to be able to use it something like site.com/verify/123/abcd, but I only want to use the index function, so both URL segments need to go to it.
I'm sure this can be done with URL routing somehow, but I can't figure out how to pass both URL segments into Verify's index function..
Something like this in routes.php should do the job:
$route['verify/(:any)/(:any)'] = "verify/index/$1/$2";
I'm pretty sure you can just pass any controller method in CodeIgniter multiple arguments without modifying routes or .htaccess unless I misunderstood the problem.
function index($arg_one, $arg_two)
{
}
$arg_one representing the 123 and $arg_two representing the abcd in your example URI.
You will either need to edit the routes or write an htaccess rule, however i didn't understand why you want to limit to just the index function.
If you didnt wanna use routes for some reason, then you could add this function to the controller in question.
public function _remap($method_in, $params = array()) {
$method = 'process_'.$method_in;
if (method_exists($this, $method)) {
return call_user_func_array(array($this, $method), $params);
}
array_unshift($params, $method_in);
$this->index($params);
}
Basically it does the same as default behavior in CI, except instead of sending a 404 on 'cant find method', it sends unfound method calls to the index.
You would need to alter your index function to take an array as the first argument.
OR if you know that you only ever want 2 arguments, you could change the last 2 lines to
$this->index($method_in, $params[0]);
Of course both solutions fail in someone uses an argument which is the same as a method in your controller.

Resources