responsive_favicons.module in Responsive Favicons 7
Same filename and directory in other branches
Responsive favicons module file.
File
responsive_favicons.moduleView source
<?php
/**
* @file
* Responsive favicons module file.
*/
/**
* Implements hook_help().
*/
function responsive_favicons_help($path, $arg) {
switch ($path) {
case 'admin/help#responsive_favicons':
$readme_file = dirname(__FILE__) . '/README.txt';
if (file_exists($readme_file)) {
$readme = file_get_contents($readme_file);
}
if (!isset($readme)) {
return '';
}
// Markdown is optionally supported if you already have it installed.
if (module_exists('markdown')) {
$filters = module_invoke('markdown', 'filter_info');
$info = $filters['filter_markdown'];
if (function_exists($info['process callback'])) {
$function = $info['process callback'];
$output = filter_xss_admin($function($readme, NULL));
}
else {
$output = '<pre>' . check_plain($readme) . '</pre>';
}
}
else {
$output = '<pre>' . check_plain($readme) . '</pre>';
}
return $output;
}
}
/**
* Implements hook_permission().
*/
function responsive_favicons_permission() {
return array(
'administer responsive favicons' => array(
'title' => t('Administer responsive favicons'),
),
);
}
/**
* Implements hook_menu().
*/
function responsive_favicons_menu() {
// List of icons to redirect.
// Note, in order for these to work alter the fast404 pattern to allow these
// requests to hit Drupal. Please see the README for more information.
$icons = array(
'apple-touch-icon.png',
'apple-touch-icon-precomposed.png',
'browserconfig.xml',
);
// Try to avoid clashing with the favicon module.
if (!module_exists('favicon')) {
$icons[] = 'favicon.ico';
}
foreach ($icons as $icon) {
$items[$icon] = array(
'page callback' => 'responsive_favicons_get_file',
'page arguments' => array(
$icon,
),
'delivery callback' => 'responsive_favicons_deliver_file',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
'file' => 'responsive_favicons.delivery.inc',
);
}
$items['admin/config/user-interface/responsive_favicons'] = array(
'title' => 'Responsive favicons',
'description' => 'Configure responsive favicons',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'responsive_favicons_config_page',
),
'access callback' => 'user_access',
'access arguments' => array(
'administer responsive favicons',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'responsive_favicons.admin.inc',
);
return $items;
}
/**
* Implements hook_page_build().
*
* Adds responsive favicons to HTML head. A trailing newline is added to ensure
* the next tag in the HTML head section starts on the next line.
*/
function responsive_favicons_page_build(&$page) {
$tags = responsive_favicons_load_all_icons();
if (!empty($tags['found'])) {
$html = array(
'#type' => 'markup',
'#markup' => implode(PHP_EOL, $tags['found']) . PHP_EOL,
);
drupal_add_html_head($html, 'responsive_favicons');
}
}
/**
* Implements hook_html_head_alter().
*/
function responsive_favicons_html_head_alter(&$head_elements) {
$favicon_remove_default = variable_get('responsive_favicons_remove_default', 0);
if (empty($head_elements['responsive_favicons']) || $favicon_remove_default == 0) {
return;
}
// Remove the default favicon from the head section.
foreach ($head_elements as $key => $element) {
if (!empty($element['#attributes'])) {
if (array_key_exists('rel', $element['#attributes'])) {
if ($element['#attributes']['rel'] === 'shortcut icon') {
unset($head_elements[$key]);
}
}
}
}
}
/**
* Load the responsive favicons that are valid.
*/
function responsive_favicons_load_all_icons() {
$icons =& drupal_static(__FUNCTION__);
if (!isset($icons)) {
if ($cached = cache_get('responsive_favicons_icons', 'cache')) {
$icons = $cached->data;
}
else {
$responsive_favicon_tags = variable_get('responsive_favicons_tags', '');
if (empty($responsive_favicon_tags)) {
$icons = array(
'found' => array(),
'missing' => array(),
);
}
else {
$html = implode(PHP_EOL, $responsive_favicon_tags);
$icons = _responsive_favicons_validate_tags($html);
if (empty($icons['missing'])) {
cache_set('responsive_favicons_icons', $icons, 'cache');
}
}
}
}
return $icons;
}
/**
* Helper function to check whether responsive favicon files exist and are
* readable. This function also strips any pasted content that is not a link
* or a meta tag.
*
* @param string $html
* html tag
* @return array $missing_files
*/
function _responsive_favicons_validate_tags($html) {
global $base_path;
$found = array();
$missing = array();
$dom = new DOMDocument();
$dom
->loadHTML($html);
// DRUPAL_ROOT contains the sub directory of the Drupal install (if present),
// in our case we do not want this as $file_path already contains this.
$docroot = preg_replace('/' . preg_quote($base_path, '/') . '$/', '/', DRUPAL_ROOT);
// Find all the apple touch icons.
$tags = $dom
->getElementsByTagName('link');
foreach ($tags as $tag) {
$url_path = _responsive_favicons_normalise_path($tag
->getAttribute('href'));
$file_path = parse_url($url_path, PHP_URL_PATH);
$tag
->setAttribute('href', $url_path);
if (file_exists($docroot . $file_path) && is_readable($docroot . $file_path)) {
$found[] = $dom
->saveXML($tag);
}
else {
$missing[] = $dom
->saveXML($tag);
}
}
// Find any Windows 8 meta tags.
$tags = $dom
->getElementsByTagName('meta');
foreach ($tags as $tag) {
$name = $tag
->getAttribute('name');
// We only validate the image file.
if ($name === 'msapplication-TileImage') {
$file_path = _responsive_favicons_normalise_path($tag
->getAttribute('content'));
$tag
->setAttribute('content', $file_path);
if (file_exists($docroot . $file_path) && is_readable($docroot . $file_path)) {
$found[] = $dom
->saveXML($tag);
}
else {
$missing[] = $dom
->saveXML($tag);
}
}
else {
$found[] = $dom
->saveXML($tag);
}
}
return array(
'found' => $found,
'missing' => $missing,
);
}
/**
* Help to normalise the path to the icons.
*
* @param $file_path
* The filename of the icon.
* @return string
* The full relative path to the icon within public files.
*/
function _responsive_favicons_normalise_path($file_path) {
global $base_path;
// Remove absolute URLs.
if (url_is_external($file_path)) {
$file_path = str_replace($base_path, '', $file_path);
}
// There appears to be no sane way of getting a relative path to a file, so
// this is the best for now.
// @see https://www.drupal.org/node/837794#comment-9124435
$wrapper = file_stream_wrapper_get_instance_by_uri('public://');
if ($wrapper instanceof DrupalLocalStreamWrapper) {
$relative_path = $wrapper
->getDirectoryPath() . '/' . variable_get('responsive_favicons_path', 'favicons') . $file_path;
}
return $base_path . $relative_path;
}
Functions
Name | Description |
---|---|
responsive_favicons_help | Implements hook_help(). |
responsive_favicons_html_head_alter | Implements hook_html_head_alter(). |
responsive_favicons_load_all_icons | Load the responsive favicons that are valid. |
responsive_favicons_menu | Implements hook_menu(). |
responsive_favicons_page_build | Implements hook_page_build(). |
responsive_favicons_permission | Implements hook_permission(). |
_responsive_favicons_normalise_path | Help to normalise the path to the icons. |
_responsive_favicons_validate_tags | Helper function to check whether responsive favicon files exist and are readable. This function also strips any pasted content that is not a link or a meta tag. |