Index: includes/bootstrap.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v retrieving revision 1.286 diff -u -p -r1.286 bootstrap.inc --- includes/bootstrap.inc 6 Jun 2009 20:15:23 -0000 1.286 +++ includes/bootstrap.inc 10 Jun 2009 19:09:40 -0000 @@ -731,7 +731,11 @@ function drupal_load($type, $name) { $filename = drupal_get_filename($type, $name); if ($filename) { - include_once DRUPAL_ROOT . '/' . $filename; + // If a module does not provide a .module file, $filename points to + // the .info file. Do not attempt to load it. + if (strpos($filename, '.info') === FALSE) { + include_once DRUPAL_ROOT . '/' . $filename; + } $files[$type][$name] = TRUE; return TRUE; Index: modules/system/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.module,v retrieving revision 1.710 diff -u -p -r1.710 system.module --- modules/system/system.module 8 Jun 2009 04:28:19 -0000 1.710 +++ modules/system/system.module 10 Jun 2009 19:10:25 -0000 @@ -1256,7 +1256,7 @@ function system_update_files_database(&$ */ function _system_get_module_data() { // Find modules - $modules = drupal_system_listing('/\.module$/', 'modules', 'name', 0); + $modules = drupal_system_listing('/\.info$/', 'modules', 'name', 0); // Set defaults for module info. $defaults = array( @@ -1270,7 +1270,7 @@ function _system_get_module_data() { // Read info files for each module. foreach ($modules as $key => $module) { // Look for the info file. - $module->info = drupal_parse_info_file(dirname($module->filepath) . '/' . $module->name . '.info'); + $module->info = drupal_parse_info_file($module->filepath); // Skip modules that don't provide info. if (empty($module->info)) { @@ -1278,6 +1278,12 @@ function _system_get_module_data() { continue; } + // Modules don't need to provide a .module file. Store it only if it actually exists. + if (file_exists(dirname($module->filepath) . '/' . $module->name . '.module')) { + $module->filepath = dirname($module->filepath) . '/' . $module->name . '.module'; + $module->filename = basename($module->filepath); + } + // Merge in defaults and save. $modules[$key]->info = $module->info + $defaults; Index: modules/php/php.inc =================================================================== RCS file: modules/php/php.inc diff -N modules/php/php.inc --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ modules/php/php.inc 10 Jun 2009 19:10:26 -0000 @@ -0,0 +1,145 @@ +' . t('The PHP filter adds the ability to include PHP code in posts. PHP is a general-purpose scripting language widely-used for web development; the content management system used by this website has been developed using PHP.') . '

'; + $output .= '

' . t('Through the PHP filter, users with the proper permission may include custom PHP code within a page of the site. While this is a powerful and flexible feature if used by a trusted user with PHP experience, it is a significant and dangerous security risk in the hands of a malicious user. Even a trusted user may accidentally compromise the site by entering malformed or incorrect PHP code. Only the most trusted users should be granted permission to use the PHP filter, and all PHP code added through the PHP filter should be carefully examined before use.') . '

'; + $output .= '

' . t('Drupal.org offers some example PHP snippets, or you can create your own with some PHP experience and knowledge of the Drupal system.', array('@drupal' => url('http://drupal.org'), '@php-snippets' => url('http://drupal.org/handbook/customization/php-snippets'))) . '

'; + $output .= '

' . t('For more information, see the online handbook entry for PHP module.', array('@php' => 'http://drupal.org/handbook/modules/php/')) . '

'; + return $output; + } +} + +/** + * Implement hook_perm(). + */ +function php_perm() { + return array( + 'use PHP for settings' => array( + 'title' => t('Use PHP for settings'), + 'description' => t('Enter PHP in settings fields where PHP is allowed. %warning', array('%warning' => t('Warning: Give to trusted roles only; this permission has security implications.'))), + ), + ); +} + +/** + * Evaluate a string of PHP code. + * + * This is a wrapper around PHP's eval(). It uses output buffering to capture both + * returned and printed text. Unlike eval(), we require code to be surrounded by + * tags; in other words, we evaluate the code as if it were a stand-alone + * PHP file. + * + * Using this wrapper also ensures that the PHP code which is evaluated can not + * overwrite any variables in the calling code, unlike a regular eval() call. + * + * @param $code + * The code to evaluate. + * @return + * A string containing the printed output of the code, followed by the returned + * output of the code. + */ +function php_eval($code) { + global $theme_path, $theme_info, $conf; + + // Store current theme path. + $old_theme_path = $theme_path; + + // Restore theme_path to the theme, as long as php_eval() executes, + // so code evaluated will not see the caller module as the current theme. + // If theme info is not initialized get the path from theme_default. + if (!isset($theme_info)) { + $theme_path = drupal_get_path('theme', $conf['theme_default']); + } + else { + $theme_path = dirname($theme_info->filename); + } + + ob_start(); + print eval('?>' . $code); + $output = ob_get_contents(); + ob_end_clean(); + + // Recover original theme path. + $theme_path = $old_theme_path; + + return $output; +} + +/** + * Implement hook_filter_tips(). + */ +function php_filter_tips($delta, $format, $long = FALSE) { + global $base_url; + if ($delta == 0) { + switch ($long) { + case 0: + return t('You may post PHP code. You should include <?php ?> tags.'); + case 1: + $output = '

' . t('Using custom PHP code') . '

'; + $output .= '

' . t('Custom PHP code may be embedded in some types of site content, including posts and blocks. While embedding PHP code inside a post or block is a powerful and flexible feature when used by a trusted user with PHP experience, it is a significant and dangerous security risk when used improperly. Even a small mistake when posting PHP code may accidentally compromise your site.') . '

'; + $output .= '

' . t('If you are unfamiliar with PHP, SQL, or Drupal, avoid using custom PHP code within posts. Experimenting with PHP may corrupt your database, render your site inoperable, or significantly compromise security.') . '

'; + $output .= '

' . t('Notes:') . '

'; + $output .= ''; + $output .= '

' . t('A basic example: Creating a "Welcome" block that greets visitors with a simple message.') . '

'; + $output .= ''; + $output .= '

' . t('Drupal.org offers some example PHP snippets, or you can create your own with some PHP experience and knowledge of the Drupal system.', array('@drupal' => url('http://drupal.org'), '@php-snippets' => url('http://drupal.org/handbook/customization/php-snippets'))) . '

'; + return $output; + } + } +} + +/** + * Implement hook_filter(). Contains a basic PHP evaluator. + * + * Executes PHP code. Use with care. + */ +function php_filter($op, $delta = 0, $format = -1, $text = '') { + switch ($op) { + case 'list': + return array(0 => t('PHP evaluator')); + case 'no cache': + // No caching for the PHP evaluator. + return $delta == 0; + case 'description': + return t('Executes a piece of PHP code. The usage of this filter should be restricted to administrators only!'); + case 'process': + return php_eval($text); + default: + return $text; + } +} + + + Index: modules/php/php.info =================================================================== RCS file: /cvs/drupal/drupal/modules/php/php.info,v retrieving revision 1.7 diff -u -p -r1.7 php.info --- modules/php/php.info 8 Jun 2009 09:23:53 -0000 1.7 +++ modules/php/php.info 10 Jun 2009 19:10:26 -0000 @@ -4,6 +4,6 @@ description = Allows embedded PHP code/s package = Core version = VERSION core = 7.x -files[] = php.module +files[] = php.inc files[] = php.install files[] = php.test