Please upgrade here. These earlier versions are no longer being updated and have security issues.
HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.
Is it possible to retrieve a list of all methods added to a class?
businessdad
MVP
I was reading about Magic Methods in Plugin Quick-Start Guide, and I was wondering, is there a way to see al the methods that have been "tacked" to a class? A simple get_class_methods()
doesn't work, as these new methods are not shown.
Thanks in advance for the help.
Tagged:
0
Answers
-
grep is your friend.
@x00: I'm talking about "Magic Methods", i.e. the ones created by declaring them as
Controller_MethodName_Create
.My shop | About Me
magic method are by definition called on the fly.
you would have to grep plugins for the controller an the create.
grep is your friend.
magic method work like this:
there is an attempt to use a method that doesn't exist. there is a check for the special __call method. the method name plus an array of parameters is passed to this. Further logic inside.
grep is your friend.
A-ha! Now I understand, it seems I'll have to do a bit more work then. Thanks for your help!
My shop | About Me
vanilla magic methods refer to the use of __call, what is passed. In PHP it refers tot he special method used for overloading __call, __callStatic, __get, __set, __isset, __unset, (the latter four are used on 'magic' properties).
http://php.net/manual/en/language.oop5.overloading.php
grep is your friend.
Argh! I was so close! I implemented a method that could return a list of the Magic Methods added to a class, but the list is declared as "private", therefore I can't access it. If nothing else, I learned that such Magic Methods have some important limitations, compared to "normal", declared methods.
My shop | About Me
php is interpreted, there is also no open classes like ruby.
this is extending the string class.
grep is your friend.
I know. In my case, I'd need to access a private property
Gdn_PluginManager->_NewMethodCollection
to retrieve all the Magic Methods associated to a class. My target would be to loop through all of them and call them one by one.What I'm trying to achieve is a functionality similar to a global "Cron", where a plugin can declare a Cron method (e.g.
Cron_MyPlugin_Create()
) and have it called regularly (this in its simplest version, obviously there's much more that can be done from there).Unfortunately, the only way I managed to implement it successfully so far has been by hacking class
Gdn_PluginManager
and exposing property_NewMethodCollection
, either by declaring it public or by using a "Get" method.Of course, I don't want to rely on such a hack, as, if I really had to modify the Core, it would be much cleaner to simply implement a
GetClassNewMethods
method straight intoGdn_PluginManager
class.My shop | About Me
Ah I wouldn't do it this way.
instead have a method to register the cron. Use
call_user_func
/call_user_func_array
within it.You can pass an object an its method like so
array($object,'method');
orarray($this,'method');
grep is your friend.
overriding creates overhead it needs to be used wisely.
grep is your friend.
Thanks @x00, I was, in fact, reviewing the design to make it simpler. Probably a method to register the Cron would be the best.
At the moment, I created a method called
CronJobs->RegisterCronJob()
. In another plugin, I call it as follows:Is that "orthodox" enough, or is there a better way? I'd love to be able to just call "RegisterCronJob" from any plugin, but issue is that I can't assume it's installed and enabled.
My shop | About Me
You could go with object, method, additional params (array).
I think what you want is for the cron plugin to register it own cron. That is the most logical way of doing it. Though actually it would be better with events.
they would make a cron
where
CronJobsPlugin
is the plugin that has the CronJob event.grep is your friend.
Thanks again. I'm not sure I understand the
$this->EventArguments['UsefulStuff']=$UsefulStuff
part. What I actually want to do is to allow my Cron plugin to call other plugins methods, which are stored in a list somewhere. This way, if a new plugin would need to run something periodically, it will just have to register itself with the Cron Plugin, which, in turn, will call the callback method at each execution.I reckon it would be done with Events too: by firing a "CronJob" event, any 3rd party plugin would just have to implement a handler and do some stuff in it. However, this means that all Cron Event Handlers will run unconditionally. Forcing a plugin to register a method would allow some sort of control over the Cron Events (for example, some could be enabled or disabled, depending on the circumstances). This is how I implemented it at the moment (I must say it was easier than I thought, even considering that I took the "wrong route" multiple times).
In short, I see there are many ways of doing it, and there isn't an "absolutely better" way.
My shop | About Me
no it is just anything you want to pass through the $Args. It also has the original sender object, which in this case you be the CronJobsPlugin instance. So you could have public methods and properties that they could use.
grep is your friend.
@x00: I'm sorry, but I'm not sure I follow you. Let me see if I understand.
1- CronPlugin would fire an event, such as
RegisterCron
.2- Other plugins that would like to be registered a method to run during a Cron execution, would implement
MyPlugin_RegisterCron_Handler
. Such handler would receive some information needed by the client plugin to register (i.e. the Sender, which is my CronPlugin and, eventually, other arguments).3- Client plugin uses the information in the handler to register itself.
4- CronPlugin will now have a set of methods to call during Cron execution.
The above means that, if a 3rd party plugin is installed, but CronPlugin is not, its method
MyPlugin_RegisterCron_Handler
is not getting called, but the plugin works anyway.Did I get it right?
My shop | About Me
almost
MyPlugin_RegisterCron_Handler
should beCronPlugin_RegisterCron_Handler
what you are actually doing is defining what the cron entails, but since it is a cron, you need to pass the necessary info. Say for instance a request is your basic unit, you would need to pass the algorithm/formula that determines it is time to perform that task (it can be quite intelligent and factor in many things). It can also help if there was a model reference in CronPlugin, which can be passed to the cron method provide a way of storing values to check later.
You also need the payload which is the task itself. This can be passed as an object method, a static method, or a standalone function.
So you could have an convenience
AddTask
method perhaps. It could add to an indexed collection(s) of task and the cron formula.then your CronPlugin will be checking every basic unit (such as every request), loop through the task to see if anything need to be performed and if so calling the method.
you can also specify what other plugins are required, when you create a plugin in the PluginInfo. It shouldn't enable through the dashboard otherwise.
If you want a proper cron, i.e. somethign that is running the background regardless of the requests, then you need to be able to interface with and support such infrastructure, it is a little bit more tricky if you are hoping to have a distributed solution.
grep is your friend.
I think I understand now. The code you wrote goes into the 3rd party plugin, right? So, workflow would be the following:
1- Cron Plugin fire
RegisterCron
event.2- Client Plugin implements a handler to register itself. Here it can pass the method to execute and, optionally, another method that Cron Plugin will run to determine if it's time to execute the first or not.
3- Cron Plugin will run the Execute method, loop through all the registered plugins, executes the "should I run it?" method of each client plugin (if it exists) and, eventually, run the Cron method.
Did I get it right, finally?
Regarding the proper Cron, I could use a hybrid solution such as the one implemented in Drupal: expose a menu entry, accessible via URL, which would fire the Cron sequence. Such menu entry would be secured, so that only localhost could call it (this is to prevent DDoS attacks). Additionally, some throttling mechanism could be implemented as well, but we're going into a lot of detail now.
My shop | About Me
the code is not formatting correctly. sorry. bare with.
grep is your friend.
ah this is a real pain in the ass. There are problem with the multi formatter. It is jack of all trades....
grep is your friend.