less.module in Less CSS Preprocessor 6.2
Same filename and directory in other branches
Handles compiling of .less files.
The theme system allows for nearly all output of the Drupal system to be customized by user themes.
File
less.moduleView source
<?php
/**
* @file
* Handles compiling of .less files.
*
* The theme system allows for nearly all output of the Drupal system to be
* customized by user themes.
*/
define('LESS_PERMISSION', 'administer less');
/**
* Implements hook_menu().
*/
function less_menu() {
$items = array();
$items['admin/settings/less'] = array(
'title' => 'LESS settings',
'description' => 'Administer LESS settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'less_settings',
),
'access arguments' => array(
LESS_PERMISSION,
),
'file' => 'less.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
/**
* Implements hook_permission().
*/
function less_perm() {
return array(
LESS_PERMISSION,
);
}
/**
* Builds the less cache
*/
function _less_build(&$vars, $hook) {
$css = $vars['css'];
$less_devel = variable_get('less_devel', FALSE);
$less_dir = variable_get('less_dir', '');
// Flush compiled LESS files if developer mode is enabled
if (!$less_dir || $less_devel) {
$less_dir = _less_new_dir();
if ($less_devel && user_access(LESS_PERMISSION) && flood_is_allowed('less_devel_warning', 1)) {
flood_register_event('less_devel_warning');
drupal_set_message(t('LESS files are being regenerated on every request. Remember to <a href="!url">turn off</a> this feature on production websites.', array(
"!url" => url('admin/settings/less'),
)), 'status');
}
}
$less_path = file_directory_path() . '/less/' . $less_dir;
foreach ($css as $media => $types) {
foreach ($types as $type => $files) {
$files_keys = array_keys($files);
foreach ($files_keys as $key => $input_file) {
if (drupal_substr($input_file, -5) == '.less') {
$css_path = $less_path . '/' . dirname($input_file);
if (!is_dir($css_path) && !@mkdir($css_path, 0775, TRUE)) {
// There is a problem with the directory.
$param = array(
'%dir' => $css_path,
);
if (user_access(LESS_PERMISSION)) {
drupal_set_message(t('LESS could not create a directory in %dir', $param), 'error');
}
watchdog('LESS', t('LESS could not create a directory in %dir', $param), array(), WATCHDOG_ERROR);
return;
}
$output_file = $css_path . '/' . basename($input_file, '.less');
// correct file names of files not following the .css.less naming convention
if (drupal_substr($output_file, -4) != '.css') {
$output_file .= '.css';
}
if (!file_exists($output_file)) {
if (_less_inc()) {
$less = new lessc();
$contents = drupal_load_stylesheet($input_file, FALSE);
$base = base_path() . dirname($input_file) . '/';
_drupal_build_css_path(NULL, $base);
// Prefix all paths within this CSS file, ignoring external and absolute paths.
$data = preg_replace_callback('/url\\([\'"]?(?![a-z]+:|\\/+)([^\'")]+)[\'"]?\\)/i', '_drupal_build_css_path', $contents);
try {
$output_data = $less
->parse($data);
file_save_data($output_data, $output_file, FILE_EXISTS_REPLACE);
} catch (Exception $e) {
$message = 'LESS error: @message, %input_file';
$message_vars = array(
'@message' => $e
->getMessage(),
'%input_file' => $input_file,
);
watchdog('LESS', $message, $message_vars, WATCHDOG_ERROR);
if (user_access(LESS_PERMISSION)) {
drupal_set_message(t($message, $message_vars), 'error');
}
}
}
}
if (file_exists($output_file)) {
array_splice($files_keys, $key, 1, $output_file);
}
}
}
if (!empty($files)) {
$css[$media][$type] = array_combine($files_keys, $files);
}
}
}
if ($vars['show_messages']) {
$vars['messages'] .= theme('status_messages');
}
$vars['css'] = $css;
$vars['styles'] = drupal_get_css($vars['css']);
}
/**
* Implements MODULE_preprocess_page().
*/
function less_preprocess_page(&$vars, $hook) {
_less_build($vars, $hook);
}
/**
* Implements MODULE_preprocess_maintenance_page().
*/
function less_preprocess_maintenance_page(&$vars, $hook) {
_less_build($vars, $hook);
}
/**
* Recursively delete a path.
*
* Lifted from imagecache, with thanks to dopry/drewish.
*/
function _less_recursive_delete($path) {
if (is_file($path) || is_link($path)) {
unlink($path);
}
elseif (is_dir($path)) {
$d = dir($path);
while (($entry = $d
->read()) !== FALSE) {
if ($entry == '.' || $entry == '..') {
continue;
}
$entry_path = $path . '/' . $entry;
_less_recursive_delete($entry_path);
}
$d
->close();
rmdir($path);
}
}
/**
* Implementation of hook_flush_caches().
*
* Flushes compiled LESS files during cache flush, except during cron.
*
* @return An array of cache table names.
*/
function less_flush_caches() {
$semaphore = variable_get('cron_semaphore', FALSE);
if (!$semaphore) {
_less_new_dir();
}
return array();
}
/**
* Helper function to create a new less dir.
*/
function _less_new_dir() {
$less_dir = uniqid('', TRUE);
$less_path = file_directory_path() . '/less/' . $less_dir;
@mkdir($less_path, 0775, TRUE);
variable_set('less_dir', $less_dir);
return $less_dir;
}
/**
* Implements hook_cron().
*/
function less_cron() {
$less_dir = variable_get('less_dir', '');
$found_files = file_scan_directory(file_directory_path() . '/less', '^.+$', array(
'.',
'..',
'CVS',
$less_dir,
), 0, FALSE);
foreach ($found_files as $found_file) {
_less_recursive_delete($found_file->filename);
}
}
function _less_inc() {
if (!class_exists('lessc', FALSE)) {
$include_locations = array(
'lessphp/lessc.inc.php',
);
// load libraries module for during install
module_load_include('module', 'libraries');
if (function_exists('libraries_get_path')) {
array_unshift($include_locations, libraries_get_path('lessphp') . '/lessc.inc.php');
}
foreach ($include_locations as $include_location) {
if (file_exists($include_location)) {
require_once $include_location;
break;
}
}
}
return class_exists('lessc', FALSE);
}
Functions
Name![]() |
Description |
---|---|
less_cron | Implements hook_cron(). |
less_flush_caches | Implementation of hook_flush_caches(). |
less_menu | Implements hook_menu(). |
less_perm | Implements hook_permission(). |
less_preprocess_maintenance_page | Implements MODULE_preprocess_maintenance_page(). |
less_preprocess_page | Implements MODULE_preprocess_page(). |
_less_build | Builds the less cache |
_less_inc | |
_less_new_dir | Helper function to create a new less dir. |
_less_recursive_delete | Recursively delete a path. |
Constants
Name![]() |
Description |
---|---|
LESS_PERMISSION | @file Handles compiling of .less files. |