Overriding classes where self:: is used

Overriding classes where self:: is used

by Martin Mastny -
Number of replies: 0
Picture of Core developers Picture of Peer reviewers Picture of Testers

Hello everyone,

I have yet a simple question about an approach or a strategy which I should take.

I'm trying to override a core_course_category class, which is a quite big class. I need to change only a tiny bit of it's functionality at ceratin places. So I took an obvious path of extending this class with my own and then use my own rather than the stock one.

When I tried to run my code for the first time, my method on an inherited class was not called. I debugged everything and found this on core_course_category class.

public static function top() {
if (!isset(self::$coursecat0)) {
$record = new stdClass();
$record->id = 0;
$record->visible = 1;
$record->depth = 0;
$record->path = '';
$record->locked = 0;
self::$coursecat0 = new self($record);
}
return self::$coursecat0;
}
The problem here is the self:: keyword, which ensures that eventhough I instantiate my child class with overriden functionality, core_course_category class is used, cause that is how self:: keyword works (see here). So I overrode this method as well, eventhough I don't need to change any 'functionality', but it seems, that there are multiple places, where 'self::' kind of kicks out my inherited class from the game and ensures core_course_category is used as 'self' was declared there.
I understand, why this is done this way. Before PHP 5.3, there was no static:: keyword which represents 'late static binding' and the actual behavior I and probably most of us expect.

Anyway I'm not sure of how to solve this. I want to override only a single/maybe two methods of core_course_category and with this approach I'll have to find all occurences of self:: and override those methods to use either static:: or whatever makes sense in that context.
There will be so much more checking when rebasing my changes onto moodle core.
I've found that a core_component::classloader, which is responsible for loading classes, can be replaced with a custom one. So theoretically I can use my own core_course_category_custom class, but still, I want to create this class with 99% of functionality the same as stock class. So this does not help either.

Would it be possible from the moodle point of view to change these calls to 'self::' to 'static::'? I mean moodle (in the recent supported versions) requires at least php 7.x, so there is no problem with compatibility. I donť see any other issues why not to replace this. And if there is a call, which needs the core class and absolutely no other class, there is always a chance to call it like 'my_core_class::' not 'self::'

Thanks for your thoughts

Average of ratings: -