| 1 |
<?php
|
| 2 |
// $Id: links_weblink.module,v 1.25 2008/12/26 03:53:36 syscrusher Exp $
|
| 3 |
|
| 4 |
/*
|
| 5 |
* links_weblink defines a "weblink" node type, for backward compatibility
|
| 6 |
* with the weblink.module by Ber Kessels. Much of the code in this new
|
| 7 |
* module is based on Ber's previous work.
|
| 8 |
*/
|
| 9 |
|
| 10 |
/**
|
| 11 |
* Implementation of hook_help()
|
| 12 |
*/
|
| 13 |
function links_weblink_help($path, $arg) {
|
| 14 |
switch($path) {
|
| 15 |
case 'admin/help#links_weblink':
|
| 16 |
return t("<p>This module is used to create links to other resources -- websites, pages, documents, etc. Each click on an outgoing link is logged and counted.</p>");
|
| 17 |
}
|
| 18 |
}
|
| 19 |
|
| 20 |
/**
|
| 21 |
* Implementation of hook_node_info()
|
| 22 |
*/
|
| 23 |
function links_weblink_node_info() {
|
| 24 |
return array(
|
| 25 |
'weblink' => array(
|
| 26 |
'name' => t('weblink'),
|
| 27 |
'module' => 'links_weblink',
|
| 28 |
'has_title' => TRUE,
|
| 29 |
'has_body' => TRUE,
|
| 30 |
'description' => t("A weblink is an article whose main purpose is to catalog a link into a directory, as distinguished from an article of some other type that may or may not have related links. It is possible that a weblink article may <i>also</i> have related links (depending on administrative settings for this site), but the weblink's primary link is a required field that is separate from the optional related links (if any)."),
|
| 31 |
),
|
| 32 |
);
|
| 33 |
}
|
| 34 |
|
| 35 |
/**
|
| 36 |
* Implementation of hook_menu()
|
| 37 |
*/
|
| 38 |
function links_weblink_menu() {
|
| 39 |
$items = array();
|
| 40 |
if (variable_get('links_weblink_enable_catalog', 1)) {
|
| 41 |
$items['links/weblink'] = array(
|
| 42 |
'title' => t('weblinks'),
|
| 43 |
'page callback' => 'links_weblink_page',
|
| 44 |
'access callback' => 'user_access',
|
| 45 |
'access arguments' => array('view weblinks'),
|
| 46 |
);
|
| 47 |
}
|
| 48 |
$items['admin/settings/links/links_weblink'] = array(
|
| 49 |
'title' => t('weblinks module'),
|
| 50 |
'description' => t('Configure settings for the weblink content type.'),
|
| 51 |
'page callback' => 'drupal_get_form',
|
| 52 |
'page arguments' => array('links_weblink_settings_form'),
|
| 53 |
'access callback' => 'user_access',
|
| 54 |
'access arguments' => array('administer site configuration'),
|
| 55 |
'type' => MENU_LOCAL_TASK,
|
| 56 |
);
|
| 57 |
return $items;
|
| 58 |
}
|
| 59 |
|
| 60 |
/**
|
| 61 |
* Implements hook_theme to register our theme functions
|
| 62 |
*/
|
| 63 |
function links_weblink_theme($existing, $type, $theme, $path) {
|
| 64 |
return array(
|
| 65 |
'links_weblink_page_form' => array(
|
| 66 |
'arguments' => array('element' => NULL),
|
| 67 |
),
|
| 68 |
'links_weblink_category' => array(
|
| 69 |
'arguments' => array('element' => NULL),
|
| 70 |
),
|
| 71 |
'links_weblink_category_children' => array(
|
| 72 |
'arguments' => array('element' => NULL),
|
| 73 |
),
|
| 74 |
);
|
| 75 |
}
|
| 76 |
|
| 77 |
/**
|
| 78 |
* Hook from links_admin to declare that deleting the main link from this
|
| 79 |
* node requires the node to be deleted as well.
|
| 80 |
*/
|
| 81 |
function links_weblink_links_admin_link_required() {
|
| 82 |
// The format is node_type => module_name
|
| 83 |
return array('weblink'=>'links_weblink');
|
| 84 |
}
|
| 85 |
|
| 86 |
function links_weblink_page_form() {
|
| 87 |
drupal_add_css(drupal_get_path('module', 'links') .'/links_weblink.css', 'module');
|
| 88 |
$form = array();
|
| 89 |
$form['#theme'] = 'links_weblink_page_form';
|
| 90 |
|
| 91 |
// This array will hold the level we are showing
|
| 92 |
// as $tid => $name
|
| 93 |
$terms = array();
|
| 94 |
$args = explode(',',arg(2));
|
| 95 |
foreach ($args as $i=>$term) {
|
| 96 |
if (intval($term)) {
|
| 97 |
$tid = intval($term);
|
| 98 |
$term = taxonomy_get_term($tid);
|
| 99 |
$terms[$tid] = $term->name;
|
| 100 |
}
|
| 101 |
}
|
| 102 |
if (count($terms)) {
|
| 103 |
$top_level = false;
|
| 104 |
} else {
|
| 105 |
$top_level = true;
|
| 106 |
// Go get all the top-level terms for applicable vocabs
|
| 107 |
$vocabs = taxonomy_get_vocabularies('weblink');
|
| 108 |
// If no vocabs are defined, we can't go any further, so abort out
|
| 109 |
// with an administrator warning.
|
| 110 |
if (! count($vocabs)) {
|
| 111 |
$vars = array();
|
| 112 |
$msg = "No categories are defined for the weblink module.";
|
| 113 |
if (user_access('administer taxonomy')) {
|
| 114 |
$vars['!admin_link'] = l(t('category administration'),'admin/content/taxonomy');
|
| 115 |
$msg .= " (go to !admin_link)";
|
| 116 |
}
|
| 117 |
$form['message'] = array(
|
| 118 |
'#type'=>'markup',
|
| 119 |
'#value'=>t($msg, $vars),
|
| 120 |
);
|
| 121 |
watchdog('links', $msg, $vars, WATCHDOG_WARNING, l(t('administer'), 'admin/content/taxonomy'));
|
| 122 |
return $form;
|
| 123 |
}
|
| 124 |
foreach ($vocabs as $vocab) {
|
| 125 |
$tree = taxonomy_get_tree($vocab->vid, 0, -1, 1);
|
| 126 |
foreach ($tree as $term) {
|
| 127 |
$terms[$term->tid] = $term->name;
|
| 128 |
}
|
| 129 |
}
|
| 130 |
}
|
| 131 |
|
| 132 |
// At this point, the array $terms contains $tid=>$name for all of the
|
| 133 |
// terms at the current level. For the top level, it will often have
|
| 134 |
// multiple elements. For lower levels, typically only one unless the
|
| 135 |
// search specified a comma-separated list in the URL, e.g.,
|
| 136 |
// path "links/weblink/2,5,7" .
|
| 137 |
|
| 138 |
$all_parents = array();
|
| 139 |
$weight = 0;
|
| 140 |
foreach ($terms as $tid=>$name) {
|
| 141 |
$element = array('#tree'=>true, '#theme'=>'links_weblink_category', '#weight'=>$weight++);
|
| 142 |
// $element = array('#tree'=>true, '#weight'=>$weight++);
|
| 143 |
$element['term'] = array(
|
| 144 |
'#type' => 'markup',
|
| 145 |
'#tree' => true,
|
| 146 |
'#value' => l($name, 'links/weblink/'.$tid),
|
| 147 |
);
|
| 148 |
$term_nodes[$tid] = array();
|
| 149 |
$result = db_query("SELECT n.nid, n.title FROM {node} n, {term_node} tn WHERE n.nid=tn.tid AND tn.tid=%d AND n.type='weblink' AND n.status=1 ORDER BY n.title", $tid);
|
| 150 |
while ($node = db_fetch_object($result)) {
|
| 151 |
$term_nodes[$tid][] = $node;
|
| 152 |
}
|
| 153 |
$children = taxonomy_get_children($tid);
|
| 154 |
$element['children'] = array(
|
| 155 |
'#theme' => 'links_weblink_category_children',
|
| 156 |
'#tree' => true,
|
| 157 |
);
|
| 158 |
$weight2 = 0;
|
| 159 |
foreach ($children as $child) {
|
| 160 |
$element['children'][] = array(
|
| 161 |
'#type' => 'markup',
|
| 162 |
'#value' => l($child->name, 'links/weblink/'.$child->tid),
|
| 163 |
'#weight' => $weight2++,
|
| 164 |
'#prefix' => '<li class="links_weblink_category_child">',
|
| 165 |
'#suffix' => '</li>',
|
| 166 |
);
|
| 167 |
}
|
| 168 |
$parents = taxonomy_get_parents($tid);
|
| 169 |
foreach ($parents as $parent) {
|
| 170 |
$all_parents[$parent->tid] = l($parent->name, 'links/weblink/'.$parent->tid);
|
| 171 |
}
|
| 172 |
$form[$tid] = $element;
|
| 173 |
}
|
| 174 |
|
| 175 |
if ($top_level) {
|
| 176 |
$title = t('Weblinks: Main Page');
|
| 177 |
} else {
|
| 178 |
$title = t('Weblinks: %topics', array('%topics'=>implode(', ',$terms)));
|
| 179 |
$breadcrumbs = drupal_get_breadcrumb();
|
| 180 |
$breadcrumbs[] = l(t('Weblinks top level'), 'links/weblink');
|
| 181 |
if (count($all_parents)) {
|
| 182 |
$breadcrumbs[] = implode(', ', $all_parents);
|
| 183 |
}
|
| 184 |
drupal_set_breadcrumb($breadcrumbs);
|
| 185 |
}
|
| 186 |
drupal_set_title($title);
|
| 187 |
|
| 188 |
// List the nodes at the current level
|
| 189 |
|
| 190 |
$terms_to_list = array();
|
| 191 |
if(variable_get('links_weblink_catalog_show_child_category_links','1')) {
|
| 192 |
$terms_to_list = $terms;
|
| 193 |
if (!$top_level) {
|
| 194 |
$terms_to_list += $children;
|
| 195 |
}
|
| 196 |
} else {
|
| 197 |
if (!$top_level)
|
| 198 |
$terms_to_list[$tid] = $term;
|
| 199 |
}
|
| 200 |
|
| 201 |
$form['nodes'] = array(
|
| 202 |
'#tree' => true,
|
| 203 |
);
|
| 204 |
$i = 0;
|
| 205 |
if (count($terms_to_list)) {
|
| 206 |
$sql = "SELECT DISTINCT n.nid, n.title FROM {node} n, {term_node} tn WHERE n.nid=tn.nid AND tn.tid IN (%s) AND n.type='weblink' AND n.status=1 ORDER BY n.title";
|
| 207 |
$result = db_query($sql, implode(',', array_keys($terms_to_list)));
|
| 208 |
while ($node = db_fetch_object($result)) {
|
| 209 |
$node_html = node_view(node_load($node->nid), true, false, true);
|
| 210 |
$form['nodes'][$i++] = array(
|
| 211 |
'#type' => 'markup',
|
| 212 |
'#value' => $node_html,
|
| 213 |
);
|
| 214 |
}
|
| 215 |
} else {
|
| 216 |
$html .= t("<p>There are no weblinks defined at this level of the category tree.</p>\n");
|
| 217 |
}
|
| 218 |
|
| 219 |
return $form;
|
| 220 |
}
|
| 221 |
|
| 222 |
/**
|
| 223 |
* Display a view of the weblinks
|
| 224 |
* URL format
|
| 225 |
* q=links/weblink
|
| 226 |
* or q=links/weblink/$term1,$term2,....
|
| 227 |
* where $term1, $term2, etc. are integer ID numbers
|
| 228 |
*
|
| 229 |
* In the default (first) form, the module will show all
|
| 230 |
* top-level terms from all vocabularies applicable to
|
| 231 |
* weblink node types and will generate links that point
|
| 232 |
* to the second form for each term.
|
| 233 |
*
|
| 234 |
* In the second form, the module will show terms as
|
| 235 |
* indicated. An internal navigation link will be
|
| 236 |
* created to any applicable parent terms, if the
|
| 237 |
* vocabularies allow nesting, and to the default
|
| 238 |
* top-level display as well.
|
| 239 |
*/
|
| 240 |
function links_weblink_page() {
|
| 241 |
$html = "";
|
| 242 |
$html .= drupal_get_form('links_weblink_page_form');
|
| 243 |
return $html;
|
| 244 |
}
|
| 245 |
|
| 246 |
function theme_links_weblink_category_children($children) {
|
| 247 |
$kids = "";
|
| 248 |
foreach ($children as $i=>$kid) {
|
| 249 |
if (is_int($i)) {
|
| 250 |
$kids .= drupal_render($kid);
|
| 251 |
}
|
| 252 |
}
|
| 253 |
$output = '<ul class="links_weblink_category_children">';
|
| 254 |
$output .= $kids;
|
| 255 |
$output .= '</ul>';
|
| 256 |
return $output;
|
| 257 |
}
|
| 258 |
|
| 259 |
function theme_links_weblink_category($element) {
|
| 260 |
//print("_category<br>");
|
| 261 |
$output = '<div class="links_weblink_category">';
|
| 262 |
$output .= '<div class="links_weblink_category_parent">' . drupal_render($element['term']) . '</div>';
|
| 263 |
if (count($element['children'])) {
|
| 264 |
$output .= drupal_render($element['children']);
|
| 265 |
}
|
| 266 |
$output .= '</div>';
|
| 267 |
return $output;
|
| 268 |
}
|
| 269 |
|
| 270 |
function theme_links_weblink_page_form($form) {
|
| 271 |
// First, check for a message. If that's set, then nothing else applies.
|
| 272 |
if (is_array($form['message'])) {
|
| 273 |
return drupal_render($form['message']);
|
| 274 |
}
|
| 275 |
$columns = variable_get('links_weblink_catalog_category_cols','2');
|
| 276 |
$table = array();
|
| 277 |
|
| 278 |
// Current column (0, 1,...$columns-1)
|
| 279 |
$col = 0;
|
| 280 |
$row = 0;
|
| 281 |
|
| 282 |
$output .= '<h3 class="links_weblink_section">' . t('Categories') . '</h3>';
|
| 283 |
foreach ($form as $i=>$element) {
|
| 284 |
if (is_int($i)) {
|
| 285 |
if (! is_array($table[$row])) {
|
| 286 |
$table[$row] = array();
|
| 287 |
$table[$row]['data'] = array();
|
| 288 |
}
|
| 289 |
$table[$row]['data'][$col++] = drupal_render($element);
|
| 290 |
if ($col >= $columns) {
|
| 291 |
$col = 0;
|
| 292 |
$row++;
|
| 293 |
}
|
| 294 |
}
|
| 295 |
}
|
| 296 |
// Finish out a row
|
| 297 |
while ($col < $columns) {
|
| 298 |
$table[$row]['data'][$col++] = '';
|
| 299 |
}
|
| 300 |
// Apply row attributes
|
| 301 |
foreach (array_keys($table) as $i) {
|
| 302 |
$table[$i]['class'] = 'links_weblink_category_row';
|
| 303 |
$table[$i]['valign'] = 'top'; // STUB for testing without CSS file
|
| 304 |
}
|
| 305 |
$output .= theme('table',NULL,$table);
|
| 306 |
// Add the links at this level and (optionally) child level
|
| 307 |
$node_html = '';
|
| 308 |
if (is_array($form['nodes']) && count($form['nodes']) > 0) {
|
| 309 |
foreach ($form['nodes'] as $i=>$element) {
|
| 310 |
if (is_int($i)) {
|
| 311 |
$node_html .= '<p>' . drupal_render($element);
|
| 312 |
}
|
| 313 |
}
|
| 314 |
}
|
| 315 |
if ($node_html != '') {
|
| 316 |
$output .= '<h3 class="links_weblink_section">' . t('Links') . '</h3>';
|
| 317 |
$output .= $node_html;
|
| 318 |
} else {
|
| 319 |
$output .= '<p>' . t('(No links in this category)') . '</p>';
|
| 320 |
}
|
| 321 |
return $output;
|
| 322 |
}
|
| 323 |
|
| 324 |
/**
|
| 325 |
* Exposes the needed permissions for this node type
|
| 326 |
*/
|
| 327 |
function links_weblink_perm() {
|
| 328 |
return array('create weblinks', 'view weblinks', 'edit own weblinks');
|
| 329 |
}
|
| 330 |
|
| 331 |
/**
|
| 332 |
* Implementation of hook_settings()
|
| 333 |
*/
|
| 334 |
function links_weblink_settings_form() {
|
| 335 |
$form = array();
|
| 336 |
if (!module_exists('links')) {
|
| 337 |
drupal_set_message(t('The "links" module is disabled or not installed. Weblinks will not function until this is corrected. Check the availability of
|
| 338 |
that module, and enable if needed, in the %modules.',array('%modules'=>l(t('modules administration page'),'admin/modules'))),'error');
|
| 339 |
}
|
| 340 |
|
| 341 |
$form['link_settings'] = array(
|
| 342 |
'#type' => 'fieldset',
|
| 343 |
'#title' => t('Link display settings'),
|
| 344 |
'#description' => t("Other settings for how weblinks behave and how they are displayed are available in the !linksettingspage.", array('!linksettingspage'=>l(t('links module settings page'),'admin/settings/links'))),
|
| 345 |
);
|
| 346 |
|
| 347 |
$form['link_settings']['links_weblink_display_teaser'] = array(
|
| 348 |
'#type' => 'radios',
|
| 349 |
'#title' => t('Link display for teaser view'),
|
| 350 |
'#default_value' => variable_get('links_weblink_display_teaser','1'),
|
| 351 |
'#options' => array(0=>t('Do not display link'), 1=>t('Display link')),
|
| 352 |
'#description' => t('This setting controls whether the clickable link is displayed near the node title (in most themes) for the teaser or listing format.'),
|
| 353 |
);
|
| 354 |
|
| 355 |
$form['link_settings']['links_weblink_display_full'] = array(
|
| 356 |
'#type' => 'radios',
|
| 357 |
'#title' => t('Link display for full-page view'),
|
| 358 |
'#default_value' => variable_get('links_weblink_display_full','1'),
|
| 359 |
'#options' => array(0=>t('Do not display link'), 1=>t('Display link')),
|
| 360 |
'#description' => t('This setting controls how many links are displayed near the node title (in most themes) in full-page displays.'),
|
| 361 |
);
|
| 362 |
|
| 363 |
$form['link_settings']['links_weblink_display_length'] = array(
|
| 364 |
'#type' => 'select',
|
| 365 |
'#title' => t('Display trim length'),
|
| 366 |
'#default_value' => variable_get('links_weblink_display_length','0'),
|
| 367 |
'#options' => array(0=>t('Unlimited'), 20=>20, 30=>30, 40=>40),
|
| 368 |
'#description' => t('Trims the displayed text (but not the actual URL) when the clickable link is displayed near the article title. Does not affect display of the link at the end of the article body.'),
|
| 369 |
);
|
| 370 |
|
| 371 |
$form['link_settings']['links_weblink_enable_list'] = array(
|
| 372 |
'#type' => 'checkbox',
|
| 373 |
'#title' => t('Show link at end of body text'),
|
| 374 |
'#return_value' => 1,
|
| 375 |
'#default_value' => variable_get('links_weblink_enable_list','1'),
|
| 376 |
'#description' => t('If enabled, the clickable link will be appended to the end of the content, when in full-page display mode.'),
|
| 377 |
);
|
| 378 |
|
| 379 |
$form['link_catalog'] = array(
|
| 380 |
'#type' => 'fieldset',
|
| 381 |
'#title' => t('Weblink catalog settings'),
|
| 382 |
);
|
| 383 |
|
| 384 |
$form['link_catalog']['links_weblink_enable_catalog'] = array(
|
| 385 |
'#type' => 'checkbox',
|
| 386 |
'#title' => t('Enable weblinks directory'),
|
| 387 |
'#return_value' => 1,
|
| 388 |
'#default_value' => variable_get('links_weblink_enable_catalog','1'),
|
| 389 |
'#description' => t('If enabled, this module will produce a directory of all weblink nodes, organized by category.'),
|
| 390 |
);
|
| 391 |
|
| 392 |
$form['link_catalog']['links_weblink_catalog_category_cols'] = array(
|
| 393 |
'#type' => 'select',
|
| 394 |
'#title' => t('Category display columns'),
|
| 395 |
'#default_value' => variable_get('links_weblink_catalog_category_cols','2'),
|
| 396 |
'#options' => array(1=>1, 2=>2, 3=>3, 4=>4, 5=>5),
|
| 397 |
'#description' => t('If the weblink catalog is enabled, this setting controls the number of columns in the table of catagories that appears at the top of link catalog pages.'),
|
| 398 |
);
|
| 399 |
|
| 400 |
$form['link_catalog']['links_weblink_catalog_show_child_category_links'] = array(
|
| 401 |
'#type' => 'checkbox',
|
| 402 |
'#title' => t('Show links in child categories'),
|
| 403 |
'#return_value' => 1,
|
| 404 |
'#default_value' => variable_get('links_weblink_catalog_show_child_category_links','1'),
|
| 405 |
'#description' => t('If enabled, the weblink catalog will list weblinks in both the selected category and its children (if the vocabulary in use is hierarchical).'),
|
| 406 |
);
|
| 407 |
|
| 408 |
return system_settings_form($form);
|
| 409 |
}
|
| 410 |
|
| 411 |
/**
|
| 412 |
* Implementation of hook_form
|
| 413 |
*/
|
| 414 |
function links_weblink_form(&$node) {
|
| 415 |
|
| 416 |
$form['title'] = array(
|
| 417 |
'#type' => 'textfield',
|
| 418 |
'#title' => t('Title'),
|
| 419 |
'#required' => TRUE,
|
| 420 |
'#default_value' => $node->title,
|
| 421 |
'#description' => t("Textual description of the weblink"),
|
| 422 |
'#weight' => -18,
|
| 423 |
);
|
| 424 |
|
| 425 |
$form['links_weblink_url'] = array(
|
| 426 |
'#type' => 'textfield',
|
| 427 |
'#title' => t('Link URL'),
|
| 428 |
'#default_value' => $node->links_weblink_url,
|
| 429 |
'#required' => TRUE,
|
| 430 |
'#description' => t('Link URL, either local or remote. The URL will be normalized to remove things like session identifiers, which are not a permanent part of the link address.'),
|
| 431 |
'#weight' => -17,
|
| 432 |
);
|
| 433 |
|
| 434 |
$form['body'] = array(
|
| 435 |
'#type' => 'textarea',
|
| 436 |
'#title' => t('Body'),
|
| 437 |
'#default_value' => $node->body,
|
| 438 |
'#required' => FALSE,
|
| 439 |
'#weight' => -16,
|
| 440 |
);
|
| 441 |
|
| 442 |
$form['format'] = filter_form($node->format);
|
| 443 |
return $form;
|
| 444 |
}
|
| 445 |
|
| 446 |
/**
|
| 447 |
* Implementation of hook_load
|
| 448 |
*/
|
| 449 |
function links_weblink_load($node) {
|
| 450 |
$links = links_load_links_for_node($node->nid, 'links_weblink', 0, TRUE);
|
| 451 |
return array('links_weblink_url'=>$links[0]['url'], 'links_weblink'=>$links);
|
| 452 |
}
|
| 453 |
|
| 454 |
/**
|
| 455 |
* Implementation of hook_prepare().
|
| 456 |
*/
|
| 457 |
function links_weblink_prepare(&$node) {
|
| 458 |
if (isset($_POST['links_weblink_url'])) {
|
| 459 |
$node->links_weblink_url = $_POST['links_weblink_url'];
|
| 460 |
}
|
| 461 |
links_weblink_node_build($node);
|
| 462 |
}
|
| 463 |
|
| 464 |
/**
|
| 465 |
* Implementation of hook_validate().
|
| 466 |
*/
|
| 467 |
function links_weblink_validate(&$node) {
|
| 468 |
links_weblink_node_build($node);
|
| 469 |
}
|
| 470 |
|
| 471 |
/**
|
| 472 |
* Implementation of hook_delete().
|
| 473 |
*/
|
| 474 |
function links_weblink_delete(&$node) {
|
| 475 |
// Delete the values from a node that is being erased
|
| 476 |
// Don't care if it's "supposed" to have links -- delete if found anyway
|
| 477 |
links_weblink_node_build($node);
|
| 478 |
links_delete_links_for_node($node, 'links_weblink');
|
| 479 |
}
|
| 480 |
|
| 481 |
/**
|
| 482 |
* Implementation of hook_insert().
|
| 483 |
*/
|
| 484 |
function links_weblink_insert(&$node) {
|
| 485 |
links_weblink_node_build($node);
|
| 486 |
links_save_links_for_node($node, 'links_weblink');
|
| 487 |
}
|
| 488 |
|
| 489 |
/**
|
| 490 |
* Implementation of hook_update().
|
| 491 |
*/
|
| 492 |
function links_weblink_update(&$node) {
|
| 493 |
links_weblink_node_build($node);
|
| 494 |
links_save_links_for_node($node, 'links_weblink');
|
| 495 |
}
|
| 496 |
|
| 497 |
/**
|
| 498 |
* Implementation of hook_link().
|
| 499 |
*/
|
| 500 |
function links_weblink_link($type='', $node=NULL, $teaser=FALSE) {
|
| 501 |
// Only node links supported here
|
| 502 |
if ($type != 'node') {
|
| 503 |
return array();
|
| 504 |
}
|
| 505 |
$list = links_get_list('links_weblink', $node, FALSE, $teaser, FALSE);
|
| 506 |
if (count($list) > 0) {
|
| 507 |
$links['links_weblink'] = $list[0];
|
| 508 |
return $links;
|
| 509 |
}
|
| 510 |
}
|
| 511 |
|
| 512 |
/**
|
| 513 |
* Implementation of hook_view
|
| 514 |
*/
|
| 515 |
function links_weblink_view(&$node, $teaser = FALSE, $page = FALSE) {
|
| 516 |
$node = node_prepare($node, $teaser);
|
| 517 |
$formatted_links = links_get_list('links_weblink', $node, $page, $teaser, TRUE);
|
| 518 |
// We know the array can only have zero or one elements in this module.
|
| 519 |
if ($page && variable_get('links_weblink_enable_list', 0) && isset($formatted_links[0])) {
|
| 520 |
$node->content['weblink'] = array(
|
| 521 |
'#value' => theme('links_weblink_append', $formatted_links[0]),
|
| 522 |
'#weight' => -1,
|
| 523 |
);
|
| 524 |
}
|
| 525 |
return $node;
|
| 526 |
}
|
| 527 |
|
| 528 |
/**
|
| 529 |
* Apply markup to the appended weblink
|
| 530 |
*/
|
| 531 |
function theme_links_weblink_append($link) {
|
| 532 |
$output = '<p><ul id="links_weblink_list"><li>' . l($link['title'], $link['href'], $link['attributes']) . '</li></ul>';
|
| 533 |
return $output;
|
| 534 |
}
|
| 535 |
|
| 536 |
/**
|
| 537 |
* To use the links API, we sometimes need to populate the internal data
|
| 538 |
* structure $node->links_weblink, which is an array of link-definition
|
| 539 |
* arrays. In this case, the outer array always contains exactly one element
|
| 540 |
* because we are interested only in the primary URL for the weblink. If
|
| 541 |
* this site allows "related links" for weblink nodes, that's handled
|
| 542 |
* by the links_related module, not here.
|
| 543 |
*/
|
| 544 |
function links_weblink_node_build(&$node, $url='') {
|
| 545 |
if (empty($url)) {
|
| 546 |
$url = links_normalize_url($node->links_weblink_url);
|
| 547 |
} else {
|
| 548 |
$url = links_normalize_url($url);
|
| 549 |
}
|
| 550 |
$node->links_weblink_url = $url;
|
| 551 |
$link = array(
|
| 552 |
'url'=>$url,
|
| 553 |
'link_title'=>$node->title,
|
| 554 |
'weight'=>0,
|
| 555 |
);
|
| 556 |
// Wrap $link as the [0] element of a trivial outer array.
|
| 557 |
$node->links_weblink = array($link);
|
| 558 |
}
|
| 559 |
|
| 560 |
function links_weblink_access($op, $node) {
|
| 561 |
global $user;
|
| 562 |
switch($op) {
|
| 563 |
case 'view':
|
| 564 |
return $node->status && user_access('view weblinks');
|
| 565 |
case 'update':
|
| 566 |
case 'delete':
|
| 567 |
return ($user->uid == $node->uid) && user_access('edit own weblinks');
|
| 568 |
case 'create':
|
| 569 |
return user_access('create weblinks');
|
| 570 |
}
|
| 571 |
}
|
| 572 |
|
| 573 |
/**
|
| 574 |
* Create the form for the node. It's similar to the form for links_related
|
| 575 |
* but allows (and in fact requires) only one link. Note that it's possible
|
| 576 |
* to enable the "weblink" node type for "related links" in addition to the
|
| 577 |
* special link that is a requirement. The only difference is the $module
|
| 578 |
* parameter when we save the link to the database.
|
| 579 |
*/
|
| 580 |
function links_weblink_form_alter($form_id, &$form) {
|
| 581 |
$type = $form['type']['#value'];
|
| 582 |
switch ($form_id) {
|
| 583 |
case $type .'_node_form':
|
| 584 |
// The actual node edit form. This allows the users to enter the
|
| 585 |
// links_related into appropriate node types' edit screens.
|
| 586 |
$node = $form['#node'];
|
| 587 |
$link = $node->links_weblink;
|
| 588 |
$link['url'] = links_normalize_url($link['url']);
|
| 589 |
break;
|
| 590 |
}
|
| 591 |
return;
|
| 592 |
}
|
| 593 |
|
| 594 |
/**
|
| 595 |
* Block display functions
|
| 596 |
*/
|
| 597 |
function links_weblink_block($op = "list", $delta = 0) {
|
| 598 |
if ($op == "list") {
|
| 599 |
return array(
|
| 600 |
0 => array('info' => t("Top weblinks")),
|
| 601 |
1 => array('info' => t("Latest weblinks")),
|
| 602 |
2 => array('info' => t("Weblinks blogroll")),
|
| 603 |
);
|
| 604 |
}
|
| 605 |
elseif ($op == 'view') {
|
| 606 |
switch ($delta) {
|
| 607 |
case 0:
|
| 608 |
return array(
|
| 609 |
'subject' => t("Top weblinks"),
|
| 610 |
'content' => links_weblink_block_list('top')
|
| 611 |
);
|
| 612 |
case 1:
|
| 613 |
return array(
|
| 614 |
'subject' => t("Latest weblinks"),
|
| 615 |
'content' => links_weblink_block_list('new')
|
| 616 |
);
|
| 617 |
case 2:
|
| 618 |
return array(
|
| 619 |
'subject' => t("Weblinks"),
|
| 620 |
'content' => t('Not yet implemented.'),
|
| 621 |
);
|
| 622 |
}
|
| 623 |
}
|
| 624 |
}
|
| 625 |
|
| 626 |
function links_weblink_block_list($type = 'top') {
|
| 627 |
$orderby = ($type == 'new') ? 'n.created' : 'ln.clicks';
|
| 628 |
return node_title_list(db_query_range(db_rewrite_sql("SELECT n.nid, n.title, l.url, ln.clicks FROM {node} n INNER JOIN {links_node} ln on n.nid = ln.nid INNER JOIN {links} l ON ln.lid = l.lid WHERE n.type = 'weblink' AND ln.module='links_weblink' AND n.status = 1 AND n.moderate = 0 ORDER by $orderby DESC"),0, 10));
|
| 629 |
}
|
| 630 |
|
| 631 |
/**
|
| 632 |
* Filter handling code
|
| 633 |
*/
|
| 634 |
function links_weblink_filter($op, $delta = 0, $format = -1, $text = "") {
|
| 635 |
switch ($op) {
|
| 636 |
case 'list':
|
| 637 |
return array(0 => t("Weblink filter"));
|
| 638 |
case 'description':
|
| 639 |
return t("Filter for weblink tokens, [weblink:node_id|text] or [weblink:node_id/link_id] or [weblink:http://weblink.example.com/]. If there is more than one link for the specified node_id, the first one will be used unless link_id is specified.");
|
| 640 |
case 'process':
|
| 641 |
return _links_weblink_filter_process($text);
|
| 642 |
default: return $text;
|
| 643 |
}
|
| 644 |
}
|
| 645 |
|
| 646 |
function _links_weblink_filter_process($text) {
|
| 647 |
|
| 648 |
// This section handles [weblink:$nid], [weblink:$nid/$lid], and the variants of these
|
| 649 |
// with the optional "|$text" title parameter.
|
| 650 |
|
| 651 |
$match = array();
|
| 652 |
preg_match_all("#\[weblink:(\d+)(?:/(\d+))?(?:\|([^\|\]]*))?\]#i", $text, $match, PREG_SET_ORDER);
|
| 653 |
foreach ($match as $m) {
|
| 654 |
$found = $m[0];
|
| 655 |
$nid = $m[1];
|
| 656 |
$lid = $m[2];
|
| 657 |
$title = $m[3];
|
| 658 |
$url = links_format_goto_url($nid, $lid);
|
| 659 |
if (empty($title)) {
|
| 660 |
$links = links_load_links_for_node($nid, '', $lid, TRUE);
|
| 661 |
$title = $links[0]['link_title'];
|
| 662 |
if (empty($title)) {
|
| 663 |
$title = t('(Link not found)');
|
| 664 |
}
|
| 665 |
}
|
| 666 |
$target = links_get_goto_target();
|
| 667 |
$attribs = empty($target) ? array() : array('target'=>links_get_goto_target());
|
| 668 |
$replacement = l($title,$url,$attribs);
|
| 669 |
$text = str_replace($found, $replacement, $text);
|
| 670 |
}
|
| 671 |
|
| 672 |
// This section handles [weblink:$url] and [weblink:$url|$text] variants
|
| 673 |
|
| 674 |
$patterns = array();
|
| 675 |
// Finds links with a protocol spec (adapted from urlfilter.module)
|
| 676 |
$pattern = "!\[weblink:([A-Za-z]+://[a-zA-Z0-9@:%_~#?&=.,/;-]*)(?:\|([^\]]+))?]!i";
|
| 677 |
$match = array();
|
| 678 |
preg_match_all($pattern, $text, $match, PREG_SET_ORDER);
|
| 679 |
foreach ($match as $m) {
|
| 680 |
$found = $m[0];
|
| 681 |
$url = $m[1];
|
| 682 |
$title = $m[2];
|
| 683 |
$link = links_get_link($url);
|
| 684 |
$lid = is_array($link) ? intval($link['lid']) : 0;
|
| 685 |
if (empty($title)) {
|
| 686 |
$title = links_suggest_link_title($url);
|
| 687 |
}
|
| 688 |
if ($lid) {
|
| 689 |
$url = links_format_goto_url(0, $lid);
|
| 690 |
}
|
| 691 |
$target = links_get_goto_target();
|
| 692 |
$attribs = empty($target) ? array() : array('target'=>links_get_goto_target());
|
| 693 |
$replacement = l($title,$url,$attribs);
|
| 694 |
$text = str_replace($found, $replacement, $text);
|
| 695 |
}
|
| 696 |
|
| 697 |
return $text;
|
| 698 |
}
|
| 699 |
|
| 700 |
function links_weblink_filter_tips($delta, $format, $long = false) {
|
| 701 |
if ($long) {
|
| 702 |
return t("You may create links to items stored in our weblink registry using a special syntax. The weblink codes will be replaced by a links to visit the real websites. Syntax: <code>[weblink:node_id]</code> (to use the first link for that node), <code>[weblink:node_id/link_id]</code> (to use a specific link for that node) or <code>[weblink:http://a.weblink.example.com/]</code> (to specify a raw URL).");
|
| 703 |
}
|
| 704 |
else {
|
| 705 |
return t("You may link to webpages <a href=\"%long-tip\">through the weblinks registry</a>", array("%long-tip" => url("filter/tips", NULL, 'weblink')));
|
| 706 |
}
|
| 707 |
}
|
| 708 |
|
| 709 |
/**
|
| 710 |
* Implements hook_links_delete_link_reference to remove $lid from
|
| 711 |
* the {links_node} table for records used by this module.
|
| 712 |
*
|
| 713 |
* TODO: In the case of weblinks, the nodes also need to be
|
| 714 |
* deleted.
|
| 715 |
*/
|
| 716 |
function links_weblink_links_delete_link_reference($lid) {
|
| 717 |
// First find out if we will need to delete any nodes
|
| 718 |
$result = db_query("SELECT nid FROM {links_node} WHERE lid=%d AND module='links_weblink'", $lid);
|
| 719 |
$nid_list = array();
|
| 720 |
while ($row=db_fetch_array($result)) {
|
| 721 |
$nid_list[] = $row['nid'];
|
| 722 |
}
|
| 723 |
db_query("DELETE FROM {links_node} WHERE lid=%d AND module='links_weblink'", $lid);
|
| 724 |
if (db_error()) {
|
| 725 |
watchdog("links","links delete references for link !lid failed for links_weblink module", array('!lid'=>$lid), WATCHDOG_ERROR);
|
| 726 |
} else {
|
| 727 |
watchdog("links","Deleted references for link !lid for links_weblink module", array('!lid'=>$lid), WATCHDOG_INFO);
|
| 728 |
if (count($nid_list)) {
|
| 729 |
watchdog("links","Deletion of link !lid requires deletion of nodes !nodes by links_weblink module, because these weblinks will no longer be valid.", array('!lid'=>$lid, '!nodes'=>implode(', ', $nid_list)), WATCHDOG_INFO);
|
| 730 |
foreach ($nid_list as $nid) {
|
| 731 |
node_delete($nid);
|
| 732 |
}
|
| 733 |
}
|
| 734 |
}
|
| 735 |
}
|