array( 'title' => t('Administer Linkit'), 'description' => t('Perform administration tasks for Linkit.'), ), ); } /** * Implements hook_ctools_plugin_directory(). */ function linkit_ctools_plugin_directory($module, $plugin) { if ($module == 'ctools' && !empty($plugin)) { return "plugins/" . $plugin; } if ($module == 'linkit' && !empty($plugin)) { return "plugins/" . $plugin; } } /** * Implements hook_ctools_plugin_TYPE() to inform the plugin system that Linkit * owns Linkit plugin types. */ function linkit_ctools_plugin_type() { $plugins['linkit_search'] = array( 'child plugins' => TRUE, 'classes' => array('handler'), ); $plugins['linkit_insert'] = array( 'process' => array( 'function' => 'linkit_insert_plugin_process', ), ); $plugins['linkit_attribute'] = array(); return $plugins; } /** * Provide defaults for insert plugins. */ function linkit_insert_plugin_process(&$plugin, $info) { // The plugin javascript can be just a filename or a full path, // in case it's just a filename, add the plugin path. if (!file_exists($plugin['javascript'])) { $plugin['javascript'] = $plugin['path'] . '/' . $plugin['javascript']; } } /** * Load a single Linkit profile. * * @param $name * A string with the name of the profile to load. * * @return * A LinkitProfile object or FALSE if no profile is found. */ function linkit_profile_load($name) { ctools_include('export'); $result = ctools_export_load_object('linkit_profiles', 'names', array($name)); if (isset($result[$name])) { return $result[$name]; } return FALSE; } /** * Load all Linkit profiles. * * @return * An array with LinkitProfile objects. */ function linkit_profile_load_all() { ctools_include('export'); $profiles = ctools_export_load_object('linkit_profiles'); return $profiles; } /** * Load all Linkit profiles that is for fields. * * @return * An array with LinkitProfile objects. */ function linkit_profile_field_load_all() { $profiles = linkit_profile_load_all(); foreach ($profiles as &$profile) { if ($profile->profile_type != LINKIT_PROFILE_TYPE_FIELD) { $profile = FALSE; } } return array_filter($profiles); } /** * Load all Linkit profiles that is for editors. * * @return * An array with LinkitProfile objects. */ function linkit_profile_editor_load_all() { $profiles = linkit_profile_load_all(); foreach ($profiles as &$profile) { if ($profile->profile_type != LINKIT_PROFILE_TYPE_EDITOR) { $profile = FALSE; } } return array_filter($profiles); } /** * Temporary saves the active profile. Active means that the user is working * with the profile in the dialog. * * @param string LinkitProfile $profile * A LinkitProfile object. */ function linkit_set_active_profile(LinkitProfile $profile) { $active_profile = &drupal_static('linkit_active_profile'); $active_profile = $profile; } /** * Get the currently active profile. * * @return * A LinkitProfile object if there is one set. * * @see linkit_set_active_profile() */ function linkit_get_active_profile() { return drupal_static('linkit_active_profile'); } /** * Fetch metadata for all Linkit search plugins. * * @return * An array of arrays with information about all available Linkit search * plugins. */ function linkit_search_plugin_load_all() { ctools_include('plugins'); $plugins = ctools_get_plugins('linkit', 'linkit_search'); // If you alter the plugin handler, be sure the new handler is registerd or // you include it in some other way. drupal_alter('linkit_search_plugins', $plugins); return $plugins; } /** * Function used by uasort to sort plugins by weight. */ function linkit_sort_plugins_by_weight($a, $b) { return $a["weight"] >= $b["weight"]; } /** * Fetch metadata for one Linkit search plugin by the given name. * * @param $plugin_name * A string with the name of the plugin to load. * * @return * An array with information about the search plugin. */ function linkit_search_plugin_load($plugin_name) { ctools_include('plugins'); $plugin = ctools_get_plugins('linkit', 'linkit_search', $plugin_name); // If you alter the plugin handler, be sure the new handler is registerd or // you include it in some other way. drupal_alter('linkit_search_plugin', $plugin); return $plugin; } /** * Fetch metadata for all Linkit insert plugins. * * @return * An array of arrays with information about all available insert plugins. */ function linkit_insert_plugin_load_all() { ctools_include('plugins'); // Load all insert plugins. $plugins = ctools_get_plugins('linkit', 'linkit_insert'); return $plugins; } /** * Fetch metadata for one Linkit insert plugin by the given name. * * @param $plugin_name * A string with the name of the plugin to load. * * @return * An array with information about the insert plugin. */ function linkit_insert_plugin_load($plugin_name) { ctools_include('plugins'); // Load all insert plugins. $plugins = ctools_get_plugins('linkit', 'linkit_insert', $plugin_name); return $plugins; } /** * Fetch metadata for all Linkit attribute plugins. * * @return * An array of arrays with information about all available attribute plugins. */ function linkit_attribute_plugin_load_all() { ctools_include('plugins'); // Load all attribute plugins. $attributes = ctools_get_plugins('linkit', 'linkit_attribute'); return $attributes; } function linkit_attribute_plugin_load($plugin_name) { ctools_include('plugins'); // Load all insert plugins. $plugins = ctools_get_plugins('linkit', 'linkit_attribute', $plugin_name); return $plugins; } /** * Implements hook_theme(). */ function linkit_theme($existing, $type, $theme, $path) { return array( 'linkit_plugin_form_table' => array( 'render element' => 'form', 'file' => 'includes/theme.inc', ), ); } /** * Implements hook_menu_alter(). */ function linkit_menu_alter(&$items) { // Override the default titles that ctools export_ui sets. // This way there is less code compared to define this in the plugin array. $items['admin/config/content/linkit/add']['title'] = 'Add new profile'; $items['admin/config/content/linkit/import']['title'] = 'Import profiles'; // Make tabs instead of action links. $items['admin/config/content/linkit/add']['type'] = MENU_LOCAL_TASK; $items['admin/config/content/linkit/import']['type'] = MENU_LOCAL_TASK; } /** * Implements hook_module_implements_alter(). * * @TODO: Document why we are doing this. * @see linkit_element_info_alter() */ function linkit_module_implements_alter(&$implementations, $hook) { if ($hook == 'element_info_alter') { $group = $implementations['linkit']; unset($implementations['linkit']); $implementations['linkit'] = $group; } } /** * Implements hook_element_info_alter(). */ function linkit_element_info_alter(&$types) { // Append a after_build function for the field integration. foreach (linkit_get_allowed_field_elements() as $element) { if (isset($types[$element])) { $types[$element]['#after_build'][] = 'linkit_field_element_after_build'; } } // Used when using ckeditor module. if (isset($types['text_format']['#pre_render']) && is_array($types['text_format']['#pre_render'])) { if (in_array('ckeditor_pre_render_text_format', $types['text_format']['#pre_render'])) { $types['text_format']['#pre_render'][] = 'linkit_pre_render_editor_element'; // Add the linkit library for the editor. $types['text_format']['#attached']['library'][] = array('linkit', 'ckeditor'); } } // Used when using wysiwyg module. if (isset($types['text_format']['#pre_render']) && is_array($types['text_format']['#pre_render'])) { if (in_array('wysiwyg_pre_render_text_format', $types['text_format']['#pre_render'])) { $types['text_format']['#process'][] = 'linkit_pre_render_editor_element'; } } } /** * Implements hook_library(). */ function linkit_library() { $path = drupal_get_path('module', 'linkit'); $common = array( 'website' => 'http://drupal.org/project/linkit', 'version' => '7.3', ); // Linkit base $libraries['base'] = array( 'title' => 'Linkit base', 'js' => array( $path . '/js/linkit.js' => array('group' => JS_DEFAULT, 'weight' => -1), // Add global settings for Linkit. array( 'type' => 'setting', // ___profile___ is just a placeholder. 'data' => array( 'linkit' => array( 'autocompletePath' => url('linkit/autocomplete/___profile___', array('query' => array(LINKIT_BAC_QUERY_KEY => ''), 'absolute' => TRUE)), 'dashboardPath' => url('linkit/dashboard/'), 'currentInstance' => new stdClass(), ), ), ), ), 'dependencies' => array( array('system', 'ui.dialog'), array('system', 'drupal.ajax'), ), ); // Linkit field ui script. $libraries['field'] = array( 'title' => 'Linkit Field UI', 'js' => array( $path . '/js/linkit.field.js' => array('group' => JS_DEFAULT), ), 'dependencies' => array( array('linkit', 'base'), ), ); // Linkit ckeditor dialog script. $libraries['ckeditor'] = array( 'title' => 'Linkit CKeditor', 'js' => array( $path . '/editors/ckeditor/linkitDialog.js' => array('group' => JS_DEFAULT), ), 'dependencies' => array( array('linkit', 'base'), ), ); // Linkit tinymce dialog script. $libraries['tinymce'] = array( 'title' => 'Linkit TinyMCE', 'js' => array( $path . '/editors/tinymce/linkitDialog.js' => array('group' => JS_DEFAULT), ), 'dependencies' => array( array('linkit', 'base'), ), ); foreach ($libraries as &$library) { $library += $common; } // Linkit BAC $libraries['bac'] = array( 'website' => 'https://github.com/betamos/Better-Autocomplete', 'version' => '1.0', 'title' => 'Better autocomplete', 'js' => array( $path . '/better-autocomplete/jquery.better-autocomplete.js' => array('group' => JS_LIBRARY), ), 'css' => array( $path . '/better-autocomplete/better-autocomplete.css' => array( 'group' => CSS_DEFAULT, 'preprocess' => FALSE, ), ), ); return $libraries; } /** * Implements hook_menu(). */ function linkit_menu() { $items = array(); // This is the Linkit dashboard menu callback. $items['linkit/dashboard/%linkit_profile'] = array( 'title' => 'Linkit', 'description' => 'Dashboard', 'delivery callback' => 'ajax_deliver', 'page callback' => 'linkit_dashboard_page', 'page arguments' => array(2), 'access callback' => TRUE, 'theme callback' => 'ajax_base_page_theme', 'type' => MENU_CALLBACK, 'file path' => 'includes', 'file' => 'form.inc', ); // The autocomplete callback, the search_string is found in the $_GET array // so dont pass that to the page callback. $items['linkit/autocomplete/%linkit_profile'] = array( 'title' => 'Linkit autocomplete response function', 'page callback' => 'linkit_autocomplete', 'page arguments' => array(2), 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); return $items; }; /** * Creates the dialog dashboard. * * We don't call drupal_get_form() in the menu callback as we don't want to * return the rendered form, we just want to print it as it is. * * @param $profile * A LinkitProfile object. */ function linkit_dashboard_page(LinkitProfile $profile) { // Set the active Linkit profile. linkit_set_active_profile($profile); // The dashboard isn't really a form. // See comment in linkit_dashboard_form() for more info. $form = drupal_get_form('linkit_dashboard_form'); //$change_profile = drupal_get_form('linkit_dashboad_profile_change_form'); return array( '#type' => 'ajax', '#commands' => array( ajax_command_html('#linkit-modal', drupal_render($form)), ajax_command_prepend('#linkit-modal', theme('status_messages')), ), ); } /** * Ajax Form callback; * * Returns the Linkit "form" when changing profile. */ function linkit_change_profile($form, $form_state) { return $form['linkit_container']; } /** * Create the dashboard page. */ function linkit_dashboard_form($form, &$form_state) { // The use of a form here is insignificant as we are not submitting any data. // A form here just cause trouble because it can be submitted and will do new // request to the action of the form. // In normal cases this isn't really a problem as the javascript is preventing // the form to be submitted, but in case of a javascript error, this event // can't be prevented. // We still have to use the FAPI to build this "form", as we want proper // classes and ids on the elements and take advantage of all the good parts of // the form generation. // So, just make sure the form tags dont get rendered. //$form['#theme_wrappers'] = array(); // Get the active Linkit profile. if (!empty($form_state['values']['profile'])) { linkit_set_active_profile(linkit_profile_load($form_state['values']['profile'])); } $active_profile = linkit_get_active_profile(); $profiles = linkit_profile_editor_load_all(); $_profiles = array(); foreach ($profiles as $profile) { $_profiles[$profile->name] = check_plain($profile->admin_title); } // Attach css to the form. $form['#attached']['css'][drupal_get_path('module', 'linkit') . '/css/linkit.css'] = array( 'preprocess' => FALSE, ); // Attach js to the form. $form['#attached']['js'] = array( drupal_get_path('module', 'linkit') . '/js/linkit.dashboard.js', ); if ($active_profile->profile_type == LINKIT_PROFILE_TYPE_EDITOR) { $form['profile'] = array( '#type' => 'radios', '#title' => t('Select profile to use'), '#default_value' => $active_profile->name, '#weight' => -100, '#options' => $_profiles, '#ajax' => array( 'callback' => 'linkit_change_profile', 'wrapper' => 'linkit-dashboard-ajax-wrapper', 'method' => 'replaceWith', 'effect' => 'fade', 'event' => 'click', ), '#prefix' => '
', '#suffix' => '
', ); foreach ($profiles as $profile) { $form['profile'] += array( $profile->name => array( '#description' => check_markup($profile->admin_description), ) ); } } $form['linkit_container'] = array( '#type' => 'container', '#weight' => 100, '#prefix' => '
', '#suffix' => '
', '#attached' => array( 'js' => array( array( 'data' => array( 'linkit' => array( 'currentInstance' => array( 'profile' => $active_profile->name, 'autocomplete' => array_filter($active_profile->data['autocomplete']), ), ), ), 'type' => 'setting', ) ), ), ); $form['linkit_container']['linkit_search'] = array( '#type' => 'textfield', '#title' => t('Search for content.'), '#description' => t('Start typing to find content or paste a URL.'), '#maxlength' => 255, '#size' => 60, '#default_value' => '', '#weight' => -10, '#attributes' => array( 'class' => array( 'linkit-search-element', ), ), '#attached' => array( 'library' => array( array('linkit', 'bac'), ), ), ); $form['linkit_container']['linkit_path'] = array( '#type' => 'textfield', '#title' => t('Link URL'), '#description' => t('This will be populated by the search, or you can fill it in yourself.'), '#required' => TRUE, '#maxlength' => NULL, '#size' => 60, '#default_value' => '', '#weight' => -1, '#attributes' => array( 'class' => array( 'linkit-path-element', ), ), ); // If we have enabled attributes, lets put them inside a fieldset. if (count($active_profile->getEnabledAttributePlugins())) { // Create the container fieldset. $form['linkit_container']['linkit_attributes'] = array( '#type' => 'fieldset', '#title' => t('Options'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => 10, '#attributes' => array( 'class' => array( 'linkit-attributes', ), ), ); // Append the attributes info the fieldset. foreach ($active_profile->getEnabledAttributePlugins() AS $name => $attribute) { // Add a class to all items. $attribute['#attributes']['class'][] = 'linkit-attribute-' . $name; // Add 'linkit_' prefix to ensure that is unique. $form['linkit_container']['linkit_attributes']['linkit_' . $name] = $attribute; } } $form['linkit_container']['linkit_insert'] = array( '#type' => 'button', '#value' => t('Insert link'), '#suffix' => '' . t('Cancel') . '', '#weight' => 100, '#attributes' => array( 'class' => array( 'linkit-insert', ), ), ); return $form; } /** * Autocomplete callback function. * * @param object $profile * A LinkitProfile object. */ function linkit_autocomplete(LinkitProfile $profile) { // Set the active Linkit profile. linkit_set_active_profile($profile); // This is not sanitized until it is used within output. $search_string = $_GET[LINKIT_BAC_QUERY_KEY]; $results = array(); // Special for link to frontpage. if (strpos($search_string, 'front') !== FALSE) { $results[] = array( 'title' => t('Frontpage'), 'description' => 'The frontpage for this site.', 'path' => url(''), 'group' => t('System'), ); } // Let the Linkit search plugins do their job. $results = array_merge($results, linkit_autocomplete_search_plugins($search_string)); // If there is results from the Linkit search plugins, don't care about // searching for absolute URL's results. if (!count($results)) { // Try to parse the string as an URL. // We will not use the drupal wrapper function drupal_pasre_url() as that // function should only be used for URL's that have been generated by the // system, and we can't be sure that this is the case here. // Check for an e-mail address then return an e-mail result and create a // mail-to link if appropriate. if (filter_var($search_string, FILTER_VALIDATE_EMAIL)) { $results = array(array( 'title' => t('E-mail @email', array('@email' => $search_string)), 'path' => 'mailto:'. check_plain($search_string), 'description' => t('Open your mail client ready to e-mail @email', array('@email' => $search_string)), 'addClass' => 'status-notice', )); } else { $parts = parse_url(trim($search_string, '/')); // This seems to be an absolute URL. if (isset($parts['scheme']) || isset($parts['host'])) { $results = array_merge($results, linkit_autocomplete_absolute_url($search_string, $parts)); } } } // If there is still no results, return a "no results" array. if (!count($results)) { $results = array( array( 'title' => t('No results'), 'addClass' => 'status-notice', 'disabled' => TRUE, ) ); } print drupal_json_output($results); drupal_exit(); } /** * Perform autocomplete search with the Linkit search plugins. * * @param $search_string * The search string. * * @return * An array with the results objects, or an empty array if no results. */ function linkit_autocomplete_search_plugins($search_string) { $matches = array(); $profile = linkit_get_active_profile(); // Get matches from all search plugins. foreach ($profile->getEnabledsearchPlugins() as $plugin_name => $plugin) { $matches = array_merge($matches, $plugin->fetchResults($search_string)); } return $matches; } /** * Retrieve relevant information about a URL. Specifically this function is * usable for internal (absolute) URL:s, but it also works for external URL:s. * * @param $url * The search string (URL) that should be scanned. * * @param $parts * An array of URL parts from parse_url(). * * @return * An associative array containing: * - url: The same as the argument $url, untouched. * - target: Either "internal" or "external". * - requested_path: If internal, the path requested relative to Drupal root. * The only exception is when frontpage is referred directly, then it will * be whatever the frontpage is set to. * - system_path: If internal and the path is valid, the Drupal system path, * e.g. "node/23". * - query_fragment: If internal, the query and fragment of the url. * Typically it is not needed for searching and is just reappended back * when processing of the path is done. It could e.g. look like * "?foo=bar#anchor". */ function linkit_parse_url($url, $parts) { global $base_url; // Make a new array, this will hold the components from parse_url() and our // own "Linkit" components. $path_info = array(); // Append the original components from parse_url() to our array. $path_info += $parts; // Save the whole URL. $path_info['url'] = $url; if (!isset($path_info['query'])) { $path_info['query'] = ''; } // Convert the query string to an array as Drupal can only handle querys as // arrays. // @see http://api.drupal.org/drupal_http_build_query parse_str($path_info['query'], $path_info['query']); // The 'q' parameter contains the path of the current page if clean URLs are // disabled. It overrides the 'path' of the URL when present, even if clean // URLs are enabled, due to how Apache rewriting rules work. if (isset($path_info['query']['q'])) { $path_info['path'] = $path_info['query']['q']; unset($path_info['query']['q']); } // Load all local stream wrappers. The $path_info['scheme'] will be tested // against this later to ensure it is local. $local_stream_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL); // Internal URL. // We can not use the url_is_external() as it treats all absolute links as // external and treats all stream wrappers as internal. $local_hosts = array($base_url); // Give other modules a chance to add/remove/alter the local hosts. drupal_alter('linkit_local_hosts', $local_hosts); $local_url = in_array(trim($path_info['scheme'] . '://' . $path_info['host'] . base_path(), '/'), $local_hosts); $local_stream_wrapper = isset($local_stream_wrappers[$path_info['scheme']]); //@TODO: maybe file_valid_uri() ? if ($local_url || $local_stream_wrapper) { // Set target as internal. $path_info['target'] = 'internal'; // If this is seems to be a valid local stream wrapper string, force the // $path_info['path'] to be set to the file_url. if ($local_stream_wrapper) { $path_info = array_merge($path_info, parse_url(file_create_url($path_info['url']))); } // Trim the path from slashes. $path_info['path'] = trim($path_info['path'], '/'); // If we have an empty path, and an internal target, we can assume that the // URL should go the the frontpage. if (empty($path_info['path'])) { $path_info['frontpage'] = TRUE; $path_info['path'] = variable_get('site_frontpage', 'node'); } // Try converting the path to an internal Drupal path. $internal_url = drupal_get_normal_path($path_info['path']); // Add the "real" system path (not the alias) if the current user have // access to the URL. $path_info['system_path'] = drupal_valid_path($internal_url) ? $internal_url : FALSE; $menu_item = menu_get_item($path_info['system_path']); if ($menu_item) { $path_info['menu']['path'] = $path_info['system_path']; $path_info['menu']['description'] = check_plain($menu_item['description']); $path_info['menu']['title'] = check_plain($menu_item['title']); } // If we have a valid stream wrapper URL, find out the internal url. if ($local_stream_wrapper) { $path_info['system_path'] = $path_info['path']; $path_info['menu']['path'] = $path_info['path']; $path_info['menu']['description'] = 'This funciton is not fully integrated yet.'; $path_info['menu']['title'] = 'This funciton is not fully integrated yet.'; } } else { // Set target as external. $path_info['target'] = 'external'; } return $path_info; } /** * Retrieve the result object from an absolute URL. Both internal and external * paths work. * * @param $url * The search string which seems to be an URL. * * @param $parts * An array of URL parts from parse_url(). * * @return * A result object. This is an associative array which consists of: * - title: The title of the result. * - description: The description of the result (may contain HTML). * - path: The target path which will be inserted as the href in the link. * - addClass: A CSS class that will be added to the DOM result item. */ function linkit_autocomplete_absolute_url($url, $parts) { $result = array(); // Retrieve relevant information about the search string and if its a URL. $path_info = linkit_parse_url($url, $parts); // Set default options to pass with the url() function if the URL is internal. $url_options = array(); // Add the URL frament. $url_options['fragment'] = isset($path_info['fragment']) ? $path_info['fragment'] : ''; // Add the URL query. $url_options['query'] = isset($path_info['query']) ? $path_info['query'] : ''; // The URL is registerd by Drupal (Internal). if (isset($path_info['menu']) && $path_info['system_path'] !== FALSE) { $result = array( 'path' => linkit_get_insert_plugin_processed_path(linkit_get_active_profile(), $path_info['menu']['path'], $url_options), 'title' => $path_info['menu']['title'] ? check_plain($path_info['menu']['title']) : check_plain($path_info['menu']['path']), 'description' => check_plain($path_info['menu']['description']) . ' ' . t('This is an internal path.'), 'addClass' => 'status-ok', ); } // No internal menu result, but the URL seems to be internal. Either we do not // have access to it or it does not exists. elseif ($path_info['target'] == 'internal') { $result = array( 'path' => linkit_get_insert_plugin_processed_path(linkit_get_active_profile(), $path_info['path'], $url_options), 'title' => t('Page not found'), 'description' => t('This page does not exist or you do not have access to it.'), 'addClass' => 'status-warning', ); } // The URL seems to be external. elseif ($path_info['target'] == 'external') { $result = array( 'title' => t('No information available'), 'description' => t('This is an external URL, but we don\'t know where it leads.'), 'path' => $path_info['url'], 'addClass' => 'status-notice', ); } // Return the results in an array as BAC will need to have it that way. return array($result); } /** * Implements hook_image_default_styles(). * * @return * An array of image styles, keyed by the style name. */ function linkit_image_default_styles() { $styles = array(); $styles['linkit_thumb'] = array( 'effects' => array( array( 'name' => 'image_scale', 'data' => array( 'width' => 50, 'height' => 50, 'upscale' => 0, ), 'weight' => 0, ), ), ); return $styles; } /** * Implements hook_wysiwyg_plugin(). */ function linkit_wysiwyg_plugin($editor, $version) { $plugin = array(); $plugin['linkit'] = array( 'path' => drupal_get_path('module', 'linkit') . '/editors/' . $editor, 'buttons' => array('linkit' => t('Linkit')), 'url' => 'http://drupal.org/project/linkit', 'load' => TRUE, ); // TinyMCE needs to know the filename. if ($editor == 'tinymce') { $plugin['linkit']['filename'] = 'editor_plugin.js'; } // Add the linkit library for the editor. drupal_add_library('linkit', $editor); return $plugin; } /** * Implements hook_wysiwyg_editor_settings_alter(). */ function linkit_wysiwyg_editor_settings_alter(&$settings, $context) { if ($context['profile']->editor == 'ckeditor') { $button_exists = isset($context['profile']->settings['buttons']['linkit']); if (!empty($context['profile']->settings['default_toolbar_grouping']) && $button_exists) { foreach ($settings['toolbar'] as &$group) { if ($group['name'] == 'links') { array_unshift($group['items'], 'linkit'); } if ($group['name'] == 'other') { if (in_array('linkit', $group['items'])) { unset($group['items'][array_search('linkit', $group['items'])]); // Regenerate the keys. $group['items'] = array_values($group['items']); } } } } } } /** * Implements hook_ckeditor_plugin(). */ function linkit_ckeditor_plugin() { return array( 'linkit' => array( // Name of the plugin used to write it 'name' => 'linkit', // Description of plugin - it would appear in plugins managment of profile settings 'desc' => t('Support for Linkit module'), // The full path to the CKEditor plugin directory, with trailing slash. 'path' => drupal_get_path('module', 'linkit') . '/editors/ckeditor/', // Buttons to show up in the toolbar config area. 'buttons' => array( 'linkit' => array( 'label' => 'Linkit', 'icon' => 'icons/linkit.png', ), ), ), ); } /** * Add Linkit settings to pages where we have an editor element. */ function linkit_pre_render_editor_element($element) { static $processed = array(); if (!isset($processed[$element['#id']])) { global $user; $all_formats = array_keys(filter_formats($user)); $profiles_formats = array(); $use_imce = FALSE; // First we need to figure out which formats that the current user can access have active Linkit profiles for them. foreach ($all_formats as $format) { // Load the first profile that is assigned to this text format. $profile = linkit_profile_load_by_format($format); if ($profile) { if (isset($profile->data['imce']) && $profile->data['imce'] == 1) { $use_imce = TRUE; } $profiles_formats[$format] = array('profile' => $profile->name); } } if (!empty($profiles_formats)) { $field_js = array( 'data' => array( 'linkit' => array( 'formats' => $profiles_formats, ), ), 'type' => 'setting', ); // Configure Linkit to have an IMCE selector. if (module_invoke('imce', 'access') && $use_imce) { $field_js['data']['linkit']['IMCEurl'] = url('imce', array('query' => array( 'app' => 'Linkit|sendto@Drupal.linkit.IMCECallback', 'absolute' => TRUE, ))); // We will only serv public files with IMCE. $field_js['data']['linkit']['publicFilesDirectory'] = variable_get('file_public_path', conf_path() . '/files'); } // Attach the linkit_base librar $element['#attached']['library'][] = array('linkit', 'base'); $element['#attached']['js'][] = $field_js; $processed[$element['#id']] = TRUE; } } return $element; } /** * Load the first profile assigned to a text format. * * @param $format * A string with the format machine name. * * @return * A LinkitProfile object or FALSE if no profile is found. */ function linkit_profile_load_by_format($format) { $profiles = linkit_profile_editor_load_all(); foreach ($profiles as $profile) { if (is_array($profile->data['text_formats']) && in_array($format, array_filter($profile->data['text_formats']))) { return $profile; } } return FALSE; } /** * Get profile type. */ function linkit_get_profile_type($type) { switch ($type) { case LINKIT_PROFILE_TYPE_EDITOR: return t('Editor'); case LINKIT_PROFILE_TYPE_FIELD: return t('Field'); default: return t('Can not find the profile type'); } } /** * Gets the path processed by the inputfilter choice. * * @param LinkitProfile $profile * The Linkit profile to use. * * @param $uri * The uri to act on. * * @param $options * An array of options to the URL function if its used. * * @return The processed uri. */ function linkit_get_insert_plugin_processed_path(LinkitProfile $profile, $uri, $options = array()) { switch ($profile->data['insert_plugin']['url_method']) { case LINKIT_URL_METHOD_RAW: $path = $uri; break; case LINKIT_URL_METHOD_RAW_SLASH: $options['alias'] = TRUE; $path = url($uri, $options); break; case LINKIT_URL_METHOD_ALIAS: $path = url($uri, $options); break; } return $path; }