chosen.module in Chosen 7.3
Same filename and directory in other branches
General functions and hook implementations.
See also
File
chosen.moduleView source
<?php
/**
* @file
* General functions and hook implementations.
*
* @see http://harvesthq.github.com/chosen/
*/
/**
* Define chosen library url
*/
define('CHOSEN_WEBSITE_URL', 'http://harvesthq.github.com/chosen');
/**
* Widget that Chosen can be applied to
*/
define('CHOSEN_WIDGETS', serialize(array(
'options_select',
'date_select',
)));
/**
* Implements hook_ctools_plugin_directory().
*
* @see hook_ctools_plugin_directory
*/
function chosen_ctools_plugin_directory($module, $plugin) {
if ($module == 'chosen' && !empty($plugin)) {
return "plugins/{$plugin}";
}
}
/**
* Implements hook_ctools_plugin_type().
*
* @see hook_ctools_plugin_type
*/
function chosen_ctools_plugin_type() {
$plugins['library'] = array(
'cache' => FALSE,
'use hooks' => FALSE,
'classes' => array(
'class',
),
);
return $plugins;
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Override chosen_admin_settings submit callback with custom
* chosen_admin_settings_form_submit() function.
*
* @see hook_form_FORM_ID_alter
*/
function chosen_form_chosen_admin_settings_alter(&$form, &$form_state, $form_id) {
unset($form['#submit']);
$form['#submit'][] = 'chosen_admin_settings_form_submit';
}
/**
* Implementation of chosen_admin_settings_form_submit().
*
* Callback function for chosen_admin_settings().
* Save the submitted values by plugin type.
*
* @see settings_form_submit
* @see _chosen_devide_array_by_plugin
*/
function chosen_admin_settings_form_submit($form, &$form_state) {
// Exclude unnecessary elements.
form_state_values_clean($form_state);
$values = _chosen_devide_array_by_plugin($form_state['values']);
// Save values by plugin.
foreach ($values as $plugin_name => $values) {
variable_set('chosen_' . $plugin_name, $values);
}
drupal_set_message(t('The configuration options have been saved.'));
}
/**
* Implementation of _chosen_devide_array_by_plugin().
*
* Helperfunction to seperate fields by plugin_name.
*
* @param $flat_array
* Array containing a flat array. The keys needs to contain the plugin_name
* in front of the original key. It will be stripped of in this process.
*
* @return $values
* Array containing the flat elements, sorted by plugin_name without the
* plugin_name in front of the key anymore.
*/
function _chosen_devide_array_by_plugin($flat_array) {
$values = array();
foreach ($flat_array as $key => $value) {
foreach (ctools_get_plugins('chosen', 'library') as $plugin_name => $plugin_settings) {
if (substr($key, 0, strlen($plugin_name)) == $plugin_name) {
$field_name = substr($key, strlen($plugin_name) + 1);
$values[$plugin_name][$field_name] = $value;
}
}
}
return $values;
}
/**
* Implements hook_menu().
*/
function chosen_menu() {
$items = array();
$items['admin/config/user-interface/chosen'] = array(
'title' => 'Chosen',
'description' => 'Configuration for Chosen plugin',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'chosen_admin_settings',
),
'access arguments' => array(
'administer site configuration',
),
'file' => 'chosen.admin.inc',
);
return $items;
}
/**
* Implements hook_form_FORM_ID_alter().
*
* Attach the generated formular to the forminstance to make the field save our
* values in it's instance data column.
*
* @see hook_field_widget_settings_form
*
* TODO: Replace CHOSEN_WIDGET constant by supported widgets by plugin.
*/
function chosen_form_field_ui_field_edit_form_alter(&$form, $form_state) {
if (isset($form['instance']['widget']['type']['#value'])) {
$type = $form['instance']['widget']['type']['#value'];
if (in_array($type, unserialize(CHOSEN_WIDGETS))) {
$field = $form['#field'];
$instance = field_info_instance($form['instance']['entity_type']['#value'], $form['instance']['field_name']['#value'], $form['instance']['bundle']['#value']);
$form['instance'] += chosen_field_widget_settings_form($instance);
}
}
}
/**
* Implementation of chosen_field_widget_settings_form().
*
* Provides the form array for the field configuration.
*
* @param $instance
* Field instance definition provided by field_info_instance().
*
* @return $form
* A renderable form array containing the chosen plugin options.
*/
function chosen_field_widget_settings_form($instance) {
$widget = $instance['widget'];
$settings = $widget['settings'];
$form['chosen'] = array(
'#type' => 'fieldset',
'#title' => t('Chosen'),
'#collapsed' => TRUE,
'#collapsible' => TRUE,
'#parents' => array(
'instance',
'widget',
'settings',
),
);
$form['chosen']['apply_chosen'] = array(
'#type' => 'checkbox',
'#title' => t('Apply Chosen on this field'),
'#default_value' => isset($settings['apply_chosen']) ? $settings['apply_chosen'] : FALSE,
);
$form['chosen']['override'] = array(
'#type' => 'checkbox',
'#title' => t('Override chosen default settings'),
'#default_value' => isset($settings['override']) ? $settings['override'] : FALSE,
);
$form['chosen']['chosen_wrapper'] = array(
'#type' => 'fieldset',
'#title' => t('Chosen settings'),
'#collapsed' => TRUE,
'#collapsible' => TRUE,
'#weight' => 20,
'#states' => array(
'visible' => array(
':input[name="instance[widget][settings][override]"]' => array(
'checked' => TRUE,
),
),
),
);
$default_values = _chosen_flattern_default_values($instance['chosen_wrapper']);
$default_values = _chosen_devide_array_by_plugin($default_values);
$settings_form = chosen_generate_forms($default_values);
$form['chosen']['chosen_wrapper'] += $settings_form;
return $form;
}
/**
* Implementation of _chosen_flattern_default_values().
*
* Helperfunction to build a one dimensional array of all fields.
*
* @param $default_values
* A plugin sepperated array of fields.
*
* @return $flattern_values
* All fields in a one dimensional array.
*/
function _chosen_flattern_default_values($default_values) {
$flattern_values = array();
foreach ($default_values as $key => $value) {
if (!is_array($value)) {
$flattern_values[$key] = $value;
// value
}
else {
$flattern_values = array_merge($flattern_values, _chosen_flattern_default_values($value));
}
}
return $flattern_values;
}
/**
* Implements hook_field_widget_form_alter().
*
* TODO: This needs to be improved. This is maybe not the correct way.
* TODO: When we replace the CHOSEN_WIDGETS constant we have to adjust this
* function.
*/
function chosen_field_widget_form_alter(&$element, &$form_state, $context) {
$type = $context['instance']['widget']['type'];
if (in_array($type, unserialize(CHOSEN_WIDGETS))) {
$settings = $context['instance']['widget']['settings'];
if (!empty($settings['apply_chosen'])) {
$element['#attributes']['class'][] = 'chosen-widget';
}
}
}
/**
* Implements hook_library().
*
* Register the chosen libraries, provided by the chosen plugins with all it's
* custom options. The options need to be extracted from the plugin options
* formular if no values have yet been saved, otherwise from the chosen_plugin
* variable.
*/
function chosen_library() {
ctools_include('plugins');
foreach (ctools_get_plugins('chosen', 'library') as $plugin_name => $plugin_settings) {
$plugin_class_name = ctools_plugin_load_class('chosen', 'library', $plugin_name, 'class');
$plugin = new $plugin_class_name();
$library_path = module_exists('libraries') ? libraries_get_path($plugin->library_name) : 'sites/all/libraries/' . $plugin->directory;
// Registerl the library.
$info[$plugin->library_name] = array(
'title' => $plugin->title,
'website' => $plugin->website,
'version' => $plugin->version,
'js' => array(
$library_path . '/' . $plugin->file_name => array(
'group' => 'JS_LIBRARY',
),
),
);
// TODO: Make css optional and make it possible to have multiple css files attached.
// Perhaps it would make sense to allow multiple js files too?
if (variable_get('chosen_use_theme', TRUE)) {
$info['chosen']['css'] = array(
$library_path . '/' . $plugin->css => array(),
);
}
// TODO: Refactor this.
$values = array();
$value = variable_get('chosen_' . $plugin_name);
if (!empty($value)) {
$values = variable_get('chosen_' . $plugin_name);
}
else {
$options = _chosen_flattern_options($plugin
->options());
foreach ($options as $key => $value) {
// TODO: recursiv.
$values[$key] = $value['#default_value'];
}
}
// Provide settings for the library.
// TODO: Get the settings from the plugin.
$module_path = drupal_get_path('module', 'chosen');
$info['drupal.' . $plugin_name] = array(
'title' => 'Drupal Chosen integration',
'website' => 'http://drupal.org/project/chosen',
'version' => '1.0',
'js' => array(
$module_path . '/chosen.js' => array(),
array(
'data' => array(
'chosen' => array(
'selector' => variable_get('chosen_jquery_selector', 'select:visible'),
'minimum_single' => variable_get('chosen_minimum_single', 20),
'minimum_multiple' => variable_get('chosen_minimum_multiple', 20),
'minimum_width' => variable_get('chosen_minimum_width', 200),
'search_contains' => variable_get('chosen_search_contains', FALSE) ? TRUE : FALSE,
'disable_search' => variable_get('chosen_disable_search', FALSE) ? TRUE : FALSE,
'disable_search_threshold' => variable_get('chosen_disable_search_threshold', 0),
'placeholder_text_multiple' => t(variable_get('chosen_placeholder_text_multiple', 'Choose some options')),
'placeholder_text_single' => t(variable_get('chosen_placeholder_text_single', 'Choose an option')),
'no_results_text' => t(variable_get('chosen_no_results_text', 'No results match')),
),
),
'type' => 'setting',
),
),
'css' => array(
// TODO: Not sure about that.
$module_path . '/css/chosen-drupal.css' => array(),
),
'dependencies' => array(
array(
'chosen',
$plugin->library_name,
),
),
);
}
return $info;
}
/**
* Implementation of _chosen_flattern_options()
*
* This function collects all field options out of a form array and generates a
* one dimensional array.
*
* @param $options
* The form array provided by a plugin.
*
* @return
* The flat array of all fields.
*/
function _chosen_flattern_options($options) {
$flat_array = array();
foreach ($options as $key => $value) {
if (isset($value['#default_value'])) {
$flat_array[$key] = $value;
}
elseif (is_array($value)) {
$flat_array = array_merge($flat_array, _chosen_flattern_options($value));
}
}
return $flat_array;
}
/**
* Implements hook_element_info_alter().
*
* Adds a prerender Function which will be called to supported widgets in order
* to be able to provide settings per fieldinstance.
*
* TODO: This has to be generated out of the plugins.
*/
function chosen_element_info_alter(&$info) {
$info['select']['#pre_render'][] = 'chosen_pre_render_select';
if (module_exists('date')) {
$info['date_combo']['#pre_render'][] = 'chosen_pre_render_select';
}
}
/**
* Implementation of chosen_pre_render_select().
*
* Atteches the library to the field and pass the fieldinstance related options.
*
* @see pre_render
*
* TODO: Get the field specific configuration.
* TODO: Pass the correct cpnfiguration.
*/
function chosen_pre_render_select($element) {
$field_info = isset($element['#field_name']) ? field_info_field($element['#field_name']) : FALSE;
$element_name = $element['#name'];
if (!empty($element['#multiple'])) {
// We need to add those brackets for multivalue fields.
$element_name = $element['#name'] . '[]';
}
$max_selected_options = FALSE;
if (isset($field_info['cardinality'])) {
if ($field_info['cardinality'] != FIELD_CARDINALITY_UNLIMITED) {
$max_selected_options = $field_info['cardinality'];
}
}
$element['#attached']['library'][] = array(
'chosen',
'drupal.chosen',
);
$element['#attached']['js'][] = array(
'data' => array(
'chosen' => array(
'multiple' => array(
$element_name => isset($element['#multiple']) ? $element['#multiple'] : FALSE,
),
'max_selected_options' => array(
$element_name => $max_selected_options,
),
),
),
'type' => 'setting',
);
return $element;
}
/**
* Implementation of chosen_get_chosen_path().
*
* Get the location of the chosen library.
*
* @return
* The location of the library, or FALSE if the library isn't installed.
*
* TODO: support library by plugin.
*/
function chosen_get_chosen_path() {
$path = FALSE;
if (function_exists('libraries_get_path')) {
$path = libraries_get_path('chosen');
if (!file_exists($path)) {
$path = FALSE;
}
}
elseif (file_exists('sites/all/libraries/chosen/chosen.jquery.min.js')) {
$path = 'sites/all/libraries/chosen';
}
return $path;
}
/**
* Implementation of chosen_generate_forms().
*
* Generates a completed configuration form out of the plugin options.
*
* @param $default_values
* The default values which will be present in the form.
*
* @return
* The completed form.
*/
function chosen_generate_forms($default_values) {
ctools_include('plugins');
foreach (ctools_get_plugins('chosen', 'library') as $plugin => $plugin_settings) {
$chosen_plugins[$plugin] = $plugin_settings['name'];
$chosen_descriptions[$plugin] = $plugin_settings['description'];
}
$form['chosen_plugin'] = array(
'#type' => 'select',
'#title' => t('Select library chosen should use'),
'#options' => $chosen_plugins,
'#default_value' => isset($default_values['chosen']['plugin']) ? $default_values['chosen']['plugin'] : 'chosen',
'#description' => $chosen_descriptions[variable_get('chosen_active_plugin', 'chosen')],
'#weight' => 20,
);
foreach (ctools_get_plugins('chosen', 'library') as $plugin_name => $plugin_settings) {
$plugin_class_name = ctools_plugin_load_class('chosen', 'library', $plugin_name, 'class');
$plugin = new $plugin_class_name();
$form[$plugin_name] = array(
'#type' => 'fieldset',
'#title' => t($plugin_settings['name'] . ' options'),
'#states' => array(
'visible' => array(
'select[name="chosen_plugin"]' => array(
'value' => $plugin_name,
),
'select[name="instance[widget][settings][chosen_wrapper][chosen_plugin]"]' => array(
'value' => $plugin_name,
),
),
),
);
$fields = _chosen_add_plugin_prefix($plugin
->options($default_values[$plugin_name]), $plugin_name);
foreach ($fields as $option => $values) {
// Iterate through $values, check if it has ?
$form[$plugin_name][$option] = $values;
$form[$plugin_name]['#weight'] = 21;
}
}
return $form;
}
/**
* Implementation of _chosen_add_plugin_prefix().
*
* Helperfunction to refactor the fields array. Adds plugin namespaces to the
* fields. To be able to group them later on.
*
* @param $array
* Field array.
*
* @param $plugin_name
* The actual plugin.
*
* @return $new_array
* Array with plugin namespaces for the fields.
*/
function _chosen_add_plugin_prefix($array, $plugin_name) {
foreach ($array as $key => $value) {
if (isset($value['#default_value'])) {
// Is field.
$new_array[$plugin_name . '_' . $key] = $value;
}
else {
if (!is_array($value)) {
// Is value.
$new_array[$key] = $value;
}
else {
// Is child.
$new_array[$key] = _chosen_add_plugin_prefix($value, $plugin_name);
}
}
}
return $new_array;
}
Functions
Constants
Name![]() |
Description |
---|---|
CHOSEN_WEBSITE_URL | Define chosen library url |
CHOSEN_WIDGETS | Widget that Chosen can be applied to |