Child pages
  • Add support for namespaces to autoloader
Skip to end of metadata
Go to start of metadata

Autoloader is a way for PHP to include missing declarations of classes/interfaces on the fly, when they are needed.

At first In-Portal wasn't using any kind of autoloader and you needed to use kApplication::recallObject or kApplication::getObject to include missing declarations. In  INP-224 - Getting issue details... STATUS  task we've added a classmap autoloader. This way now if attempt is made to instantiate a class directly (without using methods, mentioned above) it will work for a classes registered in unit configs.

Autoloading can even remove a need for a class registration in unit configs at all. Then only thing, that needs to be specified is a class name. Then from a class name thanks to PSR-0 autoloading standard (https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) it's possible to determine filename with a class declaration.

Example of declaration:

File: "/modules/custom/units/widgets/widget_eh.php"
<?php
 
namespace Intechnic\InPortal\Modules\Custom\units\widgets;
 
class WidgetEventHandler extends \kDBEventHandler {
 
}

Example of usage:

Some other file
<?php
 
$object = new Intechnic\InPortal\Modules\Custom\units\widgets\WidgetEventHandler();

Here actual file location on disk, that contains class declaration, is represented in a namespace within which class is created. Later you literally specify that namepspace+classname and autoloader can determine the rest. This way all unit related classes would be grouped under a single namespace. This completely eliminates a problem of class namespace collision, where UserHelper class was defined in Core and in Custom modules. When namespaced they full name would be as follows:

  • \Intechnic\InPortal\Core\units\helpers\UserHelper
  • \Intechnic\Modules\Custom\units\helpers\UserHelper

Of course this type of autoloading isn't a replacement for current classmap method, but rather an addition to it.

Right now name collision is solved, but these class names became somehow longer to write. Actually this might not be that big problem, because:

  1. 99% of classes comes from units and never instantiated directly, but rather specifying corresponding unit prefix (e.g. "widget")
  2. we can figure out namespaced part of class name automatically, when kApplication::recallObject or kApplication::getObject methods are used.

Here is an idea:

CodeResolution Logic
$this->Application->recallObject('UserHelper')
  1. no namespace given -> consider belonging to module within which code is being executed (e.g. "Intechnic\InPortal\Modules\Custom")
  2. from "Helper" suffix this seems to be a helper class
  3. helper classes reside under "/units/helpers/" subfolder
  4. found "user_helper.php"
$this->Application->recallObject('in-link\\UserHelper')
  1. only one "\\" occurrence found - some In-Portal own magic, not exactly a namespace
  2. "in-link" used - exactly matches name of a module (like use in templates) -> consider belonging to "Intechnic\InPortal\Modules\InLink"
  3. from "Helper" suffix this seems to be a helper class
  4. helper classes reside under "/units/helpers/" subfolder
  5. found "user_helper.php"

I've used "\\" instead of "\" because it's special PHP symbol used to escape stuff and needs to be escaped itself.

To make all of above happen we need to rename files, containing classes to names of these classes. For example since "user_helper.php" class holds UserHelper class, then filename should be changed to UserHelper.php as well. 

factory_namespace_support_core.patch

factory_namespace_support_modules.patch

Related Tasks

INP-1248 - Getting issue details... STATUS

INP-1249 - Getting issue details... STATUS