linkicon.module in Link Icon 7
Same filename and directory in other branches
A link field formatter to create icon classes based on predefined titles.
File
linkicon.moduleView source
<?php
/**
* @file
* A link field formatter to create icon classes based on predefined titles.
*/
/**
* Defines linkicon defaults.
*/
function linkicon_defaults() {
return array(
'linkicon_prefix' => 'icon',
'linkicon_icon_class' => '',
'linkicon_wrapper_class' => '',
'linkicon_global_title' => '',
'linkicon_size' => '',
'linkicon_no_text' => '',
'linkicon_position' => '',
'linkicon_load' => 0,
'linkicon_vertical' => 0,
'linkicon_tooltip' => 0,
'linkicon_maxlength' => '',
'linkicon_style' => '',
'linkicon_color' => '',
'linkicon_font' => '',
'linkicon_bundle' => '',
);
}
/**
* Returns simplified linkicon settings without `linkicon_` prefix.
*/
function linkicon_simplify_settings(array $configs = array()) {
$settings = array();
foreach (array_merge(linkicon_defaults(), $configs) as $key => $value) {
$settings[str_replace('linkicon_', '', $key)] = $value;
}
return $settings;
}
/**
* Implements hook_theme().
*/
function linkicon_theme($existing, $type, $theme, $path) {
$common = array(
'render element' => 'element',
'file' => 'linkicon.theme.inc',
);
return array(
'linkicon' => $common,
'linkicon_item' => $common,
);
}
/**
* Implements hook_field_formatter_info().
*/
function linkicon_field_formatter_info() {
return array(
'linkicon' => array(
'label' => t('Link icon, based on title'),
'field types' => array(
'link_field',
'text',
),
'settings' => linkicon_defaults(),
),
);
}
/**
* Implements hook_field_formatter_prepare_view().
*/
function linkicon_field_formatter_prepare_view($entity_type, $entities, $field, $instances, $langcode, &$items, $displays) {
// Unlike D8, we need to loop first to reach our settings.
foreach ($items as $entity_id => $entity_items) {
if (isset($instances[$entity_id]['settings']['title']) && $instances[$entity_id]['settings']['title'] == 'predefined' && isset($instances[$entity_id]['settings']['title_predefined']) && $instances[$entity_id]['settings']['title_predefined']) {
$title_predefined = linkicon_extract_allowed_values($instances[$entity_id]['settings']['title_predefined']);
$title_tooltip = linkicon_extract_allowed_values($instances[$entity_id]['settings']['title_predefined'], TRUE);
foreach ($entity_items as $delta => $value) {
$items[$entity_id][$delta]['display_title'] = $title_predefined[$value['title']];
if (isset($title_tooltip[$value['title']])) {
$items[$entity_id][$delta]['tooltip'] = $title_tooltip[$value['title']];
}
}
}
}
}
/**
* Implements hook_field_formatter_view().
*/
function linkicon_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
$element = array();
if (empty($items) || $display['type'] != 'linkicon') {
return $element;
}
$path = drupal_get_path('module', 'linkicon');
$field_type = $field['type'];
$field_name = $instance['field_name'];
list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
$config = linkicon_simplify_settings($display['settings']);
$prefix_class = check_plain($config['prefix']);
$contents = array();
foreach ($items as $delta => $item) {
// The A tag attributes.
$attributes = array();
$attributes['class'][] = 'linkicon__item';
// Linkicon requires both link text and URL available with proper
// validation during input, no need extra checks.
$icon_name = $field_type == 'link_field' ? $item['title'] : check_plain(strip_tags($item['value']));
$display_title = isset($item['display_title']) ? $item['display_title'] : $icon_name;
$tooltip = isset($item['tooltip']) ? $item['tooltip'] : $display_title;
$icon_class = drupal_clean_css_identifier(drupal_strtolower($prefix_class . '-' . $icon_name));
// This is similar as widget setting Static title, only available at
// Display for more flexible options by view modes.
if (!empty($config['global_title']) && empty($config['no_text'])) {
$display_title = $config['global_title'];
}
// Sanitize $display_title before use since html is TRUE for the link.
$item['html'] = TRUE;
// Tokenized text is sanitized by default.
$display_title = token_replace($display_title, array(
$entity_type => $entity,
));
$character_maxlength = isset($config['maxlength']) && $config['maxlength'] ? $config['maxlength'] : 60;
$icon_element = array(
'#theme' => 'linkicon_item',
'#title' => truncate_utf8($display_title, $character_maxlength, TRUE, TRUE),
'#icon_name' => check_plain($icon_name),
'#settings' => $config,
);
$item['title'] = drupal_render($icon_element);
// Link module stores classes as spaced string.
if (!empty($item['attributes']['class'])) {
$attributes['class'] = array_merge(array(
$item['attributes']['class'],
), $attributes['class']);
}
// Unlike D8 link module, D7 link expect a spaced string, so feed it.
$item['attributes']['class'] = implode(" ", $attributes['class']);
// Our pure CSS3 tooltip depends on data-title.
if ($config['tooltip']) {
$tooltip = token_replace($tooltip, array(
$entity_type => $entity,
));
$item['attributes']['data-title'] = truncate_utf8($tooltip, $character_maxlength, TRUE, TRUE);
}
// We are done for the item, pass it over to link to do its job.
$contents[$delta] = array(
'#theme' => 'link_formatter_link_default',
'#element' => $item,
'#field' => $instance,
'#display' => $display,
);
}
// Build own wrapper for greater control.
$config['id'] = drupal_clean_css_identifier("linkicon-{$entity_type}-{$bundle}-{$field_name}-{$id}");
$element[0] = array(
'#theme' => 'linkicon',
'#items' => $contents,
'#config' => $config,
);
// Attached our assets if so configured.
if (!empty($config['load'])) {
$element[0]['#attached']['css'][] = array(
'data' => $path . '/css/linkicon.css',
);
if ($config['font'] && empty($config['bundle'])) {
$element[0]['#attached']['css'][] = array(
'data' => strip_tags($config['font']),
);
}
}
return $element;
}
/**
* Extracts link title textarea values into array for link title select options.
*/
function linkicon_extract_allowed_values($values, $is_tooltip = FALSE) {
$allowed_values = array();
if ($values) {
$list = explode("\n", strip_tags($values));
foreach ($list as $value) {
if (strpos($value, "|") !== FALSE) {
list($key, $title, $tooltip) = array_pad(array_map('trim', explode("|", $value, 3)), 3, NULL);
$allowed_values[$key] = $is_tooltip && !empty($tooltip) ? $tooltip : $title;
}
else {
$allowed_values[$value] = $value;
}
}
}
return $allowed_values;
}
/**
* Implements hook_element_info_alter().
*/
function linkicon_element_info_alter(&$types) {
$types['link_field']['#process'][] = 'linkicon_field_process';
}
/**
* Implements hook_field_info_alter().
*/
function linkicon_field_info_alter(&$info) {
if (isset($info['link_field'])) {
$info['link_field']['settings']['title_predefined'] = '';
$info['link_field']['instance_settings']['title_predefined'] = '';
}
}
/**
* Overrides link_field_process() to use a select box.
*/
function linkicon_field_process($element, $form_state, $complete_form) {
$instance = field_widget_instance($element, $form_state);
$settings = $instance['settings'];
if (isset($settings['title_predefined']) && $settings['title_predefined'] && $settings['title'] == 'predefined') {
$element['title']['#type'] = 'select';
$element['title']['#options'] = linkicon_extract_allowed_values($settings['title_predefined']);
$element['title']['#empty_option'] = t('- Select -');
$element['title']['#default_value'] = isset($element['#value']['title']) ? $element['#value']['title'] : '';
// Remove irrelevant description.
unset($element['title']['#description']);
$element['#element_validate'] = array(
'_linkicon_element_validate_link_title',
);
}
return $element;
}
/**
* Validate predefined link title.
*
* Since Link title is not required, we make sure that it is not empty if the
* URL field is not. In the opposite, link.module does validation.
*
* @todo: error field receives no error class.
*/
function _linkicon_element_validate_link_title($element, &$form_state, $form) {
if (empty($element['#value']['title']) && !empty($element['#value']['url'])) {
form_set_error($element['#value']['title'], t('Title must be filled in if URL is provided.'));
}
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function linkicon_form_field_ui_display_overview_form_alter(&$form, &$form_state) {
$path = drupal_get_path('module', 'linkicon');
// Needed for preview.
$form['#attached']['css'][] = $path . '/css/linkicon.css';
$form['#attached']['css'][] = $path . '/css/linkicon.field_ui.css';
}
/**
* Implements hook_field_formatter_settings_form().
*/
function linkicon_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
form_load_include($form_state, 'inc', 'linkicon', 'includes/linkicon.admin');
$elements = _linkicon_field_formatter_settings_form($field, $instance, $view_mode, $form, $form_state);
return $elements;
}
/**
* Implements hook_field_formatter_settings_summary().
*/
function linkicon_field_formatter_settings_summary($field, $instance, $view_mode) {
module_load_include('inc', 'linkicon', 'includes/linkicon.admin');
$summary = _linkicon_field_formatter_settings_summary($field, $instance, $view_mode);
return implode('<br />', $summary);
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function linkicon_form_field_ui_field_edit_form_alter(&$form, $form_state) {
form_load_include($form_state, 'inc', 'linkicon', 'includes/linkicon.admin');
_linkicon_form_field_ui_field_edit_form_alter($form, $form_state);
}
/**
* Alters the existing link field widget settings form elements.
*/
function linkicon_field_widget_settings_form_alter(&$form, $settings) {
form_load_include($form_state, 'inc', 'linkicon', 'includes/linkicon.admin');
_linkicon_field_widget_settings_form_alter($form, $settings);
}
/**
* Validate path to icon font CSS file.
*/
function _linkicon_element_validate_font_path($element, &$form_state, $form) {
if (!empty($element['#value']) && !is_file($element['#value'])) {
form_set_error($element['#name'], t("<strong>@css_font_path</strong> doesn't exist.", array(
'@css_font_path' => $element['#value'],
)));
}
}
/**
* Implements hook_help().
*/
function linkicon_help($path, $arg) {
if ($path == 'admin/help#linkicon') {
$output = file_get_contents(dirname(__FILE__) . '/README.md');
return function_exists('_filter_markdown') ? _filter_markdown($output, NULL) : '<pre>' . $output . '</pre>';
}
return '';
}