Feature Wiki

Information about planned and released features

Tabs

Autoloading

1 Requirements

ILIAS consists of many PHP files (large and small) which include each other. They are included _before_ they are used - and often they will not be used after being included. And this propagates to additional includes within unused include-files, etc. The net result often is quite close to include '*'. One example just to illustrate this effect: The login page even includes a math-library among dozens of other files (think about it: a math library for the login page?).

This _might_ not be a big performance issue to include unused code (though I am note that sure about it), but it obscures what is going on. The dev_mode lists all include files of a given request - this would have the potential to be a very good tool to get a quick impression what is going on - if it was not for the above mentioned include-spam.

Autoloading to the resuce: PHP supports autoloading since v5 - usually in combination with namespaces. Since we don't use namespaces in ILIAS, there would be minimally-invasive alternative to still be able to use autoloading: a simple lookup-table/array (often called classmap), which can be created automatically by 'composer' and many other tools.

I suggest to strip all hard-coded includes and register a classmap-based autoloader (e.g. based on composer - or something home-grown).

Pre-Requisites and Consequences:

  • class-names must be unique for this approach to work. As far as I know the setup has some duplicate class-names (like ilInitialization) which must then be renamed (ilInitializationSetup, etc.).
  • Every time a new class is added to ILIAS the classmap-generator must be executed to update the classmap.
Benefits:
  • Less include-spam -> better insight with dev_mode enabled
  • Although the autoloader surely adds a slight overhead itself, this might even be outweighed by more lightweight requests.

1.1 Prerequisite

ILIAS-eLearning/ILIAS/pulls

  • #24 remove obsolete class ilInitialisation
  • #23 Chatroom: viewAdminTask (rename to avoid classname collision)
  • #22 remove old class stub - > fixing a classname collision
  • #21 remove old class stub - > fixing a classname collision
  • #20 COPage SourceCode Highlight: fixed violation of naming convention
  • #19 remove unused old version of nusoap
  • #18 remove unused old version of PHPCAS v0.4.20-1 (keeping v1.1.2)
  • #17 Remove duplicate ilExerciseException
  • #16 Remove duplicate Unicode lib (keeping the newer version + relocate)
  • #15 removed *unused* JSON-Emulator (no references to it anymore)
  • #14 remove dysfunctional reminescents of old PEAR ITX Templates

  • ilContObjectManifestBuilder ./Modules/LearningModule/classes/class.ilContObjectManifestBuilder.php ./Modules/Scorm2004/classes/class.ilContObjectManifestBuilder.php
ask maintainer to solve manually?

  • php4DOMAttr ./include/inc.xml5compliance.php ./Services/CAS/lib/CAS/domxml-php4-to-php5.php
  • php4DOMDocument ./include/inc.xml5compliance.php ./Services/CAS/lib/CAS/domxml-php4-to-php5.php
  • php4DOMElement ./include/inc.xml5compliance.php ./Services/CAS/lib/CAS/domxml-php4-to-php5.php
  • php4DOMNode ./include/inc.xml5compliance.php ./Services/CAS/lib/CAS/domxml-php4-to-php5.php
  • php4DOMNodelist ./include/inc.xml5compliance.php ./Services/CAS/lib/CAS/domxml-php4-to-php5.php
  • php4DOMXPath ./include/inc.xml5compliance.php ./Services/CAS/lib/CAS/domxml-php4-to-php5.php
Solution: Upgrade CAS (see Mantis Ticket #15723)
-> removal of domxml compatibility lib since 1.2 (https://github.com/Jasig/phpCAS/search?utf8=%E2%9C%93&q=domxml)
-> also multiple security issues fixed in 1.3.2 (current version is vulnerable!)

  • ilDatabaseSelectionWS (4-fold collision within scope of setup - all 4 files are perfectly identical)
    • /www/pub/ilias-trunk/setup/classes/class.ilInstallDBWS.php
    • /www/pub/ilias-trunk/setup/classes/class.ilDatabaseSelectionWS.php
    • /www/pub/ilias-trunk/setup/classes/class.ilContactWS.php
    • /www/pub/ilias-trunk/setup/classes/class.ilRegisterWS.php
  • ilTemplate /www/pub/ilias-trunk/setup/classes/class.ilTemplate.php /www/pub/ilias-trunk/Services/UICore/classes/class.ilTemplate.php
  • ilLanguage /www/pub/ilias-trunk/setup/classes/class.ilLanguage.php /www/pub/ilias-trunk/Services/Language/classes/class.ilLanguage.php
Solution:
  • prefix class.ilSetupTemplate.php and class.ilSetupLanguage (scope for refactoring should be well confined to setup)
  • remove duplicate class-definitions

Suggestion for Solution:

  • drop very old db update steps if possible (looks like all collisions are caused from updates before 07.01.2009). Updating from very old ILIAS versions would then require an intermediate step to some ILIAS 4.x version.
Here is a list of all classname collisions due to DB-Updates (db_update_1385 is the most recent causing collisions)
  • php4DOMAttr ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • php4DOMCDATASection ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • php4DOMDocument ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • php4DOMElement ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • php4DOMNode ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • php4DOMNodelist ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • php4DOMXPath ./include/inc.xml5compliance.php ./Services/Migration/DBUpdate_491/inc.xml5compliance.php
  • ilMDKeyword ./Services/MetaData/classes/class.ilMDKeyword.php ./Services/Migration/DBUpdate_426/classes/class.ilMDKeyword.php
  • ilMDSaxParser ./Services/MetaData/classes/class.ilMDSaxParser.php ./Services/Migration/DBUpdate_426/classes/class.ilMDSaxParser.php
  • ilMDTaxonPath ./Services/MetaData/classes/class.ilMDTaxonPath.php ./Services/Migration/DBUpdate_426/classes/class.ilMDTaxonPath.php
  • ilMDLifecycle ./Services/MetaData/classes/class.ilMDLifecycle.php ./Services/Migration/DBUpdate_426/classes/class.ilMDLifecycle.php
  • ilMDAnnotation ./Services/MetaData/classes/class.ilMDAnnotation.php ./Services/Migration/DBUpdate_426/classes/class.ilMDAnnotation.php
  • ilMDBase ./Services/MetaData/classes/class.ilMDBase.php ./Services/Migration/DBUpdate_426/classes/class.ilMDBase.php
  • ilMDContribute ./Services/MetaData/classes/class.ilMDContribute.php ./Services/Migration/DBUpdate_426/classes/class.ilMDContribute.php
  • ilMDDescription ./Services/MetaData/classes/class.ilMDDescription.php ./Services/Migration/DBUpdate_426/classes/class.ilMDDescription.php
  • ilMD ./Services/MetaData/classes/class.ilMD.php ./Services/Migration/DBUpdate_426/classes/class.ilMD.php
  • ilMDRelation ./Services/MetaData/classes/class.ilMDRelation.php ./Services/Migration/DBUpdate_426/classes/class.ilMDRelation.php
  • ilMDEntity ./Services/MetaData/classes/class.ilMDEntity.php ./Services/Migration/DBUpdate_426/classes/class.ilMDEntity.php
  • ilMDEducational ./Services/MetaData/classes/class.ilMDEducational.php ./Services/Migration/DBUpdate_426/classes/class.ilMDEducational.php
  • ilMDGeneral ./Services/MetaData/classes/class.ilMDGeneral.php ./Services/Migration/DBUpdate_426/classes/class.ilMDGeneral.php
  • ilMDLanguageItem ./Services/MetaData/classes/class.ilMDLanguageItem.php ./Services/Migration/DBUpdate_426/classes/class.ilMDLanguageItem.php
  • ilMDIdentifier_ ./Services/MetaData/classes/class.ilMDIdentifier_.php ./Services/Migration/DBUpdate_426/classes/class.ilMDIdentifier_.php
  • ilMDCreator ./Services/MetaData/classes/class.ilMDCreator.php ./Services/Migration/DBUpdate_426/classes/class.ilMDCreator.php
  • ilMDLanguage ./Services/MetaData/classes/class.ilMDLanguage.php ./Services/Migration/DBUpdate_426/classes/class.ilMDLanguage.php
  • ilMDIdentifier ./Services/MetaData/classes/class.ilMDIdentifier.php ./Services/Migration/DBUpdate_426/classes/class.ilMDIdentifier.php
  • ilMDFormat ./Services/MetaData/classes/class.ilMDFormat.php ./Services/Migration/DBUpdate_426/classes/class.ilMDFormat.php
  • ilMDLanguageElement ./Services/MetaData/classes/class.ilMDLanguageElement.php ./Services/Migration/DBUpdate_426/classes/class.ilMDLanguageElement.php
  • ilMDTypicalAgeRange ./Services/MetaData/classes/class.ilMDTypicalAgeRange.php ./Services/Migration/DBUpdate_426/classes/class.ilMDTypicalAgeRange.php
  • ilMDLocation ./Services/MetaData/classes/class.ilMDLocation.php ./Services/Migration/DBUpdate_426/classes/class.ilMDLocation.php
  • ilMDTechnical ./Services/MetaData/classes/class.ilMDTechnical.php ./Services/Migration/DBUpdate_426/classes/class.ilMDTechnical.php
  • ilMDRequirement ./Services/MetaData/classes/class.ilMDRequirement.php ./Services/Migration/DBUpdate_426/classes/class.ilMDRequirement.php
  • ilMDOrComposite ./Services/MetaData/classes/class.ilMDOrComposite.php ./Services/Migration/DBUpdate_426/classes/class.ilMDOrComposite.php
  • ilMDTaxon ./Services/MetaData/classes/class.ilMDTaxon.php ./Services/Migration/DBUpdate_426/classes/class.ilMDTaxon.php
  • ilMDClassification ./Services/MetaData/classes/class.ilMDClassification.php ./Services/Migration/DBUpdate_426/classes/class.ilMDClassification.php
  • ilMDRights ./Services/MetaData/classes/class.ilMDRights.php ./Services/Migration/DBUpdate_426/classes/class.ilMDRights.php
  • ilMDMetaMetadata ./Services/MetaData/classes/class.ilMDMetaMetadata.php ./Services/Migration/DBUpdate_426/classes/class.ilMDMetaMetadata.php
  • ilNestedSetXML ./Services/Xml/classes/class.ilNestedSetXML.php ./Services/Migration/DBUpdate_439/classes/class.ilNestedSetXML.php
  • ilStyleMigration ./Services/Style/classes/class.ilStyleMigration.php ./Services/Migration/DBUpdate_1385/classes/class.ilStyleMigration.php
  • ilFileSystemStorage ./Services/FileSystem/classes/class.ilFileSystemStorage.php ./Services/Migration/DBUpdate_904/classes/class.ilFileSystemStorage.php
  • ilObjFileAccess ./Modules/File/classes/class.ilObjFileAccess.php ./Services/Migration/DBUpdate_904/classes/class.ilObjFileAccess.php
  • ilFSStorageFile ./Modules/File/classes/class.ilFSStorageFile.php ./Services/Migration/DBUpdate_904/classes/class.ilFSStorageFile.php
  • ilFSStorageCourse ./Modules/Course/classes/class.ilFSStorageCourse.php ./Services/Migration/DBUpdate_904/classes/class.ilFSStorageCourse.php

2 Additional Information

  • Idea / concept: Colin Kiegel
  • Interest in funding: might not need funding..
  • Maintainer: (will be set by Jour Fixe / maintainer)
  • Implementation of the feature is done by (will be set by Jour Fixe / maintainer)
  • Testcases by: (please add your name if you want to create the testcases for this feature)

3 Discussion

CK 01.04.2015: A quick check revealed 74 collisions of classnames (with setup folder removed) - steps to reproduce

  • # install composer: https://getcomposer.org/
  • # cd into recent trunk checkout
  • rm setup/ -r # let's deal with setup later
  • echo '{"autoload": { "classmap": [ "" ] } }' > composer.json # create minimalistic autoloader-configuration (without namespace)
  • composer dumpautoload -o # create the classmap -> warning about each collisions
Prerequisite for autoloading: resolve all 74 classname-collisions (see link above) - the rest should be a piece of cake ;-)
  • Question: Are there any requirements how this kind of renaming should be done? Any recommendations/tipps too?

CK 03.04.2015:

  • Update I have placed several PullRequests (#14..#24) which resolve most classname collisions. Almost there now. :-)
  • I suggest to use the autoloader of composer - because it is a flexible and widespread tool and could also be used to resolve dependencies on external libraries in the future

OT 07.04.2015:
Sounds like a great idea! Do you know if there are any problems on the perfomance for the autoloader? I would +1 the idea of using composers autoloader, maybe we can even use it as dependency manager in the future.

RK 2015-07-20:
The SIG Refactoring discusses autoloading on its Meeting on 07 July 2015. The conclusion was as following:

  • We need a transition strategy: 
    • Maybe from global classmap to component to ...?
  • Options: 
    • 1 Classmap over the whole ILIAS-codebase
      • The resulting class map might be very huge.
      • How should Plugins be introduced?
      • Would be better with global caching?
      • Would that map be reloaded on every request if it is encoded in a php file?
      • This would require a build process of some fashion, as the classmap needs to be generated.
      • Requires the uniqueness of classnames. 
    • 2 ComponentMap with Pseudonamespaces
      • Map on the top level would be smaller. Global autoloader would load a component autoloader under the control of the component maintainer.
      • Would give freedom and responsibility to the maintainers.
      • Could be introduced incrementally via explicit registration of component autoloaders in a global component map.
      • Would require some refactoring as not all classes use a proper pseudo namespace.
      • We would need to organize the uniqueness of pseudo namespaces.
      • Would take the code base in a direction where it would be easier to introduce real namespaces.
      • Would delete information on the component where the class comes from in the calling code.
    • 3 Namespacing according to PSR-4 with unique class names
      • Colin took care about unique class names already.
      • ilCtrl needs unique class names for GUI classes.
      • Would require the following steps: - introduce "namespace XYZ;" on top of very file. - search and replace "new CLASS;" with "new NAMESPACE\CLASS;". - search and replace won't work in any case, as we also would need to take care of new $foo;
      • Would give information on which component provides the class.
      • Risk of collisions in names when using third party libraries would not exist. 
      • Would lead in a direction where dependency managment via composer would be possible and also ILIAS could be modularized.
    • 4 Namespacing according to PSR-4 without unique class names (e.g. ilMembersTableGUI in different components)
      • Would require changes in ilCtrl, maybe ilObjectFactory, and maybe some others.
      • Setup would be the same as for 3. 5 Mixture between those.
  • The SIG Refactoring will give the results of the session as input on the Feature Wiki Page. Overall we do not see enough benefit from autoloading to tackle the different problems atm. Furthermore, the different options come with trade offs and it seems impossible to get to a strong opinion on what option should be preferred. Nonetheless we would really appreciate namespaces.

4 Implementation

...

Last edited: 20. Jul 2015, 10:58, Klees, Richard [rklees]