include.module in Include 8
Same filename and directory in other branches
The Include module manages files on the include_files path.
File
include.moduleView source
<?php
/**
* @file
* The Include module manages files on the include_files path.
*/
/**
* Implements hook_init().
*
* Add the include files repository to the include_files path, if needed.
* @see include_set_root(), include_clear_root()
*/
function include_init() {
if (variable_get('include_set_root', FALSE)) {
include_set_root();
}
}
/**
* Returns the absolute path of the include files repository.
*
* This defaults to conf_path() . '/files/include' but may be customized
* by setting the 'include_root' variable and/or the default file scheme.
*/
function include_get_root() {
return variable_get('include_root', drupal_realpath(file_build_uri('')) . '/include');
}
/**
* Appends the include files repository to the include_path.
*
* This function should only be called when a file in the repository is
* needed, and cannot be found in the regular include_path. This sets the
* 'include_set_root' variable to TRUE, which ensures that this function runs
* again on every non-cached page request.
* @see include_init()
*/
function include_set_root() {
static $done = FALSE;
if ($done || cache_get('include_error', 'cache_menu')) {
return;
}
if (!variable_get('include_set_root', FALSE)) {
watchdog('include', 'Adding directory: %path to include path.', array(
'%path' => include_get_root(),
), WATCHDOG_NOTICE);
// Setting the include_set_root variable ensures that the include_path gets
// set in the include_init() function.
variable_set('include_set_root', $done = TRUE);
}
set_include_path(implode(PATH_SEPARATOR, array_unique(array_merge(explode(PATH_SEPARATOR, get_include_path()), array(
include_get_root(),
)))));
}
/**
* Clear the include files repository from the include_path.
*
* This function is called when an unrecoverable error occurs. It sets the
* include_error flag to true, which prevents any further changes to the
* filesystem or include_path.
*/
function include_clear_root() {
static $done = FALSE;
if ($done || cache_get('include_error', 'cache_menu')) {
return;
}
set_include_path(implode(PATH_SEPARATOR, array_diff(explode(PATH_SEPARATOR, get_include_path()), array(
include_get_root(),
))));
// Clearing the include_set_root variable prevents future attempts to set the
// include_path in include_init().
variable_del('include_set_root');
// Don't try this again unless something changes.
cache_set('include_error', TRUE, 'cache_menu');
}
/**
* Verifies that a file exists on the include path.
*
* @param $filename
* The filename to verify, relative to the include path.
*
* @param $cache
* (optional) FALSE to ignore previously-cached results. Defaults to TRUE.
*
* @return
* TRUE if the file exists; otherwise FALSE.
*/
function include_verify($filename, $cache = TRUE) {
$files =& drupal_static(__FUNCTION__, array());
if ($cache && isset($files[$filename])) {
return $files[$filename];
}
if ($fd = @fopen($filename, 'r', TRUE)) {
fclose($fd);
return $files[$filename] = TRUE;
}
return $files[$filename] = FALSE;
}
/**
* Verifies or installs a file or directory into the include repository.
*
* @param $path
* The target path to install, relative to the include file root. If $path
* is empty or ends in a trailing slash, it is interpreted as a directory
* name, and both $source and $type are ignored.
* @param $source
* (optional) The file data, or a uri where it may be found. If unset or
* empty, then $path is a directory name, and $type is ignored.
* @param $type
* (optional) A string which determines how $source is to be interpreted.
* Must be one of the following:
* - dir: $path is a directory name, and $source is ignored.
* - file: (Default) drupal_realpath($source) is a local file.
* - url: url($source) is a downloadable url.
* - string: $source is a string containing the file data.
*
* @return
* TRUE if the file was successfully installed; otherwise FALSE.
*/
function include_check_path($path, $source = NULL, $type = 'file') {
if (empty($source) || substr($path, -1) === '/') {
$type = 'dir';
}
$path = trim($path, '/');
if (empty($path)) {
$type = 'dir';
}
elseif ($path == '.') {
$type = 'dir';
$path = '';
}
elseif ($path == '..') {
return TRUE;
}
elseif ($type != 'dir' && include_verify($path)) {
return TRUE;
}
elseif (cache_get('include_error', 'cache_menu')) {
// Something went wrong with previous installs; abort.
return FALSE;
}
elseif ($type != 'dir' && !include_check_path(dirname($path))) {
return FALSE;
}
$target = include_get_root() . '/' . $path;
$args = array(
'%function' => __FUNCTION__,
'%source' => $source,
'%path' => $path,
'%target' => $target,
);
switch ($type) {
case 'dir':
if (!file_prepare_directory($target, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
drupal_set_message(t('Could not create directory: %target. Check permissions.', $args), 'error');
watchdog('include', 'Could not create directory: %target.', $args, WATCHDOG_ERROR);
return FALSE;
}
break;
case 'file':
if (!($source_path = drupal_realpath($source))) {
drupal_set_message(t('File not found: %source', $args), 'error');
watchdog('include', 'File not found: %source', $args, WATCHDOG_ERROR);
return FALSE;
}
elseif (!copy($source_path, $target)) {
drupal_set_message(t('Could not copy file from (%source) to (%target). Check permissions.', $args), 'error');
watchdog('include', 'Could not copy file from (%source) to (%target)', $args, WATCHDOG_ERROR);
return FALSE;
}
break;
case 'url':
if (!($args['%source'] = url($source))) {
drupal_set_message(t('Could not resolve (%source) to a download url.', $args), 'error');
watchdog('include', 'Could not resolve (%source) to a download url.', $args, WATCHDOG_ERROR);
return FALSE;
}
elseif (!($response = drupal_http_request($args['%source']))) {
drupal_set_message(t('Could not open url (%source).', $args), 'error');
watchdog('include', 'Could not open url (%source).', $args, WATCHDOG_ERROR);
return FALSE;
}
elseif (!empty($response->error)) {
$args['@error'] = $response->error;
drupal_set_message(t('Error downloading (%source): @error', $args), 'error');
watchdog('include', 'Error downloading (%source): @error', $args, WATCHDOG_ERROR);
return FALSE;
}
$source = $response->data;
// Fall-through and share code with case 'string'.
case 'string':
if (!($args['%count'] = strlen($source))) {
drupal_set_message(t('Source file at (%source) is empty.', $args), 'error');
watchdog('include', 'Source file at (%source) is empty.', $args, WATCHDOG_ERROR);
return FALSE;
}
elseif ($args['%count'] != file_put_contents($target, $source)) {
drupal_set_message(t('Could not write (%count) bytes to file: (%target). Disk full?', $args), 'error');
watchdog('include', 'Could not write (%count) bytes to file: (%target).', $args, WATCHDOG_ERROR);
return FALSE;
}
break;
default:
// Modules may implement hook_include_install_HOOK().
$modules = module_implements("include_install_{$type}");
if (empty($modules)) {
drupal_set_message(t('No installer found for include type (%type). Check your dependencies.', $args), 'error');
watchdog('include', 'No installer found for include type (%type).', $args, WATCHDOG_CRITICAL);
return FALSE;
}
foreach ($modules as $module) {
$function = $module . '_include_install_' . $type;
if (!$function($path, $source)) {
// The hook function is responsible for its own error reporting.
return FALSE;
}
}
// Each hook function is responsible for calling
// include_set_root() and include_verify() if necessary.
return TRUE;
}
if (empty($error) && $type != 'dir') {
// A file was installed; add the include file repository to the PHP
// include_path and verify that the newly-installed file can be found.
include_set_root();
if (!include_verify($path, FALSE)) {
include_clear_root();
$args['%dir'] = include_get_root();
$args['!include_path'] = url('http://php.net/manual/ini.core.php#ini.include-path');
$args['!set_include_path'] = url('http://php.net/set_include_path');
$args['!include'] = url('admin/modules', array(
'fragment' => 'edit-modules-other-include-enable',
));
drupal_set_message(t('The file at %path (realpath %target) could not be found, even after adding %dir to the PHP <a href="!include_path">include_path</a>. Your hosting provider may have disabled the <a href="!set_include_path">set_include_path</a> function. An error flag has been set, and no further attempts will be made, until the <a href="!include">Include</a> module is disabled and then re-enabled.', $args), 'error');
watchdog('include', 'Error including a downloaded file. Auto-downloading has been disabled.', WATCHDOG_CRITICAL);
return FALSE;
}
else {
drupal_set_message(t('Created include %path.', $args));
}
}
if (empty($error)) {
return TRUE;
}
watchdog('include', "Error in %function function: {$error}", $args, $error_level);
return FALSE;
}
Functions
Name | Description |
---|---|
include_check_path | Verifies or installs a file or directory into the include repository. |
include_clear_root | Clear the include files repository from the include_path. |
include_get_root | Returns the absolute path of the include files repository. |
include_init | Implements hook_init(). |
include_set_root | Appends the include files repository to the include_path. |
include_verify | Verifies that a file exists on the include path. |