Zend Framework Route Chaining not work as expected - zend-framework

I'm using ZF 1.11 for my project.
This is my routing configuration:
public function _initRoutes() {
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(false);
$router = $frontController->getRouter(); // returns a rewrite router by default
$langRoute = new Zend_Controller_Router_Route(
':lang/', array(
'lang' => 'vn'
)
);
$manufactureRoute = new Zend_Controller_Router_Route_Regex(
'manufacture/(\d+)-(.+).html',
array(
'module' => 'default',
'controller' => 'index',
'action' => 'filter'
),
array(
'1' => 'manufacture_id',
'2' => 'manufacture_name',
),
'manufacture/%d-%s.html'
);
$manufactureRoute = $langRoute->chain($manufactureRoute);
$router->addRoute('manufactureRoute', $manufactureRoute);
$frontController->setRouter($router);
}
When user access URLs like :
http://mydomain.vn/**vn**/manufacture/1-apple.html
everything works well as expected.
But the URLs like these below work well too.
http://mydomain.vn/**abc**/manufacture/1-apple.html
http://mydomain.vn/**def**/manufacture/1-apple.html
How can I make sure that user is accessing my correct URLs (with "vn"), all others are redirected to my custom 404 page.
I tried to redirect all the incorrect URLs to 404 page by setting rule in htaccess file but not success.
RewriteEngine On
RewriteBase /
RewriteCond $1 !^(index\.php|images|css|js|txt|png|jpg|gif|flv|swf|resource|publics|uploads|robots)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
***RewriteCond %{REQUEST_URI} !^/vn/ [NC]
RewriteRule ^[^/]+/(.*)$ /vn/$1 [R=301,L,NC,QSA]***
RewriteCond %{HTTP_HOST} ^(.+)\.mydomain\.vn [NC]
RewriteRule ^(.*)$ http://mydomain.vn/$1 [L,R=301]
RewriteCond %{HTTP_HOST} ^www.mydomain.vn/index.php/(.*) [NC]
RewriteRule ^(.*)$ http://mydomain.vn/$1 [L,R=301]

So, it seems like the requirements for your route are:
a fixed list of supported languages; and
the lang value is captured into a request parameter.
So, how about turning the lang route from a Zend_Controller_Router_Route route into Zend_Controller_Router_Route_Regex route with pattern something like:
(\(vn\))
The outer parens are for parameter identification, the standard regex delineation; the inner parens are escaped as part of an (at this moment, trivial) "or" condition.
Then when you add more languages - say 'en' or 'de' or whatever - you could modify the pattern to a less trivial "or" condition:
(\(vn|en|de\))
Not directly tested, just thinking out loud...

Related

Guzzle request failing depending on the network I am connected,

I am using guzzle to make request to my subdomain api.domain.com.
On the same phone hotspot. When I am at home, my guzzle request needs to have www.api.domain.com but anywhere near work, it takes api.domain.com and failed with the www. I can't figure why, this is happening.
Here's my code. Sometimes it works like that without any issue.
$client = new GuzzleHttp\Client([
'base_uri' => 'https://api.domain.com',
'timeout' => 10
]);
In my controllers
$get = $this->client->request('GET','/dashboard', [
'timeout' => 0,
'headers'=>[
],
'form_params'=> ['param'=>$param]
]);
But when I change locations and it doesn't work. I need to modify it by adding the www
$client = new GuzzleHttp\Client([
'base_uri' => 'https://www.api.domain.com',
'timeout' => 10
]);
my controllers stay the same and it works
$get = $this->client->request('GET','/dashboard', [
'timeout' => 0,
'headers'=>[
],
'form_params'=> ['param'=>$param]
]);
I get a guzzle cUrl error 6
My .htaccess looks like this in my api. I am not that knowledgeable with htaccess so do correct me if I made a mistakes.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=Authorization:%1]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.api.domain\.com [NC]
RewriteRule (.*) https://api.domain.com/$1 [L,R=301]
Disable verifying SSL
$this->client = new GuzzleClient(['defaults' => [
'verify' => false
]]);
Did you try it ?
At the end of the day, it was a issue in the server configuration that the company made.
Sorry for bothering you with this issue.

Codeigniter 3 routing error

I'm getting routing error on codeigniter 3.
Not Found
The requested URL /index.php was not found on this server. Apache/2.4.7 (Ubuntu) Server
What I did.
My .htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L]
</IfModule>
Also set AllowOverride ALL
My controller Test.php
class Test extends CI_Controller {
public function index(){
print_r('test');
die();
}
}
My route: $route['test/(:any)'] = 'test/$1';
And try to reach this page by url:
http://localhost/codeigniter/test/index.php
http://localhost/codeigniter/test/
Try this .htaccess
RewriteEngine on
RewriteCond $1 !^(index\.php|assets|image|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/$1 [L,QSA]
And if you are accessing the controller just type(assumed codeigniter as your project folder name)
http://localhost/codeigniter/test/
What's the reason for this $route['test/(:any)'] = 'test/$1';?
This nominate that there will be argument passed to this. it can be number or letter. Ex http://localhost/codeigniter/test/aaa or http://localhost/codeigniter/test/25
Look at this
Your problem is that your passing a uri(2), uri(2) is intended for the controller's method when your trying to use this route codeigniter/test/1 you should specify your method first so it goes like this $route['test/(any)'] = 'test/index/$i'; btw codeigniter is consider as your uri(0).

Zend instance in a subfolder of another Zend

Hi i have a Zend installation in main domain.
Now i want to make a subfolder and run Zend for some testing purposes. I have copied all files from main site to subfolder named www2. But when i call the subfolder like domain.com/www2 i think the main Zend instance get invoked and produces a Message: Invalid controller specified (www2) error?
my .htaccess of main Zend is
SetEnv APPLICATION_ENV development
RewriteEngine on
RewriteCond %{REQUEST_URI} "/www2/"
RewriteRule (.*) $1 [L]
and Subfolder is like
SetEnv APPLICATION_ENV development
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
What i am doing Wrong. I have full access to server.
in subfolder Zend in file application/Bootstrap.php add LIKE this:
protected function _initRoutes()
{
$this->bootstrap('frontcontroller');
/**
* #var Zend_Controller_Front $front
*/
$front = $this->getResource('frontcontroller');
/**
* #var Zend_Controller_Router_Rewrite $router
*/
$router = $front->getRouter();
$router->addRoute('www2',
new Zend_Controller_Router_Route(
'www2/:controller/:action',
array('controller' => 'index',
'action' => 'index'))
);
}
But may be you need another route...
UPD1:
first .htaccess like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/www2*
RewriteRule ^.*$ www2/index.php [NC,L]
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
You could create a subdomain www2.domain.com pointing the www2/public directory and restore all .htaccess files to their normal single-site state.
This way, the www2 copy is completely standalone app with the same url and file structure as the original www site.

Sending POST data in form with CakePHP redirecting from www to non-www

I am using CakePHP and i have just added this code to app/webroot/.htaccess in order to redirect all http://mywebsite.com to www.mywebsite.com
<IfModule mod_rewrite.c>
RewriteEngine On
##########added lines
RewriteCond %{HTTP_HOST} !^www. [NC]
RewriteCond %{HTTP_HOST} !^localhost [NC]
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
##########end of adding
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?/$1 [QSA,L]
</IfModule>
Now i have big problem. The login form doesn't work anymore. I guess it is because it tries to send the POST info to http://mywebsite.com/login and then in .htaccess it is redirected to www.mywebsite.com/login but the POST data is missing.
How can i solve this?
In CakePHP i am using this redirect when the user success in his login:
$this->redirect('/posts');
**Update:
I have also tried it with this other redirection with no results:
$this->redirect(array('controller'=>'posts', 'action' => 'index'));
THanks.

Zend Framework - Error when URL has $$$ or ~ on controller/action segment

In our ZF based site, if a url contains $$$ or ~ on the controller/action segment, it was not caught as 404 error, instead, they landed on the controller/action without the symbol, but when it tries to load the view script, the view script file is still having those symbol thus causing an error.
For example:
site.com/index$$$
script 'index$$$/index.phtml' not found in path
site.com/index-$$$
script 'index-$$$/index.phtml' not found in path
site.com/index~
script 'index~/index.phtml' not found in path
site.com/index/index~
script 'index/index~.phtml' not found in path
They must be caught as 404 error and out site can catch 404 errors if the controller/action is non existing.
ex: /badurl$$$, /non/existing~
Example: http://framework.zend.com/index.$$$/index~
Is there any existing issues / solutions to this?
Thanks in advance!
PS: we are still using ZF 1.0.3 but this also affects other sites which are in 1.8.2.
Update: This is the content of .htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI} ^/search$
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule . /search/?%1 [R=301,L]
# Redirect all https urls to http
# These are the pages excluded on the redirection
RewriteCond %{SERVER_PORT} ^443$
RewriteCond %{REQUEST_URI} !^/minify/.*
RewriteCond %{REQUEST_URI} !^/myaccount/.*
RewriteCond %{REQUEST_URI} !^/akamai/.*
RewriteCond %{REQUEST_URI} !^/navigation/.*
RewriteCond %{REQUEST_URI} !^/cache/.*
RewriteCond %{REQUEST_URI} !^/includes/.*
RewriteCond %{REQUEST_URI} !^/images/.*
RewriteCond %{REQUEST_URI} !^/pdf/.*
RewriteCond %{REQUEST_URI} !^/index.php
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1 [R=301,L]
######################################################
# if non-PHP file is requested, display the file #
RewriteRule \.(js|ico|txt|gif|jpg|png|css|xml|swf|zip|pdf|gz)$ - [L,NC]
# if PHP file is requested and it exists, display the file #
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule \.php$ - [L]
# redirect everything else to controller #
RewriteCond %{REQUEST_URI} !^/server-status.*
RewriteRule .+$ index.php [L]
# Disable Etags
FileETag none
The problem is not in your .htaccess file.
Your problem is originating in the dispatcher see the protected method in 1.0.3 Zend_Controller_Dispatcher_Abstract::_formatName(). This method hasn't changed since 1.0.3 either. So, an upgrade won't help.
It's actually removing all the special characters from the URI using preg_replace('/[^a-z0-9 ]/', '', $segment) and returning a valid class name.
Without writing your own custom dispatcher, you will have to use different naming with alphanumeric characters i.e. /xxx or /000
See Method Below:
/**
* Formats a string from a URI into a PHP-friendly name.
*
* By default, replaces words separated by the word separator character(s)
* with camelCaps. If $isAction is false, it also preserves replaces words
* separated by the path separation character with an underscore, making
* the following word Title cased. All non-alphanumeric characters are
* removed.
*
* #param string $unformatted
* #param boolean $isAction Defaults to false
* #return string
*/
protected function _formatName($unformatted, $isAction = false)
{
// preserve directories
if (!$isAction) {
$segments = explode($this->getPathDelimiter(), $unformatted);
} else {
$segments = (array) $unformatted;
}
foreach ($segments as $key => $segment) {
$segment = str_replace($this->getWordDelimiter(), ' ', strtolower($segment));
$segment = preg_replace('/[^a-z0-9 ]/', '', $segment);
$segments[$key] = str_replace(' ', '', ucwords($segment));
}
return implode('_', $segments);
}