I have hook the same below
public function hookActionProductAdd($params){
// how to call function from Admincontroller
}
i want to get parameter from $params, and i have controller, i want call Processproduct function in hookActionProductAdd when product added.
class GetProductController extends ModuleAdminController{
public function Processproduct(){
self::$slimit = ( int ) Configuration::get ( 'PS_COMMIT_ITEM' );
//do something
}
}
but i don't know how to do it.
You can get any controller by the static function :
AdminController::getController($class_name)
Same with "Controller" and "ModuleFrontController" classes
Related
Is there a way to capture parameter from router in the beforeAction, so it could be use by all functions in controller?
I have this router:
'http://<user:\w+>.' . $domain . '/<controller:\w+>/<action:\w+>' => '<controller>/<action>',
I want to use as ID in all functions in controller, and make it available without injecting it into the function? Is this possible?
A raw solution can be intercept the $params array inside the bindActionParams:
class ParamController extends Controller {
public $user;
public function bindActionParams($action, $params)
{
if(isset($params['user'])){
// may be some business based on $this or $action
$this->user = $params['user'];
}
return parent::bindActionParams($action, $params); // TODO: Change the autogenerated stub
}
}
Of course you need to extends all your controllers from ParamsController.
I am trying to test this function in a Laravel controller:
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
$project = $this->project->create(Input::all());
if ( $errors = $project->errors()->all() ) {
return Redirect::route('projects.create')
->withInput()
->withErrors($errors);
}
return Redirect::route('projects.index')
->with('flash', Lang::get('projects.project_created'));
}
My (wrong) test looks like this:
public function testStoreFails()
{
$this->mock->shouldReceive('create')
->once()
->andReturn(Mockery::mock(array(
false,
'errors' => array()
)));
$this->call('POST', 'projects');
$this->assertRedirectedToRoute('projects.create');
$this->assertSessionHasErrors();
}
The problem is, basically, that Ardent sets $project to false when the validation fails, but it also sets errors on that same object, that can be retreived with ->errors()->all().
I'm quite lost trying to find out what to return in the mock.
Note: The constructor injects the model:
public function __construct(Project $project)
{
$this->project = $project;
$this->beforeFilter('auth');
}
– Edited by following comments in answer –
If I'm understanding what you are trying to do properly, you could do this:
Mock the create() method to return a mocked Project.
Mock the save() method to return false.
Mock a MessageBag instance, which is the object that errors() would return. This mock should have a mocked all() method.
Make the mocked errors() method to return the MessageBag mock.
Assuming $this->mock is a mock of the Project class here:
// given that $this->mock = Mockery::mock('Project')
public function testStoreFails()
{
// Mock the create() method to return itself
$this->mock->shouldReceive('save')->once()->andReturn(false);
// Mock MessageBag and all() method
$errors = Mockery::mock('Illuminate\Support\MessageBag');
$errors->shouldReceive('all')->once()->andReturn(array('foo' => 'bar'));
// Mock errors() method from model and make it return the MessageBag mock
$this->mock->shouldReceive('errors')->andReturn($errors);
// Proceed to make the post call
$this->call('POST', 'projects');
$this->assertRedirectedToRoute('projects.create');
$this->assertSessionHasErrors();
}
In Message Model, I have
id/Subject/Comment/SenderID/RecipientID
So in Message Controller
public function index(){
$msgs = $this->Message->find();
$this->set('msgs', $msgs);
}
In Message view
foreach ($msgs as $msg)
echo ...
endforeach
BUT instead of outputting sender ID and recipient ID, I want to be able to get the username via an API which has already been set up, http://domain.com/userid/1, it will return the username in a json.
I know it's a bad practice to do this in view, but can you suggest how should I do this in controller?
Create a model for your API calls, tell cake not to look for a db table for it and have the function with the logic to pull the username there.
App::uses('AppModel', 'Model');
class MyAPI extends AppModel {
public $useTable = false;
public function getUserNameForID(Int $id = null) {
//Your logic here
return $userName;
}
}
Then in your controller you need to load the MyAPI model and pass it your data recursivly
$this->loadModel('MyAPI');
foreach (...) {
...
$userName = $this->MyAPI->getUserNameForID($userID);
...
}
I searched, but couldnt find something.
So, I have route rules:
...
'/reg' => '/user/user/registration',
...
in
Yii::app()->request
I couldn find any route information.
So, how can I get in module init function and having only url, route lile
/reg -> user/user/registration
UPD
The route is only available from the running controller. By the time when a module is initialized the controller is not yet available, thus you can't find out the route there. (You can follow CWebApplication::processRequest to see what happens when a request is resolved up to the point where the controller is run.)
It depends on what you try to achieve, but you could override WebModule::beforeControllerAction to do something before the module controller is run.
Today (next day after my question), I could solve this.
I will try to explain:
As Michael wrote, we cant know in module in which controller we are.
But I net get just reversed route, so, its quite esay.
Yii::app()->getUrlManager()->parseUrl('/reg');
This will return my reversed route
user/user/registration
parseUrl
Solution for Yii 1.1.15 workes for me.
class HttpRequest extends CHttpRequest {
protected $_requestUri;
protected $_pathInfo;
public function setUri($uri){
$this->_requestUri = $uri;
}
public function setPathInfo($route){
$this->_pathInfo = $route;
}
public function getPathInfo(){
/* copy from parent */
}
public function getRequestUri(){
/* copy from parent */
}
}
The usage:
$uri_path = 'my/project-alias/wall';
/** #var HttpRequest $request */
$request = clone Yii::app()->getRequest();
$request->setUri($uri_path);
$request->setPathInfo(null);
$route = Yii::app()->getUrlManager()->parseUrl($request);
//$route equals 'project/profile/wall' etc here (like in route rules);
I'm using a slightly different sub-class of CHttpRequest:
class CustomHttpRequest extends \CHttpRequest
{
/**
* #var string
*/
var $pathInfo;
/**
* #var string
*/
private $method;
public function __construct($pathInfo, $method)
{
$this->pathInfo = $pathInfo;
$this->method = $method;
}
public function getPathInfo()
{
return $this->pathInfo; // Return our path info rather than the default
}
public function getRequestType()
{
return $this->method;
}
}
Then to call it (to create a controller, which is what I want):
$request = new CustomHttpRequest($uri, $method); // e.g. 'my/project-alias/wall' and 'GET'
$route = \Yii::app()->getUrlManager()->parseUrl($request);
list($jcontroller, $actionName) = \Yii::app()->createController($route);
In short.. question is... "Say what?" To expand... "I don't get the error"
Strict Standards: Non-static method Pyro\Template::preLoad() should not be called statically, assuming $this from incompatible context in /opt/lampp/htdocs/dc/pyro/app/controllers/admin/courses.php on line 14
public function actionIndex() {
$this->data->users = $this->DB->query("SELECT id, name, description FROM :#courses")->getAll();
$this->data->title = 'Courses';
$this->data->content_area = \Pyro\Template::preLoad('admin/courses/index', $this->data); // Line 14
}
Template... its incomplete...
<?php
namespace Pyro;
class Template {
// Stores default master template
public static $defaultTemplate = 'template.php';
public function preLoad($template, $page) {
ob_start();
include( VIEWS . "{$template}.php");
$buffer = ob_get_contents();
#ob_end_clean();
return $buffer;
}
public function load($page) {
include( VIEWS . self::$defaultTemplate);
}
}
Why does this error appear? Cheers
Well the preLoad function is not static. Which means only an object of the class Template can use this method. A static method exists indepedently of any object of the class.
Template::preLoad is a static call : you didn't create a Template object, then call the preLoad method. So basically, you've got two solutions :
Making preLoad static;
Creating a Template object, and then call its preLoad function.
preLoad function should be static
public static function preLoad($template, $page) {
preLoad function isn't static. ti should look like this:
public static function preLoad($template, $page) {
ob_start();
include( VIEWS . "{$template}.php");
$buffer = ob_get_contents();
#ob_end_clean();
return $buffer;
}
Like everyone said, the you called the function with as a static method:
Template::preLoad(xxx)
The :: means static in PHP. Functions are typically called as static :: or object -> calls.
The function definition is one or the other:
public static function preLoad($template, $page)
Called like: Template::preLoad('admin/courses/index', $this->data);
OR
public function preLoad($template, $page)
Called like Template->preLoad('admin/courses/index', $this->data);
For reference, a static function is able to be called without instantiating an object. If your function doesn't need an object to run, you could make it static. Basically, this means you can't reference $this in a static method. It will run with the given inputs without having to construct the object.