How to use Reflection and interfaces in Moodle module

How to use Reflection and interfaces in Moodle module

by Zoran Jeremic -
Number of replies: 7
Hi,

I developed my own module, and I'm trying to implement interface that could later be extended by other developers. Each time, plugin is updated, I need to read information about all these classes that implement  interface and store some information in the database.  I thought to use reflection for that


$classes=get_declared_classes();
$implementsIPrototype=array();
    foreach($classes as $clazz){
       $reflect=new ReflectionClass($clazz);
       if($reflect->implementsInterface("Prototype")){
              // do something with this class
     }


I stored interface in /moodle/mod/mymodule/classes/interfaces.php. However, my interface is not visible and I got exception: Exception - Interface Prototype does not exist.

get_declared_interfaces() returns many Moodle interfaces, but not the one from my module. I also noticed that some Moodle interfaces are not returned.

Do you have any suggestions how to solve this?

Thanks,

Zoran


Average of ratings: -
In reply to Zoran Jeremic

Re: How to use Reflection and interfaces in Moodle module

by Darko Miletić -

In order for the class autoloading to work you need to follow established rules.


https://docs.moodle.org/dev/Automatic_class_loading

In reply to Darko Miletić

Re: How to use Reflection and interfaces in Moodle module

by Zoran Jeremic -

Does this apply for interfaces too? I didn't find it mention interface and I couldn't find any interface in Moodle modules to follow by example. My classes follow this naming convention and I can retrieve it with get_declared_classes() . However, when I try to check if class implements my interface:

if($reflect->implementsInterface("mod_morph_prototype")){

I got exception:

Exception - Interface mod_morph_prototype does not exist

I also tried to rename interface to follow the class naming convention, but it didn't change anything. 


Thanks,

Zoran

In reply to Zoran Jeremic

Re: How to use Reflection and interfaces in Moodle module

by Darko Miletić -

If there are issues with interfaces try using abstract class instead as a base.

In reply to Zoran Jeremic

Re: How to use Reflection and interfaces in Moodle module

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Why do you think you "need to" do this? 

From your choice of variable name, I guess that you might have a background as a Java developer. PHP is not Java, and none of the 150+ existing Moodle modules needed to do this. (https://moodle.org/plugins/browse.php?list=category&id=1)

Average of ratings: Useful (1)
In reply to Tim Hunt

Re: How to use Reflection and interfaces in Moodle module

by Zoran Jeremic -

Let me try to explain what I want to achieve so maybe you will have some better idea how to implement that.

I'm implementing a platform (moodle plugin is part of it) that will be used by researchers to develop different types of algorithms (e.g. reporting, analytics, recommendations...). They will implement these algorithms (prototypes) after I finish development, but I need to implement code that will recognize if new prototype implementation have been added to Moodle plugin, and update a database with information collected from that class, such as class name and variables names and types.

My idea was to use either interface or abstract class that will let me know that new class that researcher implemented and added to plugin, is a new prototype. In that case, on plugin upgrade I would get all declared classes in my plugin, check if it implements "prototype" interface, or if it extends "prototype" abstract class, and store information in database.  So, what I tried is to call get_declared_classes() and for each class to call get_parent_class(), but it didn't work since get_declared_classes() doesn't return any class from mod/myplugin/classes, even though they use moodle naming convention.

The other approach that came to my mind is to create a directory iterator that will check each file in mod/myplugin/classes and search for classes that extend prototype class.

Do you have any proposal?

Zoran


In reply to Zoran Jeremic

Re: How to use Reflection and interfaces in Moodle module

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Have a look a sub-plugins: https://docs.moodle.org/dev/Subplugins

That way, each algorithm would be a separate Moodle (sub-)plugins, and so Moodle will manage the install for you.

The only way that might not be good enough is if that is too heavy-weight. However, the overhead for people implementing new algorithms is only putting each class in a separate folder, with a version.php file.

Moodle has some useful helpers, like core_component::get_plugin_list_with_class, and these are backed by data stored in a cache, so are fast.

If that does not work for you, get back to us, and we can try thinking again.

Average of ratings: Useful (2)
In reply to Tim Hunt

Re: How to use Reflection and interfaces in Moodle module

by Zoran Jeremic -

Hi Tim,

Thank you so much for this suggestion. I think this is exactly what I need. Something similar I had in my mind, but I didn't know it's already supported in Moodle, so I started to implement my own settings and admin pages inside plugin. I'll switch to this approach as it looks much better.


Thanks,

Zoran