added missing module fixer and updated imagecache_actions
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
README for the Image styleds admin Drupal module
|
||||
------------------------------------------------
|
||||
|
||||
Project page: http://drupal.org/project/imagecache_actions
|
||||
Project page: https://drupal.org/project/imagecache_actions
|
||||
|
||||
Current and past maintainers for Image styles admin:
|
||||
- fietserwin (http://drupal.org/user/750928)
|
||||
- fietserwin (https://drupal.org/user/750928)
|
||||
|
||||
|
||||
Release notes for 7.x-1.x-dev
|
||||
@@ -24,12 +24,12 @@ a test/showcase sute of styles. Finally, it allows everybody to test D8 image
|
||||
module features in real life.
|
||||
|
||||
This module is not a replacement for the features module
|
||||
(http://drupal.org/project/features). If you are serious about configuration
|
||||
(https://drupal.org/project/features). If you are serious about configuration
|
||||
management and want to distribute styles to other systems, use features.
|
||||
|
||||
Use this module for 1 time export/imports between different sites, "copy &
|
||||
paste" reuse within a site, and when reporting issues to the imagecache_actions
|
||||
issue queue.
|
||||
issue queue.
|
||||
|
||||
|
||||
TODO
|
||||
|
@@ -0,0 +1,52 @@
|
||||
table#image-styles {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
#image-styles th.style-name {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
#image-styles th.effects {
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
#image-styles th.settings {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
#image-styles td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#image-styles .expand.inner {
|
||||
background: transparent url(/misc/menu-collapsed.png) left 0.6em no-repeat;
|
||||
margin-left: -12px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
#image-styles .expanded.expand.inner {
|
||||
background: transparent url(/misc/menu-expanded.png) left 0.6em no-repeat;
|
||||
}
|
||||
|
||||
#image-styles .description {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#image-styles .description .inner {
|
||||
overflow: hidden; /* truncates descriptions if too long */
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
#image-styles .description .expanded.inner {
|
||||
overflow: visible;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
#image-styles .description .expanded .details {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#image-styles .description .expanded .separator {
|
||||
display: none;
|
||||
}
|
@@ -16,7 +16,9 @@
|
||||
*/
|
||||
function image_styles_admin_duplicate_page_callback($style) {
|
||||
$duplicate_style = image_styles_admin_duplicate($style);
|
||||
drupal_set_message(t('Style %name has been duplicated to %new_name.', array('%name' => $style['name'], '%new_name' => $duplicate_style['name'])));
|
||||
drupal_set_message(t('Style %name has been duplicated to %new_name.', array(
|
||||
'%name' => isset($style['label']) ? $style['label'] : $style['name'],
|
||||
'%new_name' => isset($duplicate_style['label']) ? $duplicate_style['label'] : $duplicate_style['name'])));
|
||||
drupal_goto('admin/config/media/image-styles');
|
||||
}
|
||||
|
||||
@@ -29,14 +31,19 @@ function image_styles_admin_duplicate_page_callback($style) {
|
||||
* The preferred name for the new style. If left empty, the new name will be
|
||||
* based on the name of the style to duplicate. In both cases and when
|
||||
* necessary, the new name will be made unique by adding some suffix to it.
|
||||
* @param string|null $new_style_label
|
||||
* The preferred label for the new style. If left empty, the new label will be
|
||||
* based on the label of the style to duplicate. If that one is also empty,
|
||||
* no label will be defined for the new style, so Drupal (>=7.23) will create
|
||||
* one.
|
||||
*
|
||||
* @return array
|
||||
* An image style array with the newly created copy of the given style.
|
||||
*
|
||||
* @see image_style_name_validate()
|
||||
*/
|
||||
function image_styles_admin_duplicate($style, $new_style_name = NULL) {
|
||||
// Find a unique name for copy.
|
||||
function image_styles_admin_duplicate($style, $new_style_name = NULL, $new_style_label = NULL) {
|
||||
// Find a unique name for the copy.
|
||||
// Step 1: Find the base: name without things like '-copy' or '-copy-1'
|
||||
$style_name_base = empty($new_style_name) ? $style['name'] : $new_style_name;
|
||||
if (preg_match('/-copy(-\d+)?$/', $style_name_base)) {
|
||||
@@ -58,6 +65,25 @@ function image_styles_admin_duplicate($style, $new_style_name = NULL) {
|
||||
}
|
||||
$style['name'] = $style_name;
|
||||
|
||||
// Step 4: Find a new label for the copy.
|
||||
if (isset($new_style_label) || isset($style['label'])) {
|
||||
$style_label = empty($new_style_label) ? $style['label'] : $new_style_label;
|
||||
$copy = t('copy');
|
||||
if (preg_match("/ $copy( \d+)?$/", $style_label)) {
|
||||
$style_label = substr($style_label, 0, strpos($style_label, " $copy"));
|
||||
}
|
||||
|
||||
// Step 4a: Add " copy" to it (if the name comes from the current style).
|
||||
if (empty($new_style_label)) {
|
||||
$style_label .= " $copy";
|
||||
}
|
||||
|
||||
// Step 4b: Make "unique" (based on the number added to the name)
|
||||
if ($i > 0) {
|
||||
$style['label'] .= " $i";
|
||||
}
|
||||
}
|
||||
|
||||
// Unset isid to save it as a new style.
|
||||
unset($style['isid']);
|
||||
$style = image_style_save($style);
|
||||
@@ -74,31 +100,35 @@ function image_styles_admin_duplicate($style, $new_style_name = NULL) {
|
||||
}
|
||||
|
||||
/**
|
||||
* drupal_get_form callback: form to export an image style.
|
||||
*
|
||||
* @param array $style
|
||||
* An image style array.
|
||||
*/
|
||||
* drupal_get_form callback: form to export an image style.
|
||||
*
|
||||
* @param array $form
|
||||
* @param array $form_state
|
||||
* @param array $style
|
||||
* An image style array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function image_styles_admin_export_form($form, $form_state, $style) {
|
||||
drupal_set_title(format_string('%page_name @style_name', array('%page_name' => t('Export image style'), '@style_name' => $style['name'])), PASS_THROUGH);
|
||||
drupal_set_title(format_string('%page_name @style_name',
|
||||
array('%page_name' => t('Export image style'), '@style_name' => isset($style['label']) ? $style['label'] : $style['name'])),
|
||||
PASS_THROUGH);
|
||||
$form['serialized_style'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#rows' => 5,
|
||||
'#title' => t('Image style export data'),
|
||||
'#default_value' => serialize($style),
|
||||
'#default_value' => image_styles_admin_export_serialize($style),
|
||||
'#attributes' => array('readonly' =>'readonly'),
|
||||
'#description' => t('Copy the contents of this field to the clipboard and, on another site, paste it in the textarea of an %page_title page.', array('%page_title' => t('Import image style'))),
|
||||
'#description' => t('Copy the contents of this field to the clipboard and, on another site, paste it in the textarea of an %page_title page.',
|
||||
array('%page_title' => t('Import image style'))),
|
||||
);
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* drupal_get_form callback: form to import an image style.
|
||||
*
|
||||
* @param array $style
|
||||
* An image style array.
|
||||
*/
|
||||
function image_styles_admin_import_form($form, $form_state) {
|
||||
function image_styles_admin_import_form($form/*, $form_state*/) {
|
||||
$form['serialized_style'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#rows' => 5,
|
||||
@@ -121,7 +151,8 @@ function image_styles_admin_import_form($form, $form_state) {
|
||||
* Callback to validate the import style form.
|
||||
*/
|
||||
function image_styles_admin_import_form_validate($form, &$form_state) {
|
||||
if (image_styles_admin_import_extract_style($form_state['values']['serialized_style']) === FALSE) {
|
||||
$import = image_styles_admin_unify_newlines($form_state['values']['serialized_style']);
|
||||
if (image_styles_admin_import_extract_style($import) === FALSE) {
|
||||
form_set_error('serialized_style', t('The %field cannot be imported as an image style.', array('%field' => t('Image style import data'))));
|
||||
}
|
||||
}
|
||||
@@ -130,19 +161,64 @@ function image_styles_admin_import_form_validate($form, &$form_state) {
|
||||
* Callback to process form submission of the import style form.
|
||||
*/
|
||||
function image_styles_admin_import_form_submit($form, &$form_state) {
|
||||
$style = image_styles_admin_import_extract_style($form_state['values']['serialized_style']);
|
||||
$import = image_styles_admin_unify_newlines($form_state['values']['serialized_style']);
|
||||
$style = image_styles_admin_import_extract_style($import);
|
||||
// Import the style by "duplicating" it, but prevent adding the -copy suffix
|
||||
// by passing the requested name as 2nd parameter.
|
||||
$new_style = image_styles_admin_duplicate($style, $style['name']);
|
||||
// by passing the requested name and label as 2nd and 3rd parameter.
|
||||
$new_style = image_styles_admin_duplicate($style, $style['name'], isset($style['label']) ? $style['label'] : NULL);
|
||||
if ($new_style['name'] === $style['name']) {
|
||||
drupal_set_message(t('Style %name has been imported.', array('%name' => $style['name'])));
|
||||
}
|
||||
else {
|
||||
drupal_set_message(t('Style %name has been imported as %new_name.', array('%name' => $style['name'], '%new_name' => $new_style['name'])));
|
||||
drupal_set_message(t('Style %name has been imported as %new_name.', array(
|
||||
'%name' => isset($style['label']) ? $style['label'] : $style['name'],
|
||||
'%new_name' => isset($new_style['label']) ? $new_style['label'] : $new_style['name'])));
|
||||
}
|
||||
drupal_goto('admin/config/media/image-styles');
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes image style data so it can be exported.
|
||||
*
|
||||
* @param array $style
|
||||
* An image style array.
|
||||
*
|
||||
* @return string
|
||||
* The serialized image style. Keys that are not needed for import are not
|
||||
* serialized.
|
||||
*/
|
||||
function image_styles_admin_export_serialize($style) {
|
||||
$style = array_intersect_key($style, array('name' => 0, 'label' => 0, 'effects' => 0));
|
||||
foreach ($style['effects'] as &$effect) {
|
||||
$effect = array_intersect_key($effect, array('weight' => 0, 'name' => 0, 'data' => 0));
|
||||
}
|
||||
|
||||
array_walk_recursive($style, function(&$value) {
|
||||
if (is_string($value)) {
|
||||
$value = image_styles_admin_unify_newlines($value);
|
||||
}
|
||||
});
|
||||
return serialize($style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unifies newlines in the string to the Unix newline standard.
|
||||
*
|
||||
* #2636314: textareas may convert newlines to the underlying OS style: convert
|
||||
* all new lines to Unix style before unserializing. As string length is in the
|
||||
* serialized data, we must ensure that we also do this on each array value
|
||||
* before serializing.
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
function image_styles_admin_unify_newlines($str) {
|
||||
$str = str_replace("\r\n", "\n", $str);
|
||||
$str = str_replace("\r", "\n", $str);
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unserializes and validates a string into image style data.
|
||||
*
|
||||
@@ -154,25 +230,31 @@ function image_styles_admin_import_form_submit($form, &$form_state) {
|
||||
* image style data.
|
||||
*/
|
||||
function image_styles_admin_import_extract_style($import) {
|
||||
$style = @unserialize($import);
|
||||
$style = unserialize($import);
|
||||
|
||||
// Check if the contents of the textarea could be unserialized into an array.
|
||||
if (!is_array($style)) {
|
||||
return FALSE;
|
||||
}
|
||||
// Check if the required keys are available, we will ignore the other.
|
||||
$style = array_intersect_key($style, array('name' => 0, 'effects' => 0));
|
||||
if (count($style) !== 2) {
|
||||
|
||||
// Filter out keys that we do not process.
|
||||
$style = array_intersect_key($style, array('name' => 0, 'label' => 0, 'effects' => 0));
|
||||
|
||||
// 'name' is required and must be "machine name" string.
|
||||
if (!isset($style['name']) || !is_string($style['name']) || preg_match('/[0-9a-z_\-]+/', $style['name']) !== 1) {
|
||||
return FALSE;
|
||||
}
|
||||
// 'name' must be "machine name" string
|
||||
if (!is_string($style['name']) || preg_match('/[0-9a-z_\-]+/', $style['name']) !== 1) {
|
||||
|
||||
// Optional 'label' must be a string.
|
||||
if (isset($style['label']) && !is_string($style['label'])) {
|
||||
return FALSE;
|
||||
}
|
||||
// 'effects' must be an array
|
||||
if (!is_array($style['effects'])) {
|
||||
|
||||
// 'effects' is required and must be an array.
|
||||
if (!isset($style['effects']) || !is_array($style['effects'])) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Check effects elements
|
||||
foreach ($style['effects'] as &$effect) {
|
||||
// an effect must be an array.
|
||||
@@ -197,6 +279,7 @@ function image_styles_admin_import_extract_style($import) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// @todo: are there any security implications for creating styles like this?
|
||||
// - Unserialize() is save in itself: it only creates data (except possibly
|
||||
// for__wakeup(), but that can only be in already existing code: safe
|
||||
@@ -209,14 +292,14 @@ function image_styles_admin_import_extract_style($import) {
|
||||
// contain invalid values. This is acceptable as it can also be done by
|
||||
// operating directly on the database. In Drupal this is not normally
|
||||
// checked for during processing: error messages will make clear that the
|
||||
// data has been played with. Can incorrect dat be abused? It may contain:
|
||||
// data has been played with. Can incorrect data be abused? It may contain:
|
||||
// - incorrect types: we do not know the data structure of the various
|
||||
// effects, so we cannot check that and have to accept it as it comes.
|
||||
// Effects should check_plain in summary theme and convert to int/float
|
||||
// whenever possible befoire using it in commands.
|
||||
// whenever possible before using it in commands.
|
||||
// - PHP code, but that may be valid content for the text or custom effects:
|
||||
// Effects should check_plain in summary theme and convert to int/float
|
||||
// whenever possible befoire using it in commands.
|
||||
// whenever possible before using it in commands.
|
||||
// @todo: if the style contains an effect that contains PHP code, the user
|
||||
// should need the 'use PHP for settings' permission.
|
||||
// - HTML and or JS code: when used as parameter, this normally won't hurt.
|
||||
|
@@ -1,13 +1,13 @@
|
||||
name = Image styles admin
|
||||
description = Provides additional administrative image style functionality.
|
||||
description = Provides additional administrative functionality to duplicate, export or import image styles.
|
||||
package = Media
|
||||
core = 7.x
|
||||
|
||||
dependencies[] = image
|
||||
|
||||
; Information added by drupal.org packaging script on 2012-12-04
|
||||
version = "7.x-1.1"
|
||||
; Information added by Drupal.org packaging script on 2018-03-20
|
||||
version = "7.x-1.9"
|
||||
core = "7.x"
|
||||
project = "imagecache_actions"
|
||||
datestamp = "1354653754"
|
||||
datestamp = "1521550387"
|
||||
|
||||
|
@@ -0,0 +1,19 @@
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
Drupal.behaviors.imageStylesAdmin = {
|
||||
attach: function(context) {
|
||||
$('#image-styles').find('th.expand-all').once('expand-all', function() {
|
||||
$(this).click(function() {
|
||||
$('#image-styles').find('td.description .inner.expand').addClass('expanded');
|
||||
});
|
||||
});
|
||||
$('#image-styles').find('td.description').once('description', function() {
|
||||
$('.inner.expand', $(this)).click(function() {
|
||||
$(this).toggleClass('expanded');
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(jQuery);
|
@@ -41,36 +41,122 @@ function image_styles_admin_menu() {
|
||||
* Implements hook_preprocess_HOOK for theme image_style_list.
|
||||
*/
|
||||
function image_styles_admin_preprocess_image_style_list(&$variables) {
|
||||
// Tell imagecache_actions_preprocess_image_style_list to preprocess the next
|
||||
// call to theme_table()
|
||||
$flag = TRUE;
|
||||
image_styles_admin_preprocess_table($flag);
|
||||
// Sort the image styles by name.
|
||||
uasort($variables['styles'], function ($a, $b) {
|
||||
return strcasecmp($a['label'], $b['label']);
|
||||
});
|
||||
|
||||
// Tell imagecache_actions_preprocess_table to preprocess the next call to
|
||||
// theme_table().
|
||||
$image_styles = array_values($variables['styles']);
|
||||
|
||||
image_styles_admin_preprocess_table($image_styles);
|
||||
|
||||
// Add CSS and JS files.
|
||||
drupal_add_css(drupal_get_path('module', 'image_styles_admin') . '/image_styles_admin.css');
|
||||
if (base_path() !== '/') {
|
||||
$base_path = base_path();
|
||||
drupal_add_css("
|
||||
#image-styles .expand.inner { background-image: url($base_path/misc/menu-collapsed.png) }
|
||||
#image-styles .expanded.expand.inner { background-image: url($base_path/misc/menu-expanded.png) }",
|
||||
array('type' => 'inline'));
|
||||
}
|
||||
drupal_add_js(drupal_get_path('module', 'image_styles_admin') . '/image_styles_admin.js');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_preprocess_HOOK for theme table.
|
||||
*/
|
||||
function image_styles_admin_preprocess_table(&$variables) {
|
||||
static $is_in_image_style_list = FALSE;
|
||||
static $image_styles = NULL;
|
||||
|
||||
if (is_bool($variables)) {
|
||||
// Called from imagecache_actions_style_duplicate(): set flag
|
||||
$is_in_image_style_list = $variables;
|
||||
// If called from image_styles_admin_preprocess_image_style_list(), the
|
||||
// parameter will be a sequential array.
|
||||
if (key($variables) === 0) {
|
||||
$image_styles = $variables;
|
||||
}
|
||||
else if ($is_in_image_style_list) {
|
||||
// Normal preprocess hook call: only process if theme('table', ...) has been
|
||||
// called by theme_image_style_list()
|
||||
$variables['header'][2]['colspan'] = 4;
|
||||
foreach ($variables['rows'] as &$row) {
|
||||
array_splice($row, 2, 0, array($row[2], $row[2]));
|
||||
// Replace edit with duplicate in text and href
|
||||
$row[3] = str_replace('>' . t('edit') . '<', '>' . t('duplicate') . '<', $row[3]);
|
||||
$row[3] = preg_replace('/\/edit\/([-a-z0-9_]+)"/', '/duplicate/\1"', $row[3]);
|
||||
// Replace edit with export in text and href
|
||||
$row[4] = str_replace('>' . t('edit') . '<', '>' . t('export') . '<', $row[4]);
|
||||
$row[4] = preg_replace('/\/edit\/([-a-z0-9_]+)"/', '/export/\1"', $row[4]);
|
||||
else if (!empty($image_styles)) {
|
||||
// Normal preprocess hook call: we only process if theme('table', ...) has
|
||||
// been called via theme_image_style_list() and we have a non empty list of
|
||||
// styles;
|
||||
|
||||
// Set an ID on the table so it can be targeted by our CSS.
|
||||
$variables['attributes']['id'] = 'image-styles';
|
||||
|
||||
// Add a class to the Style name and Settings columns for styling.
|
||||
foreach ($variables['header'] as &$cell) {
|
||||
$temp_cell = is_string($cell) ? array('data' => $cell) : $cell;
|
||||
$class_names = array(
|
||||
'style-name' => t('Style name'),
|
||||
'settings' => t('Settings'),
|
||||
);
|
||||
foreach ($class_names as $class => $name) {
|
||||
if ($temp_cell['data'] == $name) {
|
||||
$temp_cell['class'][] = $class;
|
||||
$cell = $temp_cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add the effects column header.
|
||||
array_splice($variables['header'], 1, 0, array(array(
|
||||
'data' => t('Effects') . ' <span class="description expand" role="button">(' . t('expand all') . ')</span>',
|
||||
'class' => array('effects expand-all')
|
||||
)));
|
||||
|
||||
// Add a column with a summary of all effects to each row.
|
||||
foreach ($variables['rows'] as $i => &$row) {
|
||||
$style = $image_styles[$i];
|
||||
$effects_list = array();
|
||||
foreach ($style['effects'] as $key => $effect) {
|
||||
$definition = image_effect_definition_load($effect['name']);
|
||||
$effect = array_merge($definition, $effect);
|
||||
$style['effects'][$key] = $effect;
|
||||
$effect_details = isset($effect['summary theme']) ? theme($effect['summary theme'], array('data' => $effect['data'])) : '';
|
||||
$effects_list[] = '<span class="details">' . $effect['label'] . ' ' . $effect_details . '</span>';
|
||||
}
|
||||
// Add the effects summary column to the row.
|
||||
$effects_summary = array(
|
||||
'data' => '<div class="inner expand" role="button">' . implode('<span class="separator">, </span>', $effects_list) . '</div>',
|
||||
'class' => 'description'
|
||||
);
|
||||
array_splice($row, 1, 0, array($effects_summary));
|
||||
}
|
||||
|
||||
// Find the column with the edit link in it.
|
||||
$i = 0;
|
||||
$first_row = reset($variables['rows']);
|
||||
foreach ($first_row as $i => &$cell) {
|
||||
$cell_data = is_array($cell) ? $cell['data'] : $cell;
|
||||
if (strpos($cell_data, '>' . t('edit') . '<') !== FALSE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Increase the colspan for the column with the edit link to include the
|
||||
// duplicate and export links as well. This *should* be 2, but Drupal core
|
||||
// specifies 1 more than should be there.
|
||||
$variables['header'][$i]['colspan'] += 1;
|
||||
|
||||
// Add the 2 links to each row by duplicating the edit link and then
|
||||
// changing the text and the link.
|
||||
$edit_column = $i;
|
||||
foreach ($variables['rows'] as &$row) {
|
||||
$i = $edit_column;
|
||||
// Duplicate the edit link twice.
|
||||
array_splice($row, $i + 1, 0, array($row[$i], $row[$i]));
|
||||
// Replace edit with duplicate in text and href
|
||||
$i++;
|
||||
$row[$i] = str_replace('>' . t('edit') . '<', '>' . t('duplicate') . '<', $row[$i]);
|
||||
$row[$i] = preg_replace('#/admin/config/media/image-styles/edit/#', '/admin/config/media/image-styles/duplicate/', $row[$i]);
|
||||
// Replace edit with export in text and href
|
||||
$i++;
|
||||
$row[$i] = str_replace('>' . t('edit') . '<', '>' . t('export') . '<', $row[$i]);
|
||||
$row[$i] = preg_replace('#/admin/config/media/image-styles/edit/#', '/admin/config/media/image-styles/export/', $row[$i]);
|
||||
}
|
||||
|
||||
// Don't preprocess subsequent calls to theme_table().
|
||||
$is_in_image_style_list = FALSE;
|
||||
$image_styles = NULL;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user