Skip to content

Instantly share code, notes, and snippets.

@lonalore
Last active June 21, 2016 13:42
Show Gist options
  • Save lonalore/58146ac05e4861262524123112b20609 to your computer and use it in GitHub Desktop.
Save lonalore/58146ac05e4861262524123112b20609 to your computer and use it in GitHub Desktop.

Installing an external library that is required by a contributed plugin

  • Download the library - The plugin that requires the external library should provide a link to the homepage of that library or, even better, directly to that library's download page. Sometimes the plugin will specify a version for you to download, otherwise just download the latest version.
  • Extract the files - If the file you downloaded is an archive, i.e. its file extension is .zip or .tar.gz, you will need to extract it first. On Windows, use a program like 7-zip to extract it. On the Mac, you can use Stuffit Expander. For *nix systems, use the command line: tar -zxvf filename.tar.gz. After extracting the file, you should see multiple files or a single folder with the library's name.
  • Upload the library - Inside the e107_web/lib/ directory create a new directory with the e107 machine name of the library. The machine name should be provided by the plugin that requires it, sometimes implicitly as in "Install the foo library!" (in that case the machine name would be foo). Upload the library files into the directory you have just created. If the library consists of a directory, which you have just extracted, upload the entire directory into the e107_web/lib/machine_name directory.
  • Install the other plugin - Now you should be able to install the plugin that requires the external library.

The ideas and design behind Library Manager

External libraries should not be committed to the source code of plugin/theme

Reasoning
  • Policy conflicts.
  • Plugins and themes and their release cycles should not be affected by the release cycles of external libraries.
Effect

Libraries need to be obtained separately from e107 plugins and themes. For now this has to be done manually.

Libraries should not reside in plugin folders

Reasoning
  • Best practices for plugin upgrades dictate to delete the old plugin folder before the upgrade. This removes any libraries inside of that folder.
  • Multiple plugins can implement the same library.
Effect

The best practice is to place libraries into a e107_web/lib directory.

Library Manager needs to be able to detect a library's version

Reasoning

Release cycles of e107 plugins and themes can be different than the release cycles of external libraries.

Effect

Library Manager supports version detection of libraries and provides a library's version information to plugins. Plugins implementing libraries can provide version-specific integration code or at least bail out in case of incompatible versions.

The current code flow is:

<?php
$library = e107::library('detect', 'example_library');
$version = $library['version'];
?>

Only one version of a library can be installed per site

Reasoning

If two different versions of the same library are installed, there is no way to guarantee that they will not both be loaded on the same page. If that were the case, visual errors could appear in case of CSS libraries, functional errors in case of JavaScript libraries and fatal errors in case of PHP libraries.

Library Manager needs meta information about libraries

  • A specific "machine name" for plugins to reference the library by.
  • Name, Website and Download link for the Library Manager's user interface.
  • Information how to detect the version of the library (see above)
  • Files that belong to this library. Note that since this information can vary between library versions. Also some libraries come with different 'variants'. For example a 'source code variant' and a 'minified variant'. Or TinyMCE, for instance, comes with a special 'jQuery-based variant'.
  • Plugin's and theme's integration files to load alongside the library.
  • Library dependencies.

See the API documentation for config() method in e107_plugins/_blank/e_library.php file for a detailed explanation of the information currently needed.

There are currently two ways to declare this information:

  • Implementing your own class with config() method in a plugin with e_library.php file
  • Implementing your own class with config() method in a theme with theme_library.php file

Using Library Manager (as a plugin-developer)

Declaration

Library Manager includes a library registry, so if you want to use an external library in your plugin, you need to make it known first. You can do this by implementing config() method in e_library.php file of your plugin for your library, which users then have to download.

Using e_library.php file and implementing config() method
<?php
/**
 * @file
 * Provides information about external libraries.
 */

/**
 * Class PLUGIN_library.
 */
class PLUGIN_library
{

	/**
	 * Return information about external libraries.
	 */
	function config()
	{
		// A very simple library. No changing APIs (hence, no versions), no variants. 
		// Expected to be extracted into 'e107_web/lib/simple'.
       	$libraries['simple'] = array(
       		'name'              => 'Simple library',
       		'vendor_url'        => 'http://example.com/simple',
       		'download_url'      => 'http://example.com/simple',
       		'version_arguments' => array(
       			'file'    => 'readme.txt',
       			// Best practice: Document the actual version strings for later reference.
       			// 1.x: Version 1.0
       			'pattern' => '/Version (\d+)/',
       			'lines'   => 5,
       		),
       		'files'             => array(
       			'js'  => array(
       				'simple.js',
       			),
       			'css' => array(
       				'simple.css',
       			),
       		),
       	);

		return $libraries;
	}

}
Version detection

Version detection is using regular expressions. If you'd like to bypass the version detection regex you can replace the version_arguments array with a callback as demonstrated below:

<?php
/**
 * @file
 * Provides information about external libraries.
 */

/**
 * Class PLUGIN_library.
 */
class PLUGIN_library
{

	/**
	 * Return information about external libraries.
	 */
	function config()
	{
		// A very simple library. No changing APIs (hence, no versions), no variants. 
		// Expected to be extracted into 'e107_web/lib/simple'.
       	$libraries['simple'] = array(
       		'name'              => 'Simple library',
       		'vendor_url'        => 'http://example.com/simple',
       		'download_url'      => 'http://example.com/simple',
			'version callback' => 'simple_version_callback',
       		'files'             => array(
       			'js'  => array(
       				'simple.js',
       			),
       			'css' => array(
       				'simple.css',
       			),
       		),
       	);

		return $libraries;
	}

	function simple_version_callback() {
		// Use some fancy magic to get the version number... or don't.
		return TRUE;
	}

}
Loading

To load the library from inside your plugin (i.e in your e_header.php file), simply do:

<?php
e107::library('load', $name);
?>

Usually, you'll want to do something after the library has been loaded. Because you cannot always depend on the library being installed you have to check first if the loading was actually successful:

<?php
// Try to load the library and check if that worked.
if (($library = e107::library('load', $name)) && !empty($library['loaded'])) {
	// Do something with the library here.
}
?>
Detection

If you just want to check whether the library is installed, but don't want to load it right away, you can use:

<?php
$library = e107::library('detect', $name);
?>

Similar to checking whether the library was loaded above, we can then check if the library is installed:

<?php
if (($library = e107::library('detect', $name)) && !empty($library['installed'])) {
	// The library is installed. Awesome!
}
else
{
	// Something went wrong. :(
	// This contains a short status code of what went wrong, such as 'not found'.
	$error = $library['error'];
	// This contains a detailed error message.
	$error_message = $library['error_message'];
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment