Install Composer Dependancies from PHP script

I’ve been working for some time on figuring out a good way to manage Composer dependancies in WordPress plugin development. Including dependancies in WordPress plugins is easy enough, but if two separate plugins both have composer.json/vendor directories, and include the same package, you get a collision and everything crashes. So my working solution is essentially offering an API that allows plugins to push their dependancies into a central package manager.

This solution works fine when managing stuff manually and installing via the command line, but WordPress is obviously popular because of a low barrier to entry. Installing Composer packages via the command line is a high barrier to entry, so I set about creating a plugin to list and install all the shared dependancies. I got partway done, and the code is on Github, here.

Read More

I’ve been trying to reverse engineer Composer, with mostly limited luck. It’s turned into something of a mess. I’m really curious if anyone has experience with using Composer outside the CLI, or if it’s possible, or barring all that, if there are any strategies for sorta duplicating the functionality without too huge a problem.

I was able to get things to download and install, but I got hung up on writing the lock file and autoloader, both of which are pretty crucial parts of the whole thing.

tl/dr:

  • Composer is written to be packaged up and run via the CLI.
  • I want to use or mimic its functionality in a WordPress plugin.
  • Is it possible?
  • Has anyone done this? Are there existing projects I can look at?
  • I’m specifically concerned with the Autoloader and Lock file creation, but I’m unhappy with my implementation of the installer as well.

Related posts

Leave a Reply

2 comments

  1. Composer works just as well as a dependency as it does CLI. The Composer CLI is one implementation of what the composer library is designed to do.

    Composer Implementation

    The application itself bootstraps composer through the factory class.

    Factory::create(IOInterface $io, $config = null, $disablePlugins = false);
    

    The composer install command begins by boostrapping an installer

    Installer::create(IOInterface $io, Composer $composer);
    

    From there it sets some run time variables whether declared or default and goes into the Installer::run() method.

    See the InstallCommand class for more details on how to do an install.

    Areas of Interest

    Majority of what you should be working with to achieve your goals is implementing a repository for your packages. You may want to look into ArrayRepository and the variations of the installed repositories to guide your implementation. Once you have a repository you can tell composer about your packages.

    Installer::setAdditionalInstalledRepository(RepositoryInterface $repo)
    

    Noteworthy Projects

    Metadata Browsers

    • Packagist – uses composer extensively for all it provides
    • Wpackagist – similar to packagist while providing pseudo data for a repository
    • Satis – uses composer to generate a package repository similar to the above examples

    Installers

  2. First of all, you have a specific problem, then you should explain this problem, not how you got there.

    I wrote a little script to test for problems with autoloader generation or lock file creation.

    <?php
    
    include __DIR__ . '/vendor/autoload.php';
    
    $factory = new ComposerFactory();
    
    //$io =  new ComposerIONullIO();
    $io =  new ComposerIOConsoleIO( 
        new SymfonyComponentConsoleInputArgvInput(),
        new SymfonyComponentConsoleOutputConsoleOutput(),
        new SymfonyComponentConsoleHelperHelperSet()
    );
    
    $composer = $factory->createComposer( $io );
    
    $install = ComposerInstaller::create($io, $composer);
    
    $install
        ->setDryRun( false )
        ->setVerbose( false )
        ->setPreferSource( false )
        ->setPreferDist( true )
        ->setDevMode( false )
        ->setRunScripts( true )
        ->setOptimizeAutoloader( false )
        ;
    
    $install->run();
    

    i run this from command line in a directory with a composer.json and it works.

    To run it from webserver(php internal one), I use the NUllIO, and it works without problems.

    I will update the answer, if you specify the problem.

    If you want someone to fix your own code, you should pay them (or me)
    But its not ok to say: here, look at my github repository, please fix the bug