Last active
September 29, 2015 07:18
-
-
Save davereid/1566015 to your computer and use it in GitHub Desktop.
Useful D7 custom functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Block integration for the custom module. | |
*/ | |
/** | |
* Implements hook_block_view(). | |
*/ | |
function custom_block_view($delta) { | |
$function = 'custom_block_view_' . strtr($delta, '-', '_'); | |
if (function_exists($function)) { | |
return $function(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Drush integration for the custom module. | |
*/ | |
/** | |
* Implements hook_drush_cache_clear(). | |
*/ | |
function custom_drush_cache_clear(&$types) { | |
if (drush_drupal_major_version() >= 7) { | |
$types['bootstrap'] = 'custom_drush_cache_clear_bootstrap'; | |
// @todo Remove when http://drupal.org/node/1899468 is fixed. | |
if (drush_has_boostrapped(DRUSH_BOOTSTRAP_DRUPAL_FULL)) { | |
$types['entity'] = 'entity_info_cache_clear'; | |
$types['field'] = 'field_cache_clear'; | |
} | |
} | |
} | |
/** | |
* Clears the bootstrap cache. | |
*/ | |
function custom_local_drush_cache_clear_bootstrap() { | |
cache_clear_all('*', 'cache_bootstrap', TRUE); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Implements hook_hook_info_alter(). | |
*/ | |
function custom_hook_info(&$info) { | |
// Add modulename.group.inc support for most core hooks. | |
$groups['block'] = array('block_configure', 'block_info', 'block_info_alter', 'block_list_alter', 'block_save', 'block_view', 'block_view_alter'); | |
$groups['comment'] = array('comment_delete', 'comment_insert', 'comment_load', 'comment_presave', 'comment_publish', 'comment_unpublish', 'comment_update', 'comment_view', 'comment_view_alter'); | |
$groups['cron'] = array('cron', 'cron_queue_info', 'cron_queue_info_alter'); | |
$groups['date'] = array('date_formats', 'date_formats_alter', 'date_format_types', 'date_format_types_alter'); | |
$groups['entity'] = array('entity_delete', 'entity_info', 'entity_info_alter', 'entity_insert', 'entity_load', 'entity_prepare_view', 'entity_presave', 'entity_query_alter', 'entity_update', 'entity_view' ,'entity_view_alter'); | |
$groups['file'] = array('file_copy', 'file_delete', 'file_download', 'file_download_access', 'file_download_access_alter', 'file_insert', 'file_load', 'file_mimetype_mapping_alter', 'file_move', 'file_presave', 'file_update', 'file_url_alter', 'file_validate'); | |
$groups['image'] = array('image_default_styles', 'image_effect_info', 'image_effect_info_alter', 'image_styles_alter', 'image_style_delete', 'image_style_flush', 'image_style_save', 'image_toolkits'); | |
// Contrib modules. | |
$groups['admin_menu'] = array('admin_menu_replacements', 'admin_menu_output_build', 'admin_menu_output_alter', 'admin_menu_map', 'admin_menu_map_alter', 'admin_menu_cache_info'); | |
foreach ($groups as $group => $hooks) { | |
$info += array_fill_keys($hooks, array('group' => $group)); | |
} | |
} | |
/** | |
* Implements hook_menu(). | |
*/ | |
function custom_menu() { | |
$items = array(); | |
return $items; | |
} | |
/** | |
* Implements hook_menu_alter(). | |
*/ | |
function custom_menu_alter(&$items) { | |
// Make the delete page for nodes show up as a tab. | |
$items['node/%node/delete']['context'] = MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE; | |
} | |
/** | |
* Implements hook_node_view(). | |
*/ | |
function custom_node_view($node, $view_mode, $langcode) { | |
if (module_exists('comment') && $view_mode == 'teaser') { | |
_custom_node_add_unpublished_comments_link($node, $langcode); | |
} | |
} | |
function _custom_node_add_unpublished_comments_link($node, $langcode) { | |
if ($node->comment != COMMENT_NODE_HIDDEN && user_access('administer comments')) { | |
$unpublished_count = db_query('SELECT COUNT(cid) FROM {comment} WHERE nid = :nid AND status = :status', array( | |
':nid' => $node->nid, | |
':status' => COMMENT_NOT_PUBLISHED, | |
))->fetchField(); | |
if (!empty($unpublished_count)) { | |
$node->content['links']['comment']['#links']['comment-unpublished-comments'] = array( | |
'title' => format_plural($unpublished_count, '1 unpublished comment', '@count unpublished comments', array(), array('langcode' => $langcode)), | |
'href' => "node/$node->nid", | |
'fragment' => 'comments', | |
); | |
} | |
} | |
} | |
/** | |
* Filter an array of node objects based if the results of node_access(). | |
*/ | |
function custom_array_filter_node_access(array $nodes, $op = 'view', $account = NULL) { | |
$return = array(); | |
foreach ($nodes as $node) { | |
if (node_access($op, $node, $account)) { | |
$return[$node->nid] = $node; | |
} | |
} | |
return $return; | |
} | |
/** | |
* Returns a specific field value, column, and delta. | |
* | |
* @param $entity_type | |
* The type of $entity; e.g., 'node' or 'user'. | |
* @param $entity | |
* The entity containing the data to be displayed. | |
* @param $field_name | |
* The field to retrieve. | |
* @param $column | |
* The column in the field data to retrieve. Default is NULL which will | |
* return the entire field's data array. | |
* @param $delta | |
* The specific delta of the field values to return. Default is 0. If NULL is | |
* provided then all the field delta values will be returned. | |
* | |
* @return | |
* A field value, or an array of field values, or NULL if no field values | |
* were available. | |
* | |
* @see field_get_items() | |
* @see custom_array_extract_values() | |
*/ | |
function custom_field_get_value($entity_type, $entity, $field_name, $column = NULL, $delta = 0) { | |
if (!empty($entity) && $items = field_get_items($entity_type, $entity, $field_name)) { | |
if (isset($column)) { | |
$items = custom_extract_nested_values_to_array($items, array($column)); | |
} | |
if (isset($delta)) { | |
if (isset($items[$delta])) { | |
return $items[$delta]; | |
} | |
} | |
else { | |
return $items; | |
} | |
} | |
} | |
/** | |
* Extract array values out from an array of field items. | |
* | |
* @param $entity_type | |
* The entity type | |
* @param $entity | |
* An entity object of type $entity_type. | |
* @param $field | |
* A field name. | |
* @param $key | |
* A key to pass into custom_array_extract_values(). | |
* | |
* @return | |
* An array of field values. | |
* | |
* @see custom_array_extract_values() | |
* @see field_get_items() | |
*/ | |
function custom_field_extract_values($entity_type, $entity, $field, $column) { | |
if (!empty($entity) && $items = field_get_items($entity_type, $entity, $field)) { | |
return custom_extract_nested_values_to_array($items, array($column)); | |
} | |
return array(); | |
} | |
/** | |
* Find the delta value of a field item's value. | |
* | |
* @param $entity_type | |
* The entity type | |
* @param $entity | |
* An entity object of type $entity_type. | |
* @param $field | |
* A field name. | |
* @param $column | |
* The column that should have its value compared to $value. | |
* @param $value | |
* The field value to compare to. | |
* | |
* @return | |
* The delta value of the field value if found, which can evaluate to zero. | |
* If the field value is not found, FALSE will be returned. | |
*/ | |
function custom_field_get_value_delta($entity_type, $entity, $field, $column, $value) { | |
if (!empty($entity) && $items = field_get_items($entity_type, $entity, $field)) { | |
foreach ($items as $delta => $item) { | |
if (isset($item[$column]) && $item[$column] == $value) { | |
return $delta; | |
} | |
} | |
} | |
return FALSE; | |
} | |
/** | |
* Check if an entity's field has a specific delta value. | |
* | |
* @param $entity_type | |
* The entity type | |
* @param $entity | |
* An entity object of type $entity_type. | |
* @param $field | |
* A field name. | |
* @param $delta | |
* A delta value to check. | |
* | |
* @return bool | |
* TRUE is the entity's field has a value with the specific delta, or FALSE | |
* otherwise. | |
*/ | |
function custom_field_has_delta($entity_type, $entity, $field, $delta) { | |
if (!empty($entity) && $items = field_get_items($entity_type, $entity, $field)) { | |
return !empty($items[$delta]); | |
} | |
} | |
/** | |
* Duplicate of field_view_value() that extracts $item automatically by delta. | |
* | |
* @see field_view_value() | |
*/ | |
function custom_field_view_value($entity_type, $entity, $field_name, $delta = 0, $display = array(), $langcode = NULL) { | |
$output = array(); | |
if ($item = custom_field_get_value($entity_type, $entity, $field_name, NULL, $delta)) { | |
// Determine the langcode that will be used by language fallback. | |
$langcode = field_language($entity_type, $entity, $field_name, $langcode); | |
// Push the item as the single value for the field, and defer to | |
// field_view_field() to build the render array for the whole field. | |
$clone = clone $entity; | |
$clone->{$field_name}[$langcode] = array($item); | |
$elements = field_view_field($entity_type, $clone, $field_name, $display, $langcode); | |
// Extract the part of the render array we need. | |
$output = isset($elements[0]) ? $elements[0] : array(); | |
if (isset($elements['#access'])) { | |
$output['#access'] = $elements['#access']; | |
} | |
} | |
return $output; | |
} | |
/** | |
* Filter an array of objects or nested arrays by a variable depth value. | |
* | |
* @param array $items | |
* An array of objects or arrays to filter. | |
* @param array $parents | |
* An array of parent keys of the value, starting with the outermost key. | |
* @param mixed $value | |
* A value or array of values to match using custom_get_nested_value(). | |
* | |
* @return array | |
* An array of items that matched nested value $value. | |
*/ | |
function custom_filter_by_nested_value(array $items, array $parents, $value) { | |
$return = array(); | |
foreach ($items as $key => $item) { | |
$key_exists = FALSE; | |
$found_value = custom_get_nested_value($item, $parents, $key_exists); | |
if ($key_exists) { | |
if (is_array($value) && in_array($found_value, $value)) { | |
$return[$key] = $item; | |
} | |
elseif ($found_value == $value) { | |
$return[$key] = $item; | |
} | |
} | |
} | |
return $return; | |
} | |
/** | |
* Retrieves a value from an object or nested array with variable depth. | |
* | |
* This is a copy of drupal_array_get_nested_value() but with added support | |
* for objects. | |
* | |
* @param mixed $item | |
* The array or object from which to get the value. | |
* @param array $parents | |
* An array of parent keys of the value, starting with the outermost key. | |
* @param bool $key_exists | |
* (optional) If given, an already defined variable that is altered by | |
* reference if all the keys in $parents were found. | |
* | |
* @return mixed | |
* The requested nested value. Possibly NULL if the value is NULL or not all | |
* nested parent keys exist. $key_exists is altered by reference and is a | |
* Boolean that indicates whether all nested parent keys exist (TRUE) or not | |
* (FALSE). This allows to distinguish between the two possibilities when | |
* NULL is returned. | |
*/ | |
function custom_get_nested_value($item, array $parents, &$key_exists = NULL) { | |
$ref = $item; | |
foreach ($parents as $parent) { | |
if (is_array($ref) && array_key_exists($parent, $ref)) { | |
$ref = &$ref[$parent]; | |
} | |
elseif (is_object($ref) && property_exists($ref, $parent)) { | |
$ref = $ref->$parent; | |
} | |
elseif (is_object($ref) && method_exists($ref, '__get') && $ref->__get($parent) !== NULL) { | |
// Support objects that override the __get magic method. | |
// This also doesn't support if $ref->$parent exists but is set to NULL. | |
$ref = $ref->$parent; | |
} | |
else { | |
$key_exists = FALSE; | |
return NULL; | |
} | |
} | |
$key_exists = TRUE; | |
return $ref; | |
} | |
/** | |
* Extract an associative key/value array from an array of arrays or objects. | |
* | |
* @param $items | |
* An array of objects or arrays. | |
* @param array $value_parents | |
* An array of parent keys of the value, starting with the outermost key. | |
* @param array $key_parents | |
* (optional) An array of parent keys of the key to return for each item, | |
* starting with the outermost key. If not provided, the key of the item in | |
* $items will be used as the returned key. | |
*/ | |
function custom_extract_nested_values_to_array(array $items, array $value_parents, array $key_parents = NULL) { | |
$return = array(); | |
foreach ($items as $index => $item) { | |
$key = isset($key_parents) ? custom_get_nested_value($item, $key_parents) : $index; | |
$return[$key] = custom_get_nested_value($item, $value_parents); | |
} | |
return $return; | |
} | |
/** | |
* Attempt to load the current node. This is useful for sites that use Panels for node pages. | |
*/ | |
function custom_get_current_node($check_access = FALSE) { | |
$node = &drupal_static(__FUNCTION__); | |
if (!isset($node)) { | |
$node = FALSE; | |
if (preg_match('/node\/(\d+)/', current_path, $matches)) { | |
$node = node_load($matches[1]); | |
if ($check_access && !node_access('view', $node)) { | |
$node = FALSE; | |
} | |
} | |
} | |
return $node; | |
} | |
/** | |
* Add an array of classes to the body. | |
* | |
* @param $classes | |
* A string or an array of class strings to add. | |
*/ | |
function custom_add_class($classes, $hook = 'body') { | |
if (!is_array($classes)) { | |
$classes = array($classes); | |
} | |
$static = &drupal_static('custom_classes', array()); | |
if (!isset($static[$hook]['add'])) { | |
$static[$hook]['add'] = array(); | |
} | |
foreach ($classes as $class) { | |
$static[$hook]['add'][] = $class; | |
} | |
} | |
/** | |
* Remove an array of classes from the body. | |
* | |
* @param $classes | |
* A string or an array of class strings to remove. | |
*/ | |
function custom_remove_class($classes, $hook = 'body') { | |
if (!is_array($classes)) { | |
$classes = array($classes); | |
} | |
$static = &drupal_static('custom_classes', array()); | |
if (!isset($static[$hook]['remove'])) { | |
$static[$hook]['remove'] = array(); | |
} | |
foreach ($classes as $class) { | |
$static[$hook]['remove'][] = $class; | |
} | |
} | |
/** | |
* Implements hook_process() | |
* | |
* This essentially works like panels_preprocess_html(). | |
*/ | |
function custom_process(&$variables, $hook) { | |
if (!isset($variables['classes'])) { | |
return; | |
} | |
$classes = drupal_static('custom_classes', array()); | |
if (!empty($classes[$hook]['add'])) { | |
$add_classes = array_map('drupal_clean_css_identifier', $classes[$hook]['add']); | |
$variables['classes_array'] = array_unique(array_merge($variables['classes_array'], $add_classes)); | |
} | |
if (!empty($classes[$hook]['remove'])) { | |
$remove_classes = array_map('drupal_clean_css_identifier', $classes[$hook]['remove']); | |
$variables['classes_array'] = array_diff($variables['classes_array'], $remove_classes); | |
} | |
// Since this runs after template_process(), we need to re-implode the | |
// classes array. | |
$variables['classes'] = implode(' ', $variables['classes_array']); | |
} | |
/** | |
* Implements hook_ajax_render_alter(). | |
*/ | |
function custom_ajax_render_alter() { | |
// Disable XHProf module on any AJAX requests. | |
// @todo Remove when http://drupal.org/node/1485190 is fixed. | |
$GLOBALS['conf']['xhprof_enabled'] = FALSE; | |
} | |
/** | |
* A lightweight version of entity save for field values only. | |
*/ | |
custom_entity_fields_update($entity_type, $entity) { | |
list($id) = entity_extract_ids($entity_type, $entity); | |
if (empty($id)) { | |
trigger_error('Cannot call custom_entity_fields_update() on a new entity.'); | |
return FALSE; | |
} | |
// Some modules use the original property. | |
if (!isset($entity->original)) { | |
$entity->original = $entity; | |
} | |
// Ensure that file_field_update() will not trigger additional usage. | |
unset($entity->revision); | |
// Invoke the field presave and update hooks. | |
field_attach_presave($entity_type, $entity); | |
field_attach_update($entity_type, $entity); | |
// Clear the cache for this entity now. | |
entity_get_controller($entity_type)->resetCache(array($id)); | |
} | |
function custom_get_fields_by_type($type) { | |
$fields = array(); | |
foreach (field_info_field_map() as $field_name => $field_map) { | |
if ($field_map['type'] == $type) { | |
$fields[$field_name] = field_info_field($field_name); | |
} | |
} | |
return $fields; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FYI I've taken all the reusable API functions and wrapped them up into an updateable module called helper: http://drupal.org/project/helper. I will likely not be maintaining this gist anymore.