Skip to content

Instantly share code, notes, and snippets.

@jackfoust
Created October 30, 2014 02:27
Show Gist options
  • Save jackfoust/76561d1515593f150514 to your computer and use it in GitHub Desktop.
Save jackfoust/76561d1515593f150514 to your computer and use it in GitHub Desktop.
#drupal Experimental Block Rendering by Device. Drupal 7
<?php
/**
* @file
* A test case for adding visibility settings of Desktop, Tablet and Mobile to Drupal block rendering. Dropped instead for Context + Mobile Detect Library
*/
define('MOBILE_DETECT_LIBRARY_PATH', '/sites/all/libraries/Mobile_Detect');
/**
* Implements hook_form_alter().
*/
function example_device_blocks_form_alter(&$form, &$form_state, $form_id) {
if (in_array($form_id, array('block_admin_configure', 'block_add_block_form', 'menu_block_add_block_form'))) {
// If the user is a site admin, show the form, otherwise pass it silently.
if (isset($form['module']['#value'])) {
$module = $form['module']['#value'];
$delta = $form['delta']['#value'];
}
else {
$module = 'block';
$delta = $form['bid']['#value'];
}
$form['visibility']['device_filter_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Device Display Options'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => 0,
'#group' => 'visibility',
);
$device_options = array();
$previous_device_options = _example_device_blocks_load($module, $delta, FALSE, '');
if (count($previous_device_options) > 0) {
foreach ($previous_device_options as $value) {
$device_options[] = $value;
}
}
$options = array('smalltouch' => 'Smalltouch Devices', 'tablet' => 'Tablet Devices', 'non_mobile' => 'PC/Laptop Devices');
$form['visibility']['device_filter_settings']['device_types'] = array(
'#type' => 'checkboxes',
'#title' => t('Hide on'),
'#options' => $options,
'#required' => FALSE,
'#description' => t('Limit block display to selected device types. When no device types are selected this block is visible on '
. 'all devices by default. Device detection through Mobile Detect module and not CSS Media Queries.'),
'#default_value' => $device_options,
);
$form['visibility']['device_filter_settings']['previous_device_options'] = array(
'#type' => 'value',
'#value' => $previous_device_options,
);
$form['#submit'][] = 'example_device_blocks_form_submit';
}
// Submit handler for user defined block deletion
if ($form_id == 'block_custom_block_delete') {
$form['#submit'][] = 'example_device_blocks_delete_submit';
}
}
/**
* Returns block visibility.
* @param string $module
* @param int $delta
*/
function _example_device_blocks_load($module, $delta, $filter = FALSE, $current_device = '') {
$block = NULL;
if ($filter) {
$result = db_query("SELECT device_type FROM {example_device_blocks} WHERE module = :module AND delta = :delta AND device_type = :device_type", array(':module' => $module, ':delta' => $delta, ':device_type' => $current_device));
}
else {
$result = db_query("SELECT device_type FROM {example_device_blocks} WHERE module = :module AND delta = :delta", array(':module' => $module, ':delta' => $delta));
}
foreach ($result as $record) {
$block[] = $record->device_type;
}
return $block;
}
/**
* Forms API submit callback called from domain_blocks_form_alter().
*/
function example_device_blocks_form_submit($form, &$form_state) {
$values = $form_state['values'];
if (!isset($values['module'])) {
$values['module'] = 'block';
}
if (!isset($values['delta'])) {
$values['delta'] = $values['bid'];
}
// Delta may be zero for other modules than block.
if (!$values['delta'] && $values['module'] == 'block') {
$values['delta'] = db_query("SELECT MAX(bid) FROM {block_custom}")->fetchField();
}
$device_types = array();
if (!empty($values['device_types'])) {
foreach ($values['device_types'] as $device_types_name => $device_type) {
if (!empty($device_type)) {
$device_types[] = $device_type;
}
}
}
example_device_blocks_save($values['module'], $values['delta'], $device_types, $values['previous_device_options']);
}
/**
* Submit handler for user defined block deletion
*/
function example_device_blocks_delete_submit($form, &$form_state) {
db_delete('example_device_blocks')
->condition('module', 'block')
->condition('delta', $form_state['values']['bid'])
->execute();
}
/**
* @param string $module
* @param string $delta
*/
function example_device_blocks_save($module, $delta, $device_types, $previous_device_types) {
if (empty($device_types)) {
if (!empty($previous_device_types)) {
db_delete('example_device_blocks')
->condition('module', $module)
->condition('delta', $delta)
->execute();
}
}
else {
if (empty($previous_device_types)) {
db_delete('example_device_blocks')
->condition('module', $module)
->condition('delta', $delta)
->execute();
foreach ($device_types as $device_type) {
$id = db_insert('example_device_blocks')
->fields(array(
'module' => $module,
'delta' => $delta,
'device_type' => $device_type,
))
->execute();
}
}
else {
$devices_to_be_removed = array_diff($previous_device_types, $device_types);
if (!empty($devices_to_be_removed)) {
if (isset($devices_to_be_removed)) {
db_delete('example_device_blocks')
->condition('module', $module)
->condition('delta', $delta)
->condition('device_type', $devices_to_be_removed, 'IN')
->execute();
}
}
$devices_to_be_added = array_diff($device_types, $previous_device_types);
if (!empty($devices_to_be_added)) {
foreach ($devices_to_be_added as $device_type) {
$id = db_insert('example_device_blocks')
->fields(array(
'module' => $module,
'delta' => $delta,
'device_type' => $device_type,
))
->execute();
}
}
}
}
}
/**
* Implements hook_block_list_alter().
* @param type $blocks
*/
function example_device_blocks_block_list_alter(&$blocks) {
if (!path_is_admin(current_path())) {
$browser = _example_device_blocks_get_browser();
$current_device = '';
if ($browser['is_mobile']) {
$current_device = 'smalltouch';
}
if ($browser['is_tablet']) {
$current_device = 'tablet';
}
if ($browser['is_desktop']) {
$current_device = 'non_mobile';
}
if ($browser['is_mobile'] || $browser['is_tablet'] || $browser['is_desktop']) {
foreach ($blocks as $key => $block) {
if ($block->region != -1) {
$device_options = _example_device_blocks_load($block->module, $block->delta, TRUE, $current_device);
if (!empty($device_options)) {
unset($blocks[$key]);
}
}
}
}
}
}
/**
* Return a device context.
* Wrapper for mobile_detect_get_object()
*/
function _example_device_blocks_get_browser($setcookie = FALSE) {
$browser['is_mobile'] = NULL;
$browser['is_tablet'] = NULL;
$browser['is_desktop'] = NULL;
$browser['md_debug'] = NULL;
$browser['current_device'] = 'undetected';
if (!isset($_COOKIE['current_device']) || $_COOKIE['current_device'] == 'undetected') {
if (function_exists('mobile_detect_get_object')) {
$detect = mobile_detect_get_object();
if ($detect) {
$browser['md_debug'] = $detect;
$browser['is_mobile'] = $detect->isMobile();
$browser['is_tablet'] = $detect->isTablet();
if (!$browser['is_tablet'] && !$browser['is_mobile']) {
$browser['is_desktop'] = TRUE;
}
if ($browser['is_mobile']) {
$browser['current_device'] = 'smalltouch';
}
if ($browser['is_tablet']) {
$browser['current_device'] = 'tablet';
}
if ($browser['is_desktop']) {
$browser['current_device'] = 'non_mobile';
}
}
}
if ($setcookie) {
$params = session_get_cookie_params();
setcookie("md_debug", $browser['md_debug'], REQUEST_TIME + 7200, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
setcookie("current_device", $browser['current_device'], REQUEST_TIME + 7200, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
setcookie("is_mobile", $browser['is_mobile'], REQUEST_TIME + 7200, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
setcookie("is_tablet", $browser['is_tablet'], REQUEST_TIME + 7200, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
setcookie("is_desktop", $browser['is_desktop'], REQUEST_TIME + 7200, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
}
else {
$browser['current_device'] = isset($_COOKIE['current_device']) ? $_COOKIE['current_device'] : $browser['current_device'];
$browser['md_debug'] = isset($_COOKIE['md_debug']) ? $_COOKIE['md_debug'] : $browser['md_debug'];
$browser['is_mobile'] = isset($_COOKIE['is_mobile']) ? $_COOKIE['is_mobile'] : $browser['is_mobile'];
$browser['is_tablet'] = isset($_COOKIE['is_tablet']) ? $_COOKIE['is_tablet'] : $browser['is_tablet'];
$browser['is_desktop'] = isset($_COOKIE['is_desktop']) ? $_COOKIE['is_desktop'] : $browser['is_desktop'];
}
return $browser;
}
/**
* Called via settings.inc; needs to be added to settings.php manually.
*/
function example_device_blocks_mobile_detect_preboot() {
$browser = _example_device_blocks_get_browser(TRUE);
if (is_array($browser)) {
_example_device_blocks_add_query_string('device=' . $browser['current_device']);
}
}
function _example_device_blocks_add_query_string($str) {
if (isset($_SERVER['REQUEST_URI'])) {
if (strpos($_SERVER['REQUEST_URI'], '?') === FALSE) {
$_SERVER['REQUEST_URI'] .= ('?' . $str);
}
else {
$_SERVER['REQUEST_URI'] .= ('&' . $str);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment