| 1 |
<?php |
<?php |
| 2 |
|
// $Id$ |
| 3 |
/** |
/** |
| 4 |
|
* @file |
| 5 |
* The Zeitgeist module provides history services for search. |
* The Zeitgeist module provides history services for search. |
| 6 |
* |
* |
| 7 |
* It is mainly targeted to coders: look at the ZGSPAN* constants for your own |
* It is mainly targeted to coders: look at the ZGSPAN* constants for your own |
| 16 |
* WARNING 2: always truncate or hand-check the contents of the zeitgeist table |
* WARNING 2: always truncate or hand-check the contents of the zeitgeist table |
| 17 |
* after installing a new module version. |
* after installing a new module version. |
| 18 |
* |
* |
| 19 |
* @copyright 2005-2007 Frédéric G. MARAND |
* @copyright 2005-2008 Frédéric G. MARAND |
| 20 |
* @link http://drupal.org/project/zeitgeist |
* @link http://drupal.org/project/zeitgeist |
| 21 |
* @since Drupal 4.7 |
* @since Drupal 4.7 |
| 22 |
* |
* |
| 23 |
* Coding style: |
* Coding style: |
| 24 |
* @link http://wiki.audean.com/coding |
* @link http://wiki.audean.com/coding |
| 25 |
* |
* |
| 26 |
* @license Licensed under the CeCILL, version 2 |
* @license Licensed under the CeCILL version 2 and GPL version 2 or later |
| 27 |
* |
* |
| 28 |
* License note: G2 is distributed by OSInet to its customers under the |
* License note: G2 is distributed by OSInet to its customers under the |
| 29 |
* CeCILL 2.0 license. OSInet support services only apply to the module |
* CeCILL 2.0 license. OSInet support services only apply to the module |
| 37 |
* drupal.org organization or the downstream distributor, not OSInet. |
* drupal.org organization or the downstream distributor, not OSInet. |
| 38 |
*/ |
*/ |
| 39 |
|
|
|
// $Id: zeitgeist.module,v 1.9.6.2 2007/10/14 16:52:53 fgm Exp $ |
|
|
|
|
| 40 |
/** |
/** |
| 41 |
* Miscellaneous data |
* Miscellaneous data |
| 42 |
*/ |
*/ |
| 43 |
define('ZGSEARCHFORM', 'search_form'); // The name of the form to trap when recording searches |
define('ZGSEARCHFORM', 'search_form'); // The name of the form to trap when recording searches |
| 44 |
define('ZGTABLE', '{zeitgeist}'); // The name of the table holding our data |
define('ZGTABLE', '{zeitgeist}'); // The name of the table holding our data |
| 45 |
define('ZGVERSION', '$Id: zeitgeist.module,v 1.9.6.2 2007/10/14 16:52:53 fgm Exp $'); |
define('ZGVERSION', '$Id: zeitgeist.module,v 1.9.6.3 2008/08/07 19:55:06 fgm Exp $'); |
| 46 |
define('ZGSCHEMAVERSION', 'zg_schema_version'); // read-only |
define('ZGSCHEMAVERSION', 'zg_schema_version'); // read-only |
| 47 |
define('ZGONEDAY', 86400); // 24 hours * 60 minutes * 60 seconds |
define('ZGONEDAY', 86400); // 24 hours * 60 minutes * 60 seconds |
| 48 |
|
|
| 49 |
// Module paths |
// Module paths |
| 50 |
define('ZGPATHSETTINGS', 'admin/settings/zeitgeist'); |
define('ZGPATHSETTINGS', 'admin/settings/search/zeitgeist'); |
| 51 |
define('ZGPATHPAGE', 'admin/reports/zeitgeist'); |
define('ZGPATHSETTINGSCORE', 'admin/settings/search/core'); |
| 52 |
|
define('ZGPATHPAGE', 'admin/reports/zeitgeist'); |
| 53 |
|
|
| 54 |
/* |
/* |
| 55 |
* Enumerations |
* Enumerations |
| 101 |
define('ZGDEFTOPCOUNT', 5); // Default for ZGVARTOPCOUNT |
define('ZGDEFTOPCOUNT', 5); // Default for ZGVARTOPCOUNT |
| 102 |
define('ZGDEFTOPSPAN', ZGSPANMONTH); // Default for ZGVARTOPSPAN |
define('ZGDEFTOPSPAN', ZGSPANMONTH); // Default for ZGVARTOPSPAN |
| 103 |
define('ZGDEFHISTORY', 0); // Default means forever |
define('ZGDEFHISTORY', 0); // Default means forever |
| 104 |
define('ZGDEFNOFOLLOW', 1); // Default is true |
define('ZGDEFNOFOLLOW', 1); // Default is TRUE |
| 105 |
define('ZGDEFPAGEHEIGHT', 20); // Number of rows on the zeitgeist pager |
define('ZGDEFPAGEHEIGHT', 20); // Number of rows on the zeitgeist pager |
| 106 |
define('ZGDEFRECORDEMPTY', 1); // Defaut is true: record empty queries |
define('ZGDEFRECORDEMPTY', 1); // Defaut is TRUE: record empty queries |
| 107 |
define('ZGDEFTYPE', ZGDISPLAYTYPEADMIN); // Default is admin only |
define('ZGDEFTYPE', ZGDISPLAYTYPEADMIN); // Default is admin only |
| 108 |
define('ZGDEFVALIDATION', ZGVALIDATEDISPLAY); // Default is validate upon display |
define('ZGDEFVALIDATION', ZGVALIDATEDISPLAY); // Default is validate upon display |
| 109 |
|
|
| 123 |
* - node/add#nodetype The description of a node type (if applicable). |
* - node/add#nodetype The description of a node type (if applicable). |
| 124 |
* @return string HTML, localized |
* @return string HTML, localized |
| 125 |
*/ |
*/ |
| 126 |
function zeitgeist_help($section) |
function zeitgeist_help($path, $arg) { |
| 127 |
{ |
switch ($path) { |
|
switch ($section) |
|
|
{ |
|
| 128 |
case 'admin/modules#description': |
case 'admin/modules#description': |
| 129 |
$ret = t('This module provides a history of search and related features'); |
$ret = t('This module provides a history of search and related features'); |
| 130 |
break; |
break; |
| 131 |
|
|
| 132 |
case 'admin/help#zeitgeist': |
case 'admin/help#zeitgeist': |
| 133 |
$ret = t('<p>zeitgeist records recent searches when they are performed.</p> |
$ret = t('<p>zeitgeist records recent searches when they are performed.</p> |
| 134 |
<p>It also supplies a block listing the "n" latest searches, and a setting to define the value of "n".</p>'); |
<p>It also supplies a block listing the "n" latest searches, and a setting to define the value of "n".</p>'); |
| 135 |
break; |
break; |
| 136 |
|
|
| 137 |
default: |
default: |
| 138 |
$ret = null; |
$ret = NULL; |
| 139 |
break; |
break; |
| 140 |
} |
} |
| 141 |
|
|
| 142 |
return $ret; |
return $ret; |
| 143 |
} |
} |
| 144 |
|
|
| 145 |
/** |
/** |
| 146 |
* Implement hook_menu(). |
* Implement hook_menu(). |
| 147 |
* |
* |
| 148 |
* @return array |
* @return array |
| 149 |
*/ |
*/ |
| 150 |
function zeitgeist_menu() |
function zeitgeist_menu() { |
|
{ |
|
| 151 |
$items = array(); |
$items = array(); |
| 152 |
|
|
| 153 |
$items[ZGPATHSETTINGS] = array |
// Insert ZG admin as a tab on the core search settings form |
| 154 |
( |
$items[ZGPATHSETTINGSCORE] = array( |
| 155 |
|
'title' => 'Core', |
| 156 |
|
'description' => 'Normal search settings', |
| 157 |
|
'page callback' => '_zeitgeist_search_settings', |
| 158 |
|
'access arguments' => array('administer search'), |
| 159 |
|
'type' => MENU_DEFAULT_LOCAL_TASK, |
| 160 |
|
); |
| 161 |
|
|
| 162 |
|
$items[ZGPATHSETTINGS] = array( |
| 163 |
'title' => 'Zeitgeist', |
'title' => 'Zeitgeist', |
| 164 |
'description' => 'Configuration of zeitgeist search recording and display.', |
'description' => 'Configuration of zeitgeist search recording and display.', |
| 165 |
'page callback' => 'drupal_get_form', |
'page callback' => 'drupal_get_form', |
| 166 |
'page arguments' => array('_zeitgeist_admin_settings'), |
'page arguments' => array('_zeitgeist_admin_settings'), |
| 167 |
'access arguments' => array('administer search'), |
'access arguments' => array('administer search'), |
| 168 |
'type' => MENU_NORMAL_ITEM, |
'type' => MENU_LOCAL_TASK, |
| 169 |
); |
); |
| 170 |
|
|
| 171 |
$items[ZGPATHPAGE] = array |
$items[ZGPATHPAGE] = array( |
| 172 |
( |
'title' => 'Zeitgeist report', |
| 173 |
'title' => t('Zeitgeist report'), |
'description' => 'Feel the Zeitgeist', |
|
'description' => t('Feel the Zeitgeist'), |
|
| 174 |
'page callback' => '_zeitgeist_page', |
'page callback' => '_zeitgeist_page', |
| 175 |
'type' => MENU_NORMAL_ITEM, |
'type' => MENU_NORMAL_ITEM, |
| 176 |
'access arguments' => array('administer search'), |
'access arguments' => array('administer search'), |
| 177 |
); |
); |
| 178 |
|
|
| 179 |
return $items; |
return $items; |
| 180 |
} |
} |
| 181 |
|
|
| 182 |
/** |
/** |
| 183 |
* Implement a settings form. |
* Implement a settings form. |
| 184 |
* |
* |
| 185 |
* @return array An array containing form items to place on the module settings page. |
* @return array An array containing form items to place on the module settings page. |
| 186 |
*/ |
*/ |
| 187 |
function _zeitgeist_admin_settings() |
function _zeitgeist_admin_settings() { |
|
{ |
|
| 188 |
$form[ZGVARHISTORY] = array |
$form[ZGVARHISTORY] = array |
| 189 |
( |
( |
| 190 |
'#type' => 'textfield', |
'#type' => 'textfield', |
| 201 |
'#title' => t('Display settings'), |
'#title' => t('Display settings'), |
| 202 |
'#collapsible' => TRUE, |
'#collapsible' => TRUE, |
| 203 |
); |
); |
| 204 |
|
|
| 205 |
$form['zeitgeist-display']['zeitgeist-top'] = array |
$form['zeitgeist-display']['zeitgeist-top'] = array |
| 206 |
( |
( |
| 207 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 269 |
'#size' => 5, |
'#size' => 5, |
| 270 |
'#maxlength' => 5, |
'#maxlength' => 5, |
| 271 |
); |
); |
| 272 |
|
|
| 273 |
$form['zeitgeist-display']['zeitgeist-page'] = array |
$form['zeitgeist-display']['zeitgeist-page'] = array |
| 274 |
( |
( |
| 275 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 285 |
'#size' => 3, |
'#size' => 3, |
| 286 |
'#maxlength' => 3, |
'#maxlength' => 3, |
| 287 |
); |
); |
| 288 |
|
|
| 289 |
$form['zeigeist-filtering'] = array |
$form['zeigeist-filtering'] = array |
| 290 |
( |
( |
| 291 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 318 |
( |
( |
| 319 |
'#type' => 'fieldset', |
'#type' => 'fieldset', |
| 320 |
'#title' => t('Advanced settings'), |
'#title' => t('Advanced settings'), |
| 321 |
'#collapsible' => true, |
'#collapsible' => TRUE, |
| 322 |
'#collapsed' => true |
'#collapsed' => TRUE |
| 323 |
); |
); |
| 324 |
|
|
| 325 |
$form['advanced'][ZGVARNOFOLLOW] = array |
$form['advanced'][ZGVARNOFOLLOW] = array |
| 335 |
$form['advanced'][ZGVERSION] = array |
$form['advanced'][ZGVERSION] = array |
| 336 |
( |
( |
| 337 |
'#value' => '<p>' |
'#value' => '<p>' |
| 338 |
. t('This site is running Zeitgeist version %version. ', array('%version' => ZGVERSION)) |
. t('This site is running Zeitgeist version %version.', array('%version' => ZGVERSION)) |
| 339 |
. '</p>' |
. '</p>' |
| 340 |
); |
); |
| 341 |
|
|
| 346 |
$sq = 'SELECT schema_version ' |
$sq = 'SELECT schema_version ' |
| 347 |
. 'FROM {system} ' |
. 'FROM {system} ' |
| 348 |
. "WHERE type='module' AND name='zeitgeist' "; |
. "WHERE type='module' AND name='zeitgeist' "; |
| 349 |
|
// This form is only available to admins, so no need for db_rewrite_sql(). |
| 350 |
$schema_version = db_result(db_query($sq)); |
$schema_version = db_result(db_query($sq)); |
| 351 |
$form['advanced'][ZGSCHEMAVERSION] = array |
$form['advanced'][ZGSCHEMAVERSION] = array |
| 352 |
( |
( |
| 353 |
'#value' => '<p>' |
'#value' => '<p>' |
| 354 |
. t('Zeitgeist schema is at version %version. ', array('%version' => $schema_version)) |
. t('Zeitgeist schema is at version %version.', array('%version' => $schema_version)) |
| 355 |
. '</p>' |
. '</p>' |
| 356 |
); |
); |
| 357 |
|
|
| 358 |
return system_settings_form($form); |
return system_settings_form($form); |
| 359 |
} |
} |
| 360 |
|
|
| 361 |
/** |
/** |
| 362 |
* Trap searches. Warning: the mechanism |
* Trap searches. |
|
* currently in use seems to work, but might not cover |
|
|
* all cases. Please report any missing info on the |
|
|
* zeitgeist issues page at |
|
|
* http://drupal.org/node/add/project_issue/zeitgeist/bug |
|
|
* There is a known problem with advanced search artificially |
|
|
* creating an fictitious empty search prior to the actual one, |
|
|
* but this seems to be a search.module bug |
|
| 363 |
* |
* |
| 364 |
* @param string $form_id A registered form_id. We're only interested in the search form |
* Warning: the mechanism has been changed over previous versions. It is now |
| 365 |
* @param array $form_values |
* much more standard, but does not log automatic searches performed when |
| 366 |
|
* clicking on a search kind tab after an initial search, and GET searches like |
| 367 |
|
* the ones performed by crawlers. |
| 368 |
|
* |
| 369 |
|
* Please report any problem with that new mechanisme on the zeitgeist issues |
| 370 |
|
* page at http://drupal.org/node/add/project_issue/zeitgeist/bug |
| 371 |
|
* |
| 372 |
|
* @param array $form |
| 373 |
|
* @param array $form_state |
| 374 |
|
* @param string $form_id |
| 375 |
|
* A registered form_id. We're only interested in the default search forms |
| 376 |
* @return void |
* @return void |
| 377 |
*/ |
*/ |
| 378 |
function zeitgeist_form_alter(&$form, $form_state, $form_id) |
function zeitgeist_form_alter(&$form, $form_state, $form_id) { |
| 379 |
{ |
switch ($form_id) { |
| 380 |
if ($form_id != 'search_form') |
case 'search_form': |
| 381 |
return; |
array_unshift($form['#submit'], 'zeitgeist_search_form_submit'); |
| 382 |
|
break; |
| 383 |
|
|
| 384 |
// $search = $form['basic']['inline']['keys']['#default_value']; |
case 'search_theme_form': |
| 385 |
$search = $form_state['post']['keys']; |
array_unshift($form['#submit'], 'zeitgeist_search_theme_form_submit'); |
| 386 |
$category = $form['module']['#value']; |
break; |
| 387 |
|
|
| 388 |
$do_store = true; |
default: |
| 389 |
if (!isset($search)) // Empty searches |
return; |
|
{ |
|
|
$do_store = ( |
|
|
isset($form['#post']['op']) // Make sure this is not just an idle click |
|
|
&& (variable_get(ZGVARRECORDEMPTY, ZGDEFRECORDEMPTY)) // and make sure we do want to store it |
|
|
); |
|
|
} |
|
|
if ($do_store && _zeitgeist_validate($search, 'store')) |
|
|
{ |
|
|
_zeitgeist_store_search($search, $category); |
|
|
} |
|
| 390 |
} |
} |
| 391 |
|
} |
| 392 |
|
|
| 393 |
/** |
/** |
| 394 |
* @param string $op |
* @param string $op |
| 399 |
* @param int $delta |
* @param int $delta |
| 400 |
* @param array $edit |
* @param array $edit |
| 401 |
*/ |
*/ |
| 402 |
function zeitgeist_block($op = 'list', $delta = ZGBLOCKLATEST, $edit = array()) |
function zeitgeist_block($op = 'list', $delta = ZGBLOCKLATEST, $edit = array()) { |
| 403 |
{ |
switch ($op) { |
|
switch ($op) |
|
|
{ |
|
| 404 |
case 'list': |
case 'list': |
| 405 |
$blocks[ZGBLOCKLATEST]['info'] = t(variable_get('zeitgeist_latest_info', t('ZG Latest @count')), |
$blocks[ZGBLOCKLATEST]['info'] = t(variable_get('zeitgeist_latest_info', t('ZG Latest @count')), |
| 406 |
array('@count' => variable_get(ZGVARLATESTCOUNT, ZGDEFLATESTCOUNT)) |
array('@count' => variable_get(ZGVARLATESTCOUNT, ZGDEFLATESTCOUNT)) |
| 412 |
break; |
break; |
| 413 |
|
|
| 414 |
case 'configure': |
case 'configure': |
| 415 |
switch ($delta) |
switch ($delta) { |
|
{ |
|
| 416 |
case ZGBLOCKLATEST: |
case ZGBLOCKLATEST: |
| 417 |
$form = array(); |
$form = array(); |
| 418 |
_zeitgeist_block_settings_show($form, |
_zeitgeist_block_settings_show($form, |
| 430 |
default: |
default: |
| 431 |
$form = array(); |
$form = array(); |
| 432 |
break; |
break; |
| 433 |
} |
} |
| 434 |
_zeitgeist_admin_settings_submit(NULL, NULL); // clear cache |
_zeitgeist_admin_settings_submit(NULL, NULL); // clear cache |
| 435 |
return $form; |
return $form; |
| 436 |
break; |
break; |
| 437 |
|
|
| 438 |
case 'save': |
case 'save': |
| 439 |
switch ($delta) |
switch ($delta) { |
|
{ |
|
| 440 |
case ZGBLOCKLATEST: |
case ZGBLOCKLATEST: |
| 441 |
_zeitgeist_block_settings_save($edit, ZGBLOCKLATEST); |
_zeitgeist_block_settings_save($edit, ZGBLOCKLATEST); |
| 442 |
break; |
break; |
| 443 |
|
|
| 444 |
case ZGBLOCKTOP: |
case ZGBLOCKTOP: |
| 445 |
_zeitgeist_block_settings_save($edit, ZGBLOCKTOP); |
_zeitgeist_block_settings_save($edit, ZGBLOCKTOP); |
| 446 |
break; |
break; |
| 447 |
} |
} |
| 448 |
break; |
break; |
| 449 |
|
|
| 450 |
case 'view': |
case 'view': |
| 451 |
switch ($delta) |
switch ($delta) { |
|
{ |
|
| 452 |
case ZGBLOCKLATEST: |
case ZGBLOCKLATEST: |
| 453 |
$count = variable_get(ZGVARLATESTCOUNT, ZGDEFLATESTCOUNT); |
$count = variable_get(ZGVARLATESTCOUNT, ZGDEFLATESTCOUNT); |
| 454 |
$subject = variable_get('zeitgeist_latest_title', t('Latest %count searches')); |
$subject = variable_get('zeitgeist_latest_title', t('Latest %count searches')); |
| 455 |
$subject = t($subject, array('%count' => $count)); |
$subject = t($subject, array('%count' => $count)); |
| 456 |
$now = time(); |
$now = time(); |
| 457 |
$cache = cache_get(ZGCIDLATEST, 'cache'); |
$cache = cache_get(ZGCIDLATEST); |
| 458 |
if (empty($cache) || ($now >= $cache->expire)) |
if (empty($cache) || ($now >= $cache->expire)) { |
| 459 |
{ |
$block = array( |
|
$block = array |
|
|
( |
|
| 460 |
'subject' => $subject, |
'subject' => $subject, |
| 461 |
'content' => theme('zeitgeist_block_latest', $count), |
'content' => theme('zeitgeist_block_latest', $count), |
| 462 |
); |
); |
| 463 |
cache_set(ZGCIDLATEST, 'cache', serialize($block), $expires = $now + 60 * variable_get(ZGVARLATESTCACHE, 0)); |
cache_set(ZGCIDLATEST, $block, 'cache', $expires = $now + 60 * variable_get(ZGVARLATESTCACHE, 0)); |
| 464 |
} |
} |
| 465 |
else |
else { |
| 466 |
{ |
$block = $cache->data; |
| 467 |
$block = unserialize($cache->data); |
} |
|
} |
|
| 468 |
break; |
break; |
| 469 |
|
|
| 470 |
case ZGBLOCKTOP: |
case ZGBLOCKTOP: |
| 471 |
$subject = variable_get('zeitgeist_top_title', t('Top %count searches')); |
$subject = variable_get('zeitgeist_top_title', t('Top %count searches')); |
| 472 |
$subject = t($subject, array('%count' => $count)); |
$subject = t($subject, array('%count' => $count)); |
| 473 |
$now = time(); |
$now = time(); |
| 474 |
$cache = cache_get(ZGCIDTOP); |
$cache = cache_get(ZGCIDTOP); |
| 475 |
if (empty($cache) || ($now >= $cache->expire)) |
if (empty($cache) || ($now >= $cache->expire)) { |
| 476 |
{ |
$block = array( |
|
$block = array |
|
|
( |
|
| 477 |
'subject' => $subject, |
'subject' => $subject, |
| 478 |
'content' => theme('zeitgeist_block_top', $count), |
'content' => theme('zeitgeist_block_top', $count), |
| 479 |
); |
); |
| 480 |
cache_set(ZGCIDTOP, 'cache', serialize($block), $expires = $now + 60 * variable_get(ZGVARTOPCACHE, 0)); |
cache_set(ZGCIDTOP, $block, 'cache', $expires = $now + 60 * variable_get(ZGVARTOPCACHE, 0)); |
| 481 |
} |
} |
| 482 |
else |
else { |
| 483 |
{ |
$block = $cache->data; |
| 484 |
$block = unserialize($cache->data); |
} |
|
} |
|
| 485 |
break; |
break; |
| 486 |
} |
} |
| 487 |
return $block; |
return $block; |
| 488 |
break; |
break; |
|
} |
|
| 489 |
} |
} |
| 490 |
|
} |
| 491 |
|
|
| 492 |
/** |
/** |
| 493 |
* @param string $search |
* @param string $search |
| 494 |
* @param string $category |
* @param string $category |
| 495 |
* @param int $ts |
* @param int $ts |
| 496 |
*/ |
*/ |
| 497 |
function _zeitgeist_store_search($search, $category, $ts = null) |
function _zeitgeist_store_search($keys, $kind, $ts = NULL) { |
| 498 |
{ |
|
| 499 |
if (!isset($ts)) |
$do_store = empty($keys) |
| 500 |
{ |
? variable_get(ZGVARRECORDEMPTY, ZGDEFRECORDEMPTY) // Make sure we do want to store an empty search |
| 501 |
|
: TRUE; |
| 502 |
|
|
| 503 |
|
if (!$do_store || !_zeitgeist_validate($keys, 'save')) { |
| 504 |
|
return; |
| 505 |
|
} |
| 506 |
|
|
| 507 |
|
if (!isset($ts)) { |
| 508 |
$ts = time(); |
$ts = time(); |
| 509 |
} |
} |
| 510 |
$sq = 'INSERT INTO ' . ZGTABLE . ' (search, category, ts) ' |
$sq = 'INSERT INTO ' . ZGTABLE . ' (search, category, ts) ' |
| 511 |
. "VALUES ('%s', '%s', %d) "; |
. "VALUES ('%s', '%s', %d) "; |
| 512 |
db_query($sq, $search, $category, $ts); |
// No access control on logging, so no db_rewrite_sql(). |
| 513 |
} |
db_query($sq, $keys, $kind, $ts); |
| 514 |
|
} |
| 515 |
|
|
| 516 |
/** |
/** |
| 517 |
* Provides the block-specific contents common to each ZG block: |
* Provides the block-specific contents common to each ZG block: |
| 528 |
*/ |
*/ |
| 529 |
function _zeitgeist_block_settings_show(&$form, |
function _zeitgeist_block_settings_show(&$form, |
| 530 |
$infotitle, $infovar, $infodefault, |
$infotitle, $infovar, $infodefault, |
| 531 |
$titletitle, $titlevar, $titledefault) |
$titletitle, $titlevar, $titledefault) { |
| 532 |
{ |
$form['info'] = array( |
|
$form['info'] = array |
|
|
( |
|
| 533 |
'#type' => 'textfield', |
'#type' => 'textfield', |
| 534 |
'#title' => $infotitle, |
'#title' => $infotitle, |
| 535 |
'#default_value' => variable_get('zeitgeist_' . $infovar . '_info', $infodefault), |
'#default_value' => variable_get('zeitgeist_' . $infovar . '_info', $infodefault), |
| 536 |
'#weight' => -2, |
'#weight' => -2, |
| 537 |
); |
); |
| 538 |
$form['title'] = array |
$form['title'] = array( |
|
( |
|
| 539 |
'#type' => 'textfield', |
'#type' => 'textfield', |
| 540 |
'#title' => $titletitle, |
'#title' => $titletitle, |
| 541 |
'#default_value' => variable_get('zeitgeist_' . $titlevar . '_title', $titledefault), |
'#default_value' => variable_get('zeitgeist_' . $titlevar . '_title', $titledefault), |
| 542 |
'#weight' => -1, |
'#weight' => -1, |
| 543 |
); |
); |
| 544 |
} |
} |
| 545 |
|
|
| 546 |
function _zeitgeist_block_settings_save($edit, $blockname) |
function _zeitgeist_block_settings_save($edit, $blockname) { |
|
{ |
|
| 547 |
variable_set('zeitgeist_' . $blockname . '_info', $edit['info' ]); |
variable_set('zeitgeist_' . $blockname . '_info', $edit['info' ]); |
| 548 |
variable_set('zeitgeist_' . $blockname . '_title', $edit['title']); |
variable_set('zeitgeist_' . $blockname . '_title', $edit['title']); |
| 549 |
} |
} |
| 550 |
|
|
| 551 |
/** |
/** |
| 552 |
* Builds the contents of the latest searches block |
* Builds the contents of the latest searches block |
| 554 |
* @param string $count Themed HTML |
* @param string $count Themed HTML |
| 555 |
* @return array |
* @return array |
| 556 |
*/ |
*/ |
| 557 |
function _zeitgeist_block_latest($count = null) |
function _zeitgeist_block_latest($count = NULL) { |
|
{ |
|
| 558 |
global $user; |
global $user; |
| 559 |
|
|
| 560 |
if (!isset($count)) |
if (!isset($count)) { |
|
{ |
|
| 561 |
$count = variable_get(ZGVARLATESTCOUNT, ZGDEFLATESTCOUNT); |
$count = variable_get(ZGVARLATESTCOUNT, ZGDEFLATESTCOUNT); |
| 562 |
} |
} |
| 563 |
|
|
| 564 |
// We query an unlimited range because of potential duplicates |
// We query an unlimited range because of potential duplicates |
| 565 |
$sq = 'SELECT zg.search, zg.category ' |
$sq = 'SELECT zg.search, zg.category ' |
| 566 |
. 'FROM ' . ZGTABLE . ' zg ' |
. 'FROM ' . ZGTABLE . ' zg ' |
| 567 |
. 'ORDER BY zg.ts DESC' ; |
. 'ORDER BY zg.ts DESC' ; |
| 568 |
|
$sq = db_rewrite_sql($sq); |
| 569 |
$q = db_query($sq); |
$q = db_query($sq); |
| 570 |
$ar = array(); |
$ar = array(); |
| 571 |
|
|
| 572 |
// Conditional search type rendering |
// Conditional search type rendering |
| 573 |
switch (variable_get(ZGVARTYPE, ZGDEFTYPE)) |
switch (variable_get(ZGVARTYPE, ZGDEFTYPE)) { |
|
{ |
|
| 574 |
case ZGDISPLAYTYPEADMIN : // Display only for admin |
case ZGDISPLAYTYPEADMIN : // Display only for admin |
| 575 |
$show_category = ($user->uid == 1); |
$show_category = ($user->uid == 1); |
| 576 |
break; |
break; |
| 577 |
|
|
| 578 |
case ZGDISPLAYTYPEAUTH : // Display for all authenticated users |
case ZGDISPLAYTYPEAUTH : // Display for all authenticated users |
| 579 |
$show_category = ($user->uid != 0); |
$show_category = ($user->uid != 0); |
| 580 |
break; |
break; |
| 581 |
|
|
| 582 |
case ZGDISPLAYTYPEALWAYS : // Always display |
case ZGDISPLAYTYPEALWAYS : // Always display |
| 583 |
$show_category = true; |
$show_category = TRUE; |
| 584 |
break; |
break; |
| 585 |
|
|
| 586 |
default: // ZGDISPLAYTYPENEVER and any other value |
default: // ZGDISPLAYTYPENEVER and any other value |
| 587 |
$show_category = false; |
$show_category = FALSE; |
| 588 |
break; |
break; |
| 589 |
} |
} |
| 590 |
|
|
| 591 |
// then we weed out the duplicates on the fly, and stop |
// then we weed out the duplicates on the fly, and stop |
| 592 |
// when we have enough results |
// when we have enough results |
| 593 |
while (($o = db_fetch_object($q)) && ($count > sizeof($ar))) |
while (($o = db_fetch_object($q)) && ($count > sizeof($ar))) { |
| 594 |
{ |
$category = $show_category ? " ($o->category)" : NULL; |
|
$category = $show_category ? " ($o->category)" : null; |
|
| 595 |
|
|
| 596 |
if ((!empty($o->search)) && (!isset($ar["$o->search$category"])) |
if ((!empty($o->search)) && (!isset($ar["$o->search$category"])) && _zeitgeist_validate($o->search, 'view')) { |
|
&& _zeitgeist_validate($o->search, 'show')) |
|
| 597 |
$ar["$o->search$category"] = array($o->search, $o->category) ; // empty keys cannot happen |
$ar["$o->search$category"] = array($o->search, $o->category) ; // empty keys cannot happen |
| 598 |
} |
} |
| 599 |
|
} |
| 600 |
db_free_result($q); |
db_free_result($q); |
| 601 |
return $ar; |
return $ar; |
| 602 |
} |
} |
| 603 |
|
|
| 604 |
|
/** |
| 605 |
|
* Redirect to the standard search settings form. |
| 606 |
|
* |
| 607 |
|
* @return void |
| 608 |
|
*/ |
| 609 |
|
function _zeitgeist_search_settings() { |
| 610 |
|
drupal_goto('admin/settings/search'); |
| 611 |
|
} |
| 612 |
|
|
| 613 |
/** |
/** |
| 614 |
* Return zeitgeist as an object holding the boundary dates and a array of query counts |
* Return zeitgeist as an object holding the boundary dates and a array of query counts |
| 619 |
* @param int $limit Limit results to $count results, or don't limit if 0. |
* @param int $limit Limit results to $count results, or don't limit if 0. |
| 620 |
* @return object |
* @return object |
| 621 |
*/ |
*/ |
| 622 |
function _zeitgeist_stats($span = ZGSPANMONTH, $ts = NULL, $category = NULL, $count = 0) |
function _zeitgeist_stats($span = ZGSPANMONTH, $ts = NULL, $category = NULL, $count = 0) { |
| 623 |
{ |
if (!isset($ts)) { |
|
if (!isset($ts)) |
|
|
{ |
|
| 624 |
$ts = time(); |
$ts = time(); |
| 625 |
} |
} |
| 626 |
$arDate = getdate($ts); |
$ar_date = getdate($ts); |
| 627 |
|
|
| 628 |
/** |
/** |
| 629 |
* Some of these ranges go beyond the current timestamp if computed for the current |
* Some of these ranges go beyond the current timestamp if computed for the current |
| 630 |
* timestamp, but this is not an issue as there won't be any matching entries anyway |
* timestamp, but this is not an issue as there won't be any matching entries anyway |
| 631 |
*/ |
*/ |
| 632 |
switch ($span) |
switch ($span) { |
|
{ |
|
| 633 |
case ZGSPANDAY: |
case ZGSPANDAY: |
| 634 |
$ts1 = mktime(0, 0, 0, $arDate['mon'], $arDate['mday'], $arDate['year']); |
$ts1 = mktime(0, 0, 0, $ar_date['mon'], $ar_date['mday'], $ar_date['year']); |
| 635 |
$ts2 = $ts1 + ZGONEDAY; |
$ts2 = $ts1 + ZGONEDAY; |
| 636 |
break; |
break; |
| 637 |
|
|
| 638 |
case ZGSPANWEEKS: |
case ZGSPANWEEKS: |
| 639 |
$tsBase = $ts - $arDate['wday'] * ZGONEDAY; |
$ts_base = $ts - $ar_date['wday'] * ZGONEDAY; |
| 640 |
$arDateBase = getdate($tsBase); |
$ar_date_base = getdate($ts_base); |
| 641 |
$ts1 = mktime(0, 0, 0, $arDateBase['mon'], $arDateBase['mday'], $arDateBase['year']); |
$ts1 = mktime(0, 0, 0, $ar_date_base['mon'], $ar_date_base['mday'], $ar_date_base['year']); |
| 642 |
$ts2 = $ts1 + 7 * ZGONEDAY; |
$ts2 = $ts1 + 7 * ZGONEDAY; |
| 643 |
unset($arDateBase); |
unset($ar_date_base); |
| 644 |
break; |
break; |
| 645 |
|
|
| 646 |
case ZGSPANWEEKM: |
case ZGSPANWEEKM: |
| 647 |
$tsBase = $ts - (($arDate['wday'] + 6) % 7) * ZGONEDAY; |
$ts_base = $ts - (($ar_date['wday'] + 6) % 7) * ZGONEDAY; |
| 648 |
$arDateBase = getdate($tsBase); |
$ar_date_base = getdate($ts_base); |
| 649 |
$ts1 = mktime(0, 0, 0, $arDateBase['mon'], $arDateBase['mday'], $arDateBase['year']); |
$ts1 = mktime(0, 0, 0, $ar_date_base['mon'], $ar_date_base['mday'], $ar_date_base['year']); |
| 650 |
$ts2 = $ts1 + 7 * ZGONEDAY; |
$ts2 = $ts1 + 7 * ZGONEDAY; |
| 651 |
unset($arDateBase); |
unset($ar_date_base); |
| 652 |
break; |
break; |
| 653 |
|
|
| 654 |
case ZGSPANMONTH: |
case ZGSPANMONTH: |
| 655 |
$ts1 = mktime(0, 0, 0, $arDate['mon'], 1, $arDate['year']); |
$ts1 = mktime(0, 0, 0, $ar_date['mon'], 1, $ar_date['year']); |
| 656 |
// mktime fixes out-of-range correctly, so we needn't worry about year wrapping |
// mktime fixes out-of-range correctly, so we needn't worry about year wrapping |
| 657 |
$ts2 = mktime(0, 0, 0, $arDate['mon'] + 1, 1, $arDate['year']); |
$ts2 = mktime(0, 0, 0, $ar_date['mon'] + 1, 1, $ar_date['year']); |
| 658 |
break; |
break; |
| 659 |
|
|
| 660 |
case ZGSPANQUARTER: |
case ZGSPANQUARTER: |
| 661 |
$mon = 1 + (int) (($arDate['mon'] - 1) / 3); |
$mon = 1 + (int) (($ar_date['mon'] - 1) / 3); |
| 662 |
$ts1 = mktime(0, 0, 0, $mon, 1, $arDate['year']); |
$ts1 = mktime(0, 0, 0, $mon, 1, $ar_date['year']); |
| 663 |
$ts2 = mktime(0, 0, 0, $mon + 3, 1, $arDate['year']); |
$ts2 = mktime(0, 0, 0, $mon + 3, 1, $ar_date['year']); |
| 664 |
break; |
break; |
| 665 |
|
|
| 666 |
case ZGSPANYEAR: |
case ZGSPANYEAR: |
| 667 |
$ts1 = mktime(0, 0, 0, 1, 1, $arDate['year']); |
$ts1 = mktime(0, 0, 0, 1, 1, $ar_date['year']); |
| 668 |
$ts2 = mktime(0, 0, 0, 1, 1, $arDate['year']+1); |
$ts2 = mktime(0, 0, 0, 1, 1, $ar_date['year']+1); |
| 669 |
break; |
break; |
| 670 |
} |
} |
| 671 |
|
|
| 672 |
$sq = 'SELECT zg.search, zg.category, count(zg.ts) cnt ' |
$sq = 'SELECT zg.search, zg.category, count(zg.ts) cnt ' |
| 673 |
. 'FROM ' . ZGTABLE . ' zg ' |
. 'FROM ' . ZGTABLE . ' zg ' |
| 674 |
. 'WHERE (zg.ts >= %d) AND( zg.ts < %d) ' ; |
. 'WHERE (zg.ts >= %d) AND( zg.ts < %d) ' ; |
| 675 |
if (isset($category)) |
if (isset($category)) { |
|
{ |
|
| 676 |
$sq .= "AND (zg.category = '%s') " |
$sq .= "AND (zg.category = '%s') " |
| 677 |
. 'GROUP BY 1, 2 ' |
. 'GROUP BY 1, 2 ' |
| 678 |
. 'ORDER BY 3 DESC, 1 ASC, 2 ASC ' ; |
. 'ORDER BY 3 DESC, 1 ASC, 2 ASC ' ; |
| 679 |
|
$sq = db_rewrite_sql($sq); |
| 680 |
$q = (isset($count) && ($count > 0)) |
$q = (isset($count) && ($count > 0)) |
| 681 |
? db_query_range($sq, $ts1, $ts2, $category, 0, $count) |
? db_query_range($sq, $ts1, $ts2, $category, 0, $count) |
| 682 |
: db_query($sq, $ts1, $ts2, $category); |
: db_query($sq, $ts1, $ts2, $category); |
| 683 |
} |
} |
| 684 |
else |
else { |
|
{ |
|
| 685 |
$sq .= 'GROUP BY 1, 2 ' |
$sq .= 'GROUP BY 1, 2 ' |
| 686 |
. 'ORDER BY 3 DESC, 1 ASC, 2 ASC ' ; |
. 'ORDER BY 3 DESC, 1 ASC, 2 ASC ' ; |
| 687 |
|
$sq = db_rewrite_sql($sq); |
| 688 |
$q = (isset($count) && ($count > 0)) |
$q = (isset($count) && ($count > 0)) |
| 689 |
? db_query_range($sq, $ts1, $ts2, 0, $count) |
? db_query_range($sq, $ts1, $ts2, 0, $count) |
| 690 |
: db_query($sq, $ts1, $ts2); |
: db_query($sq, $ts1, $ts2); |
| 691 |
} |
} |
| 692 |
|
|
| 693 |
$ret = new stdClass(); |
$ret = new stdClass(); |
| 694 |
$ret->ts1 = $ts1; |
$ret->ts1 = $ts1; |
| 695 |
$ret->ts2 = $ts2; |
$ret->ts2 = $ts2; |
| 696 |
$ret->scores = array(); |
$ret->scores = array(); |
| 697 |
while ($o = db_fetch_object($q)) |
while ($o = db_fetch_object($q)) { |
|
{ |
|
| 698 |
$ret->scores[] = array( |
$ret->scores[] = array( |
| 699 |
'search' => $o->search, |
'search' => $o->search, |
| 700 |
'category' => $o->category, |
'category' => $o->category, |
| 701 |
'count' => $o->cnt); |
'count' => $o->cnt); |
|
} |
|
|
return $ret; |
|
| 702 |
} |
} |
| 703 |
|
return $ret; |
| 704 |
|
} |
| 705 |
|
|
| 706 |
/** |
/** |
| 707 |
* Return the timestamp for the chosen date at 00:00 |
* Return the timestamp for the chosen date at 00:00 |
| 709 |
* |
* |
| 710 |
* @param int $ts |
* @param int $ts |
| 711 |
*/ |
*/ |
| 712 |
function _zeitgeist_date($tsNow = 0) |
function _zeitgeist_date($ts_now = 0) { |
| 713 |
{ |
$ar_day = $ts_now ? getdate($ts_now) : getdate(); |
| 714 |
$arDay = $tsNow ? getdate($tsNow) : getdate(); |
$ts_day = mktime(0, 0, 0, $ar_day['mon'], $ar_day['mday'], $ar_day['year']); |
| 715 |
$tsDay = mktime(0, 0, 0, $arDay['mon'], $arDay['mday'], $arDay['year']); |
return $ts_day; |
| 716 |
return $tsDay; |
} |
|
} |
|
| 717 |
|
|
| 718 |
/** |
/** |
| 719 |
* Erase Zeitgeist log entries older than the chosen number of days |
* Erase Zeitgeist log entries older than the chosen number of days |
| 721 |
* @param int $days |
* @param int $days |
| 722 |
* @return void |
* @return void |
| 723 |
*/ |
*/ |
| 724 |
function _zeitgeist_clear_older($days) |
function _zeitgeist_clear_older($days) { |
|
{ |
|
| 725 |
$today = _zeitgeist_date(); |
$today = _zeitgeist_date(); |
| 726 |
$limit = _zeitgeist_date($today - $days * 60 * 60 * 24); |
$limit = _zeitgeist_date($today - $days * ZGONEDAY); |
| 727 |
$sq = 'DELETE FROM {zeitgeist} WHERE ts < %d'; |
$sq = 'DELETE FROM {zeitgeist} WHERE ts < %d'; |
| 728 |
|
// This form is only called from cron, so no need for db_rewrite_sql(). |
| 729 |
db_query($sq, $limit); |
db_query($sq, $limit); |
| 730 |
} |
} |
| 731 |
|
|
| 732 |
/** |
/** |
| 733 |
* Implement hook_cron |
* Implement hook_cron |
| 734 |
* This is used to clean the old entries |
* This is used to clean the old entries |
| 735 |
*/ |
*/ |
| 736 |
function zeitgeist_cron() |
function zeitgeist_cron() { |
|
{ |
|
| 737 |
// Don't waste time if we already did a clear today |
// Don't waste time if we already did a clear today |
| 738 |
$latest = variable_get(ZGVARLATESTCLEAR, 0); |
$latest = variable_get(ZGVARLATESTCLEAR, 0); |
| 739 |
$today = _zeitgeist_date(); |
$today = _zeitgeist_date(); |
| 741 |
return; |
return; |
| 742 |
|
|
| 743 |
$days = variable_get(ZGVARHISTORY, ZGDEFHISTORY); |
$days = variable_get(ZGVARHISTORY, ZGDEFHISTORY); |
| 744 |
if ($days == 0) |
if ($days == 0) { |
| 745 |
return; |
return; |
| 746 |
|
} |
| 747 |
_zeitgeist_clear_older($days); |
_zeitgeist_clear_older($days); |
| 748 |
watchdog('zeitgeist', t('Cleared ZG entries older than %days days', array('%days' => $days)), WATCHDOG_NOTICE); |
watchdog('zeitgeist', 'Cleared ZG entries older than %days days', array('%days' => $days), WATCHDOG_NOTICE); |
| 749 |
variable_set(ZGVARLATESTCLEAR, $today); |
variable_set(ZGVARLATESTCLEAR, $today); |
| 750 |
} |
} |
| 751 |
|
|
| 752 |
/** |
/** |
| 753 |
* Default rendering for the ZG block with the most popular "node" queries |
* Default rendering for the ZG block with the most popular "node" queries |
| 755 |
* |
* |
| 756 |
* @param int $count |
* @param int $count |
| 757 |
*/ |
*/ |
| 758 |
function theme_zeitgeist_block_top($count = NULL) |
function theme_zeitgeist_block_top($count = NULL) { |
| 759 |
{ |
if (is_null($count)) { |
|
if (is_null($count)) |
|
|
{ |
|
| 760 |
$count = variable_get(ZGVARTOPCOUNT, ZGDEFTOPCOUNT); |
$count = variable_get(ZGVARTOPCOUNT, ZGDEFTOPCOUNT); |
| 761 |
} |
} |
| 762 |
$ts = null; |
$ts = NULL; |
| 763 |
|
|
| 764 |
/** |
/** |
| 765 |
* Uncomment this fragment for last month's zeitgeist. Leave it commented for |
* Uncomment this fragment for last month's zeitgeist. Leave it commented for |
| 766 |
* the current month |
* the current month |
| 767 |
* |
* |
| 768 |
$arDate = getdate(); |
$ar_date = getdate(); |
| 769 |
$ts = mktime(0, 0, 0, $arDate['mon'] - 1, 1, $arDate['year']); // mktime wraps months cleanly, no worry |
$ts = mktime(0, 0, 0, $ar_date['mon'] - 1, 1, $ar_date['year']); // mktime wraps months cleanly, no worry |
| 770 |
unset($arDate); |
unset($ar_date); |
| 771 |
* -- end of fragment |
* -- end of fragment |
| 772 |
*/ |
*/ |
| 773 |
|
|
| 774 |
$arStats = _zeitgeist_stats(ZGSPANMONTH, $ts, 'node', $count); |
$ar_stats = _zeitgeist_stats(ZGSPANMONTH, $ts, 'node', $count); |
| 775 |
$arScores = array(); |
$ar_scores = array(); |
| 776 |
$attr = variable_get(ZGVARNOFOLLOW, ZGDEFNOFOLLOW) |
$attr = variable_get(ZGVARNOFOLLOW, ZGDEFNOFOLLOW) |
| 777 |
? array('rel' => 'nofollow') |
? array('rel' => 'nofollow') |
| 778 |
: NULL ; |
: NULL ; |
| 779 |
$attr = array_merge($attr, array('absolute' => TRUE)); |
$attr = array_merge($attr, array('absolute' => TRUE)); |
| 780 |
foreach ($arStats->scores as $score) |
foreach ($ar_stats->scores as $score) { |
| 781 |
{ |
$ar_scores[] = l($score['search'] . " (${score['count']})", |
|
$arScores[] = l($score['search'] . " (${score['count']})", |
|
| 782 |
"search/node/$score[search]", $attr); |
"search/node/$score[search]", $attr); |
| 783 |
} |
} |
| 784 |
unset($arStats); |
unset($ar_stats); |
| 785 |
|
|
| 786 |
|
$ret = theme('item_list', $ar_scores); |
| 787 |
|
unset($ar_scores); |
| 788 |
|
|
|
$ret = theme('item_list', $arScores); |
|
|
unset($arScores); |
|
|
|
|
| 789 |
return $ret; |
return $ret; |
| 790 |
} |
} |
| 791 |
|
|
| 792 |
/** |
/** |
| 793 |
* Default rendering for the ZG latest searches block |
* Default rendering for the ZG latest searches block |
| 794 |
* |
* |
| 795 |
* @param int $count |
* @param int $count |
| 796 |
*/ |
*/ |
| 797 |
function theme_zeitgeist_block_latest($count = NULL) |
function theme_zeitgeist_block_latest($count = NULL) { |
|
{ |
|
| 798 |
$ar = _zeitgeist_block_latest($count); |
$ar = _zeitgeist_block_latest($count); |
| 799 |
$arLinks = array(); |
$ar_links = array(); |
| 800 |
$attr = variable_get(ZGVARNOFOLLOW, ZGDEFNOFOLLOW) |
$attr = variable_get(ZGVARNOFOLLOW, ZGDEFNOFOLLOW) |
| 801 |
? array('rel' => 'nofollow') |
? array('rel' => 'nofollow') |
| 802 |
: NULL; |
: NULL; |
| 803 |
$attr = array_merge($attr, array('absolute' => true)); |
$attr = array_merge($attr, array('absolute' => TRUE)); |
| 804 |
foreach ($ar as $key => $value) |
foreach ($ar as $key => $value) { |
| 805 |
{ |
$ar_links[] = l($key, "search/$value[1]/$value[0]", $attr); |
|
$arLinks[] = l($key, "search/$value[1]/$value[0]", $attr); |
|
|
} |
|
|
$ret = theme('item_list', $arLinks); |
|
|
return $ret; |
|
| 806 |
} |
} |
| 807 |
|
$ret = theme('item_list', $ar_links); |
| 808 |
|
return $ret; |
| 809 |
|
} |
| 810 |
|
|
| 811 |
/** |
/** |
| 812 |
* Release a result set. This really belongs in the database*.inc includes, |
* Release a result set. This really belongs in the database*.inc includes, |
| 819 |
* @param resource $q |
* @param resource $q |
| 820 |
* @return void |
* @return void |
| 821 |
*/ |
*/ |
| 822 |
function db_free_result($q) |
function db_free_result($q) { |
|
{ |
|
| 823 |
global $db_type; |
global $db_type; |
| 824 |
|
|
| 825 |
switch ($db_type) |
switch ($db_type) { |
|
{ |
|
| 826 |
case 'mysql': |
case 'mysql': |
| 827 |
mysql_free_result($q); |
mysql_free_result($q); |
| 828 |
break; |
break; |
| 832 |
case 'pgsql': |
case 'pgsql': |
| 833 |
pg_free_result($q); |
pg_free_result($q); |
| 834 |
break; |
break; |
|
} |
|
| 835 |
} |
} |
| 836 |
|
} |
| 837 |
|
|
| 838 |
/** |
/** |
| 839 |
* Checks whether the search passes validation (anti-spam) |
* Checks whether the search passes validation (anti-spam) |
| 840 |
* |
* |
| 841 |
* @param string $search |
* @param string $keys |
| 842 |
* @param string $test |
* @param string $op |
| 843 |
|
* save | view |
| 844 |
* @return boolean |
* @return boolean |
| 845 |
*/ |
*/ |
| 846 |
function _zeitgeist_validate($search, $test) |
function _zeitgeist_validate($keys, $op) { |
|
{ |
|
| 847 |
$option = variable_get(ZGVARVALIDATION, ZGDEFVALIDATION); |
$option = variable_get(ZGVARVALIDATION, ZGDEFVALIDATION); |
| 848 |
$html = $search != strip_tags($search); |
$html = ($keys != strip_tags($keys)); |
| 849 |
$ret = true; |
$ret = TRUE; |
| 850 |
|
|
| 851 |
switch ($test) |
switch ($op) { |
| 852 |
{ |
case 'save': |
| 853 |
case 'store': |
if ($html && $option == ZGVALIDATERECORD) { |
| 854 |
if ($html && $option == ZGVALIDATERECORD) |
$ret = FALSE; |
| 855 |
{ |
} |
|
$ret = false; |
|
|
} |
|
|
break; |
|
|
case 'show': |
|
|
if ($html && $option == ZGVALIDATEDISPLAY) |
|
|
{ |
|
|
$ret = false; |
|
|
} |
|
| 856 |
break; |
break; |
| 857 |
|
|
| 858 |
|
case 'view': |
| 859 |
|
if ($html && $option == ZGVALIDATEDISPLAY) { |
| 860 |
|
$ret = FALSE; |
| 861 |
|
} |
| 862 |
|
break; |
| 863 |
|
|
| 864 |
default: |
default: |
| 865 |
$ret = true; |
$ret = TRUE; |
|
} |
|
|
return $ret; |
|
| 866 |
} |
} |
| 867 |
|
return $ret; |
| 868 |
|
} |
| 869 |
|
|
| 870 |
/** |
/** |
| 871 |
* Sample basic stats page. Note that you can obtain much more finely |
* Sample basic stats page. Note that you can obtain much more finely |
| 874 |
* |
* |
| 875 |
* @return string HTML |
* @return string HTML |
| 876 |
*/ |
*/ |
| 877 |
function zeitgeist_page_single_column() |
function zeitgeist_page_single_column() { |
|
{ |
|
| 878 |
$height = variable_get(ZGVARPAGEHEIGHT, ZGDEFPAGEHEIGHT); // pager height |
$height = variable_get(ZGVARPAGEHEIGHT, ZGDEFPAGEHEIGHT); // pager height |
| 879 |
|
|
| 880 |
$sq = 'SELECT zg.search, count(zg.ts) cnt ' |
$sq = 'SELECT zg.search, count(zg.ts) cnt ' |
| 892 |
$q = pager_query($sq, $height, 0, $sq_count); |
$q = pager_query($sq, $height, 0, $sq_count); |
| 893 |
$ar = array(); |
$ar = array(); |
| 894 |
$cnt = 0; |
$cnt = 0; |
| 895 |
while ($o = db_fetch_object($q)) |
while ($o = db_fetch_object($q)) { |
|
{ |
|
| 896 |
$ar[] = "$o->cnt - " . l($o->search, "search/node/$o->search"); |
$ar[] = "$o->cnt - " . l($o->search, "search/node/$o->search"); |
| 897 |
$cnt += $o->cnt; |
$cnt += $o->cnt; |
| 898 |
} |
} |
| 899 |
$ret .= theme('item_list', $ar); |
$ret .= theme('item_list', $ar); |
| 900 |
$ret .= '<p>' . t('For a total of %cnt hits for these %height searches.', |
$ret .= '<p>' . t('For a total of %cnt hits for these %height searches.', |
| 901 |
array |
array( |
|
( |
|
| 902 |
'%cnt' => $cnt, |
'%cnt' => $cnt, |
| 903 |
'%height' => $height, |
'%height' => $height, |
| 904 |
) |
) |
| 905 |
) . "</p>\n"; |
) . "</p>\n"; |
| 906 |
$ret .= theme('pager'); |
$ret .= theme('pager'); |
| 907 |
return $ret; |
return $ret; |
| 908 |
} |
} |
| 909 |
|
|
| 910 |
/** |
/** |
| 911 |
* Sample page showing ZG results. For smarter results, build your own page with |
* Sample page showing ZG results. For smarter results, build your own page with |
| 914 |
* @param int $days |
* @param int $days |
| 915 |
* @return string |
* @return string |
| 916 |
* @see _zeitgeist_stats() |
* @see _zeitgeist_stats() |
| 917 |
|
* @see zeitgeist_page_single_column() |
| 918 |
*/ |
*/ |
| 919 |
function _zeitgeist_page($days = 30) |
function _zeitgeist_page($days = 30) { |
| 920 |
{ |
if (!is_numeric($days)) { |
|
if (!is_numeric($days)) |
|
|
{ |
|
| 921 |
$days = 30; |
$days = 30; |
| 922 |
} |
} |
| 923 |
$height = variable_get(ZGVARPAGEHEIGHT, ZGDEFPAGEHEIGHT); // pager height |
$height = variable_get(ZGVARPAGEHEIGHT, ZGDEFPAGEHEIGHT); // pager height |
| 924 |
|
|
| 925 |
drupal_set_title(t('Zeitgeist over the last !days days', |
drupal_set_title(t('Zeitgeist over the last !days days', |
| 927 |
$limit = time() - ZGONEDAY * $days ; |
$limit = time() - ZGONEDAY * $days ; |
| 928 |
|
|
| 929 |
|
|
| 930 |
$arRecherches = array(); |
$ar_searches = array(); |
| 931 |
$sq = 'SELECT DISTINCT search, count(ts) AS nts ' |
$sq = 'SELECT DISTINCT search, count(ts) AS nts ' |
| 932 |
. 'FROM {zeitgeist} z ' |
. 'FROM {zeitgeist} z ' |
| 933 |
// . "WHERE z.category = 'node' " |
// . "WHERE z.category = 'node' " |
| 934 |
. 'WHERE z.ts >= %d ' |
. 'WHERE z.ts >= %d ' |
| 935 |
. 'GROUP BY search ' |
. 'GROUP BY search ' |
| 936 |
. 'ORDER BY nts DESC, search ASC '; |
. 'ORDER BY nts DESC, search ASC '; |
| 937 |
|
$sq = db_rewrite_sql($sq); |
| 938 |
$q = db_query_range($sq, $limit, 0, $height * 3); |
$q = db_query_range($sq, $limit, 0, $height * 3); |
| 939 |
while ($o = db_fetch_array($q)) |
while ($o = db_fetch_array($q)) { |
| 940 |
{ |
if ($o['search'] == '') { |
|
if ($o['search'] == '') |
|
| 941 |
$o['search'] = '<vide>'; |
$o['search'] = '<vide>'; |
|
$arRecherches[$o['search']] = $o['nts']; |
|
| 942 |
} |
} |
| 943 |
|
$ar_searches[$o['search']] = $o['nts']; |
| 944 |
|
} |
| 945 |
|
|
| 946 |
$n = count($arRecherches); |
$n = count($ar_searches); |
| 947 |
$mod = $n % 3; |
$mod = $n % 3; |
| 948 |
|
|
| 949 |
$break = count($arRecherches) / 3; |
$break = count($ar_searches) / 3; |
| 950 |
$rows = array(); |
$rows = array(); |
| 951 |
$i = 0; |
$i = 0; |
| 952 |
foreach ($arRecherches as $search => $count) |
foreach ($ar_searches as $search => $count) { |
| 953 |
{ |
if ($i < $break) { |
| 954 |
if ($i < $break) |
$rows[$i] = array( |
|
{ |
|
|
$rows[$i] = array |
|
|
( |
|
| 955 |
$search, $count, |
$search, $count, |
| 956 |
null, null, |
NULL, NULL, |
| 957 |
null, null, |
NULL, NULL, |
| 958 |
); |
); |
| 959 |
} |
} |
| 960 |
elseif ($i < 2 * $break) |
elseif ($i < 2 * $break) { |
|
{ |
|
| 961 |
$rows[$i - $break][2] = $search; |
$rows[$i - $break][2] = $search; |
| 962 |
$rows[$i - $break][3] = $count; |
$rows[$i - $break][3] = $count; |
| 963 |
} |
} |
| 964 |
else |
else { |
|
{ |
|
| 965 |
$rows[$i - 2 * $break][4] = $search; |
$rows[$i - 2 * $break][4] = $search; |
| 966 |
$rows[$i - 2 * $break][5] = $count; |
$rows[$i - 2 * $break][5] = $count; |
|
} |
|
|
$i++; |
|
| 967 |
} |
} |
| 968 |
|
$i++; |
| 969 |
|
} |
| 970 |
|
|
| 971 |
$header = array |
$header = array( |
|
( |
|
| 972 |
t('Search'), t('#'), |
t('Search'), t('#'), |
| 973 |
t('Search'), t('#'), |
t('Search'), t('#'), |
| 974 |
t('Search'), t('#'), |
t('Search'), t('#'), |
| 975 |
); |
); |
| 976 |
$attributes = array |
$attributes = array(); |
|
( |
|
|
); |
|
| 977 |
|
|
| 978 |
$ret = theme_table($header, $rows, $attributes); |
$ret = theme('table', $header, $rows, $attributes); |
| 979 |
|
|
| 980 |
$ret .= t('<p>Searches below the pager !limit are not included in this list.</p>', |
$ret .= t('<p>Searches below the pager !limit are not included in this list.</p>', |
| 981 |
array('!limit' => l(t('limit'), ZGPATHSETTINGS))); |
array('!limit' => l(t('limit'), ZGPATHSETTINGS))); |
| 982 |
return $ret; |
return $ret; |
| 983 |
} |
} |
| 984 |
|
|
| 985 |
/** |
/** |
| 986 |
* When changing ZG settings, clear the ZG block cache, since its content |
* When changing ZG settings, clear the ZG block cache, since its content |
| 989 |
* @param string $form_id |
* @param string $form_id |
| 990 |
* @param array $form_values |
* @param array $form_values |
| 991 |
*/ |
*/ |
| 992 |
function _zeitgeist_admin_settings_submit($form_id, $form_values) |
function _zeitgeist_admin_settings_submit($form, &$form_state) { |
|
{ |
|
| 993 |
cache_clear_all(ZGCIDLATEST, 'cache'); |
cache_clear_all(ZGCIDLATEST, 'cache'); |
| 994 |
cache_clear_all(ZGCIDTOP, 'cache'); |
cache_clear_all(ZGCIDTOP, 'cache'); |
| 995 |
} |
} |
| 996 |
|
|
| 997 |
/** |
/** |
| 998 |
* Implement the new Drupal 6 hook_theme() |
* Implement hook_theme(). |
| 999 |
* |
* |
| 1000 |
* @return array |
* @return array |
| 1001 |
*/ |
*/ |
| 1002 |
function zeitgeist_theme() |
function zeitgeist_theme() { |
| 1003 |
{ |
$ret = array( |
| 1004 |
$ret = array |
'zeitgeist_block_latest' => array('arguments' => array('count' => NULL)), |
| 1005 |
( |
'zeitgeist_block_top' => array('arguments' => array('count' => NULL)), |
| 1006 |
'zeitgeist_block_latest' => array('arguments' => array('count' => null)), |
); |
|
'zeitgeist_block_top' => array('arguments' => array('count' => null)), |
|
|
); |
|
| 1007 |
return $ret; |
return $ret; |
|
} |
|
| 1008 |
|
} |
| 1009 |
|
|
| 1010 |
|
/** |
| 1011 |
|
* Submit handler for the main search form. |
| 1012 |
|
* |
| 1013 |
|
* It has been inserted before the default search handler. |
| 1014 |
|
* |
| 1015 |
|
* @param array $form |
| 1016 |
|
* @param array $form_state |
| 1017 |
|
*/ |
| 1018 |
|
function zeitgeist_search_form_submit($form, &$form_state) { |
| 1019 |
|
$keys = $form_state['values']['processed_keys']; |
| 1020 |
|
$kind = $form_state['values']['module'] |
| 1021 |
|
? $form_state['values']['module'] |
| 1022 |
|
: 'node'; |
| 1023 |
|
// dsm(t("Search form (@kind): @keys", array('@kind' => $kind, '@keys' => $keys))); |
| 1024 |
|
_zeitgeist_store_search($keys, $kind); |
| 1025 |
|
} |
| 1026 |
|
|
| 1027 |
|
/** |
| 1028 |
|
* Submit handler for the theme search box form. |
| 1029 |
|
* |
| 1030 |
|
* It has been inserted before the default search handler. |
| 1031 |
|
* |
| 1032 |
|
* @param array $form |
| 1033 |
|
* @param array $form_state |
| 1034 |
|
*/ |
| 1035 |
|
function zeitgeist_search_theme_form_submit($form, &$form_state) { |
| 1036 |
|
$kind = 'node'; |
| 1037 |
|
dsm($form_state); |
| 1038 |
|
$form_id = $form_state['values']['form_id']; |
| 1039 |
|
$keys = trim($form_state['values'][$form_id]); |
| 1040 |
|
|
| 1041 |
|
// dsm(t("Search box (@kind): @keys", array('@kind' => $kind, '@keys' => $keys))); |
| 1042 |
|
_zeitgeist_store_search($keys, $kind); |
| 1043 |
|
} |