How to allow 'http' only in the Access Rules array - php

In Yii, I am finding a way how to restrict the url that accesses my controller actions to 'http' only. I am thinking about how to get the url in a Yii way so that I can place my code in the 'expression' attribute of the array.

You can write a filter method in your base controller (components/Controller.php):
public function filterOnlyHttp($filterChain = null) {
if (Yii::app()->request->isSecureConnection) {
$this->redirect('http://'.$_SERVER['HTTP_HOST'].Yii::app()->request->requestUri);
}else
$filterChain->run();
}
It will redirect your https:// to http:// requests. You can configure this filter for specific controller actions in a filters() method in a controller:
public function filters()
{
return array(
'httpOnly',
);
}
If you generally want that redirect all your https requests, then you could also put the if above (without the else part) into the init() method of your base controller in components/Controller.php.

Try defaultScheme/validSchemes
array('url', 'url','defaultScheme' => 'http')
array('url', 'url','validSchemes' => array('http'));
Check this for more info http://www.yiiframework.com/wiki/56/#hh23

Related

Yii not detecting camel case actions

Yii is giving me 404 Error if I declare an action like this:
SiteController.php
public function actionRegisterUser()
This is how I call it in the main.php
['label' => 'Register User', 'url' => ['/site/RegisterUser']],
I tried several different combinations. The only combination that will work is this naming convention in both places:
public function actionRegisteruser
'url' => ['/site/registeruser']
I used to work on another Yii project (Yii 1.0) and I could name my actions in camel case and call them without any problem. Do I need to turn on some sort of setting to do this?
I also tried playing with the rules of the Controller but that didn't solve anything.
In some cases you need camelcase link. For example, for SEO purposes (keep inbound links). You could create rewrite rule on web server side or add inline rule to URL manager on app side. Example:
'urlManager' => [
'rules' => [
'<controller:RegisterUser>/<action:\w+>'=>'register-user/<action>',
],
],
Also it's possible to write custom URL rule. Example:
namespace app\components;
use yii\web\UrlRuleInterface;
use yii\base\Object;
class CarUrlRule extends Object implements UrlRuleInterface
{
public function createUrl($manager, $route, $params)
{
if ($route === 'car/index') {
if (isset($params['manufacturer'], $params['model'])) {
return $params['manufacturer'] . '/' . $params['model'];
} elseif (isset($params['manufacturer'])) {
return $params['manufacturer'];
}
}
return false; // this rule does not apply
}
public function parseRequest($manager, $request)
{
$pathInfo = $request->getPathInfo();
if (preg_match('%^(\w+)(/(\w+))?$%', $pathInfo, $matches)) {
// check $matches[1] and $matches[3] to see
// if they match a manufacturer and a model in the database
// If so, set $params['manufacturer'] and/or $params['model']
// and return ['car/index', $params]
}
return false; // this rule does not apply
}
}
And use the new rule class in the [[yii\web\UrlManager::rules]] configuration:
[
// ...other rules...
[
'class' => 'app\components\CarUrlRule',
// ...configure other properties...
],
]
You need to specify your action like this ['/site/register-user']. As documentation says about Inline Actions:
index becomes actionIndex, and hello-world becomes actionHelloWorld

Route in Yii2 doesn't work

I cant to make request to my controller in Yii2
I have controller /controllers/IndexController.php
class IndexController extends Controller
{
public function actionIndex()
{
return $this->render('index');
}
public function actionCreateAccount()
{
return Json::encode(array('status'=>'ok'));
}
}
In my config/web.php
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false
],
When I try to make request http://account.ll/Index/CreateAccount
I receive an error
Unable to resolve the request "Index/CreateAccount".
When I try to make request http://account.ll/Index I got the same error
Whats wrong?
It should be:
http://account.li/index/index or just http://account.li/index (because index is the default action). If the default controller is IndexController, you can access it like that - http://account.li/.
http://account.li/index/create-account
Controller and action names in actual url should be in lowercase. Action names containing more than one word are transformed with hyphens in between words.
Try to change
public function actionCreateAccount()
to
public function actionCreateaccount()
Just need to change in url from http://account.ll/Index/CreateAccount to http://account.ll/Index/create-account

YII framework user friendly URL

My yii PHP project has UserController and it has an action called actionView. I can access user view page using following URL
mysite.com/user/view/id/1
I want to change that one to
mysite.com/username
How Can I do it.
I know that i can simply create rule to be more user friendly to get url such as
mysite.com/user/username
But url scheme with database resource name as direct param (mysite.com/username) is whole different story.
Url rule:
array(
'<username:\w+>'=>'user/view',
)
Note that in such scheme, you must also create rules for all your controllers and place above rule at the end, so better prefix it with user:
array(
'user/<username:\w+>'=>'user/view',
)
Resulting url will be example.com/user/username
In action:
public function actionView($username) ...
Update:
To make rule which reacts on any input variable create custom url rule class, here is some example, modify to your needs:
class PageUrlRule extends CBaseUrlRule
{
public function createUrl($manager, $route, $params, $ampersand)
{
// Ignore this rule for creating urls
return false;
}
public function parseUrl($manager, $request, $pathInfo, $rawPathInfo)
{
// Ignore / url or any controller name - which could conflict with username
if($pathInfo == '/')
{
return true;
}
// Search for username or any resource in db
// This is for mongo so it should be tuned to your db,
// just check if username exists
$criteria = new EMongoCriteria();
$criteria->url->$lang = $url;
$criteria->select(['_id']);
$criteria->limit(1);
$model = PageItem::model();
$cursor = $model->findAll($criteria);
// Create route, instead of $url id can be used
$route = sprintf('content/page/view/url/%s', urlencode($url));
// If found return route or false if not found
return $cursor->count() ? $route : false;
}
}
Then place this rule in beginning of urlmanager config
'rules' => [
[
'class' => 'application.modules.content.components.PageUrlRule'
],
// Other rules here
Important: If user has username same as your controller, it will match username and controller will be inaccessible. You must forbid registering users with same names as controllers.

Unable to generate a URL

I am currently trying to create a link on the index page that'll allow users to create an item. My routes.php looks like
Route::controller('items', 'ItemController');
and my ItemController looks like
class ItemController extends BaseController
{
// create variable
protected $item;
// create constructor
public function __construct(Item $item)
{
$this->item = $item;
}
public function getIndex()
{
// return all the items
$items = $this->item->all();
return View::make('items.index', compact('items'));
}
public function getCreate()
{
return View::make('items.create');
}
public function postStore()
{
$input = Input::all();
// checks the input with the validator rules from the Item model
$v = Validator::make($input, Item::$rules);
if ($v->passes())
{
$this->items->create($input);
return Redirect::route('items.index');
}
return Redirect::route('items.create');
}
}
I have tried changing the getIndex() to just index() but then I get a controller method not found. So, that is why I am using getIndex().
I think I have set up my create controllers correctly but when I go to the items/create url I get a
Unable to generate a URL for the named route "items.store" as such route does not exist.
error. I have tried using just store() and getStore() instead of postStore() but I keep getting the same error.
Anybody know what the problem might be? I don't understand why the URL isn't being generated.
You are using Route::controller() which does generate route names as far as I know.
i.e. you are referring to "items.store" - that is a route name.
You should either;
Define all routes specifically (probably best - see this blog here)
Use Route::resource('items', 'ItemController'); see docs here
If you use Route::resource - then you'll need to change your controller names
The error tells you, that the route name is not defined:
Unable to generate a URL for the named route "items.store" as such route does not exist.
Have a look in the Laravel 4 Docs in the Named Routes section. There are several examples that'll make you clear how to use these kind of routes.
Also have a look at the RESTful Controllers section.
Here's an example for your question:
Route::get('items', array(
'as' => 'items.store',
'uses' => 'ItemController#getIndex',
));
As The Shift Exchange said, Route::controller() doesn't generate names, but you can do it using a third parameter:
Route::controller( 'items',
'ItemController',
[
'getIndex' => 'items.index',
'getCreate' => 'items.create',
'postStore' => 'items.store',
...
]
);

How check if action exsist in Controller Plugin preDispatch

I have two modules (default and mobile) the module mobile is a rewrite the default portal in jquery mobile but with much less controllers and actions!
I thought of write a controller plugin that check if controller and action exist in module mobile, if not I would like overwrite the module mobile to default.
I try this:
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
if ($request->getModuleName() == 'mobile') {
if (!$dispatcher->isDispatchable($request)) {
// Controller or action not exists
$request->setModuleName('default');
}
}
return $request;
}
but $dispatcher->isDispatchable($request) return always true though the action not exist! :S
and i receive "Action foo does not exist and was not trapped in __call()"
How can I do?
Thanks
Have you ever wondered how to check if a controller/action exist in zend FM from any side of app ? Here is the code
$front = Zend_Controller_Front::getInstance();
$dispatcher = $front->getDispatcher();
$test = new Zend_Controller_Request_Http();
$test->setParams(array(
'action' => 'index',
'controller' => 'content',
)
);
if($dispatcher->isDispatchable($test)) {
echo "yes-its a controller";
//$this->_forward('about-us', 'content'); // Do whatever you want
} else {
echo "NO- its not a Controller";
}
EDIT
Check like this way
$classMethods = get_class_methods($className);
if(!in_array("__call", $classMethods) &&
!in_array($this->getActionMethod($request), $classMethods))
return false;
and also please see detail link
I would suggest you make a static or dynamic routes either via config resource manager, bootstrap or via front controller plugin:
Example of defining static routes in Bootstrap.php:
public function _initRoutes()
{
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter(); // default Zend MVC routing will be preserved
// create first route that will point from nonexistent action in mobile module to existing action in default module
$route = new Zend_Controller_Router_Route_Static(
'mobile/some-controller/some-action', // specify url to controller and action that dont exist in "mobile" module
array(
'module' => 'default', // redirect to "default" module
'controller' => 'some-controller',
'action' => 'some-action', // this action exists in "some-controller" in "default" module
)
);
$router->addRoute('mobile-redirect-1', $route); // first param is the name of route, not url, this allows you to override existing routes like default route
// repeat process for another route
}
This would effectively route request for /mobile/some-controller/some-action to /default/some-controller/some-action
some-controller and some-action should be replaced with proper controller and action names.
I was using static routing which is ok if you route to exact urls, but since most applications use additional params in url for controller actions to use, it is better to use dynamic routes.
In above example simply change route creation class to Zend_Controller_Router_Route and route url to "mobile/some-controller/some-action/*" and every request will be routed dynamically like in example:
/mobile/some-contoller/some-action/param1/55/param2/66
will point to
/default/some-controller/some-action/param1/55/param2/66
For more info about routing in ZF1 check this link

Categories