Help understanding PHP5 error - static-members

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.

Related

Override the condition from ActiveQuery->init()

On Yii2 i have this code in ProjectQuery
class ProjectQuery extends \yii\db\ActiveQuery
{
public function init()
{
$this->andOnCondition(['deleted' => 0]);
parent::init();
}
Obviously the deleted condition must always apply, but there could be cases where this isn't true (for example an option for the user to see his deleted projects). How can i override this condition? Do i have to use something different from init() ?
(note, i want to apply this condition to all kind of queries normally, that's why i used init() on ProjectQuery and not the ProjectSearch class)
You can still use init() but to override the 0 you should bind a parameter.
public function init()
{
$this->andOnCondition('deleted = :deleted', [':deleted' => 0]);
parent::init();
}
So to create a query that only shows the deleted projects write something like this:
$query = Project::find()->addParams([':deleted' => 1]);
To show all projects, deleted and not deleted, you could add a function to the ProjectQuery object to modify it accordingly.
public function includeDeleted() {
$this->orOnCondition(['deleted' => 1]);
return $this;
}
And then write your query like:
$query = Project::find()->includeDeleted();
You can use onCondition() to override existing on conditions:
public function init() {
$this->andOnCondition('deleted = :deleted', [':deleted' => 0]);
parent::init();
}
public function includeDeleted() {
$this->onCondition(null);
// remove unused param from old ON condition
unset($this->params[':deleted']);
return $this;
}
You can use where() in the same way if you want to override conditions added by where(), andWhere and orWhere().
Assuming that you have a class Project where you have overwritten the find() method to return a ProjectQuery instance, the following might be another option. I also assume that you regularely query for undeleted items, and not so often but explicitly for all/deleted items.
Another option could be to add another method to the Project class and remove the default initialization in the ProjectQuery class.
class ProjectQuery extends \yii\db\ActiveQuery
{
public function init()
{
parent::init();
}
...
}
And:
class Project extends \yii\db\ActiveRecord {
...
public static function find()
{
return (new ProjectQuery(get_called_class()))
->andOnCondition(['deleted' => 0]);
}
public static function findAllProjects() // or find any better name for this
{
return new ProjectQuery(get_called_class());
}
}
Now, whenever you want to query explicitly all projects you would need to use this extra method Project::findAllProjects(). So in normal circumstances you won't have to remember that you have to modify the query in some way. No danger, that this could be forgotten.
It is still not 100% satisfying, since one could use find() and add ->andOnCondition(['deleted' => 1]) which would mean no records can be found. However, regarding security this is not so critical and the problem is found easily, I guess.

Accesing arraylist property from another class using constructor

So i have a class that makes an array list for me and i need to access it in another class through a constructor but i don't know what to put into the constructor because all my methods in that class are just for manipulating that list. im either getting a null pointer exception or a out of bounds exception. ive tried just leaving the constructor empty but that dosent seem to help. thanks in advance. i would show you code but my professor is very strict on academic dishonesty so i cant sorry if that makes it hard.
You are confusing the main question, with a potential solution.
Main Question:
I have a class ArrayListOwnerClass with an enclosed arraylist property or field.
How should another class ArrayListFriendClass access that property.
Potential Solution:
Should I pass the arraylist from ArrayListOwnerClass to ArrayListFriendClass,
in the ArrayListFriendClass constructor ?
It depends on what the second class does with the arraylist.
Instead of passing the list thru the constructor, you may add functions to read or change, as public, the elements of the hidden internal arraylist.
Note: You did not specify a programming language. I'll use C#, altought Java, C++, or similar O.O.P. could be used, instead.
public class ArrayListOwnerClass
{
protected int F_Length;
protected ArrayList F_List;
public ArrayListOwnerClass(int ALength)
{
this.F_Length = ALength;
this.F_List = new ArrayList(ALength);
// ...
} // ArrayListOwnerClass(...)
public int Length()
{
return this.F_Length;
} // int Length(...)
public object getAt(int AIndex)
{
return this.F_List[AIndex];
} // object getAt(...)
public void setAt(int AIndex, object AValue)
{
this.F_List[AIndex] = AValue;
} // void setAt(...)
public void DoOtherStuff()
{
// ...
} // void DoOtherStuff(...)
// ...
} // class ArrayListOwnerClass
public class ArrayListFriendClass
{
public void UseArrayList(ArrayListOwnerClass AListOwner)
{
bool CanContinue =
(AListOwner != null) && (AListOwner.Length() > 0);
if (CanContinue)
{
int AItem = AListOwner.getAt(5);
DoSomethingWith(Item);
} // if (CanContinue)
} // void UseArrayList(...)
public void AlsoDoesOtherStuff()
{
// ...
} // void AlsoDoesOtherStuff(...)
// ...
} // class ArrayListFriendClass
Note, that I could use an indexed property.

how to call function in controller from hook in PrestaShop

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

Yii Framework - from url to route

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);

c++/cli delegates + lambda + overload funcions

I haven't any idea about how to do the same in c++/cli.
Is not clear for me how a I can create delegate and how I can invoke it.
Can someone help me?
Thanks.
public class Writer {
internal Dictionary<Type, Action<object>> Reflective = new Dictionary<Type, Action<object>>();
public Writer()
{
Reflective.Add(typeof(float), (value) => Write((float)value));
Reflective.Add(typeof(double), (value) => Write((double)value));
}
public void Write(float value)
{
Console.WriteLine("Float");
}
public void Write(double value)
{
Console.WriteLine("Double");
}
public void Write<T>(T[] values)
{
var method = this.Reflective[typeof(T)];
foreach (var value in values)
{
method(value);
}
}
}
I won't write the whole thing for you, but here's a couple of the non-obvious things to get you started:
typeof(float) ==> System::Single::typeid
// I like to specify the full namespace for explicitness.
Lambdas: C++/CLI does not support lambdas. You'll need to declare a full-fledged method, and construct a delegate to that. Fortunately, you already have that, your two Write methods should work. Don't forget when declaring the delegate, if it's an instance method, you'll need to specify the object to invoke the function on, which should be this in your code.