| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160 | <?php/** * @file * Main file for Linkit module. *//** * Define that urls should be constructed as it is (raw). */define('LINKIT_URL_METHOD_RAW', 1);/** * Define that urls should be constructed as it is (raw) with a prepending * slash. */define('LINKIT_URL_METHOD_RAW_SLASH', 2);/** * Define that paths should be constructed as an alias. */define('LINKIT_URL_METHOD_ALIAS', 3);/** * Define which query string key Better autocomplete will just. */define('LINKIT_BAC_QUERY_KEY', 's');/** * Define the minimum number of characters to perform server polling. */define('LINKIT_CHAR_LIMIT', 3);/** * Define the time from last key press to poll the server. */define('LINKIT_WAIT', 350);/** * Define the client side timeout for a request to the server. */define('LINKIT_REMOTE_TIMEOUT', 10000);/** * Define the profile type editor. */define('LINKIT_PROFILE_TYPE_EDITOR', 1);/** * Define the profile type field. */define('LINKIT_PROFILE_TYPE_FIELD', 2);// Include the file with the field functions.require_once dirname(__FILE__) . '/linkit.field.inc';/** * Implements hook_permission(). */function linkit_permission() { return array(    'administer linkit' => 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' => '<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 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' => '<a id="linkit-cancel" href="#">' . t('Cancel') . '</a>',    '#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('<front>'),      '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;}
 |