CodeIgniter - multiple entry paths with other CMS on same site - wordpress

Here's a weird question for everyone. I've got a situation where an existing site has wordpress running on it as the main CMS to the site, there's some additional code which can't be implemented in WP because of URL structures etc so we'd like to put CI on the same host.
However, there's two potential entry points needed for CI on that site - lets call them /userside and /adminside
I want both to share the same application and system folders which are all in the same accessible folder space.
I've got /userside working co-existing with WP quite easily.
Here's the .htaccess file
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/userside [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /userside/index.php [L]
RewriteRule ^/adminside [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /adminside/index.php [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
My folder layout is as follows
FTP ROOT/
ci/ <- codeigniter root
application/
system/
http/
index.php <- WP index.php
adminside/
index.php <- CI index.php
userside/
index.php <- CI index.php
... wp-content etc
I've copied userside's files to adminside and tried symlinking as well but neither work.
In CI's application/config i've modified the base_url to be:
list($_trash, $_base, $rest) = explode('/', $_SERVER['REQUEST_URI'], 3);
$config['base_url'] = "http://".$_SERVER['HTTP_HOST']."/".$_base;
Which means it automatically puts the first segment of the URI as the application base, i've debugged this code and it sets it correctly.
Now here's the problem, when I access /userside/somecontroller, it works, however, when I access /adminside/somecontroller it doesn't. I get a 404 page.
I can get it to access the default controller's index() function by just accessing /adminside - that works but not when I specify a controller and method.
eg:
http://www.mysite.com/userside/mycontroller/mymethod <- works
http://www.mysite.com/userside/mycontroller/mymethod <- doesn't work - 404 displayed
/userside was set up first and I can't see anywhere that ties CI to /userside other than in application/config/config.php
Permissions have been checked and are identical, owners are identical.
Anyone got an idea why this isn't working? I don't want to have to split the site into a subdomain as we have specific reasons and as it works with /userside there's only something simple keeping me from making /adminside work as well.

You need the RewriteRule to get rid of index.php and append the method:
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/userside(.*)$ /userside/index.php$1 [L]
RewriteRule ^/adminside(.*)$ /adminside/index.php$1 [L]
RewriteRule ^(.*)$ index.php/$1 [L]
</IfModule>

This was a little less complicated than I thought.
You simply put CI's .htaccess in the sub-folder you want to run CI in and then set the appropriate site URL variables to match.
I did find a document that showed how to give you access to all of WP's libraries from CI by simply loading wp-load.php from the root of the WP side in CI's index.php.
Hope this helps other people.

Related

.htaccess file Wordpress RewriteRule Block Rearrange to the top

I was having issues (401 error) trying to reach my website via rest API. I moved the Wordpress block in my .htaccess file to the top and now my website is reachable. This is the first block that I now have in my .htaccess file?
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Do I need to combine the two lines of the RewriteRule lines like this? Does it change anything functionally?
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Prior to me making any changes, the first block in the .htaccess file was:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
So by moving the "Wordpress block" it just adds the one line RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Do I need to combine the two lines
You certainly don't "need" to combine those two lines.
It will probably make no difference to accessing your rest API if you do.
A single, combined directive
By combining those two directives, as you have done, will mean the HTTP_AUTHORIZATION env var (used to help with HTTP Authentication) will only be set on requests that are routed through WordPress (including the homepage). And (on Apache*1) the REDIRECT_HTTP_AUTHORIZATION env var will not be generated when requests are rewritten to the WordPress front-controller (index.php), ie. page requests other than the homepage. Although I'm pretty sure that WordPress does not take advantage of this anyway. The HTTP_AUTHORIZATION env var will not be set on requests to static resources (images, CSS, JS, etc.) as it would have been before.
Two separate directives
With the two separate directives, as in the orginal code, the HTTP_AUTHORIZATION env var is set on every request, including requests for static resources. (But ordinarily, this is redundant.) And (on Apache*1) the REDIRECT_HTTP_AUTHORIZATION env var will be generated when requests are rewritten to the WordPress front-controller (index.php), ie. page requests other than the homepage.
(*1 As opposed to LiteSpeed, where env vars of the form REDIRECT_... are not generated anyway.)
I moved the Wordpress block in my .htaccess file to the top and now my website is reachable.
That isn't necessarily the correct thing to do. Ordinarily, the WordPress code block (the front-controller) should appear later in the file. There may have just been a single conflicting rule that should have been "modified" or perhaps moved to after the WordPress code block. But moving those directives to after the WordPress code block may effectively "disable" those rules entirely.
UPDATE:
Prior to me moving the "Wordpress" block to the top, this is what the
first block had:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
That code block is just an erroneous "copy" of the WordPress code block (less the HTTP_AUTHORIZATION var) and should be deleted altogether!

Wordpress and CI rewrite rule in htaccess

I have installed WordPress in example.com. I have also installed CodeIgniter in ci folder here example.com/ci/, ci is the folder name , register is the controller name and working URL of CI is example.com/ci/register . My base URL starts with https:// .
Now I have one WordPress URL example.com/hotel, hotel is the page that I have created in WordPress admin, it works fine.
I want to run my CI path like example.com/hotel/ci/register, I think we can do it with some rewrite rule so that my URL would look like example.com/hotel/ci/register. I have added given htaccess for wordpress that redirecting me here example.com/hotel/ci/register. It is showing me 404 error of CI. It means now I am in CI. Now I did following things in routes.php file.
$route['default_controller'] = 'register';
$route['404_override'] = 'register';
Now this URL example.com/hotel/ci/register is working, but this is not right way, next time there will be more controllers then it will not work.
Note: I can not create hotel folder because hotel is a page in the WordPress. If I create hotel folder then WordPress URL example.com/hotel/ will not work. It will redirect WordPress page to the hotel folder. So I have to do it without creating hotel folder. Note example.com=myurl.com .
I need to find another good solution.Any advise or guidance would be greatly appreciated?
Following is my reWrite rule in wordpress htaccess:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/?hotel/ci/register(/.*)?$ /ci/$1 [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
And following is my CI htaccess:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
</IfModule>
Interesting problem! I set up a Docker container with a fresh install of Wordpress and Codeigniter, I created a hotel page in WP, and a Register controller and view in CI, and got testing. I spent way too long on this, but I did find an answer.
First, your Wordpress .htaccess. As #tobiv pointed out in a comment, you should not add anything between the BEGIN/END WordPress comments as it might get whacked by a WP update. Your redirect has to come before the standard WP rules though, so add it at the top of the file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^hotel/ci/register /ci/register [L]
</IfModule>
# BEGIN WordPress
# ... These are the default, unchnaged WP rules
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
<IfModule mod_rewrite.c> and RewriteEngine On are duplicated which seems messy but you do need them, as your new rule has to go first so it processes the request before the WP rules do.
You don't need to modify the Codeigniter .htaccess file, the default one is all you need. It should be in the root of your Codeigniter installation, ci/.htaccess:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
At this point https://example.com/hotel/ci/register will show the Codeigniter 404 page. If you have logging enabled (see config/config.php), and you watch the logfile, you'll see why:
ERROR - 2017-11-14 17:57:20 --> 404 Page Not Found: Hotel/ci
And here's the root of the whole problem. Since the initial redirect is an internal redirect (means the URL shown in the browser does not change), the URI Codeigniter receives to process is the one still shown in the browser address bar - hotel/ci/register. Codeigniter will try to handle a request like that in 2 ways:
Look for a matching route in application/config/routes.php
Or look for a controller named application/controllers/Hotel.php, with a method called ci;
In our case there is no Hotel controller, and no route to describe how to handle such a request, so boom, 404.
One simple solution is to create a route to handle this request:
$route['hotel/ci/register'] = 'register/index';
And now https://example.com/hotel/ci/register works!
Notes:
Setting your default route to register ($route['default_controller'] = 'register';) means that https://example.com/ci/ will also show register. I'm not sure if you want that? You might run into duplicate-content SEO problems if that URL shows the same as https://example.com/hotel/ci/register, so maybe you want something else, or a 404, there.
Make sure you remove your $route['404_override'] = 'register'; route;
CI base_url is not relevant for this problem, though obviously should be set. Depending on how you want your links to be I think either http://example.com/ci/ or http://example.com/hotel/ci/ would be right.
I am not quite sure what the purpose of this condition in your CI .htaccess is for:
RewriteCond $1 !^(index\.php|resources|robots\.txt)
The existing default conditions already skip files and directories which exist on disk. That's what the !-f and !-d conditions mean - "if the requested pattern does not match a file or directory on disk, then do the redirect".
If you have a robots.txt file on disk (in your ci/ dir), and someone requests https://example.com/ci/robots.txt, the !-f condition will fail, and the rewrite is skipped - meaning the request is handled without rewrites and robots.txt is returned successfully. Same for index.php. If you have a directory called ci/resources, and someone requests https://example.com/ci/resources, the !-d condition will fail, the redirect is skipped, and the request is successfull.
I'm not sure about your resources part, but maybe you can remove that condition completely.
If you don't need pretty Codeigniter URLs (I mean other than https://example.com/hotel/ci/register, this change won't affect it), and it turns out you don't need that extra condition above, you can get rid of the CI .htaccess completely to simplify things. To do that, just change the Wordpress RewriteRule to the non-pretty version:
RewriteRule ^hotel/ci/register /ci/index.php/register [L]
And delete your CI .htacces.
I think you are on the right path, try this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/hotel/ci(/.*)?$ /ci/$1 [L] # remove the register part
# so that it would be handled by CI
# also remove the "?" in front of hotel
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
keep your CI htaccess as it is:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
</IfModule>
the last part is match your CI config.php to your new url model
$config['base_url'] = "http://example.com/hotel/ci/";
I don't thing this will be the great answer of your question but if i face the same problem i will use routes see the example code.
$route['(:any)/ci/register'] = "register";
what will the above code do (:any) means any word in first uri and after that you can defined any url you want i defined ci/register you can also do that like this.
$route['(:any)/register'] = "here_you_can_add_your_controller/function";
this will work if hit url like this.
http://www.example.com/any_word_you_want/register
it will hit your controller function. you need to echo something and it will show in your browser.
you can also defined the hotel word in your base url as #am05mhz shows in his answer but i don't thing that's a great idea because in future may you have 2 more words in your url.
Note : the above code example only work if your .htaccess give access of routs as you shows in your question the .htaccess is work for you. For full knowledge of routs please check the documentation of codeigniter URI routing
Use htaccess [P] flag instead.
Make sure the substitute (target) string will start with http://. Otherwise, it will treat the substitute string as an internal file path.
Check the code below.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^/?hotel/ci/(.*)?$ http://example.com/ci/$1 [P]
# If you want rewrite any URI as long it has */ci/* in it.
# Use the following rule instead.
# RewriteRule ^(.*)/ci/(.*)?$ http://example.com/ci/$1 [P]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
Also, you don't need to update CI's base url. Empty string will do.
$config['base_url'] = '';
Hope that helps.
Links:
https://httpd.apache.org/docs/current/rewrite/flags.html#flag_p

How to ignore sub-folder requests and continue processing URI mapping using mod_rewrite?

An default example file for a default Wordpress deployment is:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
I have a special case scenario though where I have a subfolder as such in my root web directory that I need ignored:
/folderA/folderB/specialCase.php
I basically need:
/folderA/folderB/*
to be ignored, but I do need:
/folderA/folderB/specialCase.php
to be directly accessible and served.
The problem is that /folderA/folderB currently maps to a URI in my Wordpress install. Since the directories actually exist in the web root folder, currently Apache is serving up the index.php within /folderA/folderB/.
I need it to skip over these subfolders and continue processing URI mappings as usual, except in the special case where specialCase.php is requested?
Difficult? Hard? I'm stumped at the moment. Have been experimenting with the [PT] (passthrough) flags but no luck so far.
Thanks!
Couldn't you just check for that specific file, and serve it. Otherwise redirect the rest to the wordpress rules. Maybe something like this.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^/folderA/folderB/specialCase\.php$ [NC]
RewriteRule ^ - [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_URI} ^/folderA/folderB/?$ [NC,OR]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Also you could probably add another .htaccess in folderA/folderB/.htaccess with this
DirectoryIndex disabled
Which will also prevent it from serving index.php in that directory only.

Wordpress RewriteRule Conflicts with .passwd

In my root .htaccess file I have the following Wordpress code:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
Slightly different to the standard code because the Wordpress files are in a "wordpress" directory but rewrites still appear relative to the domain root. For example a blog post can be called site.com/this-is-a-blog-post.php and the rewrite works.
This works great except when I want to use htpasswd to protect a directory on the site. If I add the following code to a .htaccess file in any directory I get a 404 when trying to browse to that directory:
AuthName "Private"
AuthUserFile "/home/passwd"
AuthType Basic
require valid-user
This code works correctly when the last line of the Wordpress rewrite code is commented out, but with the Wordpress code intact my password protected directory gives a 404.
So I have a conflict between the two .htaccess files somehow. I have tried writing a bunch of RewriteCond's to try and exclude the subdirectory with the password applied but can't nail it.
Ok, Murphy's Law, just worked it out after posting the question!
The extra condition needed for the Wordpress rewrite is:
RewriteCond %{REQUEST_URI} (/|\.htm|\.php|\.html|#.*|\?.*|/[^.]*)$ [NC]
So the complete Wordpress rewrite code becomes:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (/|\.htm|\.php|\.html|#.*|\?.*|/[^.]*)$ [NC]
RewriteRule . /wordpress/index.php [L]
Now I'll go finish my humble pie.

Rewrite index and one folder to static pages with WordPress rewrites on the other

I'm looking to have all WordPress rewrites to work except:
Home page as a static html page, content is in index.html in the root folder
/business be routed to a business folder in the root dir which contains static html pages.
When I set the index to . /index.html [L] none of the regular wordpress rewrites work. However if I set DirectoryIndex /index.html I can't figure out how to get rewrites to work for /business which contains HTML files that need to be served up on the http://mywebsite.com/business url. Full rewrite rules:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# RewriteRule . /index.php [L]
RewriteRule . /index.html [L]
Any help is appreciated and, more than just an answer, an explanation of what each portion of the lines you provide does may help myself and others understand how to take this on on their own next time.
UPDATE: Rules are still not working. /wp-admin has worked all along though.
Try to stick with default WordPress rewrites and simply add DirectoryIndex to prefer .html files over .php files:
DirectoryIndex index.html index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
So rewrites will only happen when requested files or directories are missing (RewriteConds with !-f and !-d flags). And if there is a static index.html along with index.php in a directory (root directory for example), it will be served first.
http://httpd.apache.org/docs/2.2/mod/mod_dir.html#directoryindex
Try:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteRule ^business/ - [L]
RewriteRule ^index\.php$ - [L]
RewriteRule ^$ /index.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
Two issues need to be solved:
Serve a particular HTML file whenever someone needs the front page.
Serve static files from a static directory alongside WordPress.
To solve the first issue, I would rename index.html to front-page.php and move it inside my current theme folder. Then WordPress would serve it (or rather: use it as a template) whenever someone requests the front page, according to the Template Hierarchy.
There is a cost to this solution compared to actually serving a static file: Whenever someone requests you front page, WordPress will still be loaded. If the goal of serving your front page statically is to save server resources by not loading WordPress or PHP on every page load, you should look into caching plugins.
The second issue should not be an issue at all, because the standard WordPress rewrite rules already allow for static files and directories. The lines
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
mean that the redirect to WordPress won't happen if the URL requested is an actual file (-f) or directory (-d). Therefore you will not need any extra rewrite rules to access the /business directory.
The standard WordPress rewrite rules are explained below:
RewriteEngine On # Turn on the rewrite engine
RewriteBase / # Use the domain root as the base of rewrites
RewriteRule ^index\.php$ - [L] # If someone requests the WordPress entry point, stop here
RewriteCond %{REQUEST_FILENAME} !-f # If the requested URL is not an actual file ...
RewriteCond %{REQUEST_FILENAME} !-d # ... and if the requested URL is not an actual directory ...
RewriteRule . /index.php [L] # ... then rewrite it to the main WordPress entry point
When /index.php is loaded, this file will then in turn load WordPress and everything that comes with it.
Replace this code with your HTACCESS file in root
# Switch rewrite engine off in case this was installed under HostPay.
RewriteEngine Off
SetEnv DEFAULT_PHP_VERSION 53
DirectoryIndex index.cgi index.php
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
And also change the URL's from database...

Resources