You are here

icon.module in Icon API 7

Same filename and directory in other branches
  1. 8 icon.module

icon.module Provides icon integration with menu items.

File

icon.module
View source
<?php

/**
 * @file
 * icon.module
 * Provides icon integration with menu items.
 */
define('ICON_ADMIN_PATH', 'admin/config/media/icon');

// Include necessary files. Normally these would all be in the main .module
// file, however it's easier to manage in separate files.
$includes = array(
  'bundles',
  'cache',
  'element',
  'render',
  'theme',
  'utilities',
);
foreach ($includes as $include) {
  require_once dirname(__FILE__) . "/includes/{$include}.inc";
}

/**
 * Implements hook_hook_info().
 */
function icon_hook_info() {
  $hooks = array();
  $icon_hooks = array(
    'icon_bundles',
    'icon_bundle_delete',
    'icon_bundle_list_alter',
    'icon_permission',
    'icon_providers',
    'icon_render_hooks',
  );
  foreach ($icon_hooks as $hook) {
    $hooks[$hook] = array(
      'group' => 'icon',
    );
  }
  return $hooks;
}

/**
 * Implements hook_library().
 */
function icon_library() {
  $libaries_path = drupal_get_path('module', 'icon') . '/libraries';
  $libraries['icon_selector'] = array(
    'title' => 'Icon Selector',
    'website' => 'http://drupal.org/project/icon',
    'version' => '1.0.0',
    'css' => array(
      $libaries_path . '/icon_selector/css/icon_selector.css' => array(),
    ),
    'js' => array(
      $libaries_path . '/icon_selector/js/icon_selector.js' => array(),
      0 => array(
        'type' => 'setting',
        'data' => array(
          'icon_selector' => array(
            'bundles' => array_keys(icon_bundles()),
          ),
        ),
      ),
    ),
  );
  return $libraries;
}

/**
 * Implements hook_menu().
 */
function icon_menu() {
  $module_path = drupal_get_path('module', 'icon');
  $items = array();
  $items[ICON_ADMIN_PATH] = array(
    'title' => 'Icons',
    'description' => 'Overview of all available icons.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'icon_bundle_overview_form',
    ),
    'access arguments' => array(
      'administer icons',
    ),
    'file' => 'admin.inc',
    'file path' => $module_path . '/includes',
  );
  $items[ICON_ADMIN_PATH . '/overview'] = array(
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'title' => 'Bundles',
    'description' => 'Overview of all available icon bundles.',
    'weight' => -10,
  );
  $import_providers = icon_providers_support_import();
  if (!empty($import_providers)) {
    $items[ICON_ADMIN_PATH . '/import'] = array(
      'type' => MENU_LOCAL_TASK,
      'title' => 'Import',
      'description' => 'Import a bundle from a provider.',
      'page callback' => 'drupal_get_form',
      'page arguments' => array(
        'icon_provider_import_form',
      ),
      'access arguments' => array(
        'administer icons',
      ),
      'file' => 'import.inc',
      'file path' => $module_path . '/includes',
    );
  }
  $items[ICON_ADMIN_PATH . '/bundle/%icon_bundle'] = array(
    'title callback' => 'icon_bundle_get_title',
    'title arguments' => array(
      5,
    ),
    'description' => 'An icon bundle.',
    'page callback' => 'icon_bundle_list',
    'page arguments' => array(
      5,
    ),
    'access arguments' => array(
      'administer icons',
    ),
    'theme callback' => 'icon_bundle_get_theme',
    'theme arguments' => array(
      5,
    ),
    'file' => 'admin.inc',
    'file path' => $module_path . '/includes',
  );
  $items[ICON_ADMIN_PATH . '/bundle/%icon_bundle/icons'] = array(
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'title' => 'Icons',
    'description' => 'Provide an overview of all available icon bundles.',
    'weight' => -10,
  );
  $items[ICON_ADMIN_PATH . '/bundle/%icon_bundle/configure'] = array(
    'type' => MENU_LOCAL_TASK,
    'title' => 'Configure',
    'description' => 'Form callback for configuring an icon bundle.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'icon_bundle_configure_form',
      5,
    ),
    'access arguments' => array(
      'administer icons',
    ),
    'file' => 'admin.inc',
    'file path' => $module_path . '/includes',
  );
  $items[ICON_ADMIN_PATH . '/bundle/%icon_bundle/delete'] = array(
    'title' => 'Delete',
    'description' => 'Confirmation page for deleting an icon bundle from the database.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'icon_bundle_delete_form',
      5,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'administer icons',
    ),
    'file' => 'admin.inc',
    'file path' => $module_path . '/includes',
  );
  $items[ICON_ADMIN_PATH . '/bundle/%icon_bundle/reset'] = array(
    'title' => 'Reset',
    'description' => 'Confirmation page for resetting a module or theme provided bundle that has been overridden in the database.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'icon_bundle_reset_form',
      5,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      'administer icons',
    ),
    'file' => 'admin.inc',
    'file path' => $module_path . '/includes',
  );

  // The actual path will be set in hook_menu_alter() but we want the item to be
  // defined here to let the menu system fill-in defaults. To ensure we do not
  // have path collisions, we just temporarily a child of our admin path.
  $view_path_alias = ICON_ADMIN_PATH . '/tmp';
  $items[$view_path_alias] = $items[ICON_ADMIN_PATH];
  $items[$view_path_alias]['access arguments'] = array(
    'view icons',
  );
  $items[$view_path_alias . '/%icon_bundle'] = $items[ICON_ADMIN_PATH . '/bundle/%icon_bundle'];
  $items[$view_path_alias . '/%icon_bundle']['access arguments'] = array(
    'view icons',
  );
  $items[$view_path_alias . '/%icon_bundle']['title arguments'] = array(
    1,
  );
  $items[$view_path_alias . '/%icon_bundle']['page arguments'] = array(
    1,
  );
  $items[$view_path_alias . '/%icon_bundle']['theme arguments'] = array(
    1,
  );
  return $items;
}

/**
 * Implements hook_menu_alter().
 */
function icon_menu_alter(&$items) {

  // Create a path alias for users with the "view icons" permission.
  $view_path_alias = variable_get('icon_api_view_path_alias');

  // If variable is not set and path is not taken, set it.
  if ($view_path_alias === NULL && empty($items['icons'])) {
    $view_path_alias = 'icons';
    variable_set('icon_api_view_path_alias', $view_path_alias);
  }
  $tmp_path = ICON_ADMIN_PATH . '/tmp';
  if (!empty($view_path_alias)) {
    $items[$view_path_alias] = $items[$tmp_path];
    $items[$view_path_alias . '/%icon_bundle'] = $items[$tmp_path . '/%icon_bundle'];
  }
  unset($items[$tmp_path]);
  unset($items[$tmp_path . '/%icon_bundle']);
}

/**
 * Implements hook_permission().
 *
 * Invokes hook_icon_permission() so sub-modules can be grouped together with
 * the Icon API module on the permissions table.
 */
function icon_permission() {
  return array_merge_recursive(array(
    'administer icons' => array(
      'title' => t('Administer Icons'),
      'description' => t('Grants selected roles full administrative permissions for all aspects of the Icon API. It supersedes all permissions below.'),
      'restrict access' => TRUE,
    ),
    'view icons' => array(
      'title' => t('View Icons'),
      'description' => t('Grants selected roles permission to view all icons in enabled bundles.'),
    ),
  ), module_invoke_all('icon_permission'));
}

/**
 * Returns information about icons render hooks.
 *
 * @param string $hook
 *   (optional) The name of the render hook to return information for. If
 *   omitted, render hook information provided by all modules and themes will
 *   be returned.
 * @param bool $reset
 *   Boolean to force reset of the cached data. Default: FALSE.
 *
 * @return array|false
 *   An associative array containing render hook information from all modules
 *   and themes, the information for the render hook specified by $hook, or
 *   FALSE if the render hook $name is not registered.
 *
 * @see hook_icon_render_hooks()
 */
function &icon_render_hooks($hook = NULL, $reset = FALSE) {
  $hooks =& drupal_static(__FUNCTION__);
  if (!isset($hooks) || $reset) {
    if (!$reset && ($cache = cache_get('icon_render_hooks')) && !empty($cache->data)) {
      $hooks = $cache->data;
    }
    else {
      $hooks = array();

      // Gather information from extensions that implement
      // hook_icon_render_hooks().
      foreach (icon_extension_implements('icon_render_hooks') as $extension => $type) {
        $extension_hooks = (array) icon_extension_invoke($type, $extension, 'icon_render_hooks');
        foreach ($extension_hooks as $render_hook => $data) {
          if (!is_string($render_hook) && is_string($data)) {
            $render_hook = $data;
            $data = array();
          }
          $data['name'] = $render_hook;
          $data['type'] = $type;
          $data[$type] = $extension;
          if (!isset($data['file'])) {
            $data['file'] = 'module' === $type ? $extension . '.module' : 'template.php';
          }
          if (!isset($data['path'])) {
            $data['path'] = drupal_get_path($type, $extension);
          }
          $hooks[$render_hook] = $data;
        }
      }

      // Allow extensions to alter render hook information.
      drupal_alter('icon_render_hooks', $hooks);

      // Cache the render hook information.
      cache_set('icon_render_hooks', $hooks);
    }
  }
  if (isset($hook)) {
    if (!empty($hooks[$hook])) {
      return $hooks[$hook];
    }
    else {
      $false = FALSE;
      return $false;
    }
  }
  return $hooks;
}

/**
 * Default properties for a bundle definition.
 *
 * @param array $bundle
 *   An associative array of bundle information, passed by reference.
 * @param string $name
 *   The machine name of the bundle.
 */
function icon_bundle_defaults(&$bundle = array(), $name = '') {
  $bundle += array(
    'icons' => array(),
    'name' => $name,
    'provider' => '',
    'settings' => array(),
    'status' => 1,
    'title' => $name,
    'version' => '',
    '#attached' => array(),
  );
  return $bundle;
}

/**
 * Returns information about all icon bundles.
 *
 * @param string $name
 *   The name of the bundle to load.
 * @param bool $reset
 *   Boolean to force reset of the cached data. Default: FALSE.
 *
 * @return array|false
 *   An associative array containing information for all bundles.
 *
 * @see hook_icon_info()
 */
function icon_bundles($name = NULL, $reset = FALSE) {
  $bundles =& drupal_static(__FUNCTION__);
  if (!isset($bundles) || $reset) {
    if (!$reset && ($cache = cache_get('icon_bundles')) && !empty($cache->data)) {
      $bundles = $cache->data;
    }
    else {
      $bundles = array();

      // Gather information from extensions that implement hook_icon_bundles().
      foreach (icon_extension_implements('icon_bundles') as $extension => $type) {
        $extension_bundles = (array) icon_extension_invoke($type, $extension, 'icon_bundles');
        foreach ($extension_bundles as $bundle_name => $bundle) {
          icon_bundle_defaults($bundle, $bundle_name);
          if (empty($bundle['provider'])) {
            $bundle['provider'] = $extension;
          }

          // Alphabetically sort the icons.
          if (!empty($bundle['icons'])) {
            ksort($bundle['icons']);
          }

          // In cases where themes may provide sprite icons (such as Bootstrap),
          // we need to specify the theme to use for this bundle. These types
          // of bundles do not attach a separate CSS file with the bundle and
          // the sprite classes are instead, generated with the theme's CSS.
          // @see icon_bundle_get_theme()
          // @see icon_menu().
          if ($type === 'theme' && $bundle['render'] === 'sprite' && empty($bundle['#attached']['css'])) {
            $bundle['theme'] = $extension;
          }
          $bundles[$bundle_name] = $bundle;
        }
      }

      // Gather database bundles (which overrides any module implementations).
      $database_bundles = db_select('icon_bundle', 'b')
        ->fields('b')
        ->execute();
      foreach ($database_bundles as $database_bundle) {
        $bundle = unserialize($database_bundle->bundle);
        if ($bundle === FALSE) {
          $bundle = array();
        }
        else {
          icon_bundle_defaults($bundle, $bundle['name']);
          if (!empty($bundles[$database_bundle->name])) {
            $bundle['overridden'] = TRUE;
          }
        }
        $bundle['database'] = TRUE;
        $bundle['status'] = (int) $database_bundle->status;
        if (isset($bundles[$database_bundle->name])) {
          $bundle = array_merge($bundles[$database_bundle->name], $bundle);
        }
        $bundles[$database_bundle->name] = $bundle;
      }

      // Allow extensions to alter the bundles.
      drupal_alter('icon_bundles', $bundles);

      // Cache the info.
      cache_set('icon_bundles', $bundles);
    }
  }
  if (isset($name)) {
    if (!empty($bundles[$name])) {
      return $bundles[$name];
    }
    else {
      $false = FALSE;
      return $false;
    }
  }
  return $bundles;
}

/**
 * Delete the icon bundle that matches {icon_bundle}.name in the database.
 *
 * @param array $bundle
 *   The icon bundle array.
 *
 * @return bool
 *   TRUE if successful, FALSE if bundle does not exist or on failure.
 */
function icon_bundle_delete(array $bundle = array()) {
  if (empty($bundle['name']) || !icon_bundle_load($bundle['name'])) {
    return FALSE;
  }

  // Execute the query.
  try {

    // Execute query and remove database entries.
    db_delete('icon_bundle')
      ->condition('name', $bundle['name'])
      ->execute();

    // Delete files if not in code and path starts in public folder and exists.
    if (empty($bundle['overridden']) && strpos($bundle['path'], 'public://') === 0 && file_exists($bundle['path'])) {
      file_unmanaged_delete_recursive($bundle['path']);
    }

    // Determine which hook to invoke.
    $hook = 'icon_bundle_' . (!empty($bundle['overridden']) ? t('reset') : t('delete'));

    // Invoke hook_icon_bundle_reset() or hook_icon_bundle_delete() accordingly.
    foreach (icon_extension_implements($hook) as $extension => $type) {
      icon_extension_invoke($type, $extension, $hook, $bundle);
    }
    icon_clear_all_caches();
    drupal_set_message(t('The icon bundle %bundle has been successfully !action.', array(
      '!action' => !empty($bundle['overridden']) ? t('reset') : t('deleted'),
      '%bundle' => $bundle['title'],
    )));
    return TRUE;
  } catch (Exception $e) {
    drupal_set_message(t('An error occurred while attempting to !action the icon bundle "%bundle":<br /><code>@message</code>', array(
      '!action' => !empty($bundle['overridden']) ? t('reset') : t('delete'),
      '%bundle' => $bundle['title'],
      '@message' => $e
        ->getMessage(),
    )), 'error');
  }
  return FALSE;
}

/**
 * Disable the icon bundle that matches {icon_bundle}.name in the database.
 *
 * @param array $bundle
 *   The icon bundle array.
 *
 * @return bool
 *   TRUE if successful, FALSE if the bundle is already disabled or on failure.
 */
function icon_bundle_disable(array $bundle = array()) {
  $bundle['status'] = 0;
  if (icon_bundle_save($bundle)) {
    drupal_set_message(t('The icon bundle %bundle has been disabled.', array(
      '%bundle' => $bundle['title'],
    )));
    icon_clear_all_caches();
    return TRUE;
  }
  drupal_set_message(t('An error occurred while attemping to disable the icon bundle: %bundle.', array(
    '%bundle' => $bundle['title'],
  )), 'error');
  return FALSE;
}

/**
 * Enable the icon bundle that matches {icon_bundle}.name in the database.
 *
 * @param array $bundle
 *   The icon bundle array.
 *
 * @return bool
 *   TRUE if successful, FALSE if the bundle is already enabled or on failure.
 */
function icon_bundle_enable(array $bundle = array()) {
  $bundle['status'] = 1;
  if (icon_bundle_save($bundle)) {
    drupal_set_message(t('The icon bundle %bundle has been enabled.', array(
      '%bundle' => $bundle['title'],
    )));
    icon_clear_all_caches();
    return TRUE;
  }
  drupal_set_message(t('An error occurred while attemping to enable the icon bundle: %bundle.', array(
    '%bundle' => $bundle['title'],
  )), 'error');
  return FALSE;
}

/**
 * Helper function to return the proper theme.
 *
 * Necessary for displaying a list of icons of a specific bundle.
 */
function icon_bundle_get_theme($bundle, $global = FALSE) {
  global $theme;
  return !empty($bundle['theme']) && !$global ? $bundle['theme'] : $theme;
}

/**
 * Helper function to return the page title for bundles.
 */
function icon_bundle_get_title($bundle) {
  return !empty($bundle['title']) ? $bundle['title'] : t('Bundle');
}

/**
 * Load a specific bundle.
 *
 * @param string $name
 *   The name of the bundle to load.
 *
 * @return array
 *   An associative array of bundle information as returned from
 *   icon_bundles().
 */
function icon_bundle_load($name) {
  $loaded =& drupal_static(__FUNCTION__, array());
  if (empty($loaded[$name])) {
    $loaded[$name] = icon_bundles($name);
  }
  return $loaded[$name];
}

/**
 * Save an icon bundle in the {icon_bundle} table.
 *
 * @param array $bundle
 *   The icon bundle array.
 *
 * @return int|false
 *   If the save failed, returns FALSE. If successful, returns SAVED_NEW or
 *   SAVED_UPDATED, depending on the drupal_write_record() operation
 *   that was performed.
 */
function icon_bundle_save(array $bundle = array()) {
  if (empty($bundle['name'])) {
    return FALSE;
  }

  // Allow extensions to alter the bundle before it's saved.
  drupal_alter('icon_bundle_save', $bundle);
  $primary_keys = array();
  $record = array(
    'name' => $bundle['name'],
  );
  $existing_bundle = icon_bundle_load($bundle['name']);
  if (!$existing_bundle) {
    $existing_bundle = array();
  }

  // If the existing bundle is from the database, update the record.
  if (!empty($existing_bundle['database'])) {
    $primary_keys[] = 'name';
  }

  // Determine if there are differences between an existing bundle and this one.
  $diff = icon_array_diff_recursive($existing_bundle, $bundle);

  // If the status has changed, update the status field.
  if (isset($diff['status'])) {
    $record['status'] = (int) $bundle['status'];

    // Remove status from $diff to determine if anything else needs to be saved.
    unset($diff['status']);
  }

  // If there are still differences, replace the entire {icon_bundle}.bundle
  // field with the updated bundle array.
  if (!empty($diff)) {
    $record['bundle'] = $bundle;
  }

  // Only write to the database if necessary.
  if (isset($record['status']) || isset($record['bundle'])) {
    if ($status = drupal_write_record('icon_bundle', $record, $primary_keys)) {
      icon_clear_all_caches();
      return $status;
    }
  }
  return FALSE;
}

/**
 * Default properties for a provider definition.
 *
 * @param array $provider
 *   An associative array of provider information, passed by reference.
 * @param string $name
 *   The machine name of the provider.
 */
function icon_provider_defaults(&$provider = array(), $name = '') {
  $provider += array(
    'default bundle' => array(),
    'name' => $name,
    'title' => $name,
    'url' => '',
  );
  return $provider;
}

/**
 * Returns information about all icon providers.
 *
 * @param string $name
 *   The name of the provider to load.
 * @param bool $reset
 *   Boolean to force reset of the cached data. Default: FALSE.
 *
 * @return array|false
 *   An associative array containing information for all providers.
 *
 * @see hook_icon_info()
 */
function icon_providers($name = NULL, $reset = FALSE) {
  $providers =& drupal_static(__FUNCTION__);
  if (!isset($providers) || $reset) {
    if (!$reset && ($cache = cache_get('icon_providers')) && !empty($cache->data)) {
      $providers = $cache->data;
    }
    else {
      $providers = array();

      // Invoke hook_icon_providers().
      foreach (icon_extension_implements('icon_providers') as $extension => $type) {
        $extension_providers = (array) icon_extension_invoke($type, $extension, 'icon_providers');
        foreach ($extension_providers as $provider_name => $provider) {
          if ($provider_name === 'automatic') {
            drupal_set_message(t('The !type %extension tried to specify a provider with the name: %name. This is a reserved name and cannot be used, please rename your provider.', array(
              '!type' => $type,
              '%extension' => $extension,
              '%name' => $provider_name,
            )), 'warning');
            continue;
          }
          icon_provider_defaults($provider, $provider_name);
          $provider['name'] = $provider_name;
          $provider['type'] = $type;
          $provider[$type] = $extension;
          $providers[$provider_name] = $provider;
        }
      }

      // Allow extensions to alter the providers.
      drupal_alter('icon_providers', $providers);

      // Cache the info.
      cache_set('icon_providers', $providers);
    }
  }
  if (!empty($name)) {
    if (!empty($providers[$name])) {
      return $providers[$name];
    }
    return FALSE;
  }
  return $providers;
}

/**
 * Returns information about whether a provider supports importing.
 *
 * @todo make this "JSON importing"?
 *
 * @param string $name
 *   The name of the provider to load.
 *
 * @return array|false
 *   Returns an array of providers that support importing or just $name if it
 *   was provided. Returns FALSE if there are no providers or specific $name
 *   does not exist.
 */
function icon_providers_support_import($name = NULL) {
  $providers =& drupal_static(__FUNCTION__);
  if (!isset($providers)) {
    $providers = array();
    foreach (icon_providers() as $provider) {
      if (icon_extension_hook($provider['type'], $provider[$provider['type']], 'icon_' . $provider['name'] . '_import_validate') && icon_extension_hook($provider['type'], $provider[$provider['type']], 'icon_' . $provider['name'] . '_import_process')) {
        $providers[$provider['name']] = $provider;
      }
    }
  }
  if (!empty($name)) {
    if (!empty($providers[$name])) {
      return $providers[$name];
    }
    return FALSE;
  }
  return $providers;
}

/**
 * Load a specific provider.
 *
 * @param string $name
 *   The name of the provider to load.
 *
 * @return array
 *   An associative array of provider information as returned from
 *   icon_providers().
 */
function icon_provider_load($name) {
  $loaded =& drupal_static(__FUNCTION__, array());
  if (empty($loaded[$name])) {
    if (($cache = cache_get($name, 'cache_icon_providers')) && !empty($cache->data)) {
      $loaded[$name] = $cache->data;
    }
    else {
      $provider = icon_providers($name);
      cache_set($name, $provider, 'cache_icon_providers');
      $loaded[$name] = $provider;
    }
  }
  return $loaded[$name];
}

/**
 * Provides the list of permitted wrapper options.
 *
 * @return array
 *   An associative array of key/value pairs, where the wrapper HTML element is
 *   the key and an human readable label is the value.
 */
function icon_wrapper_options() {

  // Use the advanced drupal_static() pattern, since this is called very often.
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['options'] =& drupal_static(__FUNCTION__);
  }
  $options =& $drupal_static_fast['options'];
  if (!isset($options)) {
    $options = array(
      '' => t('None'),
      'div' => 'Div',
      'span' => 'Span',
      'h2' => 'H2',
      'h3' => 'H3',
      'h4' => 'H4',
      'h5' => 'H5',
      'h6' => 'H6',
      'p' => 'P',
      'em' => 'Em',
      'strong' => 'Strong',
    );
    drupal_alter(__FUNCTION__, $options);
  }
  return $options;
}

Functions

Namesort descending Description
icon_bundles Returns information about all icon bundles.
icon_bundle_defaults Default properties for a bundle definition.
icon_bundle_delete Delete the icon bundle that matches {icon_bundle}.name in the database.
icon_bundle_disable Disable the icon bundle that matches {icon_bundle}.name in the database.
icon_bundle_enable Enable the icon bundle that matches {icon_bundle}.name in the database.
icon_bundle_get_theme Helper function to return the proper theme.
icon_bundle_get_title Helper function to return the page title for bundles.
icon_bundle_load Load a specific bundle.
icon_bundle_save Save an icon bundle in the {icon_bundle} table.
icon_hook_info Implements hook_hook_info().
icon_library Implements hook_library().
icon_menu Implements hook_menu().
icon_menu_alter Implements hook_menu_alter().
icon_permission Implements hook_permission().
icon_providers Returns information about all icon providers.
icon_providers_support_import Returns information about whether a provider supports importing.
icon_provider_defaults Default properties for a provider definition.
icon_provider_load Load a specific provider.
icon_render_hooks Returns information about icons render hooks.
icon_wrapper_options Provides the list of permitted wrapper options.

Constants

Namesort descending Description
ICON_ADMIN_PATH @file icon.module Provides icon integration with menu items.