I implement cakephp debugkit plugin in my project.
In my appcontroller.php file i add
var $helpers = array('Html', 'Form', 'Paginator', 'Js', 'Session');
public $components = array('DebugKit.Toolbar');
and in before filter i implement
function beforeFilter() {
if ($this->Session->check('GlobalFields')==false) {
$this->Session->write('GlobalFields.tbl_assets.template_information_global', '');
$this->Session->write('GlobalFields.tbl_assets.hilitelibrary', '');
$this->Session->write('GlobalFields.tbl_assets.hilitesortedby', '');
$this->Session->write('GlobalFields.tbl_assets.sc_url_prefix', '');
}
}
but it showing error
Fatal error: Call to a member function check() on a non-object.
and i check that debug($this->Session) returns null.
if i remove public $components = array('DebugKit.Toolbar'); then its run correctly.
but i want to implement that debugkit with session.
please help me to solve this problem.
Well what happens here is that by setting:
public $components = array('DebugKit.Toolbar');
you are overriding the default value of that which includes the SessionComponent.
You are attaching the SessionHelper in the $helpers variable but those two classes are different - the first one (the component) allows you do interact with session data within the Controller and the second one (the helper) is used in your views.
So the solution to your issue is setting:
public $components = array('Session','DebugKit.Toolbar');
Also if you were using any other components globally you should add them there too.
Related
I have a custom authentication service and in ZF2 I accessed this as follows:
Application/view/layout/layout.phtml
$authenticationService = $this->getHelperPluginManager()
->getServiceLocator()
->get('AuthenticationService');
$currentIdentity = $authenticationService->getIdentity();
Now the Zend\ServiceManager#getServiceLocator() is deprecated.
How to get a service available in a view script (or concrete in this case in the layout) in ZF3?
For this purpose there is already Identity View Helper
As documentation says
// Use it any .phtml file
// return user array you set in AuthenticationService or null
$user = $this->identity();
The solution is to assign a global view variable in the onBootstrap(...):
namespace Application;
use ...
class Module
{
public function onBootstrap(MvcEvent $e)
{
...
$serviceManager = $e->getApplication()->getServiceManager();
$viewModel = $e->getApplication()->getMvcEvent()->getViewModel();
$viewModel->authenticationService = $serviceManager->get('AuthenticationService');
}
...
}
Another (perhaps an even better/cleaner) solution is to use a ViewHelper. See also here.
Laravel 5.1 has just been released, I would like to know how could I tell the AuthController to get the login & register view from a custom directory? the default is: resources/views/auth...
The trait AuthenticateAndRegisterUsers only has this:
trait AuthenticatesAndRegistersUsers
{
use AuthenticatesUsers, RegistersUsers {
AuthenticatesUsers::redirectPath insteadof RegistersUsers;
}
}
The code you're showing there only fills one function: it tells our trait to use the redirectPath from the AuthenticatesUsers trait rather than the one from RegistersUsers.
If you check inside the AuthenticatesUsers trait instead, you will find a getLogin() method. By default, this one is defined as
public function getLogin()
{
return view('auth.login');
}
All you have to do to get another view is then simply overwriting the function in your controller and returning another view. If you for some reason would like to load your views from a directory other than the standard resources/Views, you can do so by calling View::addLocation($path) (you'll find this defined in the Illuminate\View\FileViewFinder implementation of the Illuminate\View\ViewFinderInterface.
Also, please note that changing the auth views directory will do nothing to change the domain or similar. That is dependent on the function name (as per the definition of Route::Controller($uri, $controller, $names=[]). For more details on how routing works, I'd suggest just looking through Illuminate\Routing\Router.
for those who is using laravel 5.2, you only need to override property value of loginView
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php
public function showLoginForm()
{
$view = property_exists($this, 'loginView')
? $this->loginView : 'auth.authenticate';
if (view()->exists($view)) {
return view($view);
}
return view('auth.login');
}
so to override the login view path, you only need to do this
class yourUserController {
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
.....
protected $loginView = 'your path';
}
Here is a question on the Caching Proxy design pattern.
Is it possible to create with PHP a dynamic Proxy Caching implementation for automatically adding cache behaviour to any object?
Here is an example
class User
{
public function load($login)
{
// Load user from db
}
public function getBillingRecords()
{
// a very heavy request
}
public function computeStatistics()
{
// a very heavy computing
}
}
class Report
{
protected $_user = null;
public function __construct(User $user)
{
$this->_user = $user;
}
public function generate()
{
$billing = $this->_user->getBillingRecords();
$stats = $this->_user->computeStatistics();
/*
...
Some rendering, and additionnal processing code
...
*/
}
}
you will notice that report will use some heavy loaded methods from User.
Now I want to add a cache system.
Instead of designing a classic caching system, I just wonder if it is possible to implement a caching system in a proxy design pattern with this kind of usage:
<?php
$cache = new Cache(new Memcache(...));
// This line will create an object User (or from a child class of User ex: UserProxy)
// each call to a method specified in 3rd argument will use the configured cache system in 2
$user = ProxyCache::create("User", $cache, array('getBillingRecords', 'computeStatistics'));
$user->load('johndoe');
// user is an instance of User (or a child class) so the contract is respected
$report = new report($user)
$report->generate(); // long execution time
$report->generate(); // quick execution time (using cache)
$report->generate(); // quick execution time (using cache)
each call to a proxyfied method will run something like:
<?php
$key = $this->_getCacheKey();
if ($this->_cache->exists($key) == false)
{
$records = $this->_originalObject->getBillingRecords();
$this->_cache->save($key, $records);
}
return $this->_cache->get($key);
Do you think it is something we could do with PHP? do you know if it is a standard pattern? How would you implement it?
It would require to
implement dynamically a new child class of the original object
replace the specified original methods with the cached one
instanciate a new kind of this object
I think PHPUnit does something like this with the Mock system...
You can use the decorator pattern with delegation and create a cache decorator that accepts any object then delegates all calls after it runs it through the cache.
Does that make sense?
Scenerio:
Using Yii-rights + Yii-user module in my project. In Rights, I generated operations based on my controller action, under update I added a child UpdateOwn.
For UpdateOwn, the bizrule is suppose to be a simple comparison that the logged in user's ID is equal to $model->user_id field.
Problem:
I understand yii checkaccess allow you to pass in variables as parameters and comparing with your defined bizrule. But how does it work for Yii-rights module? How or what are the data/params passed in to be used in bizrule? How can I define or pass my own data/params?
Yii-rights is a wrapper for standart yii-rbac. In rights module you have web-interface for your RBAC. When you creating AuthItem (Operation in rights web interface) you can define your own bizrule.
Here is code for creating AuthItem:
$item = $this->_authorizer->createAuthItem($formModel->name, $type, $formModel->description, $formModel->bizRule, $formModel->data);
$item = $this->_authorizer->attachAuthItemBehavior($item);
_authorizer here is an example of RAuthorizer class. Then we go to RDbAuthManager, which extends CDbAuthManager, where we createAuthItem function:
public function createAuthItem($name,$type,$description='',$bizRule=null,$data=null)
{
$this->db->createCommand()
->insert($this->itemTable, array(
'name'=>$name,
'type'=>$type,
'description'=>$description,
'bizrule'=>$bizRule,
'data'=>serialize($data)
));
return new CAuthItem($this,$name,$type,$description,$bizRule,$data);
}
This is how created AuthItem, in rights. Personally i prefer to use web interface. It have alot of great fetures and much easier to handle then go to code each time.
Then when we perform checkAccess() on AuthItem we call execute bizRule:
public function executeBizRule($bizRule,$params,$data)
{
return $bizRule==='' || $bizRule===null || ($this->showErrors ? eval($bizRule)!=0 : #eval($bizRule)!=0);
}
This is how RBAC in yii work, and rights is just a cool wrapper for it. Rights doesn't change logic of how things must be done.
So in basic yii-rbac if you want to allow update only Own records you do:
$bizRule='return Yii::app()->user->id==$params["user"]->username;';
$task=$auth->createTask('updateOwnUser','update a your own account',$bizRule);
$task->addChild('updateUser');
Then you call it like this:
$user=$this->loadUser();
$params = array('user' => $user);
if(Yii::app()->user->checkAccess('updateOwnUser', $params){
..................
}
In rights it's already implemented with filters. Only thing what you need to do is add to your controller:
class MyController extends RController{
.............
public function filters()
{
return array(
'rights',
............
);
}
.............
}
So define your bizrule for item in web interface, change your controller code, and actually thats it. To know what variables to use in bizrule you can watch on RightsFilter.php code, where checkAccess() performed.
And on top of all of this i'll say about how checkAccess() does :
For each assigned auth item of the user, it first checks if the bizRule for the assignment returns true.
If true, it calls the item's checkAccess method. If the item's bizRule returns true,
2.1. If the item name is the same as the name passed in the original checkAccess() method, it returns true;
2.2. Otherwise, for every child item, it calls its checkAccess.
Hope this will clarify some aspects of RBAC and help in your task.
The yii-rights module has the following properties:
/**
* #property boolean whether to enable business rules.
*/
public $enableBizRule = true;
/**
* #property boolean whether to enable data for business rules.
*/
public $enableBizRuleData = false;
To set bizrule data via the web interface you have to set $enableBizRuleData = true in your application configuration.
Please note that the UI is limited and you can set data only for Auth-Items not for Auth-Assignments. Also the value for data has to be a serialized PHP variable.
As mentioned by #ineersa you can access $data in unserialized form in your bizRule.
It's also worth noting, that Yii checks first the bizRule for the Auth-Item and then additionally for the Auth-Assignment.
[edit] added example
Auth Item
bizRule
Check if the assignment has all the keys specified in the item data
return BizRule::compareKeys($params, $data, 'Editor');
data
a:1:{s:8:"language";b:1;}
Auth Assignment
Check if the application language matches the assignment data
bizRule
return BizRule::compareApplicationLanguage($params, $data);
data
a:1:{s:8:"language";s:5:"de_de";}
[edit] added code link
Here is the full Helper Code
I am currently trying to configure a routing option in Symfony2 so /cms will route to /cms/role/view. However, the passing of defaults doesn't seem to work properly.
/src/MyProject/CMSBundle/Resources/config/routing.yml
MyProjectCMS_specific:
pattern: /cms/{page}/{option}
defaults: { _controller: MyProjectCMSBundle:Main:index, page: role, option: view }
requirements:
_method: GET
/src/MyProject/CMSBundle/Controller/MainController.php
<?php
namespace MyProject\CMSBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class MainController extends Controller
{
public function indexAction($page, $option)
{
$response = null;
/* Switch statement that determines the page to be loaded. */
return $response;
}
}
?>
The problem is that when I try to go to `localhost/app_dev.php/cms', it gives me the following error:
Controller "MyProject\CMSBundle\Controller\MainController::indexAction()" requires that you provide a value for the "$page" argument (because there is no default value or because there is a non optional argument after this one).
500 Internal Server Error - RuntimeException
However, if I try to visit localhost/app_dev.php/cms/role or localhost/app_dev.php/cms/role/view, it gives me the correct page. I've tried adding a default route to /cms, but it still gives me the same error. How is this possible and how can I fix this?
Thanks in advance.
I don't know what is the difference between what you wrote and
public function indexAction($page = "role", $option = "view")
but maybe you could try it and tell us.