Skip to content

Instantly share code, notes, and snippets.

@cedricziel
Last active October 27, 2021 08:12
Show Gist options
  • Save cedricziel/08ea469db5197e24552c to your computer and use it in GitHub Desktop.
Save cedricziel/08ea469db5197e24552c to your computer and use it in GitHub Desktop.
TYPO3 Extension with 3rd part composer dependencies. composer.json is placed in Resources/Private - Updated

Motivation

As long as composer support in CMS is "not there yet", you need to get around somehow.

Say you want to use the (awesome) markdown library, you need a way to get it in.

How

  1. Use a container extension with a private namespace
  2. Create composer.json
  3. Include the autoloader for both contexts
  4. profit

Why a separate composer.json?

Code

composer.json

Create a file composer.json in your container extension in Resources/Private (you can use composer init):

{
    "name": "cedricziel/packagename",
    "config": {
      "vendor-dir": "Libraries"
    },
    "require": {
        "michelf/php-markdown": "~1.4"
    },
    "authors": [
        {
            "name": "Cedric Ziel",
            "email": "cedric @t cedric-ziel.com"
        }
    ]
}

Note the vendor-dir directive. This allows you to determine where composer will put the libs and the class loader you have to include.

ext_tables.php && ext_localconf.php

I cant explain the exact sematics very well, but you will want to have both. Otherwise your classes wont load in a cached context.

ext_tables.php

<?php
if (!defined('TYPO3_MODE')) {
	die('Access denied.');
}

$composerAutoloadFile = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY)
	. 'Resources/Private/Libraries/autoload.php';

require_once($composerAutoloadFile);

ext_localconf.php

<?php
if (!defined('TYPO3_MODE')) {
	die('Access denied.');
}

$composerAutoloadFile = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath($_EXTKEY)
	. 'Resources/Private/Libraries/autoload.php';

require_once($composerAutoloadFile);

Notes

This is a workaround - let me get this straight. Problems could arise if you do that overly often with many different libraries and end up with different loadable classes. I therefore propose you creat one such container extension per project.

@rengaw83
Copy link

I think it would be better when you use Resources/Private/PHP as path for your composer.json. Or not?

@cedricziel
Copy link
Author

Adjust it to your taste, @rengaw83 - There is no convention and this is a managed library instead of dropping a bunch of classes somewhere.

@DenisMir
Copy link

@cedricziel Is this still the way to go for dependency management in extensions in TYPO3 6.2 LTS?

@cedricziel
Copy link
Author

This approach is valid for all versions (in fact: every version that reads the ext_* files) until composer is natively supported (which i dont expect to happen too soon).

@DenisMir
Copy link

DenisMir commented Jul 1, 2015

Thank you very much for your help.

@christianbaer
Copy link

How do you call such an autoloaded 3rd-Party-Class in you own Controller? Just like this?

$foo = new \Vendor\Classname();

Maybe you have a repo with an extension, where you actually use a 3rd party library? Would love to see it in reality :)

@cedricziel
Copy link
Author

@christianbaer yes. basically you can leverage PHP native namespaces the way they are meant to be.

Please have a look at http://php.net/manual/de/language.namespaces.php and https://getcomposer.org/doc/01-basic-usage.md#autoloading to get a better understanding about those topics

@madsbrunn
Copy link

As far as I know ext_localconf.php are always loaded so it should only be nescessary to require the autoload file there (please correct me if I'm wrong).

@cedricziel
Copy link
Author

Added an example extension that uses a composer script to package the library https://github.com/cedricziel/typo3-ext-slugify

@AlexeyFreelancer
Copy link

@cedricziel Should I manually execute composer install and commit Libraries folder into repository?

@Romaixn
Copy link

Romaixn commented Apr 27, 2021

This gist is up-to-date in 2021 ? (or Composer has been included..)

EDIT: This gist work in 2021, thanks ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment