Best way to implement vendors in Plugins

  • I'm searching for an easy way to include vendor namespaces in a plugin.


    Currently, I try to develop a plugin, that requires third party software organized in namespaces. If I call the namespaces (e.g. use vendor\Base64), I get an error (Class 'vendor\Base64' not found), because the namespace is unknown. I also tried to autoload the namespace without success. I don't want to include all files. Is there a good practice how to do this?


    PHP
    1. function __autoload($namespace)
    2. {
    3. $namespace = getcwd() . '/../plugins/Plugin1/vendors/' . str_replace('\\', '/', $namespace) . '.php';
    4. require_once($namespace);
    5. }
  • @Starlight


    Your vendor library are following PSR-0? We support PSR-0 through ZF1 standard autoloader class. There is no need to provide your own autoload function here. For instance, for a vendor library that follow PSR-0, you could do:


    PHP
    1. <?phpuse iMSCP_Plugin_Action as PluginAction;/*** Class iMSCP_Plugin_YourPluginName*/class iMSCP_Plugin_YourPluginName extends PluginAction{ /** * Plugin initialization * * @return void */ public function init() { /** @var Zend_Loader_StandardAutoloader $loader */ $loader = Zend_Loader_AutoloaderFactory::getRegisteredAutoloader('Zend_Loader_StandardAutoloader'); $loader->registerNamespace('3rdVendor', __DIR__ . '/vendor/3rdVendor'); }}

    In the above example, 3rdVendor is the library vendor name wherea __DIR__ . '/vendor/3rdVendor' would resolve to the /var/www/imscp/gui/plugins/YourPluginName/vendor/3rdVendor path. With the above setup, you should be able to load classes as follows in your code:

    PHP
    1. <?php
    2. use 3rdVendor\FirstClassName;
    3. use 3rdVendor\SecondClassName as SuperClassName;
    4. $firstClassNameObject = new FirstClassName();
    5. $superClassNameObject = new SuperClassName();
    6. ...


    If you need PSR-4, we can add support for it too.


    See also

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • @Starlight


    PSR-4 support added. See https://github.com/i-MSCP/imsc…88a02797b7...e1b26a783933


    To resume:

    But, from plugin context, you need to retrieve the autoloader and add your vendor libraries as shown in my first answer. However, with i-MSCP 1.5.2 (Plugin API 1.5.1), it will be preferable to process as follows:


    because the Zend_Loader_AutoloaderFactory class which is now an alias of the \iMSCP\Loader\AutoLoaderFactory class will be removed in a later release.


    Note that you can register several namespaces and/or prefixes at the same time, using the registerNamespaces() and registerPrefixes() methods, passing an array to them.

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • Thanks @Nuxwin, that works for iMSCP v1.5.1.


    Would be great, if that would be documented in the Wiki, too.


    Additional questions:
    Is there a way to
    a) check the API version installed,
    b) find out what API version is the minimum possible to provide a plugin for?

  • Would be great, if that would be documented in the Wiki, too.

    I'll and I hope that following you work, you'll participate too.


    Note that following your question, I made several change in the 1.5.x branch regarding autoloading (with backward compatibility in mind till 1.6.0):

    • All i-MSCP depdencencies ( idna library, zend framework ...) will be installed through the PHP dependency manager (composer)
    • i-MSCP will make use of the composer autoloader and will expose it throuh the iMSCP\Application::getAutoloader() method. The composer autoloader implements PEAR, PSR-0 and PSR-4. I'll update my example at this regard soon.

    check the API version installed,

    The plugin API version is available through the PluginApi parameter. However for best compatibility, it is preferable to retrieve it via the plugin manager (frontend level):


    with older i-MSCP Series, best way is to retrieve the plugin manager from the registry and get the plugin API version as follows:

    PHP
    1. use iMSCP::Registry as Registry;$pluginApiVersion = Registry::get('pluginManager')->pluginGetApiVersion();

    Starting with 1.5.x Serie:


    PHP
    1. use iMSCP::Registry as Registry;$pluginApiVersion = Registry::get('iMSCP_Application')->getPluginManager()->pluginGetApiVersion();

    Then, once after, do what you want with the plugin API version (eg, using PHP version_compare() function).

    b) find out what API version is the minimum possible to provide a plugin for?

    There are already a way to tell the plugin manager that a plugin is not compatible with an i-MSCP version bellow a specific plugin API version. This is done via the require_api field of the plugin info.php file. For instance, the LetsEncrypt plugin comes with the following info file:

    As you can see, there is a require_api field that make the plugin manager able to check the minimum i-MSCP plugin API version required. If the condition is not met, the plugin manager will refuse to install the plugin (or to update it, depending of the context). The check is made before any file replacement.


    The check is done here:

    Regarding the plugin info fileds, see:

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206

  • I'll and I hope that following you work, you'll participate too.

    Sure, I will do. Let me first try to get my plugin working as expected and I'm going to document the important parts. Nevertheless, for the tricky parts, I need your help. You know the code better.



    Quote from Starlight

    b) find out what API version is the minimum possible to provide a plugin for?


    Here you got me wrong. I actually wanted to find out, how to identify the lowest API version, the plugin would probably work with. It's a bit tricky: I develop a plugin with iMSCP 1.5.1 and API v 1.5.0. And I wonder, is this also working with iMSCP 1.1.6 or 1.4.7 or not. Just to set the api_version parameter right.

  • Here you got me wrong. I actually wanted to find out, how to identify the lowest API version, the plugin would probably work with. It's a bit tricky: I develop a plugin with iMSCP 1.5.1 and API v 1.5.0. And I wonder, is this also working with iMSCP 1.1.6 or 1.4.7 or not. Just to set the api_version parameter right.

    Strictly speaking, there are no easy way to track down changes that are result of plugin API version incrementation other than looking at the i-MSCP changelog and errata files.
    If you have an idea about a better way to track these changes, you're welcome. We could add a specific file in i-MSCP repository which would enumerate change that can involve BC break.

    badge.php?id=1239063037&bid=2518&key=1747635596&format=png&z=547451206