summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Stein2011-06-02 18:49:06 (GMT)
committerJoel Stein2011-06-02 18:49:06 (GMT)
commit8b582b0183a1aad0d0a461a6fb6c00d0f0501cf8 (patch)
tree3ac16b5c630859da7a98268e55d0038685b31a9e
parentbefc0d5f6f4de23cfc8324456f66f7bd0c6726e4 (diff)
Added test suite; renamed skin_save variable to skin_cache; added skin_directory variable; added skin_clear_cache function; moved from managed to unmanaged storage of skin files.7.x-1.37.x-1.x
-rw-r--r--skin.admin.inc32
-rw-r--r--skin.install14
-rwxr-xr-xskin.module33
-rw-r--r--tests/skin_test.info8
-rw-r--r--tests/skin_test.module46
-rw-r--r--tests/skin_test.test91
6 files changed, 204 insertions, 20 deletions
diff --git a/skin.admin.inc b/skin.admin.inc
index 9c328c6..2337ee5 100644
--- a/skin.admin.inc
+++ b/skin.admin.inc
@@ -10,16 +10,22 @@ function skin_settings_form($form, &$form_state) {
'#description' => t("Enter each path you want skinned, one per line. The '*' character is a wildcard. %front is the front page.", array('%front' => '<front>')),
'#default_value' => variable_get('skin_paths', ''),
);
- $form['skin_save'] = array(
+ $form['skin_cache'] = array(
'#type' => 'radios',
- '#title' => t('CSS and Javascript'),
- '#description' => t('Optimized CSS and Javascript files are frequently deleted, which could break your skin. You can save an additional copy of these files, so they persist until the next time you build your skin. These files are saved in the "skin" directory within your <a href="@files_url">file system path</a>. You can also adjust your optimization settings on the <a href="@performance_url">performance page</a>.', array('@files_url' => 'admin/config/file-system', '@performance_url' => url('admin/config/development/performance'))),
+ '#title' => t('Cache CSS and Javascript files'),
+ '#description' => t('Optimized CSS and Javascript files are frequently deleted, which could break your skin. You can cache copies of these files so they persist until the next time you build your skin. You can also adjust your optimization settings on the <a href="@url">performance page</a>.', array('@url' => url('admin/config/development/performance'))),
'#options' => array(
- 0 => "Don't save any files",
- 1 => "Save a copy of optimized CSS and JS files",
- 2 => "Save a copy of all CSS and JS files",
+ 0 => "Don't cache any files",
+ 1 => "Cache optimized CSS and JS files",
+ 2 => "Cache all CSS and JS files",
),
- '#default_value' => variable_get('skin_save', 1),
+ '#default_value' => variable_get('skin_cache', 1),
+ );
+ $form['skin_directory'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Skin directory'),
+ '#description' => t('The directory where copies of CSS and Javascript files are cached.'),
+ '#default_value' => variable_get('skin_directory', variable_get('file_public_path', conf_path() . '/files') . '/skin'),
);
$form['skin_clear_cache'] = array(
'#type' => 'checkbox',
@@ -31,10 +37,20 @@ function skin_settings_form($form, &$form_state) {
}
/**
+ * Settings form validate.
+ */
+function skin_settings_form_validate($form, &$form_state) {
+ // The directory must be defined if Skin is configured to cache files.
+ if ($form_state['values']['skin_cache'] > 0 and empty($form_state['values']['skin_directory'])) {
+ form_set_error('skin_directory', t('Please enter a skin directory.'));
+ }
+}
+
+/**
* Settings form submit.
*/
function skin_settings_form_submit($form, &$form_state) {
if ($form_state['values']['skin_clear_cache']) {
- file_unmanaged_delete_recursive('public://skin');
+ skin_clear_cache();
}
}
diff --git a/skin.install b/skin.install
index b96a2af..8bdb8fa 100644
--- a/skin.install
+++ b/skin.install
@@ -5,6 +5,18 @@
*/
function skin_uninstall() {
variable_del('skin_paths');
- variable_del('skin_save');
+ variable_del('skin_cache');
+ variable_del('skin_directory');
variable_del('skin_clear_cache');
}
+
+/**
+ * Deletes records of managed files, since we don't manage them in Skin.
+ * Updates variable name.
+ */
+function skin_update_7102() {
+ db_delete('file_managed')
+ ->condition('uri', 'public://skin%', 'LIKE')
+ ->execute();
+ variable_set('skin_cache', variable_get('skin_save', 1));
+}
diff --git a/skin.module b/skin.module
index 7a14e92..8429212 100755
--- a/skin.module
+++ b/skin.module
@@ -32,7 +32,7 @@ function skin_menu() {
function skin_help($path, $arg) {
switch ($path) {
case 'admin/config/skin':
- return '<p>' . t('This module makes it easy to create a "skin" of your theme. Define your paths below, visit your skinned pages, and view the source to save your skinned HTML.') . '</p>';
+ return '<p>' . t('This module makes it easy to create a "skin" of your theme. Define your paths below, visit your skinned pages, and view the source to copy your skinned HTML.') . '</p>';
}
}
@@ -50,6 +50,13 @@ function skin_exit() {
}
/**
+ * Clears the Skin file cache.
+ */
+function skin_clear_cache() {
+ file_unmanaged_delete_recursive(variable_get('skin_directory', variable_get('file_public_path', conf_path() . '/files') . '/skin'));
+}
+
+/**
* Manipulates the rendered HTML.
*
* $matches[0] - entire match
@@ -62,8 +69,12 @@ function _skin_replace_callback($matches) {
$url = $matches[2];
$parts = parse_url($url);
- // Skip if URL didn't parse, or it's just a URL fragment ("#").
- if (empty($parts) or (count($parts) == 1 and isset($parts['fragment']))) {
+ // Skip if URL didn't parse,
+ if (empty($parts)
+ // or if there's no path,
+ or (!isset($parts['path']))
+ // or if it's a "mailto" link.
+ or (isset($parts['scheme']) and $parts['scheme'] == 'mailto')) {
return $matches[0];
}
@@ -87,13 +98,13 @@ function _skin_replace_callback($matches) {
// It's a CSS or Javascript file.
if (in_array($extension, array('css', 'js'))) {
- $save = variable_get('skin_save', 1);
+ $cache = variable_get('skin_cache', 1);
$optimized = empty($parts['query']);
- $skin_uri = 'public://skin/' . $path;
- // Save the file.
- if ($save == 2 || ($save == 1 && $optimized)) {
- // Save file in directory resembling its original location.
- if (file_prepare_directory(dirname($skin_uri), FILE_CREATE_DIRECTORY)) {
+ $filename = variable_get('skin_directory', variable_get('file_public_path', conf_path() . '/files') . '/skin') . '/' . $path;
+ // Cache the file.
+ if ($cache == 2 || ($cache == 1 && $optimized)) {
+ // Cache file in directory resembling its original location.
+ if (file_prepare_directory(dirname($filename), FILE_CREATE_DIRECTORY)) {
// Optimized CSS files have resolved imports and prefixed paths.
// Unoptimized Javascript files don't need to be resolved.
if ($optimized || $extension == 'js') {
@@ -106,8 +117,8 @@ function _skin_replace_callback($matches) {
_drupal_build_css_path(NULL, $base_url . $base_path . dirname($path) . '/');
$contents = preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', '_drupal_build_css_path', $contents);
}
- if (file_save_data($contents, $skin_uri, FILE_EXISTS_REPLACE)) {
- $url = file_create_url($skin_uri);
+ if (file_unmanaged_save_data($contents, $filename, FILE_EXISTS_REPLACE)) {
+ $url = file_create_url($filename);
}
}
}
diff --git a/tests/skin_test.info b/tests/skin_test.info
new file mode 100644
index 0000000..b60fcc1
--- /dev/null
+++ b/tests/skin_test.info
@@ -0,0 +1,8 @@
+name = Skin Tests
+description = Test module for Skin.
+core = 7.x
+package = Testing
+dependencies[] = skin
+dependencies[] = simpletest
+files[] = skin_test.test
+hidden = TRUE \ No newline at end of file
diff --git a/tests/skin_test.module b/tests/skin_test.module
new file mode 100644
index 0000000..e1ab136
--- /dev/null
+++ b/tests/skin_test.module
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * Implements hook_menu().
+ */
+function skin_test_menu() {
+ $items['skin/test'] = array(
+ 'title' => 'Skin Test',
+ 'page callback' => 'skin_test_page',
+ 'access callback' => TRUE,
+ );
+ return $items;
+}
+
+/**
+ * Skin test page.
+ *
+ * This page needs to include various links and images. It also includes the
+ * login form by default (during testing).
+ */
+function skin_test_page() {
+ $output = '<p>' . l(t('Homepage link'), '<front>') . '</p>';
+ $output .= '<p><a href="relative">' . t('Relative Link') . '</a></p>';
+ $output .= '<p><a href="#">'. t('Anchor link') . '</a></p>';
+ $output .= '<p>' . l(t('Email link'), 'mailto:test@example.com') . '</p>';
+ $output .= '<p><img src="' . url('misc/druplicon.png') . '" longdesc="' . url('skin/test') . '" /></p>';
+ return $output;
+}
+
+/**
+ * Implements hook_css_alter().
+ *
+ * Don't optimize system.base.css, so we can test it separately.
+ */
+function skin_css_alter(&$css) {
+ $css['modules/system/system.base.css']['preprocess'] = FALSE;
+}
+
+/**
+ * Implements hook_js_alter().
+ *
+ * Don't optimize drupal.js, so we can test it separately.
+ */
+function skin_js_alter(&$javascript) {
+ $javascript['misc/drupal.js']['preprocess'] = FALSE;
+}
diff --git a/tests/skin_test.test b/tests/skin_test.test
new file mode 100644
index 0000000..bbfbaa9
--- /dev/null
+++ b/tests/skin_test.test
@@ -0,0 +1,91 @@
+<?php
+
+class SkinTestCase extends DrupalWebTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => t('Skin tests'),
+ 'description' => t('Ensure that Skin works.'),
+ 'group' => t('Skin'),
+ );
+ }
+
+ /**
+ * Setup our environment. We have a page at "skin/test" which we'll test.
+ * We also want to optimize CSS and Javascript files.
+ */
+ public function setUp() {
+ parent::setUp('skin', 'skin_test');
+ variable_set('skin_paths', 'skin/test');
+ variable_set('preprocess_css', 1);
+ variable_set('preprocess_js', 1);
+ $this->skin_public_files = variable_get('file_public_path', conf_path() . '/files');
+ $this->skin_directory = variable_get('skin_directory', $this->skin_public_files . '/skin');
+ }
+
+ /**
+ * Tests conversion of URLs to absolute URLs.
+ */
+ public function testAbsoluteURLs() {
+ $this->drupalGet('skin/test');
+
+ $this->assertRaw(l(t('Homepage link'), '<front>', array('absolute' => TRUE)), t('Homepage link is absolute.'));
+ $this->assertLinkByHref(url('skin/relative', array('absolute' => TRUE)), 0, t('Relative link is absolute.'));
+ $this->assertLinkByHref('mailto:test@example.com', 0, t('Mailto link was not rewritten.'));
+ $this->assertNoPattern('|href="' . url('<front>') . '|', t('No relative links or CSS references exist.'));
+ $this->assertNoPattern('|@import url\("' . url('<front>') . '|', t('No relative CSS import references exist.'));
+ $this->assertPattern('|src="' . file_create_url('misc/druplicon.png') . '"|', t('Image reference is absolute.'));
+ $this->assertNoPattern('|src="' . url('<front>') . '|', t('No relative images or Javascript references exist.'));
+ $this->assertPattern('|longdesc="' . url('skin/test', array('absolute' => TRUE)) . '"|', t('Image long description is absolute.'));
+ $this->assertPattern('|action="' . url('skin/test', array('absolute' => TRUE)) . '"|', t('Form action is absolute.'));
+ }
+
+ /**
+ * Tests saving of optimized CSS and Javascript files.
+ */
+ public function testSavingOptimizedFiles() {
+ variable_set('skin_cache', 1);
+
+ $this->drupalGet('skin/test');
+
+ $this->assertTrue(file_exists($this->skin_directory . '/' . $this->skin_public_files . '/css'), t('Optimized CSS files are cached.'));
+ $this->assertTrue(file_exists($this->skin_directory . '/' . $this->skin_public_files . '/js'), t('Optimized Javascript files are cached.'));
+
+ $this->assertFalse(file_exists($this->skin_directory . '/modules/system/system.base.css'), t('Unoptimized CSS files are not cached.'));
+ $this->assertFalse(file_exists($this->skin_directory . '/misc/drupal.js'), t('Unoptimized Javascript files are not cached.'));
+
+ drupal_flush_all_caches();
+
+ $this->assertTrue(file_exists($this->skin_directory . '/' . $this->skin_public_files . '/css'), t('Optimized CSS files are cached.'));
+ $this->assertTrue(file_exists($this->skin_directory . '/' . $this->skin_public_files . '/js'), t('Optimized Javascript files are cached.'));
+
+ skin_clear_cache();
+
+ $this->assertFalse(file_exists($this->skin_directory), t('Optimized CSS and Javascript files are not cached.'));
+ }
+
+ /**
+ * Tests saving of all CSS and Javascript files.
+ */
+ public function testSavingAllFiles() {
+ variable_set('skin_cache', 2);
+
+ $this->drupalGet('skin/test');
+
+ $this->assertTrue(file_exists($this->skin_directory . '/modules/system/system.base.css'), t('CSS files are cached.'));
+ $this->assertTrue(file_exists($this->skin_directory . '/misc/drupal.js'), t('Javascript files are cached.'));
+
+ $css_contents = file_get_contents($this->skin_directory . '/modules/system/system.base.css');
+ $this->assertTrue(strpos($css_contents, url('misc/throbber.gif', array('absolute' => TRUE))) !== FALSE, 'CSS image references are absolute.');
+
+ drupal_flush_all_caches();
+
+ $this->assertTrue(file_exists($this->skin_directory . '/modules/system/system.base.css'), t('CSS files are cached.'));
+ $this->assertTrue(file_exists($this->skin_directory . '/misc/drupal.js'), t('Javascript files are cached.'));
+
+ skin_clear_cache();
+
+ $this->assertFalse(file_exists($this->skin_directory), t('CSS and Javascript files are not cached.'));
+ }
+
+}