composer_manager.module in Composer Manager 6
Same filename and directory in other branches
Provides consolidated management of third-party Composer-compatible packages required by contributed modules.
File
composer_manager.moduleView source
<?php
/**
* @file
* Provides consolidated management of third-party Composer-compatible packages
* required by contributed modules.
*/
/**
* Implements hook_init().
*/
function composer_manager_init() {
try {
composer_manager_register_autoloader();
} catch (\RuntimeException $e) {
// @see https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drupal_is_cli/7
if (!(!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0))) {
watchdog('composer_manager', $e
->getMessage(), array(), WATCHDOG_ERROR);
}
}
}
/**
* Implements hook_menu().
*/
function composer_manager_menu() {
$items = array();
$items['admin/settings/composer-manager'] = array(
'title' => 'Composer Manager',
'description' => 'View the status of packages managed by Composer and configure the location of the composer.json file and verdor directory.',
'page callback' => 'composer_manager_packages_page',
'access arguments' => array(
'administer site configuration',
),
'file' => 'composer_manager.admin.inc',
);
$items['admin/settings/composer-manager/packages'] = array(
'title' => 'Packages',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/settings/composer-manager/settings'] = array(
'title' => 'Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'composer_manager_settings_form',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'composer_manager.admin.inc',
'type' => MENU_LOCAL_TASK,
);
return $items;
}
/**
* Implements hook_form_FORM_ID_alter() for system_modules().
*/
function composer_manager_form_system_modules_alter(&$form, &$form_state) {
$form['#submit'][] = 'composer_manager_system_modules_submit';
$form['#module_list'] = module_list();
}
/**
* Form submission handler for system_modules().
*
* Determines what modules have been enabled or disabled and rewrites the
* consolidated composer.json file if one of the modules has dependencies.
*
* @see composer_manager_write_if_changed()
*/
function composer_manager_system_modules_submit($form, &$form_state) {
$module_list = module_list();
// Get list of modules that have been enabled or disabled.
$enabled = array_diff_key($module_list, $form['#module_list']);
$disabled = array_diff_key($form['#module_list'], $module_list);
$modules = array_merge($enabled, $disabled);
composer_manager_write_if_changed($modules);
}
/**
* Writes the composer.json file if one of the enabled / disabled modules
* has a composer.json file.
*
* This is a primitive check to ensure that the composer.json file is built only
* when it has changes. This check always passes when run via the command line,
* as it is assumed that Drush is being used to enable or disable the the
* modules. A static boolean is also set flagging whether one or more modules
* being acted on contains a composer.json file, which is used in Drush hooks.
*
* @param array $modules
* The enabled / disabled modules being scanned for a composer.json file.
*/
function composer_manager_write_if_changed(array $modules) {
$changed =& composer_manager_static(__FUNCTION__, FALSE);
if (variable_get('composer_manager_autobuild_file', 1) || drupal_is_cli()) {
if (composer_manager_packages_have_changed($modules)) {
$changed = TRUE;
composer_manager_write_file();
}
}
}
/**
* Returns TRUE if at least one passed modules has a composer.json file or
* implements hook_composer_json_alter(). These conditions indicate that the
* consolidated composer.json file has likely changed.
*
* @param array $modules
* The list of modules being scanned for composer.json files, usually a list
* of modules that were installed or uninstalled.
*
* @return bool
*/
function composer_manager_packages_have_changed(array $modules) {
foreach ($modules as $module) {
// Check if the module has a composer.json file.
$module_path = drupal_get_path('module', $module);
if (file_exists($module_path . '/composer.json')) {
return TRUE;
}
// Check if the module implements hook_composer_json_alter().
if (module_hook($module, 'composer_json_alter')) {
return TRUE;
}
}
return FALSE;
}
/**
* Returns TRUE if at least one module has a composer.json file.
*
* @param array $modules
* An array of modules being checked.
*
* @return boolean
*
* @deprecated since 6.x-1.6 https://www.drupal.org/node/2297415
*
* @see composer_manager_packages_have_changed()
*/
function composer_manager_has_composer_file(array $modules) {
foreach ($modules as $module) {
$module_path = drupal_get_path('module', $module);
if (file_exists($module_path . '/composer.json')) {
return TRUE;
}
}
return FALSE;
}
/**
* Registers the autoloader for all third-party packages.
*/
function composer_manager_register_autoloader() {
static $registered = FALSE;
if (!$registered) {
$autoloader = composer_manager_vendor_dir() . '/autoload.php';
if (!file_exists($autoloader)) {
$message = t('Autoloader not found: @file', array(
'@file' => $autoloader,
));
throw new \RuntimeException($message);
}
$registered = TRUE;
require $autoloader;
}
}
/**
* Writes the consolidated composer.json file for all modules that require
* third-party packages managed by Composer.
*
* @return bool
*/
function composer_manager_write_file() {
// Ensure only one process runs at a time. 10 seconds is more than enough.
// It is rare that a conflict will happen, and it isn't mission critical that
// we wait for the lock to release and regenerate the file again.
if (!lock_acquire(__FUNCTION__, 10)) {
return FALSE;
}
require_once __DIR__ . '/composer_manager.writer.inc';
try {
$data = composer_manager_fetch_data();
$json = composer_manager_build_json($data);
if ($json) {
$dir_uri = variable_get('composer_manager_file_dir', file_directory_path() . '/composer');
composer_manager_put_file($dir_uri, $json);
}
$success = TRUE;
} catch (\RuntimeException $e) {
$success = FALSE;
if (user_access('administer site configuration')) {
drupal_set_message(t('Error writing composer.json file'), 'error');
}
watchdog('composer_manager', $e
->getMessage(), array(), WATCHDOG_ERROR);
}
lock_release(__FUNCTION__);
return $success;
}
/**
* Returns the path to the vendor directory.
*
* @return string
*/
function composer_manager_vendor_dir() {
$vendor_dir = variable_get('composer_manager_vendor_dir', 'sites/all/vendor');
$is_absolute = 0 === strpos($vendor_dir, '/');
if (!$is_absolute) {
$vendor_dir = getcwd() . '/' . $vendor_dir;
}
return $vendor_dir;
}
/**
* @see https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drupal_static/7
*/
function &composer_manager_static($name, $default_value = NULL, $reset = FALSE) {
static $data = array(), $default = array();
// First check if dealing with a previously defined static variable.
if (isset($data[$name]) || array_key_exists($name, $data)) {
// Non-NULL $name and both $data[$name] and $default[$name] statics exist.
if ($reset) {
// Reset pre-existing static variable to its default value.
$data[$name] = $default[$name];
}
return $data[$name];
}
// Neither $data[$name] nor $default[$name] static variables exist.
if (isset($name)) {
if ($reset) {
// Reset was called before a default is set and yet a variable must be
// returned.
return $data;
}
// First call with new non-NULL $name. Initialize a new static variable.
$default[$name] = $data[$name] = $default_value;
return $data[$name];
}
// Reset all: ($name == NULL). This needs to be done one at a time so that
// references returned by earlier invocations of drupal_static() also get
// reset.
foreach ($default as $name => $value) {
$data[$name] = $value;
}
// As the function returns a reference, the return should always be a
// variable.
return $data;
}
Functions
Name | Description |
---|---|
composer_manager_form_system_modules_alter | Implements hook_form_FORM_ID_alter() for system_modules(). |
composer_manager_has_composer_file Deprecated | Returns TRUE if at least one module has a composer.json file. |
composer_manager_init | Implements hook_init(). |
composer_manager_menu | Implements hook_menu(). |
composer_manager_packages_have_changed | Returns TRUE if at least one passed modules has a composer.json file or implements hook_composer_json_alter(). These conditions indicate that the consolidated composer.json file has likely changed. |
composer_manager_register_autoloader | Registers the autoloader for all third-party packages. |
composer_manager_static | |
composer_manager_system_modules_submit | Form submission handler for system_modules(). |
composer_manager_vendor_dir | Returns the path to the vendor directory. |
composer_manager_write_file | Writes the consolidated composer.json file for all modules that require third-party packages managed by Composer. |
composer_manager_write_if_changed | Writes the composer.json file if one of the enabled / disabled modules has a composer.json file. |