View source
<?php
define('LINKIT_URL_METHOD_RAW', 1);
define('LINKIT_URL_METHOD_RAW_SLASH', 2);
define('LINKIT_URL_METHOD_ALIAS', 3);
define('LINKIT_BAC_QUERY_KEY', 's');
define('LINKIT_CHAR_LIMIT', 3);
define('LINKIT_WAIT', 350);
define('LINKIT_REMOTE_TIMEOUT', 10000);
define('LINKIT_PROFILE_TYPE_EDITOR', 1);
define('LINKIT_PROFILE_TYPE_FIELD', 2);
define('LINKIT_PROFILE_TYPE_MENU', 3);
require_once dirname(__FILE__) . '/linkit.field.inc';
function linkit_permission() {
return array(
'administer linkit' => array(
'title' => t('Administer Linkit'),
'description' => t('Perform administration tasks for Linkit.'),
),
);
}
function linkit_ctools_plugin_directory($module, $plugin) {
if ($module == 'ctools' && !empty($plugin)) {
return "plugins/" . $plugin;
}
if ($module == 'linkit' && !empty($plugin)) {
return "plugins/" . $plugin;
}
}
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;
}
function linkit_insert_plugin_process(&$plugin, $info) {
if (!file_exists($plugin['javascript'])) {
$plugin['javascript'] = $plugin['path'] . '/' . $plugin['javascript'];
}
}
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;
}
function linkit_profile_load_all() {
ctools_include('export');
$profiles = ctools_export_load_object('linkit_profiles');
uasort($profiles, 'linkit_profile_sort_weight');
return $profiles;
}
function linkit_profile_sort_weight($a, $b) {
$a_weight = isset($a->weight) ? $a->weight : 0;
$b_weight = isset($b->weight) ? $b->weight : 0;
if ($a_weight == $b_weight) {
return strcmp($a->name, $b->name);
}
return $a_weight < $b_weight ? -1 : 1;
}
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);
}
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);
}
function linkit_profile_menu_load_all() {
$profiles = linkit_profile_load_all();
foreach ($profiles as &$profile) {
if ($profile->profile_type != LINKIT_PROFILE_TYPE_MENU) {
$profile = FALSE;
}
}
return array_filter($profiles);
}
function linkit_set_active_profile(LinkitProfile $profile) {
$active_profile =& drupal_static('linkit_active_profile');
$active_profile = $profile;
}
function linkit_get_active_profile() {
return drupal_static('linkit_active_profile');
}
function linkit_search_plugin_load_all() {
ctools_include('plugins');
$plugins = ctools_get_plugins('linkit', 'linkit_search');
drupal_alter('linkit_search_plugins', $plugins);
return $plugins;
}
function linkit_sort_plugins_by_weight($a, $b) {
return $a["weight"] >= $b["weight"];
}
function linkit_search_plugin_load($plugin_name) {
ctools_include('plugins');
$plugin = ctools_get_plugins('linkit', 'linkit_search', $plugin_name);
drupal_alter('linkit_search_plugin', $plugin);
return $plugin;
}
function linkit_insert_plugin_load_all() {
ctools_include('plugins');
$plugins = ctools_get_plugins('linkit', 'linkit_insert');
return $plugins;
}
function linkit_insert_plugin_load($plugin_name) {
ctools_include('plugins');
$plugins = ctools_get_plugins('linkit', 'linkit_insert', $plugin_name);
return $plugins;
}
function linkit_attribute_plugin_load_all() {
ctools_include('plugins');
$attributes = ctools_get_plugins('linkit', 'linkit_attribute');
return $attributes;
}
function linkit_attribute_plugin_load($plugin_name) {
ctools_include('plugins');
$plugins = ctools_get_plugins('linkit', 'linkit_attribute', $plugin_name);
return $plugins;
}
function linkit_theme($existing, $type, $theme, $path) {
return array(
'linkit_plugin_form_table' => array(
'render element' => 'form',
'file' => 'includes/theme.inc',
),
);
}
function linkit_menu_alter(&$items) {
$items['admin/config/content/linkit/add']['title'] = 'Add new profile';
$items['admin/config/content/linkit/import']['title'] = 'Import profiles';
$items['admin/config/content/linkit/add']['type'] = MENU_LOCAL_TASK;
$items['admin/config/content/linkit/import']['type'] = MENU_LOCAL_TASK;
}
function linkit_module_implements_alter(&$implementations, $hook) {
if ($hook == 'element_info_alter') {
$group = $implementations['linkit'];
unset($implementations['linkit']);
$implementations['linkit'] = $group;
}
}
function linkit_element_info_alter(&$types) {
foreach (linkit_get_allowed_field_elements() as $element) {
if (isset($types[$element])) {
$types[$element]['#after_build'][] = 'linkit_field_element_after_build';
}
}
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';
}
}
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';
}
}
}
function linkit_library() {
$path = drupal_get_path('module', 'linkit');
$common = array(
'website' => 'http://drupal.org/project/linkit',
'version' => '7.3',
);
$libraries['base'] = array(
'title' => 'Linkit base',
'js' => array(
$path . '/js/linkit.js' => array(
'group' => JS_DEFAULT,
'weight' => -1,
),
array(
'type' => 'setting',
'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',
),
array(
'linkit',
'dashboard',
),
array(
'linkit',
'bac',
),
),
);
$libraries['dashboard'] = array(
'title' => 'Linkit dashboard',
'js' => array(
$path . '/js/linkit.dashboard.js' => array(
'group' => JS_DEFAULT,
'weight' => 0,
),
),
);
$libraries['field'] = array(
'title' => 'Linkit Field UI',
'js' => array(
$path . '/js/linkit.field.js' => array(
'group' => JS_DEFAULT,
),
),
'dependencies' => array(
array(
'linkit',
'base',
),
),
);
$libraries['ckeditor'] = array(
'title' => 'Linkit CKeditor',
'js' => array(
$path . '/editors/ckeditor/linkitDialog.js' => array(
'group' => JS_DEFAULT,
),
),
'dependencies' => array(
array(
'linkit',
'base',
),
),
);
$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;
}
$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;
}
function linkit_menu() {
$items = array();
$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',
);
$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;
}
function linkit_dashboard_page(LinkitProfile $profile) {
linkit_set_active_profile($profile);
$form = drupal_get_form('linkit_dashboard_form');
return array(
'#type' => 'ajax',
'#commands' => array(
ajax_command_html('#linkit-modal', drupal_render($form)),
ajax_command_prepend('#linkit-modal', theme('status_messages')),
),
);
}
function linkit_change_profile($form, $form_state) {
return $form['linkit_container'];
}
function linkit_dashboard_form($form, &$form_state) {
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);
}
$form['#attached']['css'][drupal_get_path('module', 'linkit') . '/css/linkit.css'] = array(
'preprocess' => FALSE,
);
$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' => '<div id="linkit-profile-changer">',
'#suffix' => '</div>',
);
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' => '<div id="linkit-dashboard-ajax-wrapper">',
'#suffix' => '</div>',
'#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 ($active_profile
->getEnabledAttributePlugins()) {
$form['linkit_container']['linkit_attributes'] = array(
'#type' => 'fieldset',
'#title' => t('Options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 10,
'#attributes' => array(
'class' => array(
'linkit-attributes',
),
),
);
foreach ($active_profile
->getEnabledAttributePlugins() as $name => $attribute) {
$attribute['#attributes']['class'][] = 'linkit-attribute-' . $name;
$form['linkit_container']['linkit_attributes']['linkit_' . $name] = $attribute;
}
}
$form['linkit_container']['linkit_insert'] = array(
'#type' => 'button',
'#value' => t('Insert link'),
'#suffix' => '<a id="linkit-cancel" href="#">' . t('Cancel') . '</a>',
'#weight' => 100,
'#attributes' => array(
'class' => array(
'linkit-insert',
),
),
);
return $form;
}
function linkit_autocomplete(LinkitProfile $profile) {
linkit_set_active_profile($profile);
$search_string = $_GET[LINKIT_BAC_QUERY_KEY];
$results = array();
if (strpos($search_string, 'front') !== FALSE) {
$results[] = array(
'title' => t('Frontpage'),
'description' => 'The frontpage for this site.',
'path' => url('<front>'),
'group' => t('System'),
);
}
$results = array_merge($results, linkit_autocomplete_search_plugins($search_string));
if (empty($results)) {
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, '/'));
if (isset($parts['scheme']) || isset($parts['host'])) {
$results = array_merge($results, linkit_autocomplete_absolute_url($search_string, $parts));
}
}
}
if (empty($results)) {
$results = array(
array(
'title' => t('No results'),
'addClass' => 'status-notice',
'disabled' => TRUE,
),
);
}
print drupal_json_output($results);
drupal_exit();
}
function linkit_autocomplete_search_plugins($search_string) {
$matches = array();
$profile = linkit_get_active_profile();
foreach ($profile
->getEnabledsearchPlugins() as $plugin_name => $plugin) {
$matches = array_merge($matches, $plugin
->fetchResults($search_string));
}
return $matches;
}
function linkit_parse_url($url, $parts) {
global $base_url;
$path_info = array();
$path_info += $parts;
$path_info['url'] = $url;
if (!isset($path_info['query'])) {
$path_info['query'] = '';
}
parse_str($path_info['query'], $path_info['query']);
if (isset($path_info['query']['q'])) {
$path_info['path'] = $path_info['query']['q'];
unset($path_info['query']['q']);
}
$local_stream_wrappers = file_get_stream_wrappers(STREAM_WRAPPERS_LOCAL);
$local_hosts = array(
$base_url,
);
drupal_alter('linkit_local_hosts', $local_hosts);
$local_url = isset($path_info['scheme']) && isset($path_info['host']) && in_array(trim($path_info['scheme'] . '://' . $path_info['host'] . base_path(), '/'), $local_hosts);
$local_stream_wrapper = isset($local_stream_wrappers[$path_info['scheme']]);
if ($local_url || $local_stream_wrapper) {
$path_info['target'] = 'internal';
if ($local_stream_wrapper) {
$path_info = array_merge($path_info, parse_url(file_create_url($path_info['url'])));
}
$path_info['path'] = trim($path_info['path'], '/');
if (empty($path_info['path'])) {
$path_info['frontpage'] = TRUE;
$path_info['path'] = variable_get('site_frontpage', 'node');
}
$internal_url = drupal_get_normal_path($path_info['path']);
$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 ($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 {
$path_info['target'] = 'external';
}
return $path_info;
}
function linkit_autocomplete_absolute_url($url, $parts) {
$result = array();
$path_info = linkit_parse_url($url, $parts);
$url_options = array();
$url_options['fragment'] = isset($path_info['fragment']) ? $path_info['fragment'] : '';
$url_options['query'] = isset($path_info['query']) ? $path_info['query'] : '';
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',
);
}
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',
);
}
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 array(
$result,
);
}
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;
}
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,
);
if ($editor == 'tinymce') {
$plugin['linkit']['filename'] = 'editor_plugin.js';
}
drupal_add_library('linkit', $editor);
return $plugin;
}
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'])]);
$group['items'] = array_values($group['items']);
}
}
}
}
}
}
function linkit_ckeditor_plugin() {
return array(
'linkit' => array(
'name' => 'linkit',
'desc' => t('Support for Linkit module'),
'path' => drupal_get_path('module', 'linkit') . '/editors/ckeditor/',
'buttons' => array(
'linkit' => array(
'label' => 'Linkit',
'icon' => 'icons/linkit.png',
),
),
),
);
}
function linkit_pre_render_editor_element($element) {
global $user;
$element['#attached']['library'][] = array(
'linkit',
'base',
);
$all_formats = array_keys(filter_formats($user));
$all_profiles = linkit_profile_editor_load_all();
$profiles_formats = array();
$use_imce = FALSE;
foreach ($all_formats as $format) {
$profiles_formats[$format] = array(
'profile' => NULL,
'enabled_profiles' => array(),
);
}
foreach ($all_profiles as $profile) {
if (empty($profile->disabled) && is_array($profile->data['text_formats'])) {
foreach (array_filter($profile->data['text_formats']) as $text_format) {
if (in_array($text_format, $all_formats)) {
if (empty($profiles_formats[$text_format]['profile'])) {
$profiles_formats[$text_format]['profile'] = $profile->name;
}
$profiles_formats[$text_format]['enabled_profiles'][$profile->name] = TRUE;
if (isset($profile->data['imce']) && $profile->data['imce'] == 1) {
$use_imce = TRUE;
}
}
}
}
}
if (!empty($profiles_formats)) {
$field_js = array(
'data' => array(
'linkit' => array(
'formats' => $profiles_formats,
),
),
'type' => 'setting',
);
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,
),
));
$field_js['data']['linkit']['publicFilesDirectory'] = variable_get('file_public_path', conf_path() . '/files');
}
$element['#attached']['js'][] = $field_js;
if (isset($element['#format']) && isset($element['#pre_render'])) {
if (in_array('ckeditor_pre_render_text_format', $element['#pre_render'])) {
foreach ($profiles_formats as $format => $profile) {
if ($format == $element['#format']) {
$element['#attached']['library'][] = array(
'linkit',
'ckeditor',
);
break;
}
}
}
}
}
return $element;
}
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;
}
function linkit_get_profile_type($type) {
switch ($type) {
case LINKIT_PROFILE_TYPE_EDITOR:
return t('Editor');
case LINKIT_PROFILE_TYPE_FIELD:
return t('Field');
case LINKIT_PROFILE_TYPE_MENU:
return t('Menu');
default:
return t('Can not find the profile type');
}
}
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;
}
function linkit_form_menu_edit_item_alter(&$form, &$form_state) {
$profiles = linkit_profile_menu_load_all();
foreach ($profiles as $profile) {
$form['link_path']['#linkit'] = array(
'profile' => $profile->name,
'button_text' => t($profile->data['button_text']),
);
break;
}
}