'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":
@message
', 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;
}