MVC public folder htaccess is not working - php

I recently moved my index.php (the file that handles routing) and CSS, JavaScript, and font assets to a public/ folder. I only want items in this public/ folder to be accessible for security purposes. I ran into this problem when I realized I could visit mysite.com/composer.lock and view the composer lock file with my old .htaccess and folder setup.
Here is what I want
If I visit mysite.com/car/create, I want it to actually point to mysite.com/public/index.php?path=car/create
If I link to an asset such as mysite.com/css/style.css, I want it to really point to mysite.com/public/css/style.css
Here is my folder structure
Here is my .htaccess which is not working at all
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ public/index.php?path=$1 [L,QSA]
</IfModule>
How can I fix this? It just generates empty pages and I can still directly visit files in the root directory, etc.

Your existing directives specifically avoid rewriting requests for existing files, so it would still enable you to visit files in the root directory. It will also rewrite static resources to public/index.php?path=, which will presumably fail.
Try the following instead:
RewriteEngine On
# Stop processing if already in the /public directory
RewriteRule ^public/ - [L]
# Static resources if they exist
RewriteCond %{DOCUMENT_ROOT}/public/$1 -f
RewriteRule (.+) public/$1 [L]
# Route all other requests
RewriteRule (.*) public/index.php?path=$1 [L,QSA]

Related

Add Subdirectory to WP-CONTENT URL using HTACCESS in Wordpress Multisite

I'm in the process of transitioning my single site WordPress installation into a multi-site. I'm trying to fix the broken CSS/JS from my main site.
I currently have two sites on my network:
http://www.example.com (primary)
http://dev.example.com (secondary)
My multi-site installation is inside of a subdirectory we will call "wordpress". So the file path looks like public_html/wordpress.
My goal is for neither site to have the "wordpress" subdirectory in the URL. Everything seems to be working except for broken CSS and JS on the primary site (the secondary site looks fine).
When inspecting the code, all of the CSS and JS calls point to http://www.example.com/wp-content/ but the files are not found there. The files will be found if I go to http://www.example.com/wordpress/wp-content in my browser. I want to hide the wordpress folder and still be able to retrieve the files.
I'm confused on how to setup the HTACCESS file. I already made some initial changes to it in order to get the multi-site within the subdirectory working. These were all following guides I found on StackOverflow and elsewhere online in regard to how to move your site into a multi-site with subdirectory and hiding the subdirectory. I haven't found anything about addressing the broken CSS/JS issue.
I figured I need to make updates to one or more of 3 HTACCESS files.
1.) public_html/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/wordpress/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /wordpress/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ /wordpress/index.php [L]
</IfModule>
2.) public_html/wordpress/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /wordpress/
RewriteRule ^index\.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
</IfModule>
3.) public_html/wordpress/wp-content/.htaccess
This file didn't exist but I created it. My thinking was that files are being called without the wordpress subdirectory but they need to act like they have the subdirectory included in them. For example, currently http://www.example.com/wp-content/uploads/image.jpg is broken but http://www.example.com/wordpress/wp-content/uploads/image.jpg works. I want it to be the other way around or I want both paths to work.
<IfModule mod_rewrite.c>
RewriteEngine on
# ADD WORDPRESS IF URL DOES NOT HAVE IT
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/wordpress/
RewriteRule ^(.*)$ /wordpress/$1
</IfModule>
I've tried adding different lines to the various HTACCESS files but none of them worked. I also not sure what line number I should insert a new rule. It's possible that one of my new rules is correct but it is in the wrong place. Below is one that I really thought would work but didn't.
RewriteRule ^/wp-content/(.*)$ /wordpress/wp-content/$1 [R=301,NC,L]
First, you should remove all the .htaccess files and keep only the one in the root: public_html/.htaccess
Second, your last rule isn't working because is slightly wrong.
You should change it from:
RewriteRule ^/wp-content/(.*)$ /wordpress/wp-content/$1 [R=301,NC,L]
To:
RewriteRule ^wp-content/(.*)$ wordpress/wp-content/$1 [L,NC]
Because you don't need the starting / and you don't need to 301 redirect. You want to keep your wordpress folder hidden and just map the requested URLs from wp-content/(.*) to wordpress/wp-content/$1
Also, this rule must be the first in your .htaccess file to have priority over following default Wordpress rules. Your final and only .htaccess from public_html/ should look like this:
RewriteEngine On
RewriteBase /
RewriteRule ^wp-content/(.*)$ wordpress/wp-content/$1 [L,nc]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
I hope it helps you.
You shouldn't have to set up several .htaccess files in your sub-directories.
The only .htaccess file that need to be modified is the one located in the application root directory. In your case, it seems to be your public_html/.htaccess or your public_html/wordpress.
Now by default WordPress generates an .htaccess file in that directory which looks something like the following:
# 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
In order to rewrite your URLs, you need to add your RewriteRules before the WordPress code block.
Since RewriteRules are processed from top to bottom, if the request is first rewritten to index.php by the WordPress block, then your rule will never be processed.
Therefore your RewriteRule:
RewriteRule ^/wp-content/(.*)$ /wordpress/wp-content/$1 [R=301,NC,L]
should be enough if it's placed at the top of the root directory's .htaccess, and remove the .htaccess file in the sub-directories
Most Multisite networks are installed in the root directory of your site. This means that if your server is using example.com, then this will be the URL for your base site on the network.
If you’ve installed WordPress Multisite in a subdirectory, then you can’t use subdomains.
If you already have a single site installation at example.com, and you add another WordPress installation in a subdirectory running Multisite, then its address will be example.com/wordpress.
Any site you create on your new network will be at example.com/wordpress/my-new-site. Creating a subdirectory would be impossible here, as it would have to be at an address like example.com/wordpress/my-new-site.network Which just doesn’t work.

htaccess redirecting to files available in the public directory

[ Background ]
This is the structure to my application:
app/
controllers/
...
modules/
...
views/
...
public/
css/
main.css
images/
...
js/
...
index.php
.htaccess
For various reasons (security, organization, etc.) the public application (website) is loaded and displayed by public/index.php At the "root" of my server I have the following .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /BU/cs-602/developer-story/
RewriteRule ^(\/||index\.*)$ public/index.php [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RedirectMatch ^(/BU/cs-602/developer-story.)([\w\d\s\/\-\:\_%\ ]*\.css)$ $1public/$2 [L]
RewriteRule ^([\w\d\-\_\/\ ]*)$ public/index.php?p=$1 [L,QSA]
</IfModule>
These rules should rewrite/ redirect all requests from the server "root" to public/index.php Since I am developing locally on my development server this project is not actually at the root of my server but is located at /BU/cs-602/developer-story/ This is why I added the RewriteBase rule.
If I remove the RedirectMatch rule everything from an MVC standpoint works:
URLs like http://localhost/BU/cs-602/developer-story or http://localhost/BU/cs-602/developer-story/ become http://localhost/BU/cs-602/developer-story/public/index.php AND URLs like http://localhost/BU/cs-602/developer-story/user/id become http://localhost/BU/cs-602/developer-story/public/index.php?p=user/id.
Here is a live htaccess test.
[ Question ]
How can I fix the .htaccess file or the RedirectMatch rule to redirect request to resources like CSS or JS files? The current rule works in the tester but not on my server unless I remove the RedirectMatch rule.
I would like a URL like http://localhost/BU/cs-602/developer-story/css/main.css to become http://localhost/BU/cs-602/developer-story/public/css/main.css that way in my HTML I do something like:
<img src="images/logo.png">
The server actually loads:
<img src="public/images/logo.png">
This way I do not have to prefix all my resources with public/.
[ Disclosure ]
This question is for help with a final project at my University, but this type question is allowed and not violating academic policies. Making a project with htaccess and MVC is not a requirement, just something I'm doing to challenge myself.
UPDATE:
Here is my original RedirectMacth rule. Anything that is not a PHP or HTML file is redirected:
RedirectMatch ([\w\d\s\/\-\:\_%\ ]*\.(?!php|htm|html)) $1 [L]
I found the solution after reviewing the error logs on my server. My various attempts were causing redirect loops. Here is my working .htaccess file in case it helps anyone trying to do something similar.
The key is to short circuit the .htaccess file when necessary so it doesn't keep rewriting your URLs infinitely. I added inline comments to explain the process:
# Redirect all requests to the public directory.
<IfModule mod_rewrite.c>
RewriteEngine On
# Only needing for local develoment in my case.
RewriteBase /BU/cs-602/developer-story/
# If nothing or an index page is requested go to `public/index.php` and stop processing.
RewriteRule ^(\/||.*index\..*)$ public/index.php [L,QSA]
# If the URL already contains the `public/` directory go to URL and stop processing.
RewriteRule ^(.*public\/.*)$ $1 [L,QSA]
# If it appears this URL is for a resource (JS, CSS, etc.) prefix with `public/`.
RewriteCond %{REQUEST_URI} ^([\w\d\s\-\_\/\%]*)\.(?!php|htm|html).*$
# Go to the modified URL if the last rule triggered and stop processing.
RewriteRule ^(.*)$ public/$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
# Rewrite all remaing URLs to our apps MVC structure.
RewriteRule ^([\w\d\s\-\_\/\%]*)$ public/index.php?p=$1 [L,QSA]
</IfModule>

Rewriting the URL's of 2 subfolders in a /public (root document) folder

Currently I have a "public" folder being root directory where all my frontend code goes.
But since my public folder contains both the website content and app content, I would like to split it more up.
So my idea was:
.htaccess (rewriting public url)
src (php backend code)
public/
web/
index.php
app/
account.php
So my problem is, I can easily go to the pages like this:
http://example.com/web/index.php
http://example.com/app/account.php
but I would like to remove "web" and "app" from the URL's...
http://example.com/index.php
http://example.com/account.php
How can I do that using .htaccess? I'm running apache 2.4.
EDIT
An example of what I've tried:
RewriteEngine On
RewriteCond %{REQUEST_URI} !app/
RewriteRule (.*) /app/$1
RewriteCond %{REQUEST_URI} !web/
RewriteRule (.*) /web/$1
Probably you need to tune up your requests. But a first approach is:
First, make sure that you have mod rewrite enabled.
Second, write the following in the .htaccess
RewriteEngine On
RewriteRule ^[/]?index.php$ /web/index.php [NS,NC,L]
RewriteRule ^[/]?account.php$ /app/account.php [NS,NC,L]
You will need to read the documentation to make other rules. You can read it here
https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
Also pay special attention on the flags. Read the documentation to set the ones that applies to your situation.
I've tried so many different things now, but I finally figured it out.
RewriteEngine on
RewriteBase /
# Rewrite every web request
RewriteCond "%{DOCUMENT_ROOT}/web/%{REQUEST_URI}" -f
RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/web/$1"
# Rewrite every app request
RewriteCond "%{DOCUMENT_ROOT}/app/%{REQUEST_URI}" -f
RewriteRule "^(.+)" "%{DOCUMENT_ROOT}/app/$1"
# Remove .php extension
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
This works when having a setup:
public/ (root folder)<br>
web/ (contains website frontend)<br>
app/ (contains app frontend)<br>
.htaccess (contains the code above)

Need Help To Protect my MVC PHP app folder using htaccess

I have an issue with my .htaccess.
Let's say that my app folder are:
/APP/
/CONTENT/
/UPLOADS/
/ASSETS/
And I have a .htaccess file that point all requests to my index.php, and the index php there is an included file called router.php that manage my roots:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([\s\S]*)$ index.php?url=$0 [QSA,L]
What i would want to do right now is to point APP and CONTENT folder also to the .htaccess and like that, i can display my custom 404 error page.

htaccess file not redirecting root level request to sub-directory level

I was having my wordpress website which domain example.com installed on root directory which is public_html recently I migrate my website content to a sub-directory public_html/my_subdir. to load the content from the sub-directory I modified the .htaccess file which is placed on public_html root folder to load the content from the sub-directory where I placed the website content.
Now my .htaccess file working fine when I hit the URL example.com it loads the content from my sub-directory which is public_html/my_subdir but when I go to example.com/wp-admin or example.com/contactus or any other path except root domain then it will load content from the root directory itself not from the sub-directory public_html/my_subdir.
below is the .htaccess file which I placed on root level,
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/my_subdir/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /my_subdir/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ my_subdir/index.php [L]
</IfModule>
Did I miss anything here, please help me to point out.
As per instruction, all content is supposed to be moved to a subdirectory, leaving only .htaccess in the root.
Since you wrote it will load content from the root directory, I guess there are some files left in the root.
These two conditions are canceling rewrite if the requested file or directory are presented:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Therefore, I suggest removing content from the root.
Otherwise, I guess it is possible to create simple .htaccess in the root that will be just redirecting to a subdirectory while adding a standard WordPress .htaccess in the subdirectory itself.
Basically, a final solution depends on what exactly you are trying to achieve.

Categories