View source
<?php
define('ADVANCED_LINK_EXTERNAL', 'external');
define('ADVANCED_LINK_INTERNAL', 'internal');
define('ADVANCED_LINK_BOTH', 'both');
define('ADVANCED_LINK_TARGET_DEFAULT', 'default');
define('ADVANCED_LINK_SEARCH_START', 'start');
define('ADVANCED_LINK_SEARCH_CONTAINS', 'contains');
function advanced_link_perm() {
return array(
'access advanced_link autocomplete',
);
}
function advanced_link_menu() {
$items = array();
$items['advanced_link/autocomplete'] = array(
'page callback' => 'advanced_link_autocomplete',
'access callback' => 'advanced_link_autocomplete_access',
'type' => MENU_CALLBACK,
);
return $items;
}
function advanced_link_autocomplete_access() {
return user_access('access advanced_link autocomplete') || user_access('administer nodes');
}
function advanced_link_autocomplete($type_name, $field_name) {
$args = func_get_args();
$string = implode('/', array_slice($args, 2));
$matches = advanced_link_url_load($args[0], $args[1], $string);
if (!$matches) {
$matches[''] = t('No matching results.');
}
drupal_json($matches);
}
function advanced_link_autocomplete_url_filter_conditions($urls_filter, $query, $collumn) {
if ($urls_filter) {
$urls_filter = str_replace("*", "%", $urls_filter);
$filters = explode("\n", $urls_filter);
$query .= " AND (";
foreach ($filters as $filter) {
$filter = trim($filter);
$query .= "{$collumn} LIKE '{$filter}' OR ";
}
$query = substr_replace($query, '', strlen($query) - 3, 3);
$query .= ")";
}
return $query;
}
function advanced_link_url_load($field_name, $type_name, $string = NULL) {
module_load_include('inc', 'content', 'includes/content.crud');
$instance = content_field_instance_read(array(
'field_name' => $field_name,
'type_name' => $type_name,
));
$search_type = $instance[0]['widget']['urls_search'];
$urls_filter = isset($instance[0]['widget']['urls_filter']) ? trim($instance[0]['widget']['urls_filter']) : NULL;
if ($search_type == ADVANCED_LINK_SEARCH_CONTAINS) {
$condition_menu = '%s[^\\%]*$';
$condition_alias = '%%%s%%';
}
else {
$condition_menu = '^%s[^\\%]*$';
$condition_alias = '%s%%';
}
if ($string) {
$urls_list = array();
$urls_list_menu = array();
global $db_type;
if ($db_type == 'pgsql') {
$operator = '~';
}
else {
$operator = 'REGEXP';
}
$query_text = "SELECT path FROM {menu_router} WHERE path " . $operator . " lower('" . $condition_menu . "')";
$query_text = advanced_link_autocomplete_url_filter_conditions($urls_filter, $query_text, 'path');
$query_text .= " ORDER BY path ASC";
$query = db_query_range($query_text, $string, 0, 20);
while ($result = db_fetch_object($query)) {
$urls_list_menu[$result->path] = $result->path;
}
$query_text = "SELECT dst FROM {url_alias} WHERE dst LIKE lower('" . $condition_alias . "')";
$query_text = advanced_link_autocomplete_url_filter_conditions($urls_filter, $query_text, 'dst');
$query_text .= " ORDER BY dst ASC";
$query = db_query_range($query_text, $string, 0, 20 - count($urls_list_menu));
while ($result = db_fetch_object($query)) {
$urls_list[$result->dst] = $result->dst;
}
return $urls_list + $urls_list_menu;
}
else {
return FALSE;
}
}
function advanced_link_widget_info() {
return array(
'advanced_link' => array(
'label' => t('Advanced Link'),
'field types' => array(
'link',
),
'multiple values' => CONTENT_HANDLE_CORE,
),
);
}
function advanced_link_widget(&$form, &$form_state, $field, $items, $delta = 0) {
$element = array(
'#type' => $field['widget']['type'],
'#default_value' => isset($items[$delta]) ? $items[$delta] : '',
'#title' => $field['widget']['label'],
'#weight' => $field['widget']['weight'],
'#description' => $field['widget']['description'],
'#required' => $field['required'],
'#field' => $field,
);
return $element;
}
function advanced_link_validator($element, &$form_state) {
$urls_allowed = isset($element['#field']['widget']['urls_allowed']) ? $element['#field']['widget']['urls_allowed'] : ADVANCED_LINK_BOTH;
$urls_filter = isset($element['#field']['widget']['urls_filter']) ? trim($element['#field']['widget']['urls_filter']) : NULL;
$values = $element['#value'];
$url = trim($values['url']);
if ($url) {
if ($urls_allowed != ADVANCED_LINK_BOTH) {
if ($urls_allowed != link_validate_url($url)) {
form_set_error($element['#field_name'], t('URLs need to be @url_allowed', array(
'@url_allowed' => drupal_strtoupper($urls_allowed),
)));
}
}
if ($urls_filter) {
$match = drupal_match_path($url, $urls_filter);
if (!$match) {
form_set_error($element['#field_name'], t("You can't use such URLs."));
}
}
}
}
function advanced_link_widget_settings($op, $widget) {
switch ($op) {
case 'form':
$form['urls_allowed'] = array(
'#type' => 'radios',
'#title' => t('URLs allowed'),
'#options' => array(
ADVANCED_LINK_INTERNAL => t('Allowed only internal.'),
ADVANCED_LINK_EXTERNAL => t('Allowed only external.'),
ADVANCED_LINK_BOTH => t('Allowed both (external and internal).'),
),
'#default_value' => isset($widget['urls_allowed']) ? $widget['urls_allowed'] : ADVANCED_LINK_BOTH,
'#description' => t('More filtering options can be found in "URLs filter" textfield.'),
);
$filter_description = t("Enter one page per line as Drupal paths or only another external. Note, that filtering applies to any 'URLs allowed' mode. The '*' character is a wildcard. Example paths are blog for the <em>blog</em> page and blog/* for every personal blog. %front is the front page.", array(
'%front' => '<front>',
));
$form['urls_filter'] = array(
'#type' => 'textarea',
'#title' => t('URLs filter'),
'#default_value' => isset($widget['urls_filter']) ? $widget['urls_filter'] : '',
'#description' => $filter_description,
);
$form['title_list'] = array(
'#type' => 'textarea',
'#title' => t('List of allowed titles'),
'#default_value' => isset($widget['title_list']) ? $widget['title_list'] : '',
'#description' => t("Enter the list of allowed titles separated by new line.<br />Leave empty to allow user input any text in title."),
);
$form['urls_search'] = array(
'#type' => 'radios',
'#title' => t('Suggest urls that'),
'#options' => array(
ADVANCED_LINK_SEARCH_START => t('start with specified characters'),
ADVANCED_LINK_SEARCH_CONTAINS => t('contain specified characters'),
),
'#default_value' => isset($settings['urls_search']) ? $settings['urls_search'] : ADVANCED_LINK_SEARCH_START,
'#description' => t('Select search type for autocomplete suggestion.'),
);
return $form;
case 'save':
return array(
'urls_filter',
'urls_allowed',
'title_list',
'urls_search',
);
}
}
function advanced_link_theme() {
return array(
'advanced_link' => array(
'arguments' => array(
'element' => NULL,
),
),
);
}
function theme_advanced_link($element) {
if (empty($element['#field']['multiple'])) {
if (isset($element['url']) && isset($element['title'])) {
$element['url']['#title'] = $element['#title'] . ' ' . $element['url']['#title'];
$element['title']['#title'] = $element['#title'] . ' ' . $element['title']['#title'];
}
elseif ($element['url']) {
$element['url']['#title'] = $element['#title'];
}
}
$output = '';
$output .= '<div class="advanced_link-field-subrow clear-block advanced_link-autocomplete">';
if (isset($element['title'])) {
if (trim($element['#field']['widget']['title_list'])) {
$output .= '<div class="advanced_link-field-title advanced_link-field-column">' . theme('select', $element['title']) . '</div>';
}
else {
$output .= '<div class="advanced_link-field-title advanced_link-field-column">' . theme('textfield', $element['title']) . '</div>';
}
}
$output .= '<div class="advanced_link-field-url' . (isset($element['title']) ? ' advanced_link-field-column' : '') . '">' . theme('textfield', $element['url']) . '</div>';
$output .= '</div>';
if (!empty($element['attributes']['target'])) {
$output .= '<div class="advanced_link-attributes">' . theme('checkbox', $element['attributes']['target']) . '</div>';
}
return $output;
}
function advanced_link_elements() {
$elements = array();
$elements['advanced_link'] = array(
'#input' => TRUE,
'#process' => array(
'advanced_link_process',
),
'#element_validate' => array(
'advanced_link_validator',
),
);
return $elements;
}
function advanced_link_process($element, $edit, $form_state, $form) {
$urls_allowed = $element['#field']['widget']['urls_allowed'];
$field_name = $element['#field_name'];
$type_name = $element['#type_name'];
$field = $form['#field_info'][$element['#field_name']];
$delta = $element['#delta'];
$element['url'] = array(
'#type' => 'textfield',
'#maxlength' => LINK_URL_MAX_LENGTH,
'#title' => t('URL'),
'#attributes' => array(
'style' => 'width: 100%',
),
'#description' => $element['#description'],
'#required' => $delta == 0 && $field['url'] !== 'optional' ? $element['#required'] : FALSE,
'#default_value' => isset($element['#value']['url']) ? $element['#value']['url'] : NULL,
);
if ($urls_allowed != ADVANCED_LINK_EXTERNAL && advanced_link_autocomplete_access()) {
$element['url']['#autocomplete_path'] = 'advanced_link/autocomplete/' . $element['#field_name'] . '/' . $element['#type_name'];
}
if ($field['title'] != 'none' && $field['title'] != 'value') {
if (isset($field['widget']['title_list']) && trim($field['widget']['title_list'])) {
$final_array_word = advanced_link_extract_allowed_values($field['widget']['title_list']);
$element['title'] = array(
'#type' => 'select',
'#options' => $final_array_word,
'#title' => t('Title'),
'#required' => $delta == 0 && $field['title'] == 'required' ? $field['required'] : FALSE,
'#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
);
}
else {
$element['title'] = array(
'#type' => 'textfield',
'#maxlength' => $element['#field']['widget']['title_lenght'],
'#title' => t('Title'),
'#required' => $delta == 0 && $field['title'] == 'required' ? $field['required'] : FALSE,
'#default_value' => isset($element['#value']['title']) ? $element['#value']['title'] : NULL,
);
}
}
if (!is_array($field['attributes'])) {
$field['attributes'] = array();
}
$field['attributes'] += _advanced_link_default_attributes();
$attributes = isset($element['#value']['attributes']) ? $element['#value']['attributes'] : $field['attributes'];
if (!empty($field['attributes']['target']) && $field['attributes']['target'] == LINK_TARGET_USER) {
$element['attributes']['target'] = array(
'#type' => 'checkbox',
'#title' => t('Open URL in a New Window'),
'#return_value' => LINK_TARGET_NEW_WINDOW,
'#default_value' => $attributes['target'],
);
}
return $element;
}
function _advanced_link_default_attributes() {
return array(
'title' => '',
'target' => ADVANCED_LINK_TARGET_DEFAULT,
'class' => '',
'rel' => '',
);
}
function advanced_link_extract_allowed_values($values) {
$values_as_array = explode("\n", $values);
$result_values = array(
'' => '',
);
foreach ($values_as_array as $title) {
$result_values[trim(htmlentities($title))] = trim(htmlentities($title));
}
return $result_values;
}