971 lines
30 KiB
Plaintext
971 lines
30 KiB
Plaintext
![]() |
<?php
|
||
|
|
||
|
/**
|
||
|
* @file
|
||
|
* Breakpoints
|
||
|
* @todo: provide button to reload breakpoints from theme
|
||
|
*/
|
||
|
|
||
|
define('BREAKPOINTS_SOURCE_TYPE_THEME', 'theme');
|
||
|
define('BREAKPOINTS_SOURCE_TYPE_MODULE', 'module');
|
||
|
define('BREAKPOINTS_SOURCE_TYPE_CUSTOM', 'custom');
|
||
|
define('BREAKPOINTS_GROUP', 'group');
|
||
|
|
||
|
/**
|
||
|
* Implements hook_permission().
|
||
|
*/
|
||
|
function breakpoints_permission() {
|
||
|
return array(
|
||
|
'administer breakpoints' => array(
|
||
|
'title' => t('Administer Breakpoints'),
|
||
|
'description' => t('Administer all breakpoints'),
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_ctools_plugin_directory().
|
||
|
*/
|
||
|
function breakpoints_ctools_plugin_directory($module, $plugin) {
|
||
|
if ($module == 'ctools' && $plugin == 'export_ui') {
|
||
|
return 'plugins/' . $plugin;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_ctools_plugin_api().
|
||
|
*/
|
||
|
function breakpoints_ctools_plugin_api($owner, $api) {
|
||
|
return array('version' => 1);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_enable().
|
||
|
* Import breakpoints from all enabled themes.
|
||
|
*/
|
||
|
function breakpoints_enable() {
|
||
|
$themes = list_themes();
|
||
|
foreach ($themes as $theme_key => $theme) {
|
||
|
if (!$theme->status) {
|
||
|
unset($themes[$theme_key]);
|
||
|
}
|
||
|
}
|
||
|
breakpoints_themes_enabled(array_keys($themes));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_themes_enabled();
|
||
|
* Import breakpoints from all new enabled themes.
|
||
|
* Do not use breakpoints_breakpoints_group_reload_from_theme as is clears the cache.
|
||
|
*/
|
||
|
function breakpoints_themes_enabled($theme_list, $rebuild_menu = TRUE) {
|
||
|
$themes = list_themes();
|
||
|
$updated = FALSE;
|
||
|
$new_breakpoint_group = FALSE;
|
||
|
foreach ($theme_list as $theme_key) {
|
||
|
if (isset($themes[$theme_key]->info['breakpoints'])) {
|
||
|
$updated = TRUE;
|
||
|
$weight = 0;
|
||
|
$theme_settings = $themes[$theme_key]->info['breakpoints'];
|
||
|
$multipliers = isset($themes[$theme_key]->info['multipliers']) ? $themes[$theme_key]->info['multipliers'] : array();
|
||
|
$settings = breakpoints_settings();
|
||
|
$current_multipliers = drupal_map_assoc($settings->multipliers);
|
||
|
$breakpoint_group = breakpoints_breakpoint_group_load($theme_key);
|
||
|
if(!$breakpoint_group) {
|
||
|
// Build a group for each theme
|
||
|
$new_breakpoint_group = TRUE;
|
||
|
$breakpoint_group = breakpoints_breakpoint_group_empty_object();
|
||
|
$breakpoint_group->machine_name = $theme_key;
|
||
|
$breakpoint_group->name = $themes[$theme_key]->info['name'];
|
||
|
$breakpoint_group->type = BREAKPOINTS_SOURCE_TYPE_THEME;
|
||
|
}
|
||
|
foreach ($theme_settings as $name => $media_query) {
|
||
|
$breakpoint = breakpoints_breakpoint_load($name, $theme_key, 'theme');
|
||
|
if (!$breakpoint) {
|
||
|
$breakpoint = breakpoints_breakpoint_empty_object();
|
||
|
$breakpoint->name = $name;
|
||
|
$breakpoint->source = $theme_key;
|
||
|
$breakpoint->source_type = 'theme';
|
||
|
$breakpoint->theme = '';
|
||
|
$breakpoint->status = TRUE;
|
||
|
$breakpoint->weight = $weight++;
|
||
|
$breakpoint->machine_name = breakpoints_breakpoint_config_name($breakpoint);
|
||
|
}
|
||
|
$breakpoint->breakpoint = $media_query;
|
||
|
$breakpoint->multipliers = isset($multipliers[$name]) ? drupal_map_assoc($multipliers[$name]) : array();
|
||
|
$current_multipliers += drupal_map_assoc($breakpoint->multipliers);
|
||
|
breakpoints_breakpoint_save($breakpoint);
|
||
|
$breakpoint_group->breakpoints[] = $breakpoint->machine_name;
|
||
|
}
|
||
|
breakpoints_settings_save($current_multipliers);
|
||
|
breakpoints_breakpoint_group_save($breakpoint_group);
|
||
|
if($new_breakpoint_group) {
|
||
|
$message_text = 'The breakpoints from theme %theme are imported and <a href="@url">a new group is created</a>.';
|
||
|
} else {
|
||
|
$message_text = 'The breakpoints from theme %theme are imported and <a href="@url">an existing group was updated</a>.';
|
||
|
}
|
||
|
$message = t($message_text, array(
|
||
|
'%theme' => $themes[$theme_key]->info['name'],
|
||
|
'@url' => url('admin/config/media/breakpoints/groups/' . $theme_key),
|
||
|
));
|
||
|
drupal_set_message($message, 'status');
|
||
|
}
|
||
|
}
|
||
|
if ($rebuild_menu && $updated) {
|
||
|
variable_set('menu_rebuild_needed', TRUE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_themes_disabled();
|
||
|
* Remove breakpoints from all disabled themes.
|
||
|
*/
|
||
|
function breakpoints_themes_disabled($theme_list) {
|
||
|
$themes = list_themes();
|
||
|
foreach ($theme_list as $theme_key) {
|
||
|
$breakpoints = breakpoints_breakpoint_load_all_theme($theme_key);
|
||
|
foreach ($breakpoints as $breakpoint) {
|
||
|
breakpoints_breakpoint_delete($breakpoint, $theme_key);
|
||
|
}
|
||
|
breakpoints_breakpoint_group_delete_by_name($theme_key);
|
||
|
}
|
||
|
variable_set('menu_rebuild_needed', TRUE);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_menu().
|
||
|
*/
|
||
|
function breakpoints_menu() {
|
||
|
$items = array();
|
||
|
|
||
|
// @todo: link to all breakpoints and a list of all groups
|
||
|
// cf theme settings page
|
||
|
$items['admin/config/media/breakpoints'] = array(
|
||
|
'title' => 'Breakpoints',
|
||
|
'description' => 'Manage breakpoints',
|
||
|
'page callback' => 'drupal_get_form',
|
||
|
'page arguments' => array('breakpoints_admin_breakpoints'),
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/create_style'] = array(
|
||
|
'title' => 'Add responsive style',
|
||
|
'description' => 'Add a responsive image style',
|
||
|
'page callback' => 'drupal_get_form',
|
||
|
'page arguments' => array('breakpoints_add_style_form'),
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'weight' => 30,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/multipliers'] = array(
|
||
|
'title' => 'Multipliers',
|
||
|
'description' => 'Manage multipliers',
|
||
|
'page callback' => 'drupal_get_form',
|
||
|
'page arguments' => array('breakpoints_multipliers_form'),
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'weight' => 20,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/settings'] = array(
|
||
|
'title' => 'Settings',
|
||
|
'description' => 'Manage breakpoint settings',
|
||
|
'page callback' => 'drupal_get_form',
|
||
|
'page arguments' => array('breakpoints_admin_settings_form'),
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'weight' => 30,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/multipliers/%/delete'] = array(
|
||
|
'title' => '',
|
||
|
'page callback' => 'drupal_get_form',
|
||
|
'page arguments' => array('breakpoints_admin_multiplier_delete_form', 5),
|
||
|
'type' => MENU_CALLBACK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups'] = array(
|
||
|
'title' => 'Groups',
|
||
|
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||
|
'weight' => 10,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/global'] = array(
|
||
|
'title' => 'All breakpoints',
|
||
|
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||
|
'weight' => -1,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/add'] = array(
|
||
|
'title' => 'Add a new group',
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_group_edit_form'),
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 99,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/import'] = array(
|
||
|
'title' => 'Import a new group',
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_group_import_form'),
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 99,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/import-breakpoint'] = array(
|
||
|
'title' => 'Import a new breakpoint',
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_import_form'),
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 99,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/%/%'] = array(
|
||
|
'title' => '',
|
||
|
'page callback' => 'breakpoints_admin_breakpoint_actions_page',
|
||
|
'page arguments' => array('', 4, 5),
|
||
|
'type' => MENU_CALLBACK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
|
||
|
$breakpoint_groups = breakpoints_breakpoint_group_load_all();
|
||
|
foreach ($breakpoint_groups as $breakpoint_group_name => $breakpoint_group) {
|
||
|
if (!empty($breakpoint_group->machine_name)) {
|
||
|
$items['admin/config/media/breakpoints/groups/' . $breakpoint_group->machine_name] = array(
|
||
|
'title' => $breakpoint_group->name,
|
||
|
'page arguments' => array('breakpoints_admin_breakpoints', $breakpoint_group->machine_name),
|
||
|
'type' => MENU_LOCAL_TASK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
$items['admin/config/media/breakpoints/groups/' . $breakpoint_group->machine_name . '/edit'] = array(
|
||
|
'title' => 'Edit ' . $breakpoint_group->name,
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_group_edit_form', $breakpoint_group->machine_name),
|
||
|
'type' => MENU_CALLBACK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
$items['admin/config/media/breakpoints/groups/' . $breakpoint_group->machine_name . '/delete'] = array(
|
||
|
'title' => 'Delete ' . $breakpoint_group->name,
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_group_delete_form', $breakpoint_group->machine_name),
|
||
|
'type' => MENU_CALLBACK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/' . $breakpoint_group->machine_name . '/export'] = array(
|
||
|
'title' => 'Export ' . $breakpoint_group->name,
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_group_export_form', $breakpoint_group->machine_name),
|
||
|
'type' => MENU_LOCAL_ACTION,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/' . $breakpoint_group->machine_name . '/duplicate'] = array(
|
||
|
'title' => 'Duplicate ' . $breakpoint_group->name,
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_group_duplicate_form', $breakpoint_group->machine_name),
|
||
|
'type' => MENU_CALLBACK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
|
||
|
$items['admin/config/media/breakpoints/groups/' . $breakpoint_group->machine_name . '/%/%'] = array(
|
||
|
'title' => '',
|
||
|
'page arguments' => array('breakpoints_admin_breakpoint_actions_form', $breakpoint_group->machine_name, 6, 7),
|
||
|
'type' => MENU_CALLBACK,
|
||
|
'access arguments' => array('administer breakpoints'),
|
||
|
'file' => 'breakpoints.admin.inc',
|
||
|
'weight' => 15,
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $items;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load general settings.
|
||
|
*/
|
||
|
function breakpoints_settings() {
|
||
|
$config = new StdClass;
|
||
|
$config->multipliers = variable_get('breakpoints_multipliers', array('1x', '1.5x', '2x'));
|
||
|
return $config;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save general settings.
|
||
|
*/
|
||
|
function breakpoints_settings_save($multipliers) {
|
||
|
variable_set('breakpoints_multipliers', $multipliers);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sort breakpoints by weight.
|
||
|
*/
|
||
|
function _breakpoints_sort_by_weight($a, $b) {
|
||
|
if (isset($a->weight) && isset($b->weight)) {
|
||
|
if ($a->weight == $b->weight) {
|
||
|
if (isset($a->source_type) && $a->source_type == BREAKPOINTS_SOURCE_TYPE_CUSTOM) {
|
||
|
return -1;
|
||
|
}
|
||
|
if (isset($b->source_type) && $b->source_type == BREAKPOINTS_SOURCE_TYPE_CUSTOM) {
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
return ($a->weight < $b->weight) ? -1 : 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Sort breakpoints by weight.
|
||
|
*/
|
||
|
function _breakpoints_sort_by_weight_array($a, $b) {
|
||
|
return _breakpoints_sort_by_weight((object) $a, (object) $b);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Construct config name.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_config_name($breakpoints_breakpoint) {
|
||
|
if (is_string($breakpoints_breakpoint)) {
|
||
|
return $breakpoints_breakpoint;
|
||
|
}
|
||
|
else {
|
||
|
return drupal_strtolower('breakpoints'
|
||
|
. '.' . $breakpoints_breakpoint->source_type
|
||
|
. '.' . $breakpoints_breakpoint->source
|
||
|
. '.' . $breakpoints_breakpoint->name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load a single breakpoint.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load($name, $source, $source_type) {
|
||
|
$key = drupal_strtolower('breakpoints.' . $source_type . '.' . $source . '.' . $name);
|
||
|
return breakpoints_breakpoint_load_by_fullkey($key);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load a single breakpoint using the full config key.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load_by_fullkey($machine_name = NULL) {
|
||
|
$breakpoints = &drupal_static(__FUNCTION__);
|
||
|
|
||
|
if (!isset($breakpoints)) {
|
||
|
$breakpoints = _breakpoints_breakpoint_load_all_callback();
|
||
|
}
|
||
|
|
||
|
if ($machine_name) {
|
||
|
$breakpoint = isset($breakpoints[$machine_name]) ? $breakpoints[$machine_name] : FALSE;
|
||
|
return $breakpoint;
|
||
|
}
|
||
|
else {
|
||
|
return $breakpoints;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* CTools export 'load all callback' CRUD callback for breakpoints.
|
||
|
*/
|
||
|
function _breakpoints_breakpoint_load_all_callback($reset = FALSE) {
|
||
|
if (!$reset && $cache = cache_get('breakpoints:breakpoints')) {
|
||
|
return $cache->data;
|
||
|
}
|
||
|
else {
|
||
|
ctools_include('export');
|
||
|
$breakpoints = ctools_export_load_object('breakpoints', 'all');
|
||
|
cache_set('breakpoints:breakpoints', $breakpoints);
|
||
|
return $breakpoints;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all breakpoints.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load_all($theme_key = '') {
|
||
|
$breakpoints_user = breakpoints_breakpoint_load_all_custom();
|
||
|
$breakpoints_module = breakpoints_breakpoint_load_all_module();
|
||
|
$breakpoints_theme = breakpoints_breakpoint_load_all_theme($theme_key);
|
||
|
$breakpoints = array_merge($breakpoints_theme, $breakpoints_module, $breakpoints_user);
|
||
|
uasort($breakpoints, '_breakpoints_sort_by_weight');
|
||
|
return $breakpoints;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all enabled breakpoints.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load_all_active($theme_key = '') {
|
||
|
$breakpoints = breakpoints_breakpoint_load_all($theme_key);
|
||
|
$enabled = array();
|
||
|
if (!empty($breakpoints)) {
|
||
|
foreach ($breakpoints as $breakpoint_name => $breakpoint) {
|
||
|
if ($breakpoint->status) {
|
||
|
$enabled[$breakpoint_name] = $breakpoint;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return $enabled;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all breakpoints by source type.
|
||
|
*/
|
||
|
function _breakpoints_breakpoint_load_all_by_type($source_type, $source = '') {
|
||
|
$breakpoints = breakpoints_breakpoint_load_by_fullkey();
|
||
|
foreach ($breakpoints as $machine_name => $breakpoint) {
|
||
|
if ($breakpoint->source_type != $source_type) {
|
||
|
unset($breakpoints[$machine_name]);
|
||
|
continue;
|
||
|
}
|
||
|
if ($source != '' && $breakpoint->source != $source) {
|
||
|
unset($breakpoints[$machine_name]);
|
||
|
}
|
||
|
}
|
||
|
return $breakpoints;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all custom breakpoints.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load_all_custom() {
|
||
|
$breakpoints = _breakpoints_breakpoint_load_all_by_type(BREAKPOINTS_SOURCE_TYPE_CUSTOM);
|
||
|
return $breakpoints;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all user defined breakpoints.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load_all_module() {
|
||
|
return _breakpoints_breakpoint_load_all_by_type(BREAKPOINTS_SOURCE_TYPE_MODULE);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all breakpoints from the theme.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_load_all_theme($theme_key = '') {
|
||
|
return _breakpoints_breakpoint_load_all_by_type(BREAKPOINTS_SOURCE_TYPE_THEME, $theme_key);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Empty breakpoint object.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_empty_object() {
|
||
|
return (object) breakpoints_breakpoint_empty_array();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Empty breakpoint array.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_empty_array() {
|
||
|
return array(
|
||
|
'name' => '',
|
||
|
'machine_name' => '',
|
||
|
'breakpoint' => '',
|
||
|
'source' => '',
|
||
|
'source_type' => '',
|
||
|
'status' => TRUE,
|
||
|
'weight' => 0,
|
||
|
'multipliers' => array(),
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save a single breakpoint.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_save(&$breakpoint) {
|
||
|
ctools_include('export');
|
||
|
|
||
|
if (!isset($breakpoint->machine_name) || empty($breakpoint->machine_name)) {
|
||
|
$breakpoint->machine_name = breakpoints_breakpoint_config_name($breakpoint);
|
||
|
}
|
||
|
$update = (isset($breakpoint->id) && is_numeric($breakpoint->id)) ? array('id') : array();
|
||
|
// Remove unused multipliers.
|
||
|
$breakpoint->multipliers = array_filter($breakpoint->multipliers);
|
||
|
if (is_null($breakpoint->multipliers)){
|
||
|
$breakpoint->multipliers = array();
|
||
|
}
|
||
|
// Add the '1x' multiplier.
|
||
|
$breakpoint->multipliers = array_merge($breakpoint->multipliers, array('1x' => '1x'));
|
||
|
$result = drupal_write_record('breakpoints', $breakpoint, $update);
|
||
|
breakpoints_breakpoint_reset();
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete a single breakpoint.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_delete($breakpoint) {
|
||
|
$name = breakpoints_breakpoint_config_name($breakpoint);
|
||
|
return breakpoints_breakpoint_delete_by_fullkey($name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete a single breakpoint.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_delete_by_fullkey($key) {
|
||
|
if (!empty($key)) {
|
||
|
$sql = "DELETE FROM {breakpoints} where machine_name = :key";
|
||
|
db_query($sql, array(':key' => $key));
|
||
|
}
|
||
|
breakpoints_breakpoint_reset();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clears the breakpoint caches.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_reset() {
|
||
|
ctools_include('export');
|
||
|
ctools_export_load_object_reset('breakpoints');
|
||
|
drupal_static_reset('breakpoints_breakpoint_load_by_fullkey');
|
||
|
cache_clear_all('breakpoints:breakpoints', 'cache');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Toggle status of a single breakpoint.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_toggle_status($machine_name) {
|
||
|
$breakpoint = breakpoints_breakpoint_load_by_fullkey($machine_name);
|
||
|
if ($breakpoint) {
|
||
|
$breakpoint->status = !$breakpoint->status;
|
||
|
breakpoints_breakpoint_save($breakpoint);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if a breakpoint name already exists.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_name_exists($machine_name) {
|
||
|
$breakpoints = breakpoints_breakpoint_load_all_custom();
|
||
|
$fullkey = 'custom.user.' . $machine_name;
|
||
|
return array_key_exists($fullkey, $breakpoints);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if a breakpoint machine name already exists.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_machine_name_exists($machine_name) {
|
||
|
// Just try to load the breakpoint object, we profit from ctool's cache mechanism,
|
||
|
// better that doing a query to the db every time this function is called.
|
||
|
return (bool) breakpoints_breakpoint_load_by_fullkey($machine_name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Empty breakpoint group object.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_empty_object() {
|
||
|
return (object) breakpoints_breakpoint_group_empty_array();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Empty breakpoint group array.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_empty_array() {
|
||
|
return array(
|
||
|
'machine_name' => '',
|
||
|
'name' => '',
|
||
|
'breakpoints' => array(),
|
||
|
'type' => 'custom',
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if a group name already exists.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_name_exists($machine_name) {
|
||
|
// Check for reserved words.
|
||
|
if ($machine_name == 'global' || $machine_name == 'add') {
|
||
|
return TRUE;
|
||
|
}
|
||
|
// Check if group name is used before.
|
||
|
$group_check = breakpoints_breakpoint_group_load($machine_name);
|
||
|
if ($group_check && isset($group_check->machine_name) && !empty($group_check->machine_name)) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load all breakpoint groups.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_load_all($reset = FALSE) {
|
||
|
$groups = &drupal_static(__FUNCTION__);
|
||
|
|
||
|
if (!isset($groups)) {
|
||
|
if (!$reset && $cache = cache_get('breakpoints:groups')) {
|
||
|
return $cache->data;
|
||
|
}
|
||
|
else {
|
||
|
ctools_include('export');
|
||
|
$groups = ctools_export_load_object('breakpoint_group', 'all');
|
||
|
cache_set('breakpoints:groups', $groups);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $groups;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load a single breakpoint group.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_load($name = NULL) {
|
||
|
$groups = breakpoints_breakpoint_group_load_all();
|
||
|
|
||
|
if ($name) {
|
||
|
$group = isset($groups[$name]) ? $groups[$name] : FALSE;
|
||
|
return $group;
|
||
|
}
|
||
|
else {
|
||
|
return $groups;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate a single breakpoint group.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_validate($group) {
|
||
|
if (!is_object($group)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
foreach (array('machine_name', 'name', 'breakpoints', 'type') as $property) {
|
||
|
if (!property_exists($group, $property)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validate a single breakpoint.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_validate($breakpoint) {
|
||
|
if (!is_object($breakpoint)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
foreach (array_keys(breakpoints_breakpoint_empty_array()) as $property) {
|
||
|
if (!property_exists($breakpoint, $property)) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Save a single breakpoint group.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_save(&$breakpoint_group) {
|
||
|
ctools_include('export');
|
||
|
|
||
|
$update = (isset($breakpoint_group->id) && is_numeric($breakpoint_group->id)) ? array('id') : array();
|
||
|
$result = drupal_write_record('breakpoint_group', $breakpoint_group, $update);
|
||
|
// rebuild menu if we add a new group
|
||
|
if (empty($update)) {
|
||
|
variable_set('menu_rebuild_needed', TRUE);
|
||
|
}
|
||
|
breakpoints_breakpoint_group_reset();
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete a single breakpoint group.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_delete($breakpoint_group) {
|
||
|
$name = $breakpoint_group->machine_name;
|
||
|
breakpoints_breakpoint_group_delete_by_fullkey($name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete a single breakpoint group by fullkey.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_delete_by_name($machine_name) {
|
||
|
$name = $machine_name;
|
||
|
breakpoints_breakpoint_group_delete_by_fullkey($name);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Delete a single breakpoint group by fullkey.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_delete_by_fullkey($key) {
|
||
|
if (!empty($key)) {
|
||
|
$sql = "DELETE FROM {breakpoint_group} where machine_name = :key";
|
||
|
db_query($sql, array(':key' => $key));
|
||
|
}
|
||
|
variable_set('menu_rebuild_needed', TRUE);
|
||
|
breakpoints_breakpoint_group_reset();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clears the breakpoint group caches.
|
||
|
*/
|
||
|
function breakpoints_breakpoint_group_reset() {
|
||
|
ctools_include('export');
|
||
|
ctools_export_load_object_reset('breakpoint_group');
|
||
|
drupal_static_reset('breakpoints_breakpoint_group_load_all');
|
||
|
cache_clear_all('breakpoints:groups', 'cache');
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_theme().
|
||
|
*/
|
||
|
function breakpoints_theme() {
|
||
|
return array(
|
||
|
'breakpoints_admin_breakpoints_table' => array(
|
||
|
'render element' => 'form',
|
||
|
'theme_key' => NULL,
|
||
|
),
|
||
|
'breakpoints_multipliers_table_form' => array(
|
||
|
'render element' => 'form',
|
||
|
'theme_key' => NULL,
|
||
|
)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Export callback.
|
||
|
* @see breakpoints_schema()
|
||
|
*/
|
||
|
function breakpoint_group_export_breakpoints($object, $field, $value, $indent) {
|
||
|
ctools_include('export');
|
||
|
$export = array();
|
||
|
if (isset($object->breakpoints)) {
|
||
|
foreach ($object->breakpoints as $breakpoint) {
|
||
|
if (!is_array($breakpoint) && !is_object($breakpoint)) {
|
||
|
$breakpoint = breakpoints_breakpoint_load_by_fullkey($breakpoint);
|
||
|
}
|
||
|
$export[] = $breakpoint->machine_name;
|
||
|
}
|
||
|
}
|
||
|
return ctools_var_export($export, $indent);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Reload the breakpoints as defined by the group.
|
||
|
*/
|
||
|
function breakpoints_breakpoints_group_reload(&$group, $force = TRUE) {
|
||
|
switch ($group->type) {
|
||
|
case BREAKPOINTS_SOURCE_TYPE_THEME:
|
||
|
// delete all breakpoints defined by this theme.
|
||
|
$breakpoints = breakpoints_breakpoint_load_all_theme($group->machine_name);
|
||
|
foreach ($breakpoints as $breakpoint) {
|
||
|
breakpoints_breakpoint_delete($breakpoint);
|
||
|
}
|
||
|
|
||
|
// Reload all breakpoints from theme.info.
|
||
|
$reloaded_group = breakpoints_breakpoints_group_reload_from_theme($group->machine_name);
|
||
|
|
||
|
// Reset the breakpoints for this group.
|
||
|
if ($force) {
|
||
|
$group->breakpoints = $reloaded_group->breakpoints;
|
||
|
breakpoints_breakpoint_group_save($group);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function breakpoints_breakpoints_group_reload_from_theme($theme_key) {
|
||
|
// Clear caches so theme.info is fresh.
|
||
|
system_rebuild_theme_data();
|
||
|
drupal_theme_rebuild();
|
||
|
|
||
|
$themes = list_themes();
|
||
|
if (isset($themes[$theme_key]->info['breakpoints'])) {
|
||
|
$weight = 0;
|
||
|
$theme_settings = $themes[$theme_key]->info['breakpoints'];
|
||
|
$multipliers = isset($themes[$theme_key]->info['multipliers']) ? $themes[$theme_key]->info['multipliers'] : array();
|
||
|
$settings = breakpoints_settings();
|
||
|
$current_multipliers = drupal_map_assoc($settings->multipliers);
|
||
|
// Build a group for each theme
|
||
|
$breakpoint_group = breakpoints_breakpoint_group_empty_object();
|
||
|
$breakpoint_group->machine_name = $theme_key;
|
||
|
$breakpoint_group->name = $themes[$theme_key]->info['name'];
|
||
|
$breakpoint_group->type = BREAKPOINTS_SOURCE_TYPE_THEME;
|
||
|
foreach ($theme_settings as $name => $media_query) {
|
||
|
$breakpoint = breakpoints_breakpoint_load($name, $theme_key, 'theme');
|
||
|
if (!$breakpoint) {
|
||
|
$breakpoint = breakpoints_breakpoint_empty_object();
|
||
|
$breakpoint->name = $name;
|
||
|
$breakpoint->source = $theme_key;
|
||
|
$breakpoint->source_type = 'theme';
|
||
|
$breakpoint->theme = '';
|
||
|
$breakpoint->status = TRUE;
|
||
|
$breakpoint->weight = $weight++;
|
||
|
$breakpoint->machine_name = breakpoints_breakpoint_config_name($breakpoint);
|
||
|
}
|
||
|
$breakpoint->breakpoint = $media_query;
|
||
|
$breakpoint->multipliers = isset($multipliers[$name]) ? drupal_map_assoc($multipliers[$name]) : array();
|
||
|
$current_multipliers += drupal_map_assoc($breakpoint->multipliers);
|
||
|
breakpoints_breakpoint_save($breakpoint);
|
||
|
$breakpoint_group->breakpoints[] = $breakpoint->machine_name;
|
||
|
}
|
||
|
breakpoints_settings_save($current_multipliers);
|
||
|
return $breakpoint_group;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Revert the breakpoints of a group.
|
||
|
*/
|
||
|
function breakpoints_breakpoints_group_revert(&$group) {
|
||
|
breakpoints_breakpoints_group_reload($group);
|
||
|
$group->overridden = 0;
|
||
|
breakpoints_breakpoint_group_save($group);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Duplicate a group.
|
||
|
*/
|
||
|
function breakpoints_breakpoints_group_duplicate($group, $new_name, $new_machine_name) {
|
||
|
$new_group = breakpoints_breakpoint_group_empty_object();
|
||
|
$new_group->machine_name = $new_machine_name;
|
||
|
$new_group->name = $new_name;
|
||
|
$new_group->type = BREAKPOINTS_SOURCE_TYPE_CUSTOM;
|
||
|
$new_group->breakpoints = $group->breakpoints;
|
||
|
breakpoints_breakpoint_group_save($new_group);
|
||
|
return $new_group;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Override the breakpoints of a group.
|
||
|
*/
|
||
|
function breakpoints_breakpoints_group_override($group) {
|
||
|
foreach ($group->breakpoints as $key => $breakpoint) {
|
||
|
$breakpoint = breakpoints_breakpoint_load_by_fullkey($breakpoint);
|
||
|
$old_breakpoint = clone $breakpoint;
|
||
|
if ($breakpoint->source_type == BREAKPOINTS_SOURCE_TYPE_THEME && $breakpoint->source == $group->machine_name) {
|
||
|
unset($breakpoint->id);
|
||
|
$breakpoint->machine_name = 'custom.' . $breakpoint->source . '.' . str_replace('-', '_', drupal_clean_css_identifier($breakpoint->name));
|
||
|
$breakpoint->source_type = BREAKPOINTS_SOURCE_TYPE_CUSTOM;
|
||
|
|
||
|
// make sure it doesn't already exists.
|
||
|
if (breakpoints_breakpoint_load_by_fullkey($breakpoint->machine_name) === FALSE) {
|
||
|
breakpoints_breakpoint_save($breakpoint);
|
||
|
}
|
||
|
|
||
|
// Add to the group and delete old breakpoint.
|
||
|
$group->breakpoints[$key] = $breakpoint->machine_name;
|
||
|
breakpoints_breakpoint_delete($old_breakpoint, $group->machine_name);
|
||
|
}
|
||
|
}
|
||
|
$group->overridden = 1;
|
||
|
breakpoints_breakpoint_group_save($group);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Export breakpoints ready for theme.info inclusion.
|
||
|
*/
|
||
|
function breakpoints_breakpoints_group_exporttotheme(&$group) {
|
||
|
$export = array();
|
||
|
foreach ($group->breakpoints as $breakpoint_name) {
|
||
|
$breakpoint = breakpoints_breakpoint_load_by_fullkey($breakpoint_name);
|
||
|
if ($breakpoint && $breakpoint->status) {
|
||
|
$export[$breakpoint->name] = $breakpoint->breakpoint;
|
||
|
}
|
||
|
}
|
||
|
return $export;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* array_filter callback.
|
||
|
*/
|
||
|
function _breakpoints_filter_styles($var) {
|
||
|
static $exists = NULL;
|
||
|
if (is_null($exists)) {
|
||
|
$exists = module_exists('resp_img') && defined('RESP_IMG_STYLE_PREFIX');
|
||
|
}
|
||
|
if (!$exists) {
|
||
|
return TRUE;
|
||
|
}
|
||
|
return strpos(is_array($var) ? $var['name'] : $var, RESP_IMG_STYLE_PREFIX) !== 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_permission().
|
||
|
*/
|
||
|
function breakpoints_form_system_theme_settings_alter(&$form, &$form_state) {
|
||
|
if (isset($form_state['build_info']['args'][0])) {
|
||
|
$form['actions']['rescan_breakpoints'] = array(
|
||
|
'#type' => 'submit',
|
||
|
'#value' => t('Scan this theme for breakpoints'),
|
||
|
'#submit' => array('breakpoints_form_system_theme_settings_alter_submit'),
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function breakpoints_form_system_theme_settings_alter_submit(&$form, &$form_state) {
|
||
|
$theme = $form_state['build_info']['args'][0];
|
||
|
$group = breakpoints_breakpoint_group_load($theme);
|
||
|
if ($group) {
|
||
|
breakpoints_breakpoints_group_reload($group);
|
||
|
}
|
||
|
else {
|
||
|
breakpoints_themes_enabled(array($theme));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_features_export().
|
||
|
*/
|
||
|
function breakpoint_group_features_export($data, &$export, $module_name = '') {
|
||
|
features_include();
|
||
|
$pipe = ctools_component_features_export('breakpoint_group', $data, $export, $module_name);
|
||
|
foreach ($data as $group_name) {
|
||
|
$group = breakpoints_breakpoint_group_load($group_name);
|
||
|
foreach ($group->breakpoints as $breakpoint_name) {
|
||
|
$breakpoint = breakpoints_breakpoint_load_by_fullkey($breakpoint_name);
|
||
|
if ($breakpoint->source_type != BREAKPOINTS_SOURCE_TYPE_THEME) {
|
||
|
$pipe['breakpoints'][] = $breakpoint_name;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return $pipe;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements hook_flush_caches().
|
||
|
*/
|
||
|
function breakpoints_flush_caches() {
|
||
|
if (variable_get('breakpoints_flush_caches_disabled', FALSE)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// hook_flush_caches gets invoked with both drupal_flush_all_caches and system_cron
|
||
|
// To avoid frequent menu/theme flushes, we must backtrace caller.
|
||
|
$backtrace = debug_backtrace();
|
||
|
if (isset($backtrace[3]) && ($backtrace[3]['function'] == 'drupal_flush_all_caches') && empty($backtrace[3]['args'])) {
|
||
|
|
||
|
$themes = list_themes();
|
||
|
foreach ($themes as $theme_key => $theme) {
|
||
|
if ($theme->status) {
|
||
|
$group = breakpoints_breakpoint_group_load($theme_key);
|
||
|
if ($group) {
|
||
|
breakpoints_breakpoints_group_reload($group, FALSE);
|
||
|
}
|
||
|
else {
|
||
|
breakpoints_themes_enabled(array($theme_key), FALSE);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|