| 1 |
<?php
|
| 2 |
// $Id: dmoz.module,v 1.1 2006/05/24 17:39:46 trunks Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Dmoz gateway for Llengua.org
|
| 7 |
*
|
| 8 |
* Developed by Jose A. Reyero, http://www.reyero.net
|
| 9 |
* for interactors, http://www.interactors.coop
|
| 10 |
*
|
| 11 |
* Touched a little bit by Javier Linares, http://javierlinares.com
|
| 12 |
*/
|
| 13 |
|
| 14 |
// Perl interpreter
|
| 15 |
define('DMOZ_PERL', '/usr/bin/perl');
|
| 16 |
|
| 17 |
/**
|
| 18 |
* Implementation of hook_help().
|
| 19 |
*/
|
| 20 |
function dmoz_help($section) {
|
| 21 |
switch ($section) {
|
| 22 |
case 'admin/modules#description':
|
| 23 |
return t('Drupal gateway for the Open Directory Project, http://dmoz.org');
|
| 24 |
case 'node/add#dmoz':
|
| 25 |
return t('ODP link');
|
| 26 |
}
|
| 27 |
}
|
| 28 |
|
| 29 |
/**
|
| 30 |
* Implementation of hook_settings().
|
| 31 |
*/
|
| 32 |
function dmoz_settings(){
|
| 33 |
$output = '';
|
| 34 |
$output .= form_textfield(t('ODP Category'), 'dmoz_category', variable_get('dmoz_category', ''), 50, 100, t('Category of the ODP to import'));
|
| 35 |
foreach(taxonomy_get_vocabularies() as $vid => $vocab){
|
| 36 |
$vocabulary[$vid] = $vocab->name;
|
| 37 |
}
|
| 38 |
$output .= form_select(t('Drupal Vocabulary'), 'dmoz_vocabulary', variable_get('dmoz_vocabulary', ''), $vocabulary, t('Drupal Vocabulary to store the dmoz categories'));
|
| 39 |
|
| 40 |
$group = form_radios(t('Update on cron'), 'dmoz_cron', variable_get('dmoz_cron', 0), array(t('Disabled'), t('Enabled')), t('Automatic update. Enable to run all the process automatically on cron.'));
|
| 41 |
$group .= form_textfield(t('Process step'), 'dmoz_process_rows', variable_get('dmoz_process_rows', 100), 20, 20, t('Number of rows to process on each cron. Default 100'));
|
| 42 |
$output .= form_group(t('Cron settings'),$group);
|
| 43 |
|
| 44 |
$group = form_textfield(t('Remote Structure file'), 'dmoz_struct_url', variable_get('dmoz_struct_url', 'http://rdf.dmoz.org/rdf/structure.rdf.u8.gz'), 50, 100, t('URL of Structure file to download'));
|
| 45 |
$group .= form_textfield(t('Remote Content file'), 'dmoz_content_url', variable_get('dmoz_content_url', 'http://rdf.dmoz.org/rdf/content.rdf.u8.gz'), 50, 100, t('URL of Content file to download'));
|
| 46 |
$output .= form_group(t('Remote URLs'), $group);
|
| 47 |
|
| 48 |
$group = form_textfield(t('Scripts directory'), 'dmoz_dir_scripts', variable_get('dmoz_dir_scripts', 'modules/dmoz/scripts'), 50, 100, t('Directory for working'));
|
| 49 |
$group .= form_textfield(t('Working directory'), 'dmoz_dir_working', variable_get('dmoz_dir_working', 'files/dmoz'), 50, 100, t('Directory for working'));
|
| 50 |
$group .= form_textfield(t('Structure file'), 'dmoz_struct_file', variable_get('dmoz_struct_file', 'structure.rdf.u8'), 50, 100, t('Structure file'));
|
| 51 |
$group .= form_textfield(t('Content file'), 'dmoz_content_file', variable_get('dmoz_content_file', 'content.rdf.u8'), 50, 100, t('Content file'));
|
| 52 |
$group .= form_textfield(t('Extracted Structure file'), 'dmoz_struct_extract', variable_get('dmoz_struct_extract', 'extracted-structure.rdf.u8'), 50, 100, t('Extracted Structure file'));
|
| 53 |
$group .= form_textfield(t('Extracted Content file'), 'dmoz_content_extract', variable_get('dmoz_content_extract', 'extracted-content.rdf.u8'), 50, 100, t('Extracted Content file'));
|
| 54 |
$output .= form_group(t('Local Files and Folders'), $group);
|
| 55 |
// Check PERL version
|
| 56 |
exec(DMOZ_PERL.' -v', $result, $exit);
|
| 57 |
|
| 58 |
if($exit){
|
| 59 |
drupal_set_message(t('PERL not found.'), 'warning');
|
| 60 |
} else {
|
| 61 |
$output .= form_item(t('PERL version'), implode('<br/>',$result));
|
| 62 |
}
|
| 63 |
|
| 64 |
|
| 65 |
//$output .= form_radios(t('Process stage'), 'dmoz_stage', variable_get('dmoz_stage', ''), _dmoz_stages(), t("Current stage of process to be run on %cron_url", array('%cron_url' => l('cron.php', 'cron.php'))));
|
| 66 |
|
| 67 |
return $output;
|
| 68 |
}
|
| 69 |
|
| 70 |
/**
|
| 71 |
* Implementation of hook_menu().
|
| 72 |
*/
|
| 73 |
function dmoz_menu($may_cache) {
|
| 74 |
$items = array();
|
| 75 |
|
| 76 |
if ($may_cache) {
|
| 77 |
$items[] = array(
|
| 78 |
'type' => MENU_CALLBACK,
|
| 79 |
'path' => 'dmoz',
|
| 80 |
'title' => t('ODP Category'),
|
| 81 |
'callback' => 'dmoz_page',
|
| 82 |
'access' => user_access('access content'));
|
| 83 |
$items[] = array(
|
| 84 |
'type' => MENU_CALLBACK,
|
| 85 |
'path' => 'dfeed',
|
| 86 |
'title' => t('ODP RSS Feed'),
|
| 87 |
'callback' => 'dmoz_feed',
|
| 88 |
'access' => user_access('access content'));
|
| 89 |
$items[] = array(
|
| 90 |
'type' => MENU_CALLBACK,
|
| 91 |
'path' => 'dscript',
|
| 92 |
'title' => t('ODP JavaScript'),
|
| 93 |
'callback' => 'dmoz_script',
|
| 94 |
'access' => user_access('access content'));
|
| 95 |
$items[] = array(
|
| 96 |
'path' => 'admin/dmoz',
|
| 97 |
'title' => t('dmoz control'),
|
| 98 |
'callback' => 'dmoz_admin_page',
|
| 99 |
'access' => user_access('administer content'));
|
| 100 |
|
| 101 |
}
|
| 102 |
|
| 103 |
return $items;
|
| 104 |
}
|
| 105 |
|
| 106 |
/**
|
| 107 |
* Menu callback for admin page
|
| 108 |
*/
|
| 109 |
function dmoz_admin_page($op = NULL){
|
| 110 |
require_once drupal_get_path('module', 'dmoz') . '/dmoz_stages.inc';
|
| 111 |
$op = isset($_POST['op']) ? $_POST['op'] : $op;
|
| 112 |
$edit = isset($_POST['edit']) ? $_POST['edit'] : array();
|
| 113 |
$stage = $edit['stage'] ? $edit['stage'] : variable_get('dmoz_stage', '');
|
| 114 |
$output = '';
|
| 115 |
switch($op){
|
| 116 |
case t('Start'):
|
| 117 |
dmoz_stage('start', $stage );
|
| 118 |
break;
|
| 119 |
case t('Cron'):
|
| 120 |
dmoz_stage('cron', $stage);
|
| 121 |
break;
|
| 122 |
default:
|
| 123 |
|
| 124 |
}
|
| 125 |
|
| 126 |
if($contents = _dmoz_status('output contents')){
|
| 127 |
$output .= form_group(t('Output'),'<pre>'.$contents.'</pre>');
|
| 128 |
}
|
| 129 |
if($contents = _dmoz_status('error contents')){
|
| 130 |
$output .= form_group(t('Errors'),'<pre>'.$contents.'</pre>');
|
| 131 |
}
|
| 132 |
$output .= form_group(t('Status'), dmoz_admin_stats());
|
| 133 |
$form .= form_radios(t('Process stage'), 'stage', variable_get('dmoz_stage', ''), _dmoz_stages());
|
| 134 |
$form .= form_submit(t('Start'));
|
| 135 |
$form .= form_submit(t('Cron'));
|
| 136 |
$output .= form(form_group(t('Process control'),$form));
|
| 137 |
if($results = _dmoz_log(NULL, 'watchdog')){
|
| 138 |
$output .= form_group(t('Watchdog'), dmoz_implode('<br />',$results, ' '));
|
| 139 |
}
|
| 140 |
if($results = _dmoz_log(NULL, 'log')){
|
| 141 |
$output .= form_group(t('Results'), dmoz_implode('<br />',$results, ' '));
|
| 142 |
}
|
| 143 |
|
| 144 |
print theme('page', $output);
|
| 145 |
}
|
| 146 |
|
| 147 |
/**
|
| 148 |
* Full statistics about files and data
|
| 149 |
*/
|
| 150 |
function dmoz_admin_stats(){
|
| 151 |
$output = '';
|
| 152 |
// Timing
|
| 153 |
$header = array(t('Event'), t('Time'));
|
| 154 |
$rows[] = array(t('Last process'), format_date(variable_get('dmoz_last_process', 0)));
|
| 155 |
$rows[] = array(t('Last update'), format_date(variable_get('dmoz_last_update', 0)));
|
| 156 |
$output .= theme('table', $header, $rows);
|
| 157 |
$rows = array();
|
| 158 |
// Files
|
| 159 |
$header = array(t('Files'),t('Path'),t('Size'), t('Date'));
|
| 160 |
$files[] = array( 'type' =>t('Compressed Structure'), 'path' => _dmoz_file(basename(variable_get('dmoz_struct_url', 'http://rdf.dmoz.org/rdf/structure.rdf.u8.gz'))));
|
| 161 |
$files[] = array( 'type' =>t('Compressed Content'), 'path' => _dmoz_file(basename(variable_get('dmoz_content_url', 'http://rdf.dmoz.org/rdf/content.rdf.u8.gz'))));
|
| 162 |
$files[] = array( 'type' =>t('Expanded Structure'), 'path' => _dmoz_file(basename(variable_get('dmoz_struct_file', 'structure.rdf.u8'))));
|
| 163 |
$files[] = array( 'type' =>t('Expanded Content'), 'path' => _dmoz_file(basename(variable_get('dmoz_content_file', 'content.rdf.u8'))));
|
| 164 |
$files[] = array( 'type' =>t('Extracted Structure'), 'path' => _dmoz_file(basename(variable_get('dmoz_struct_extract', 'extracted-structure.rdf.u8'))));
|
| 165 |
$files[] = array( 'type' =>t('Extracted Content'), 'path' => _dmoz_file(basename(variable_get('dmoz_content_extract', 'extracted-content.rdf.u8'))));
|
| 166 |
|
| 167 |
foreach($files as $file){
|
| 168 |
if(file_exists($file['path'])){
|
| 169 |
$info = stat($file['path']);
|
| 170 |
$file['size'] = round (($info['size'] /1000000),2) . ' Mb';
|
| 171 |
$file['date'] = format_date($info['mtime']);
|
| 172 |
} else {
|
| 173 |
$file['size'] = '--';
|
| 174 |
$file['date'] = '--';
|
| 175 |
}
|
| 176 |
$rows[] = $file;
|
| 177 |
}
|
| 178 |
$output .= theme('table', $header, $rows);
|
| 179 |
// Get numbers from db
|
| 180 |
$stats['%cats_loaded'] = db_result(db_query("SELECT COUNT(*) FROM {dmoz_structure}"));
|
| 181 |
$stats['%cats_processed'] = db_result(db_query("SELECT COUNT(*) FROM {dmoz_structure} WHERE processed = 1"));
|
| 182 |
$stats['%cats_pct'] = $stats['%cats_loaded'] ? 100 *$stats['%cats_processed'] / $stats['%cats_loaded'] : '--';
|
| 183 |
$stats['%links_loaded'] = db_result(db_query("SELECT COUNT(*) FROM {dmoz_xurls}"));
|
| 184 |
$stats['%links_processed'] = db_result(db_query("SELECT COUNT(*) FROM {dmoz_xurls} WHERE processed = 1"));
|
| 185 |
$stats['%links_pct'] = $stats['%links_loaded'] ? 100 * $stats['%links_processed'] / $stats['%links_loaded'] : '--';
|
| 186 |
$stats['%cats_current'] = db_result(db_query("SELECT COUNT(*) FROM {dmoz_term_data}"));
|
| 187 |
$stats['%links_current'] = db_result(db_query("SELECT COUNT(*) FROM {dmoz_node}"));
|
| 188 |
// Build table
|
| 189 |
$header = array(t('Database'),t('Categories'), t('Links'));
|
| 190 |
$rows = array();
|
| 191 |
$rows[] = array( t('Loaded'), $stats['%cats_loaded'],$stats['%links_loaded']);
|
| 192 |
$rows[] = array( t('Processed'),
|
| 193 |
$stats['%cats_processed'] .' ('.round($stats['%cats_pct'],2).'%)',
|
| 194 |
$stats['%links_processed'] .' ('.round($stats['%links_pct'],2).'%)');
|
| 195 |
$rows[] = array( t('Current'),
|
| 196 |
$stats['%cats_current'] ,
|
| 197 |
$stats['%links_current'] );
|
| 198 |
$output .= theme('table', $header, $rows);
|
| 199 |
return $output ;
|
| 200 |
}
|
| 201 |
|
| 202 |
/**
|
| 203 |
* Recursive implode
|
| 204 |
*/
|
| 205 |
function dmoz_implode($glue, $pieces, $indent = ''){
|
| 206 |
foreach($pieces as $key => $element){
|
| 207 |
if(is_array($element)) $pieces[$key] = $indent.dmoz_implode($glue, $element);
|
| 208 |
}
|
| 209 |
return implode($glue, $pieces);
|
| 210 |
}
|
| 211 |
|
| 212 |
/**
|
| 213 |
* Implementation of hook_cron()
|
| 214 |
*/
|
| 215 |
function dmoz_cron(){
|
| 216 |
if(variable_get('dmoz_cron', 0)) dmoz_stage('cron');
|
| 217 |
}
|
| 218 |
|
| 219 |
/**
|
| 220 |
* Stage control.
|
| 221 |
*
|
| 222 |
* This is a full featured state machine
|
| 223 |
*/
|
| 224 |
function dmoz_stage($op = 'cron', $stage = NULL){
|
| 225 |
require_once drupal_get_path('module', 'dmoz') . '/dmoz_stages.inc';
|
| 226 |
$current = variable_get('dmoz_stage', 'idle');
|
| 227 |
if(!$stage){
|
| 228 |
$stage = $current;
|
| 229 |
} elseif($stage != $current){
|
| 230 |
variable_set('dmoz_stage', $stage);
|
| 231 |
variable_set('dmoz_last_process', time());
|
| 232 |
_dmoz_status('reset');
|
| 233 |
_dmoz_watchdog("Dmoz module stage switched to $stage, op=$op");
|
| 234 |
}
|
| 235 |
$function = 'dmoz_stage_'.$stage;
|
| 236 |
if(function_exists($function)){
|
| 237 |
$result[] = $function($op);
|
| 238 |
} else {
|
| 239 |
_dmoz_watchdog("$function not implemented" , WATCHDOG_WARNING);
|
| 240 |
}
|
| 241 |
}
|
| 242 |
|
| 243 |
/**
|
| 244 |
* Implementation of hook_taxonomy
|
| 245 |
*
|
| 246 |
* $op = insert, update, delete
|
| 247 |
*/
|
| 248 |
function dmoz_taxonomy($op, $type, $edit) {
|
| 249 |
//print "DEBUG: dmoz_taxonomy op=$op type=$type";
|
| 250 |
//var_dump($edit);
|
| 251 |
if($type == 'term'){
|
| 252 |
// This hook is not consistent and passes object/array depending on op
|
| 253 |
$term = is_object($edit) ? $edit : array2object($edit);
|
| 254 |
switch($op){
|
| 255 |
case 'update':
|
| 256 |
if(isset($term->catid)){
|
| 257 |
db_query("UPDATE {dmoz_term_data} SET catid=%d, topic='%s', lastupdate=%d, lastrefresh=%d WHERE tid=%d", $term->catid, $term->topic, $term->lastupdate, $term->lastrefresh, $term->tid);
|
| 258 |
if(db_affected_rows()) break;
|
| 259 |
}
|
| 260 |
// No break, follow if no rows updated
|
| 261 |
case 'insert':
|
| 262 |
if(isset($term->catid)){
|
| 263 |
db_query("INSERT INTO {dmoz_term_data}(tid, catid, topic, lastupdate, lastrefresh) VALUES(%d, %d, '%s', %d, %d)", $term->tid, $term->catid, $term->topic, $term->lastupdate, $term->lastrefresh);
|
| 264 |
// Create alias ?? Too many alias may sink performance
|
| 265 |
// module_invoke('path', 'set_alias', "dmoz/$term->tid", $term->topic);
|
| 266 |
}
|
| 267 |
break;
|
| 268 |
case 'delete':
|
| 269 |
db_query("DELETE FROM {dmoz_term_data} WHERE tid=%d",$term->tid);
|
| 270 |
break;
|
| 271 |
}
|
| 272 |
}
|
| 273 |
}
|
| 274 |
|
| 275 |
/**
|
| 276 |
* Callback for dmoz category pages
|
| 277 |
* dmoz/x -> dmoz_page
|
| 278 |
* dfeed/x -> dmoz_feed
|
| 279 |
* jslist/x -> javascript to copy and paste in page
|
| 280 |
*/
|
| 281 |
function dmoz_page(){
|
| 282 |
$args = func_get_args();
|
| 283 |
dmoz_list('page', $args);
|
| 284 |
}
|
| 285 |
|
| 286 |
function dmoz_feed(){
|
| 287 |
$args = func_get_args();
|
| 288 |
dmoz_list('feed', $args);
|
| 289 |
}
|
| 290 |
|
| 291 |
function dmoz_script(){
|
| 292 |
$args = func_get_args();
|
| 293 |
dmoz_list('script', $args);
|
| 294 |
}
|
| 295 |
|
| 296 |
function dmoz_list($op = 'page', $params){
|
| 297 |
// Pre-process args
|
| 298 |
if(!count($params)){
|
| 299 |
// List root terms
|
| 300 |
$vid = variable_get('dmoz_vocabulary', '');
|
| 301 |
$terms = taxonomy_get_children(0,$vid);
|
| 302 |
$tids = array_keys($terms);
|
| 303 |
} elseif(is_numeric($params[0])) {
|
| 304 |
// Numeric term
|
| 305 |
$tids = array($params[0]);
|
| 306 |
} else {
|
| 307 |
$topic = implode('/',$params);
|
| 308 |
drupal_set_message("Topic: $topic");
|
| 309 |
if($cat = dmoz_get_category($topic, 'topic')){
|
| 310 |
$tids = array($cat->tid);
|
| 311 |
};
|
| 312 |
}
|
| 313 |
|
| 314 |
// Set default params
|
| 315 |
$operator = 'or';
|
| 316 |
$depth = 0;
|
| 317 |
if ($tids) {
|
| 318 |
// Build title:
|
| 319 |
$result = db_query('SELECT name FROM {term_data} WHERE tid IN (%s)', implode(',', $tids));
|
| 320 |
$names = array();
|
| 321 |
while ($term = db_fetch_object($result)) {
|
| 322 |
$names[] = $term->name;
|
| 323 |
}
|
| 324 |
// Needed for '+' to show up in RSS discovery URLs
|
| 325 |
$str_tids = implode(',',$tids);
|
| 326 |
$rss_tids = urlencode($str_tids);
|
| 327 |
|
| 328 |
if ($names) {
|
| 329 |
drupal_set_title($title = implode(', ', $names));
|
| 330 |
|
| 331 |
switch ($op) {
|
| 332 |
case 'page':
|
| 333 |
$output = "<hr />\n";
|
| 334 |
// Build breadcrumb based on first hierarchy of first term:
|
| 335 |
$current->tid = $tids[0];
|
| 336 |
|
| 337 |
drupal_set_breadcrumb(dmoz_get_breadcrumbs($tids[0]));
|
| 338 |
|
| 339 |
drupal_add_link(array('rel' => 'alternate',
|
| 340 |
'type' => 'application/rss+xml',
|
| 341 |
'title' => 'RSS - '. $title,
|
| 342 |
'href' => url('dfeed/'. $rss_tids)));
|
| 343 |
|
| 344 |
$output .= theme('item_list',dmoz_get_children($tids[0]));
|
| 345 |
$output .= "<hr />\n";
|
| 346 |
$output .= dmoz_render_nodes(dmoz_select_nodes($tids, $operator, $depth, FALSE));
|
| 347 |
$output .= theme('xml_icon', url("dfeed/$rss_tids"));
|
| 348 |
// $output .= _dmoz_license($tids[0]);
|
| 349 |
print theme('page', $output);
|
| 350 |
break;
|
| 351 |
|
| 352 |
case 'feed':
|
| 353 |
$term = taxonomy_get_term($tids[0]);
|
| 354 |
$channel['link'] = url('dfeed/'. $str_tids, NULL, NULL, TRUE);
|
| 355 |
$channel['title'] = variable_get('site_name', 'drupal') .' - '. $title;
|
| 356 |
$channel['description'] = $term->description;
|
| 357 |
|
| 358 |
$result = taxonomy_select_nodes($tids, $operator, $depth, FALSE);
|
| 359 |
dmoz_node_feed($result, $channel);
|
| 360 |
break;
|
| 361 |
case 'script':
|
| 362 |
// Preparing data
|
| 363 |
$term = dmoz_get_category($tids[0], 'tid');
|
| 364 |
$channel['link'] = url('dscript/'. $str_tids, NULL, NULL, TRUE);
|
| 365 |
$channel['title'] = variable_get('site_name', 'drupal') .' - '. $title;
|
| 366 |
$channel['name'] = $term->name;
|
| 367 |
$channel['topic'] = $term->topic;
|
| 368 |
$channel['description'] = $term->description;
|
| 369 |
$channel['categories'] = dmoz_get_children($tids[0]);
|
| 370 |
$result = taxonomy_select_nodes($tids, $operator, $depth, FALSE);
|
| 371 |
dmoz_javascript($result, $channel);
|
| 372 |
break;
|
| 373 |
default:
|
| 374 |
drupal_not_found();
|
| 375 |
}
|
| 376 |
}
|
| 377 |
else {
|
| 378 |
drupal_not_found();
|
| 379 |
}
|
| 380 |
}
|
| 381 |
}
|
| 382 |
|
| 383 |
/**
|
| 384 |
* Implementation of hook_block().
|
| 385 |
*/
|
| 386 |
function dmoz_block($op = 'list', $delta = 0) {
|
| 387 |
|
| 388 |
if ($op == 'list') {
|
| 389 |
return array('0' => array('info' =>t("DMOZ License block")));
|
| 390 |
}
|
| 391 |
else if ($op == 'view') {
|
| 392 |
|
| 393 |
$block['subject'] = '';
|
| 394 |
$block['content'] = _dmoz_license (arg(1));
|
| 395 |
|
| 396 |
return $block;
|
| 397 |
}
|
| 398 |
|
| 399 |
}
|
| 400 |
|
| 401 |
/**
|
| 402 |
* Creates a JavaScript to print results in a web page
|
| 403 |
*/
|
| 404 |
function dmoz_javascript($result, $channel){
|
| 405 |
global $base_url;
|
| 406 |
$output = '';
|
| 407 |
// Preparing information
|
| 408 |
$channel_defaults = array(
|
| 409 |
'version' => '2.0',
|
| 410 |
'title' => variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', ''),
|
| 411 |
'link' => $base_url,
|
| 412 |
'description' => variable_get('site_mission', ''),
|
| 413 |
'language' => $locale
|
| 414 |
);
|
| 415 |
$channel = array_merge($channel_defaults, $channel);
|
| 416 |
|
| 417 |
// Title and categories
|
| 418 |
$output .= dmoz_js_print('<div class="dmoz-header">');
|
| 419 |
$output .= dmoz_js_print($channel['name'],'h2');
|
| 420 |
$output .= dmoz_js_print($channel['description'],'p');
|
| 421 |
$output .= dmoz_js_print('</div>'); // End dmoz-header
|
| 422 |
|
| 423 |
$output .= dmoz_js_print('<div class="dmoz-categories">');
|
| 424 |
$output .= dmoz_js_print(t('Categories'),'h3');
|
| 425 |
$output .= dmoz_js_print(theme('item_list', $channel['categories']));
|
| 426 |
$output .= dmoz_js_print('</div>'); // End dmoz-categories
|
| 427 |
// Links
|
| 428 |
$output .= dmoz_js_print('<div class="dmoz-links">');
|
| 429 |
$output .= dmoz_js_print(t('Links'),'h3');
|
| 430 |
$output .= dmoz_js_print('<ul>');
|
| 431 |
while ($node = db_fetch_object($result)) {
|
| 432 |
// Load the specified node:
|
| 433 |
$item = node_load(array('nid' => $node->nid));
|
| 434 |
$link = $node->url ? $node->url : url("node/$node->nid", NULL, NULL, 1);
|
| 435 |
$output .= dmoz_js_print(theme('dlink_list',$item),'li');
|
| 436 |
|
| 437 |
}
|
| 438 |
$output .= dmoz_js_print('</ul>');
|
| 439 |
$output .= dmoz_js_print('</div>'); // End dmoz-links
|
| 440 |
|
| 441 |
$output .= dmoz_js_print('<span class="drupalmod">');
|
| 442 |
$output .= dmoz_js_print(
|
| 443 |
t('Service provided by <a href="%site_url">%site_name</a> using data from <a href="http://dmoz.org">dmoz.org</a>',
|
| 444 |
array('%site_name' =>variable_get('site_name', 'drupal'), '%site_url' => $base_url)));
|
| 445 |
$output .= dmoz_js_print('</span>');
|
| 446 |
$output .= dmoz_js_print('<span class="license">');
|
| 447 |
$output .= dmoz_js_print(_dmoz_license($channel['topic']));
|
| 448 |
$output .= dmoz_js_print('</span>');
|
| 449 |
|
| 450 |
drupal_set_header('Content-Type: application/x-javascript; charset=utf-8');
|
| 451 |
print $output;
|
| 452 |
}
|
| 453 |
|
| 454 |
function dmoz_js_print($text, $tag=NULL){
|
| 455 |
// Filter problem chars
|
| 456 |
// $text = htmlspecialchars($text, ENT_QUOTES);
|
| 457 |
$text = str_replace(
|
| 458 |
array("'" , "\n" ),
|
| 459 |
array(''', '\n' ),
|
| 460 |
$text);
|
| 461 |
$output = $tag ? "<$tag>$text</$tag>" : $text;
|
| 462 |
return "document.write('$output\\n');\n";
|
| 463 |
}
|
| 464 |
|
| 465 |
/**
|
| 466 |
* Finds all nodes that match selected taxonomy conditions.
|
| 467 |
*
|
| 468 |
* Note: taxonomy_select_nodes limits number to 15
|
| 469 |
*
|
| 470 |
* @param $tids
|
| 471 |
* An array of term IDs to match.
|
| 472 |
* @param $operator
|
| 473 |
* How to interpret multiple IDs in the array. Can be "or" or "and".
|
| 474 |
* @param $depth
|
| 475 |
* How many levels deep to traverse the taxonomy tree. Can be a nonnegative
|
| 476 |
* integer or "all".
|
| 477 |
* @param $pager
|
| 478 |
* Whether the nodes are to be used with a pager (the case on most Drupal
|
| 479 |
* pages) or not (in an XML feed, for example).
|
| 480 |
* @return
|
| 481 |
* A resource identifier pointing to the query results.
|
| 482 |
*/
|
| 483 |
function dmoz_select_nodes($tids = array(), $operator = 'or', $depth = 0, $pager = FALSE) {
|
| 484 |
if (count($tids) > 0) {
|
| 485 |
// For each term ID, generate an array of descendant term IDs to the right depth.
|
| 486 |
$descendant_tids = array();
|
| 487 |
if ($depth === 'all') {
|
| 488 |
$depth = NULL;
|
| 489 |
}
|
| 490 |
foreach ($tids as $index => $tid) {
|
| 491 |
$term = taxonomy_get_term($tid);
|
| 492 |
$tree = taxonomy_get_tree($term->vid, $tid, -1, $depth);
|
| 493 |
$descendant_tids[] = array_merge(array($tid), array_map('_taxonomy_get_tid_from_term', $tree));
|
| 494 |
}
|
| 495 |
|
| 496 |
if ($operator == 'or') {
|
| 497 |
$str_tids = implode(',', call_user_func_array('array_merge', $descendant_tids));
|
| 498 |
$sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1 ORDER BY n.title';
|
| 499 |
$sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid IN ('. $str_tids .') AND n.status = 1';
|
| 500 |
}
|
| 501 |
else {
|
| 502 |
$joins = '';
|
| 503 |
$wheres = '';
|
| 504 |
foreach ($descendant_tids as $index => $tids) {
|
| 505 |
$joins .= ' INNER JOIN {term_node} tn'. $index .' ON n.nid = tn'. $index .'.nid';
|
| 506 |
$wheres .= ' AND tn'. $index .'.tid IN ('. implode(',', $tids) .')';
|
| 507 |
}
|
| 508 |
$sql = 'SELECT DISTINCT(n.nid), n.sticky, n.title, n.created FROM {node} n '. $joins .' WHERE n.status = 1 '. $wheres .' ORDER BY n.title ASC';
|
| 509 |
$sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n '. $joins .' WHERE n.status = 1 ' . $wheres;
|
| 510 |
}
|
| 511 |
$sql = db_rewrite_sql($sql);
|
| 512 |
$sql_count = db_rewrite_sql($sql_count);
|
| 513 |
if ($pager) {
|
| 514 |
$result = pager_query($sql, variable_get('default_nodes_main', 10), 0, $sql_count);
|
| 515 |
}
|
| 516 |
else {
|
| 517 |
$result = db_query($sql);
|
| 518 |
}
|
| 519 |
}
|
| 520 |
|
| 521 |
return $result;
|
| 522 |
}
|
| 523 |
|
| 524 |
/**
|
| 525 |
* Adapted function for generating RSS feeds from a set of nodes.
|
| 526 |
* No taxonomy links. No links in teaser.
|
| 527 |
*
|
| 528 |
* @param $nodes
|
| 529 |
* An object as returned by db_query() which contains the nid field.
|
| 530 |
* @param $channel
|
| 531 |
* An associative array containing title, link, description and other keys.
|
| 532 |
* The link should be an absolute URL.
|
| 533 |
*/
|
| 534 |
function dmoz_node_feed($nodes = 0, $channel = array()) {
|
| 535 |
global $base_url, $locale;
|
| 536 |
|
| 537 |
if (!$nodes) {
|
| 538 |
$nodes = db_query_range(db_rewrite_sql('SELECT n.nid FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, 15);
|
| 539 |
}
|
| 540 |
|
| 541 |
while ($node = db_fetch_object($nodes)) {
|
| 542 |
// Load the specified node:
|
| 543 |
$item = node_load(array('nid' => $node->nid));
|
| 544 |
$link = $item->url ? $item->url : url("node/$node->nid", NULL, NULL, 1);
|
| 545 |
|
| 546 |
// Allow modules to add additional item fields
|
| 547 |
$extra = array();
|
| 548 |
//$extra = node_invoke_nodeapi($item, 'rss item');
|
| 549 |
//$extra = array_merge($extra, array(array('key' => 'pubDate', 'value' => date('r', $item->created))));
|
| 550 |
$items .= format_rss_item($item->title, $link, $item->teaser, $extra);
|
| 551 |
}
|
| 552 |
|
| 553 |
$channel_defaults = array(
|
| 554 |
'version' => '2.0',
|
| 555 |
'title' => variable_get('site_name', 'drupal') .' - '. variable_get('site_slogan', ''),
|
| 556 |
'link' => $base_url,
|
| 557 |
'description' => variable_get('site_mission', ''),
|
| 558 |
'language' => $locale
|
| 559 |
);
|
| 560 |
$channel = array_merge($channel_defaults, $channel);
|
| 561 |
|
| 562 |
$output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
| 563 |
$output .= "<!DOCTYPE rss [<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">]>\n";
|
| 564 |
$output .= "<rss version=\"". $channel["version"] . "\" xml:base=\"". $base_url ."\">\n";
|
| 565 |
$output .= format_rss_channel($channel['title'], $channel['link'], $channel['description'], $items, $channel['language']);
|
| 566 |
$output .= "</rss>\n";
|
| 567 |
|
| 568 |
drupal_set_header('Content-Type: text/xml; charset=utf-8');
|
| 569 |
print $output;
|
| 570 |
}
|
| 571 |
|
| 572 |
/**
|
| 573 |
* Accepts the result of a pager_query() call, such as that performed by
|
| 574 |
* taxonomy_select_nodes(), and formats each node along with a pager.
|
| 575 |
*/
|
| 576 |
function dmoz_render_nodes($result) {
|
| 577 |
|
| 578 |
$output = '<div class="dmoz-dlinks">';
|
| 579 |
if (db_num_rows($result) > 0) {
|
| 580 |
while ($node = db_fetch_object($result)) {
|
| 581 |
$items[] = theme('dlink_list',node_load(array('nid' => $node->nid)));
|
| 582 |
}
|
| 583 |
$output .= theme('item_list',$items);
|
| 584 |
}
|
| 585 |
else {
|
| 586 |
$output .= t('There are currently no links in this category.');
|
| 587 |
}
|
| 588 |
$output .= '</div>';
|
| 589 |
|
| 590 |
return $output;
|
| 591 |
}
|
| 592 |
|
| 593 |
/**
|
| 594 |
* Gets a category by name or catid
|
| 595 |
*/
|
| 596 |
function dmoz_get_category($key, $field = 'catid', $getparents = FALSE){
|
| 597 |
$category = db_fetch_object(db_query("SELECT t.*, d.* FROM {term_data} t JOIN {dmoz_term_data} d USING(tid) WHERE d.$field = '%s'", (string)$key));
|
| 598 |
if($category && is_numeric($category->tid)){
|
| 599 |
if($getparents && $parents = taxonomy_get_parents($category->tid)){
|
| 600 |
$category->parent = $parents;
|
| 601 |
};
|
| 602 |
return $category;
|
| 603 |
} else {
|
| 604 |
return NULL;
|
| 605 |
}
|
| 606 |
}
|
| 607 |
|
| 608 |
/**
|
| 609 |
* Gets breadcrumb for given term id
|
| 610 |
*/
|
| 611 |
function dmoz_get_breadcrumbs($tid){
|
| 612 |
$links = array();
|
| 613 |
$current->tid = $tid;
|
| 614 |
while ($parents = dmoz_get_parents($current->tid)) {
|
| 615 |
$current = array_shift($parents);
|
| 616 |
$links[] = l($current->name, 'dmoz/'. $current->tid);
|
| 617 |
}
|
| 618 |
$links[] = l(t('Home'), '');
|
| 619 |
$links = array_reverse($links);
|
| 620 |
return $links;
|
| 621 |
}
|
| 622 |
|
| 623 |
/**
|
| 624 |
* Gets links for children
|
| 625 |
*/
|
| 626 |
function dmoz_get_children($tid){
|
| 627 |
$children = dmoz_category_get_children($tid);
|
| 628 |
foreach($children as $tid => $term){
|
| 629 |
$links[] = l($term->name, 'dmoz/'.$term->tid, NULL, NULL, NULL, TRUE). ' ('.$term->count.')'; //Absolute
|
| 630 |
}
|
| 631 |
return $links;
|
| 632 |
}
|
| 633 |
|
| 634 |
/**
|
| 635 |
* Gets first level children for given term id
|
| 636 |
*
|
| 637 |
* This function is similar to taxonomy_get_children but doesnt load the full tree
|
| 638 |
*/
|
| 639 |
function dmoz_category_get_children($tid){
|
| 640 |
// Get children
|
| 641 |
$result = db_query('SELECT t.*, d.* FROM {term_hierarchy} h LEFT JOIN {term_data} t ON h.tid = t.tid LEFT JOIN {dmoz_term_data} d ON h.tid = d.tid WHERE h.parent = %d AND t.vid = %d ORDER BY t.name', $tid, variable_get('dmoz_vocabulary', ''));
|
| 642 |
$children = array();
|
| 643 |
while ($term = db_fetch_object($result)) {
|
| 644 |
$children[$term->tid] = $term;
|
| 645 |
}
|
| 646 |
return $children;
|
| 647 |
}
|
| 648 |
|
| 649 |
/**
|
| 650 |
* Find all parents of a given term ID.
|
| 651 |
*/
|
| 652 |
function dmoz_get_parents($tid, $key = 'tid') {
|
| 653 |
if ($tid) {
|
| 654 |
$result = db_query('SELECT t.* FROM {term_hierarchy} h, {term_data} t WHERE h.parent = t.tid AND h.tid = %d ORDER BY weight, name', $tid);
|
| 655 |
$parents = array();
|
| 656 |
while ($parent = db_fetch_object($result)) {
|
| 657 |
$parents[$parent->$key] = $parent;
|
| 658 |
}
|
| 659 |
return $parents;
|
| 660 |
}
|
| 661 |
else {
|
| 662 |
return array();
|
| 663 |
}
|
| 664 |
}
|
| 665 |
|
| 666 |
/**
|
| 667 |
* List of processing steps
|
| 668 |
*/
|
| 669 |
function _dmoz_stages(){
|
| 670 |
return array(
|
| 671 |
'stop' => t('Stop. Process disabled'),
|
| 672 |
'idle' => t('Idle. Wating until next update'),
|
| 673 |
'error' => t('Error. Waiting for administrator'),
|
| 674 |
'download_structure' => t('Download Structure'),
|
| 675 |
'download_content' => t('Download Content'),
|
| 676 |
'expand_structure' => t('Expand Structure'),
|
| 677 |
'expand_content' => t('Expand Content'),
|
| 678 |
'extract_structure' => t('Extract Structure'),
|
| 679 |
'extract_content' => t('Extract Content'),
|
| 680 |
'import_structure' => t('Import Structure'),
|
| 681 |
'import_content' => t('Import Content'),
|
| 682 |
'process_structure' => t('Process Structure'),
|
| 683 |
'process_content' => t('Process Content'),
|
| 684 |
'cleanup' => t('Cleanup'),
|
| 685 |
'recount' => t('Recount')
|
| 686 |
);
|
| 687 |
}
|
| 688 |
|
| 689 |
/**
|
| 690 |
* Appends base path to file
|
| 691 |
*/
|
| 692 |
function _dmoz_file($file, $absolute = FALSE){
|
| 693 |
$path = variable_get('dmoz_dir_working', 'files/dmoz');
|
| 694 |
// If file doesnt exist, realpath returns false
|
| 695 |
$path = $absolute ? realpath($path) : $path;
|
| 696 |
$path .= '/'.$file;
|
| 697 |
return $path;
|
| 698 |
}
|
| 699 |
|
| 700 |
/**
|
| 701 |
* Dmoz License. Better hardcoded just to avoid mistakes :-)
|
| 702 |
*
|
| 703 |
* Accepts category as text or tid
|
| 704 |
*/
|
| 705 |
function _dmoz_license($category = NULL){
|
| 706 |
|
| 707 |
if (!$category) {
|
| 708 |
$category = urlencode(variable_get('dmoz_category', 'Top'));
|
| 709 |
} elseif (is_numeric($category)) {
|
| 710 |
$term = dmoz_get_category($category, 'tid');
|
| 711 |
$category = $term->topic;
|
| 712 |
}
|
| 713 |
|
| 714 |
if (preg_match("/^Kids_and_Teens.*/", $category)) {
|
| 715 |
// Kids and Tens License
|
| 716 |
$output = '<table border="0" bgcolor="#bae160" cellpadding="3" cellspacing="0">
|
| 717 |
<tr>
|
| 718 |
<td>
|
| 719 |
<table width="100%" cellpadding="2" cellspacing="0" border="0">
|
| 720 |
<tr align="center">
|
| 721 |
<td><font face="sans-serif, Arial, Helvetica" size="2" color="#FFFFFF">Ajuda a construir el directori fet per persones més gran del Web.</font></td>
|
| 722 |
</tr>
|
| 723 |
<tr bgcolor="#FFFFFF" align="center">
|
| 724 |
<td><font face="sans-serif, Arial, Helvetica" size="2">
|
| 725 |
<a href="http://dmoz.org/cgi-bin/add.cgi?where='.$category.'">Afegeix-hi un lloc</a> -
|
| 726 |
<a href="http://dmoz.org/Kids_and_Teens/about.html"><b> Kids and Teens Open Directory Project</b></a> -
|
| 727 |
<a href="http://dmoz.org/cgi-bin/ktapply.cgi?where=/'.$category.'">Fes-te\'n editor</a>
|
| 728 |
</font>
|
| 729 |
</td></tr>
|
| 730 |
</table>
|
| 731 |
</td>
|
| 732 |
</tr>
|
| 733 |
</table>';
|
| 734 |
|
| 735 |
} else {
|
| 736 |
// General License
|
| 737 |
$output = '<table border="0" bgcolor="#bae160" cellpadding="3" cellspacing="0">
|
| 738 |
<tr>
|
| 739 |
<td>
|
| 740 |
<table width="100%" cellpadding="2" cellspacing="0" border="0">
|
| 741 |
<tr align="center">
|
| 742 |
<td><font face="sans-serif, Arial, Helvetica" size="2" color="#FFFFFF">Ajuda a construir el directori fet per persones més gran del Web.</font></td>
|
| 743 |
</tr>
|
| 744 |
<tr bgcolor="#FFFFFF" align="center">
|
| 745 |
<td><font face="sans-serif, Arial, Helvetica" size="2">
|
| 746 |
<a href="http://dmoz.org/cgi-bin/add.cgi?where='.$category.'">Afegeix-hi un lloc</a> -
|
| 747 |
<a href="http://dmoz.org/about.html"><b>Open Directory Project</b></a> -
|
| 748 |
<a href="http://dmoz.org/cgi-bin/apply.cgi?where=/'.$category.'">Fes-te\'n editor</a>
|
| 749 |
</font>
|
| 750 |
</td></tr>
|
| 751 |
</table>
|
| 752 |
</td>
|
| 753 |
</tr>
|
| 754 |
</table>';
|
| 755 |
}
|
| 756 |
return $output;
|
| 757 |
}
|
| 758 |
|
| 759 |
/**
|
| 760 |
* This module implements its own logging system
|
| 761 |
*/
|
| 762 |
function _dmoz_log($msg = NULL, $type = 'log'){
|
| 763 |
static $messages = array();
|
| 764 |
if($msg){
|
| 765 |
$messages[$type][] = $msg;
|
| 766 |
} else {
|
| 767 |
return $messages[$type];
|
| 768 |
}
|
| 769 |
}
|
| 770 |
|
| 771 |
function _dmoz_watchdog($message, $severity = WATCHDOG_NOTICE){
|
| 772 |
watchdog('dmoz', $message, $severity);
|
| 773 |
_dmoz_log($message, 'watchdog');
|
| 774 |
}
|
| 775 |
|
| 776 |
// vim:set filetype=php:
|
| 777 |
?>
|