Codeigniter: Deep level arguments - codeigniter

I think, this probably is novice question, but I am novice in CodeIgniter :)
Well here is the problem, I'm trying to make categories and subcategories (dynamically generated) for store, and the main problem is that, I could manage to set different options to main category with _remap function in my controller. But, if I am trying to get deeper, then the same _remap function applies, and I am stuck there.
For example, the main category uri is http://project.com/store/fruits/, but for the subcategory, of course - http://project.com/store/fruits/apples.
I want to apply different view to 3rd segment, and still be able to control main category (fruits) with _remap function.
I want to use one controller over and over, but I think, it must be crazy to copy and paste the same function content for all subcategories (hundreds of them, disguised).
Maybe there is some way to do that, but I can't find out how... Help here! :)
/Rob

Not sure why you would need the _remap function.
If "store" is your controller, you can set each top level category as a function inside store. What's passed (via the remaining URI) to each function would be the subcategories and those can be captured and looked up in a database to get the info you need. Something like this:
Function fruits(){
$sub1 = $this->uri->segment(3); // this will be apples, etc...
...
// if it's empty - call viewX
// else call db lookup for $sub1 data here and pass to viewY
}
Or...If you used .htaccess, you could reroute like this:
RewriteCond %{REQUEST_FILENAME} store.*
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^store/([a-zA-Z]+)/([a-zA-Z]+)$ store/someFunction/cat=$1&subcat=$2 [L]
This is for illustration purposes - it needs to be modified to work in your environment.

Thanks, jco for your effort, but actually, I found _remap() function working pretty well for my needs.
I created public _remap() function with two arguments - $first_level and $next_levels, and then I controlled everything after these $next_levels given information.

Related

Laravel Implicit Controller pagination

I have one of routes defined like this in laravel routes file.
Route::controller('login/home/admin/', 'AdminController');
But it seems laravel pagination does not work in methods. So i changed Route to allow page variable like this in one of the methods.
Route::get('login/home/admin/users/{page}', 'AdminController#getUsers');
Route::controller('login/home/admin/', 'AdminController');
Now problem is login/home/admin/users/2 loads but pagination does not work and if I try this login/home/admin/users?page=2 I am redirected.
EDIT:
My method is defined like this and does not work.
public function getUsers(){
var_dump( Input::get('page') ); // Returns NULL
$users = User::paginate(10);
...
...
}
and in view
...
{{ $users->links() }}
...
This view generates pagination but only first page works. Page 2 and other pages show records of page 1.
I doubt its because Input::get('page') is not working for some reason.
EDIT 2
None of following routes worked for me.
Route::get('login/home/admin/users/', 'AdminController#getUsers');
Route::controller('login/home/admin/', 'AdminController');
and
Route::get('login/home/admin/users/{page}', 'AdminController#getUsers');
Route::controller('login/home/admin/', 'AdminController');
and
Route::controller('login/home/admin/', 'AdminController');
Change your Route to
Route::get('login/home/admin/users/', 'AdminController#getUsers');
Laravel Pagination automatically takes care of your page variable in request
Here is the extract for Laravel documentation:
There are several ways to paginate items. The simplest is by using the
paginate method on the query builder or an Eloquent query. The
paginate method provided by Laravel automatically takes care of
setting the proper limit and offset based on the current page being
viewed by the user. By default, the current page is detected by the
value of the ?page query string argument on the HTTP request. Of
course, this value is automatically detected by Laravel, and is also
automatically inserted into links generated by the paginator.
ok this was something silly in htaccess that was not letting ?page=x or any other GET variable pass to code. Compared my htaccess to real htaccess of Laravel 4.2 and there was something different.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [L]
#RewriteRule ^(.*)$ index.php?/$1 [L] <-- CULPRIT

Rewriting url with the following regular expression

I'm trying to do a mod rewrite to get this url: localhost/test/index.php?hello
I created a file for this page called hello.php and it is in the folder /test
To clarify, I have another page that has a link to my hello.php, but what is the correct url so I can display localhost/test/index.php?hello in the url when I click the link to access my hello.php page.
The following doesn't seem like it is right:
RewriteRule ^.*$ index.php?$1 [L]
Try this if you want to just do php files.
RewriteEngine on
RewriteRule (.*)\.php$ /index.php?$1 [L]
To clarify what my answer does. It gives you more friendly URLs which it sounded like what your were asking for.
So you can use localhost/hello.php and it will be internally redirect to /localhost/index.php?hello. Internally means they will never see localhost/index.php?hello and will always see localhost/hello.php in their browser.
You can do any URL and it will rewrite to a php file. e.g. localhost/index.php?newpage and you can use /localhost/newpage.php
Hope that is clearer.
EDIT
You want the reverse but I don't know how your PHP is constructed but query strings are typically field/value pairs. For example name=john, page=contact, action=hello etc. You have index.php?hello but hello has no content or value.
That's probably why you're having such a hard time even re-writing your URL. Using $_GETwould require a value.
So what I would do, is if your URL was like this using field/value pairs
index.php?action=hello
Then in the index.php file you could do something like
$action = $_GET["action"];
if($action == "hello"){
//show contents of hello, include a page or whatever
}
Once you have good URLs it would be easy to rewrite it.
So if the URL that you want shown is like
index.php?action=hello and you want to redirect it to hello.php
Your .htaccess would look like this
RewriteRule ^action=([^/]+) /$1.php [R,L]
That would redirect it to the php file. If you don't want to show the redirection and keep it an internal redirect you can remove the R flag and just keep [L].
I personally don't want the user to see really long query strings URL example. mysite.com?page=music&artist=someartist&title=sometitle
So all my URL's are rewritten to be shorter and friendlier like my original answer.
you don't need .htaccess for 2. as far as you're using GET parametr - use it in index.php:
if (isset($_GET['hello'])) include('hello.php');
this will show the contents of hello.php inside index.php

Mod Rewrite - hide .php, hide optional querystring

I figured out how to hide .php, but I need to hide any query string on the URL, and provide for there not being one.
Here's my current rule: RewriteRule ^/?([a-z]+)$ $1.php
I've searched everywhere, to no avail.
Lets say you have a page that displays items from some kind of a lookup. So the requested resource is www.example.com/page.php?display=news.
In this case you can use something like RewriteRule ^/news/$ page.php?display=news This way you can create friendly URLs for different resources which might need a query string value passed in.
Lets say you want to make this generic. So display can have values news, about, company which map to the urls /news/ /about/ /company/ then you simply change your rule to
RewriteRule ^/([^/]+)/?$ page.php?display=$1
You can also use this second method to say change your shopping cart system's URLs to a friendly one. Say your shopping cart uses a query string like - shop.php?category=1&product=10. You can convert this into a URL like shop/category/1/product/10. The rule would be
RewriteRule ^shop/category/([^/]+)/product/([^/]+)$ shop.php?category=$1&product=$2

CodeIgniter, multiple possible segments in one route

Ok, so maybe that title is a bit confusing. What I'd like to do is trap any info, if any after the first URI segement if that segment is something specific and forward that on to another controller. Here's my routes file:
$route['default_controller'] = "main";
$route['404_override'] = '';
$route['testroute'] = "main";
So, what this does right now is, if I got to mydomain.com/testroute it shows me the default page, which it should. However, what I'd like is if I go to mydomain.com/testroute/testmethod/ where testmethod is a method in the main controller I'd like it to forward that as well. So basically I'd like it to route to the main controller regardless of if there are more segments after the testroute, but if there are they should get passed as method calls of the main controller.
Simply catch the parameter given and pass it to the controller e.g. like this:
$route['testroute/(:any)'] = "main/$1";
(:any) actually catches any type of string. There are other selectors, as well. More on this topic can be found here.
Edit (answer to your comment):
If you want a general route to the index() method of your main controller, just add both routes:
$route['testroute'] = "main";
$route['testroute/(:any)'] = "main/$1";
Uh, what? That's how CodeIgniter's controllers work already. Show us some code? What isn't working about it?
Have you configured URL rewriting in your .htaccess file so you don't need the /index.php/testroute in the URL?
Open .htaccess, and try this code if you haven't already rewritten this:
RewriteEngine on
RewriteCond $1 !^(index\.php|robots\.txt)
RewriteRule ^(.*)$ index.php/$1 [L]
If you haven't configured rewriting then it won't work without that^, but you can access like mydomain.com/path/to/ci/index.php/testroute/testmethod

Getting the original REQUEST_URI when using mod_rewrite AND mod_proxy

I'm using a custom.conf file for rewrites and codeigniter for some features of the site, mainly the articles.
My original url gets rewritten, so I have http://example.com/article-a101, this uses the custom.conf file to rewrite to codeigniter/article/read/101. I think I must send this as a proxy call using the [P] flag in mod_rewrite to make it rewrite again in codeigniters .htaccess file. Once it hits the code igniter .htaccess, it uses that mod rewrite structure to call the index file and use the article controller and the read function sending in the 101 as the parameter.
What I'm trying to figure it is how do I get the original url in the address bar as its not in the $_SERVER variable. Since I use the [P] on the first rewrite, request_uri has codeigniter/article/read/101.
custom.conf
RewriteRule ^/([_a-zA-Z0-9-]+)-a([0-9]+)$ /codeigniter/article/read/$2 [P,L]
codeigniters .htaccess, fairly basic
RewriteRule ^(.*)$ index.php?/$1 [L]
Here's my current solution that I know there must be a better method for
RewriteRule ^/([_a-zA-Z0-9-]+)-a([0-9]+)$ /codeigniter/article/read/$2?orig_url=%{REQUEST_URI}&%{QUERY_STRING} [P,L]
This stays hidden from the user, and I can access the original url through the query string, but doesn't seem like an elegant solution.
I'm pretty sure you cant do it any other way with mod_rewrite
but you could do it with codeigniter routing.
$route['^([_a-zA-Z0-9-]+)-a([0-9]+)$'] = "article/read/$2";
assuming your controller is named article and your function is named read
if you visited /article-a101
then $this->uri->uri_string(); would return article-a101 (the original url, which should be in your url bar now)
and $this->uri->ruri_string(); would return article/read/101 (where you actually are)

Resources