I have a Zend view template with the following line of code:
$this->headTitle()->setSeparator(' - ')
My question is, where is the setSeparator() method declared?
I understand that headTitle is a View Helper but when I look in the Zend_View_Helper_HeadTitle class I see no setSeparator method, nor any setter. Presumably the method (or an appropriate setter) is declared in the class' ancestors however I can't seem to find exactly where...
Thanks!
It is defined in Zend_View_Helper_Placeholder_Container_Abstract.
The access to this method takes place in Zend_View_Helper_Placeholder_Container_Standalone class in its magic method __call :
$container = $this->getContainer();
if (method_exists($container, $method)) {
$return = call_user_func_array(array($container, $method), $args);
It is defined using PHP magic method __set. The magic method is defined in the Zend_View_Helper_Placeholder_Container_Standalone class which is the base class for Zend_View_Helper_HeadLink.
Related
Im trying to load my model in my controller and tried this:
return Post::getAll();
got the error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context
The function in the model looks like this:
public function getAll()
{
return $posts = $this->all()->take(2)->get();
}
What's the correct way to load the model in a controller and then return it's contents?
You defined your method as non-static and you are trying to invoke it as static. That said...
1.if you want to invoke a static method, you should use the :: and define your method as static.
// Defining a static method in a Foo class.
public static function getAll() { /* code */ }
// Invoking that static method
Foo::getAll();
2.otherwise, if you want to invoke an instance method you should instance your class, use ->.
// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }
// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();
Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:
$foos = Foo::all()->take(10)->get();
In that code we are statically calling the all method via Facade. After that, all other methods are being called as instance methods.
Why not try adding Scope? Scope is a very good feature of Eloquent.
class User extends Eloquent {
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
public function scopeWomen($query)
{
return $query->whereGender('W');
}
}
$users = User::popular()->women()->orderBy('created_at')->get();
Eloquent #scopes in Laravel Docs
TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10); instead of MyModel::find(10);.
To the best of my knowledge, starting PhpStorm 2017.2 code inspection fails for methods such as MyModel::where(), MyModel::find(), etc (check this thread), and this could get quite annoying.
One (elegant) way to get around this is to explicitly call ::query() wherever it makes sense to. This will let you benefit from free auto-completion and a nice formatting/indentating for your queries.
Examples
BAD
Snippet where inspection complains about static method calls
// static call complaint
$myModel = MyModel::find(10);
// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_foo', true)
->where('is_bar', false)
->get();
GOOD
Well formatted code with no complaints
// no complaint
$myModel = MyModel::query()->find(10);
// a nicely formatted and indented query with no complaints
$myFilteredModels = MyModel::query()
->where('is_foo', true)
->where('is_bar', false)
->get();
Just in case this helps someone, I was getting this error because I completely missed the stated fact that the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:
public function scopeRecentFirst($query)
{
return $query->orderBy('updated_at', 'desc');
}
You should call it like:
$CurrentUsers = \App\Models\Users::recentFirst()->get();
Note that the prefix scope is not present in the call.
Solution to the original question
You called a non-static method statically. To make a public function static in the model, would look like this:
public static function {
}
In General:
Post::get()
In this particular instance:
Post::take(2)->get()
One thing to be careful of, when defining relationships and scope, that I had an issue with that caused a 'non-static method should not be called statically' error is when they are named the same, for example:
public function category(){
return $this->belongsTo('App\Category');
}
public function scopeCategory(){
return $query->where('category', 1);
}
When I do the following, I get the non-static error:
Event::category()->get();
The issue, is that Laravel is using my relationship method called category, rather than my category scope (scopeCategory). This can be resolved by renaming the scope or the relationship. I chose to rename the relationship:
public function cat(){
return $this->belongsTo('App\Category', 'category_id');
}
Please observe that I defined the foreign key (category_id) because otherwise Laravel would have looked for cat_id instead, and it wouldn't have found it, as I had defined it as category_id in the database.
You can give like this
public static function getAll()
{
return $posts = $this->all()->take(2)->get();
}
And when you call statically inside your controller function also..
I've literally just arrived at the answer in my case.
I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.
Hope that help?
Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.
For use the syntax like return Post::getAll(); you should have a magic function __callStatic in your class where handle all static calls:
public static function __callStatic($method, $parameters)
{
return (new static)->$method(...$parameters);
}
I am calling a method as follows:
$self->class->method
I would like to pass a reference to this method as a parameter into a subroutine.
I have tried
\&{ $self->class->method }
but I get the following error:
Unable to create sub named ""
Any ideas on how to do this?
You can take a reference to static class method, but in your case you could use anonymous closure to achieve similar,
my $ref = sub { $self->class->method };
# ..
my $result = $ref->();
The class method is a little strange. I would expect a method with a name like that to return the class string, but it clearly returns an object as it has a method method.
I recommend that you use UNIVERSAL::can, which returns a reference to the given method if it exists. So you can write code like this
my $method_ref = $self->class->can('method');
mysub($method_ref);
You can also use the curry module to achieve this:
use curry;
my $mref = $self->class->curry::method;
I load an assembly and from that a class of the object I want to create. From that class I check for interfaces (mono_class_get_interfaces) and find the interface class I want (IDispose).
I create the object with mono_object_new and call mono_runtime_object_init directly afterward. I then call mono_object_castclass_mbyref to cast the object to an interface reference. Then I retrieve the interface method I want to call (Dispose) from the interface class with mono_class_get_method_from_name.
I call mono_object_get_virtual_method to make sure I have the correct implementation and then try to call it with mono_runtime_invoke using the interface MonoObject * reference and the interface virtual method MonoMethod * (args = NULL) -> which is unsuccessful.
I have also tried to call mono_method_get_unmanaged_thunk with the same parameter, that doesn't work either.
In both cases I get a value back for the exception argument. Problem is, I haven't found a way to look inside the exception...
Question is:
Is the sequence of calls correct to work with managed interfaces and call the correct (most specific) interface methods?
How to get more information on the MonoException (I assume the MonoObject * returned by invoke is a MonoException instance)?
There is no need to invoke any castclass function to cast a managed reference to an 'interface reference': the value is the same.
Once you have your IDispose MonoClass* pointer, you should get the MonoMethod* for the method you want to call and pass that to mono_object_get_virtual_method(). The result of this function is what you should pass to mono_runtime_invoke().
For the exception, you can invoke the get_Message method method, for example, or any of the methods you'd call to deal with it if you were in C# code.
Simple tested code below, str is a MonoString*:
icloneable_class = mono_class_from_name (mono_get_corlib (), "System", "ICloneable");
iface_method = mono_class_get_method_from_name (icloneable_class, "Clone", 0);
iface_impl_method = mono_object_get_virtual_method (str, iface_method);
exc = NULL;
obj = mono_runtime_invoke (iface_impl_method, str, NULL, &exc);
The method is correctly invoked and exc will be NULL.
In the Objective-C Runtime Reference, I see class_addMethod but not class_removeMethod. How do I dynamically remove a method?
Also, does class_addMethod add an instance method or a class method?
As Inerdial mentioned in his comment, the main question (How can a method be removed from a class at runtime?) is somewhat exhaustively answered here.
MattDiPasquale asks as well:
Also, does class_addMethod add an instance method or a class method?
Inerdial is correct again:
class_addMethod adds an instance method, and that to add a class method, you need to add an instance method to the class' class.
Given a Class c, we can get our hands on the class of which it is an instance (known as its "metaclass") as simply as
Class metac = object_getClass(c);
To then "add a class method" to c, we add a method to metac using class_addMethod.
If, for example, elsewhere we have already defined
id myClassMethodImplementation(id self, SEL _cmd) {
//implementation
}
We can then add a class method to c as follows:
BOOL success = class_addMethod(metac, #selector(myClassMethod), (IMP)myClassMethodImplementation, "##:");
or equivalently
BOOL success = class_addMethod(object_getClass(c), #selector(myClassMethod), (IMP)myClassMethodImplementation, "##:");
To simply add this same method as an instance method on c, we simply write
BOOL success = class_addMethod(c, #selector(myClassMethod), (IMP)myClassMethodImplementation, "##:");
References:
1. Objective-C Runtime Reference 2. Objective-C Runtime Programming Guide - Type Encodings 3. Cocoa with Love - What is a meta-class in Objective-C?
I am quite confused how to use partialLoop
Currently I use
foreach ($childrenTodos as $childTodo) {
echo $this->partial('todos/_row.phtml', array('todo' => $childTodo));
}
$childrenTodos is a Doctrine\ORM\PersistantCollection, $childTodo is a Application\Models\Todo
I tried doing
echo $this->partialLoop('todos/_row.phtml', $childrenTodos)
->setObjectKey('Application\Models\Todo');
But in the partial when I try to access properties/functions of my Todo class, I cant seem to get them always ending up with either call to undefined method Zend_View::myFunction() when I use $this->myFunction() in the partial or if I try $this->todo->getName() I get "Call to a member function getName() on a non-object". How do I use partialLoops?
Try this
echo $this->partialLoop('todos/_row.phtml', $childrenTodos)
->setObjectKey('object');
Then in your partial you can access the object like this
$this->object
object is the name of the variable that an object will be assigned to
You can also do this once in your Bootstrap or other initialization class if you have access to the view object like so
protected function initPartialLoopObject()
{
$this->_view->partialLoop()->setObjectKey('object');
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
$viewRenderer->setView($this->_view);
}
I also had "Call to function on non object" error when trying suggested syntax, seems like they've changed something on later versions of Zend Framework. The following works for me on ZF1.12:
echo $this->partialLoop()
->setObjectKey('object')
->partialLoop('todos/_row.phtml', $childrenTodos);