Multiple language when using public folder in htaccess file - .htaccess

I have this .htacces file I like it a lot but how do I add multi language to it? so it understand that localhost/en/ is not a file or folder. right now it use a public folder as the "root" so localhost = public/
Great if I then wanna do so I still use the public folder as a root but the first / / in the url is the language
Example: localhost/en/ = link to the public folder and localhost/it/ also link to the public folder
Example 2: localhost/en/admin link to public/admin/
PS: the public/ is not suppose to been seen in the URL
This code do exactly what I wan't except the part with language.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(public)/
RewriteRule (.*) /public/$1
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*) $1\.php [L]
ErrorDocument 401 /errors/errors.php
ErrorDocument 404 /errors/errors.php
ErrorDocument 500 /errors/errors.php

Related

Remove CI4 public/index.php with .htaccess rewrite rule on subdomain/folder

I have a subdomain called test.mysite.com and I have a CI4 installation inside a folder there called project. So the actual url for the CI4 installation is test.mysite.com/project/public/index.php. I want to remove the public/index.php portion from the url but continue to use the public folder to have my files, as they should.
I'm using this .htaccess on the project folder root:
DirectoryIndex /public/index.php
RewriteEngine on
RewriteCond $1 !^(index\.php|images|assets|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ./public/index.php/$1 [L]
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
But it's not working. When I access test.mysite.com/project it leads me to a server list of files. I know the .htaccess file is being properly read because when I add an error there it gives me a warning
EDIT:
CI4 already comes with an htaccess inside the public folder:
# Disable directory browsing
Options All -Indexes
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# If you installed CodeIgniter in a subfolder, you will need to
# change the following line to match the subfolder you need.
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
# RewriteBase /
# Redirect Trailing Slashes...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.+)/$
RewriteRule ^ %1 [L,R=301]
# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 index.php
</IfModule>
# Disable server signature start
ServerSignature Off
# Disable server signature end
When I access test.mysite.com/project it leads me to a server list of files
Because your DirectoryIndex is set to /public/index.php (which presumably does not exist, as the index document is located at /project/public/index.php) and directory indexes (mod_autoindex) is presumably enabled (it should be disabled, so that such a request results in a 403 Forbidden).
the difference is that the other website that is working is not on a subdomain and it’s on the root, so it’s not the same htaccess
I'm not sure why it would be any different?
With the .htaccess file in the /project subdirectory, arrange your mod_rewrite (and mod_dir) directives like this instead:
DirectoryIndex index.php
Options -Indexes
RewriteEngine on
RewriteCond $1 !^public/(index\.php|images|assets|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) public/index.php/$1 [L]
The presence of robots\.txt and favicon\.ico in the first condition implies you are rewriting requests from the document root. Since search engines request /robots.txt (in the document root), not /project/robots.txt (or /project/public/robots.txt). The same applies to /favicon.ico. If you are not rewriting these two requests then these two entries are not required.
This also assumes you are linking directly to your static resources using the public subdirectory. eg. /projects/public/images/foo.jpg. This isn't necessarily desirable since it exposes /public in the URL path. Users won't necessarily see this as it's not directly visible in the browser's address bar, but search engines and anyone who views the HTML source / network traffic will see it.
Just to add, that first condition (ie. RewriteCond directive) is "just" an opimisation. If it's set incorrectly, your site will probably work OK and you won't see a difference, except that it will be performing many more filesystem checks than it needs to do.
Alternative structure
An alternative approach is to have two .htaccess files. A basic /project/.htaccess file that simply rewrites everything to the public subdirectory and a more comprehensive (CI) .htaccess file at /project/public/.htaccess that actually routes the request to CI. This then allows you to omit public from all URLs, including URLs to your static resources.
For example:
/project/.htaccess
DirectoryIndex index.php
Options -Indexes
RewriteEngine On
# Unconditionally rewrite everything to the "public" subdirectory
RewriteRule (.*) public/$1 [L]
/project/public/.htaccess
The presence of mod_rewrite directives in the subdirectory .htaccess file naturally prevent a rewrite loop from the RewriteRule directive in the parent directory. (Assuming mod_rewrite inheritance has not been enabled.)
RewriteEngine on
RewriteCond $1 !^(index\.php|images|assets|css|js|robots\.txt|favicon\.ico)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [L]
<IfModule mod_headers.c>
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
Working for years with Codeigniter 3 I had this issue too. First I tried the .htaccess road but after realizing Codeigniter 3 could also benefit from a more secure structure, I applied the same experience to Codeigniter 4.
The basic idea is to move the whole framework to a folder off the web root. And move the public folder to the root (WEBROOT can also be a subfolder under the public html folder)
PRIVATEFOLDER
\codeigniter:
\app
\vendor
\writable
WEBROOT
assets\
index.php
.htaccess
Then I'll modify index.php (and spark and preload.php if used). This will do in index.php:
// This is the line that might need to be changed... etc
define('ENGINEPATH', 'PRIVATEFOLDER/codeigniter');
require ENGINEPATH . '/app/Config/Paths.php';
And /app/Config/Paths.php to this:
namespace Config;
class Paths
{
public $systemDirectory = ENGINEPATH . '/vendor/codeigniter4/framework/system';
public $appDirectory = ENGINEPATH . '/app';
public $writableDirectory = ENGINEPATH . '/writable';
public $testsDirectory = ENGINEPATH . '/tests';
public $viewDirectory = ENGINEPATH . 'app/Views';
}
Now, set the $baseURL to the WEBROOT url and you should be able to navigate without index.php and public, and the app code is protected outside the public folder.

How do you redirect all request to public/ folder in laravel 5

I have a classic Larevel 5 project structure and I need to redirect all requests to public/.
I am on a classic hosting environment so public/ is a subfolder of my document root.
I shall imagine it can be done via .htaccess but I still need to figure out how. Anyone can help?
Thanks
There are two solutions:
1. Using .htaccess with mod_rewrite
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
2. You can add a index.php file containing the following code and put it under your root Laravel folder (public_html folder).
<?php
header('Location: public/');
You don't need to change anything in Laravel's default public/.htaccess file.
Just create a new .htaccess in the same level your public folder and add the following content to it:
DirectoryIndex index.php
RewriteEngine On
RewriteRule ^$ public/index.php [L]
RewriteRule ^((?!public/).*)$ public/$1 [L,NC]
That simple!
This is an extract from another answer which may also help you.
--
Modify your public_html/.htaccess to redirect all requests to the public subfolder.
# public_html/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect All Requests To The Subfolder
RewriteRule ^ /public
</IfModule>
Make sure you have the proper public_html/public/.htaccess (GitHub).
# public_html/public/.htaccess
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization}
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
If you use cPanel, then:
1.Go to folder:
/var/cpanel/userdata/my_domain
2.Edit the both domains:
my.domain and my.domain_SSL
Add to the documentroot section /public:
documentroot: /home/user/public_html/public
3.Rebuild Apache config:
/scripts/rebuildhttpdconf && service httpd restart
if you using apache , add .htaccess file to your root directory with this lines :
RewriteEngine on
RewriteCond %{REQUEST_URI} !^public
RewriteRule ^(.*)$ public/$1 [L]
and make sure your apache redirect and rewrite modules is working fine .
you can use vhost to redirect the all request to your public directory with set public as root of your project .
The ideal scenario is to have /home/user/public as a symlink from /home/user/laravel/public.

not redirecting a certain file in base folder

If have a mod write which works fine, but I want it to not apply to one certain file ("somefile.php") in the base folder. All other files (especially "somefile.php" files in subfolders) shall be effected by the rule.
I tried adding a RewriteCond for this case before the RewriteRule but I could not figure out the correct syntax. My last wrong try is:
RewriteCond %{REQUEST_URI} !(^$)/somefile.php
I think it has to be something like that. Can you correct this syntax?
Edit:
Here is a reduced version of my rewrite mod (RewriteCond modified according to first answer):
ErrorDocument 404 /page404.php
Options -Indexes
DirectoryIndex index.php
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(/|/index\.php)$
RewriteRule ^(.+)$ main.php?path=$1 [L,QSA]
My base folder is: //localhost/somefolder_but_i_dont_know_its_name/
Edit 2:
I found a workaround (it does not answer my syntax question but seems to solve the underlying problem):
ErrorDocument 404 /page404.php
Options -Indexes
DirectoryIndex index.php
RewriteEngine on
RewriteCond %{REQUEST_URI} (.*)somefile\.php
RewriteRule ^([^/]+)/?$ - [L,QSA]
RewriteRule ^(.+)$ main.php?path=$1 [L,QSA]

Redirect to subfolder with same name on localhost

I have a webproject saved in a "base" folder of the domain "example.com" which contains a main.php and several subfolders. The second part of the code below redirects all requests (except main.php itself and page404.php) to this main.php and hands over the originally requested URL in the variable "path".
In addition there is a first part which redirects all requests of pages of the baseurl to a subfolder "folder1". So in the end the request of
www.example.com/somepage.php
will lead to
example.com/main.php?path=www.example.com/folder1/somepage.php
(Requests to other subfolders shall only be redirected to the main.php. So www.example.com/somefolder/somepage.php will lead to example.com/main.php?path=www.example.com/somefolder/somepage.php - without adding "folder1".)
The code below actually does what I want:
ErrorDocument 404 /page404.php
Options -Indexes
DirectoryIndex index.php
<IfModule mod_rewrite.c>
RewriteEngine on
#first part: redirect to folder1/
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/*
RewriteCond %{REQUEST_URI} !^page404*
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ folder1/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ index.php
#second part: redirect to main.php
RewriteCond %{REQUEST_FILENAME} (.*)\.php [NC]
RewriteCond %{REQUEST_URI} !main\.php
RewriteCond %{REQUEST_URI} !page404\.php
RewriteRule ^([^?]*)$ /main.php?path=$1 [NC,L,QSA]
</IfModule>
But I have two questions:
Side question: I have the feeling that actually redirecting to "folder1" is way to complicated (even though it works) when I only want to add the "folder1" to the path variable in case a file of the base folder is called. Can you show me a better way to archieve this?
Main question: I have the same project on a localhost where the main folder is named "folder1" which contains the folder "folder1". So there the request of htttp://localhost/folder1/somepage.php shall lead to htttp://localhost/folder1/main.php?path=htttp://localhost/folder1/folder1/somepage.php (I replaced "http" by "htttp" to avoid automatic link recognition of SO) - How do I have to change the code above to have it working in the "localhost/folder1" scenario?
This stuff can be simplified:
ErrorDocument 404 /page404.php
Options -Indexes
DirectoryIndex index.php
RewriteEngine on
# ignore main.php, page404.php OR any files/directory for any rules below
RewriteCond %{REQUEST_URI} ^/(main|page404)\.php
RewriteRule ^ - [L]
#first part: /folder1/path
RewriteRule ^([^/]+?\.php)$ main.php?path=folder1/$1 [L,QSA]
#second part: rewrite to main.php
RewriteRule ^(.+?\.php)$ main.php?path=$1 [L,QSA]

.htaccess infinite loop on 404 in subfolders

I got a little problem concerning a project I'm working on.
I want to maintain only one .htaccess file in the root folder of this project. It is modular, so there are many different subfolders. My current .htacccess looks as follows:
ErrorDocument 401 /401.php
ErrorDocument 404 /404.php
RewriteEngine On
#strip www from domain
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
#ignore existing files and directories
RewriteCond %{REQUEST_FILENAME} -f [NC,OR]
RewriteCond %{REQUEST_FILENAME} -d [NC]
RewriteRule .* - [L]
# Check if query string exists
RewriteCond %{QUERY_STRING} ^$
# Check that the request is not for an existing file
RewriteCond %{REQUEST_FILENAME} !-f
The problem is that every 404 error in a subfolder leads to an infinite loop because it looks for i.e. http://mydomain.tld/modules/index.php?p=404 instead of http://mydomain.tld/index.php?p=404 .
I know I could hardcode the URL in my .htaccess, but the problem is that it's kind of a community-hosting platform, where the community is specified dynamically via the subdomain and I want to keep the request in that specific subdomain.
Is there any possible way to force the .htaccess to use the index.php in the root-folder without giving the absolute url?
Thanks in advance!

Resources