spelling_table = $wpdb->prefix . 'scrib_spelling'; $this->options = get_option('scrib'); $this->options['site_url'] = get_settings('siteurl') . '/'; $this->options['search_url'] = get_settings('siteurl') .'/search/'; $this->options['browse_url'] = get_permalink($this->options['browse_id']) . '/'; $this->options['browse_name'] = trim(substr(get_page_uri($this->options['browse_id']), strrpos(get_page_uri($this->options['browse_id']), '/')), '/'); $this->the_matching_posts = NULL; $this->the_matching_posts_ordinals = NULL; $this->search_terms = NULL; $this->the_matching_post_counts = NULL; $this->taxonomy_name = $this->options['taxonomies']; $this->taxonomies = $this->taxonomies_register(); $this->taxonomies_for_related = $this->options['taxonomies_for_related']; $this->taxonomies_for_spelling = $this->options['taxonomies_for_spelling']; $this->harvest_table = $wpdb->prefix . 'scrib_harvest'; $this->kses_allowedposttags(); // allow more tags } public function activate() { global $wpdb; // setup default options if(!get_option('scrib')) update_option('scrib', array('taxonomies' => array('keyword' => 'Keyword', 'scope' => 'Scope', 'auth' => 'Author', 'format' => 'Format', 'isbn' => 'ISBN', 'sourceid' => 'Source ID', 'subj' => 'Subject', 'title' => 'Title'), 'taxonomies_for_related' => array('auth', 'subj'), 'taxonomies_for_spelling' => array('auth', 'subj', 'title'))); $options = get_option('scrib'); // setup the browse page, if it doesn't exist if(empty($options['browse_id']) || $wpdb->get_var("SELECT ID FROM $wpdb->posts WHERE ID = ". intval($options['browse_id']) .' AND post_status = "publish" AND post_type = "page" ') == FALSE){ // create the default browse page $postdata['post_title'] = 'Browse'; $postdata['post_name'] = 'browse'; $postdata['comment_status'] = 0; $postdata['ping_status'] = 0; $postdata['post_status'] = 'publish'; $postdata['post_type'] = 'page'; $postdata['post_content'] = 'Browse new titles.'; $postdata['post_excerpt'] = 'Browse new titles.'; $postdata['post_author'] = 0; $post_id = wp_insert_post($postdata); // insert the post // set the options with this new page $options['browse_id'] = (int) $post_id; update_option('scrib', $options); } // setup the catalog author, if it doesn't exist if(empty($options['catalog_author_id']) || get_userdata($options['catalog_author_id']) == FALSE){ // create the default author $random_password = substr(md5(uniqid(microtime())), 0, 6); $user_id = wp_create_user('cataloger', $random_password); $user = new WP_User($user_id); $user->set_role('contributor'); // set the options $options['catalog_author_id'] = (int) $user_id; update_option('scrib', $options); } // setup widget defaults, if they don't exisit if(!get_option('widget_scrib_searchedit')) update_option('widget_scrib_searchedit', unserialize('a:5:{s:5:"title";s:9:"Searching";s:14:"title-no-terms";s:10:"New Titles";s:8:"text-top";s:76:"Your search found [[scrib_hit_count]] items with all of the following terms:";s:11:"text-bottom";s:152:"Click [x] to remove a term, or use the facets below to narrow your search. What are facets?";s:13:"text-no-terms";s:169:"Showing new titles added to the collection. Use the facets below to explore the collection. What are facets?";}')); if(!get_option('widget_scrib_scope')) update_option('widget_scrib_scope', unserialize('a:1:{s:5:"title";s:12:"Searching In";}')); if(!get_option('widget_scrib_spelling')) update_option('widget_scrib_spelling', unserialize('a:1:{s:5:"title";s:13:"Did You Mean?";}')); if(!get_option('widget_scrib_facets')) update_option('widget_scrib_facets', array('number' => 9, 1 => array('title' => 'Narrow by Subject', 'facets' => 'subj', 'show_search' => 'on', 'format' => 'cloud'))); } public function kses_allowedposttags() { global $allowedposttags; unset($allowedposttags['font']); $allowedposttags['ul']['class'] = array(); $allowedposttags['ol']['class'] = array(); $allowedposttags['li']['class'] = array(); $allowedposttags['div']['class'] = array(); $allowedposttags['div']['style'] = array(); $allowedposttags['h1']['id'] = array(); $allowedposttags['h1']['class'] = array(); $allowedposttags['h2']['id'] = array(); $allowedposttags['h2']['class'] = array(); $allowedposttags['h3']['id'] = array(); $allowedposttags['h3']['class'] = array(); $allowedposttags['h4']['id'] = array(); $allowedposttags['h4']['class'] = array(); $allowedposttags['h5']['id'] = array(); $allowedposttags['h5']['class'] = array(); $allowedposttags['h6']['id'] = array(); $allowedposttags['h6']['class'] = array(); // tags required for YouTube embeds $allowedposttags['embed']['src'] = array(); $allowedposttags['embed']['type'] = array(); $allowedposttags['embed']['wmode'] = array(); $allowedposttags['embed']['width'] = array(); $allowedposttags['embed']['height'] = array(); $allowedposttags['object']['width'] = array(); $allowedposttags['object']['height'] = array(); $allowedposttags['param']['name'] = array(); $allowedposttags['param']['value'] = array(); return(TRUE); } public function addmenus(){ add_options_page('Scriblio Settings', 'Scriblio', 5, __FILE__, array(&$this, 'admin_menu')); } public function admin_menu(){ require(ABSPATH . PLUGINDIR .'/'. plugin_basename(dirname(__FILE__)) .'/scriblio_admin.php'); } public function query_vars($vars){ // filter wp's query vars, add scrib vars return(array_unique(array_merge($this->taxonomies, $vars))); } public function taxonomies_register($reset = NULL) { // define the Scrib taxonomies global $wpdb; // get the taxonomies from the config or punt and read them from the DB if(get_option('Scrib_taxonomies') && !$reset){ $taxonomies = get_option('Scrib_taxonomies'); }else{ $taxonomies = $this->taxonomies_getall(); update_option('Scrib_taxonomies', $facets); } // register those taxonomies foreach($taxonomies as $taxonomy){ if($taxonomy == 'keyword' || $taxonomy == 'keyword') continue; // we don't want to register these 'special' taxonomies register_taxonomy( $taxonomy, 'post' ); } return($taxonomies); } public function taxonomies_getall() { global $wpdb; return(array_merge(array('keyword', 'scope'), $wpdb->get_col("SELECT taxonomy FROM $wpdb->term_taxonomy GROUP BY taxonomy"))); } public function is_term($term, $taxonomy = '') { global $wpdb; $wild = FALSE; $wild = strpos($term, '*'); if ( is_int($term) ) { if ( 0 == $term ) return 0; $where = "t.term_id = '$term'"; } else { if ( ! $term = sanitize_title($term) ) return 0; if($wild){ $where = "t.slug LIKE '$term%'"; }else{ $where = "t.slug = '$term'"; } } $term_id = $wpdb->get_col("SELECT term_id FROM $wpdb->terms as t WHERE $where"); if ( empty($taxonomy) || empty($term_id) ) return $term_id; return $wpdb->get_col("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $where AND tt.taxonomy = '$taxonomy'"); } public function get_matching_posts(){ global $bsuite, $wp_query, $wpdb; $post_ids = NULL; if( $this->search_terms ){ $search_terms = $this->search_terms; // figure out what page of posts to show // $paged, $posts_per_page, and $limit are here for cases // where the query doesn't have an explicit LIMIT declaration $paged = (int) $wp_query->query_vars['paged'] ? (int) $wp_query->query_vars['paged'] : 1; $posts_per_page = (int) $wp_query->query_vars['posts_per_page'] ? (int) $wp_query->query_vars['posts_per_page'] : (int) get_settings('posts_per_page'); $this->posts_per_page = $posts_per_page; $limit = 'LIMIT '. ($paged - 1) * $posts_per_page .', '. $posts_per_page; $key = md5( serialize( $this->search_terms ) . $paged ); $cache = wp_cache_get( 'scrib_querycache_'. $key , 'default' ); //print_r($cache); if ( isset($cache['count']) && $cache['count'] === 0 ){ $this->the_matching_posts = FALSE; $this->the_matching_facets = FALSE; $this->the_matching_posts_count = 0; $this->the_matching_posts_ordinals = FALSE; return(FALSE); } if( !$cache ){ $from[] = " FROM $wpdb->posts a "; // the scope $author_id = ''; if($wp_query->query_vars['scope'] == 'catalog') $author_id = 'AND a.post_author = '. (int) $this->options['catalog_author_id']; if($wp_query->query_vars['scope'] == 'blog') $author_id = 'AND a.post_author <> '. (int) $this->options['catalog_author_id']; unset($search_terms['scope']); // the keywords if(!empty($search_terms['keyword'])){ $boolean = ''; if(ereg('"|\+|\-|\(|\<|\>|\*', $this->search_terms['keyword'])) $boolean = ' IN BOOLEAN MODE'; $keyword_post_ids = $wpdb->get_col(" SELECT a.ID, MATCH (b.content, b.title) AGAINST ('". $wpdb->escape(implode($this->search_terms['keyword'], ' ')) ."'$boolean) AS score FROM $wpdb->posts a LEFT JOIN $bsuite->search_table b ON ( b.post_id = a.ID ) WHERE 1=1 AND (MATCH (b.content, b.title) AGAINST ('". $wpdb->escape(implode($this->search_terms['keyword'], ' ')) ."'$boolean)) $author_id AND (post_status IN ('publish', 'private')) ORDER BY score DESC LIMIT 1000 "); unset($search_terms['keyword']); } // the other facets if(!empty($search_terms)){ foreach($search_terms as $taxonomy => $values) foreach($values as $value) $tt_ids[] = $this->is_term ( $value, $taxonomy ); } $tt_ids = array_filter($tt_ids); $taliases = range('a','z'); $i = 1; if(count($tt_ids) > 0){ foreach($tt_ids as $tt_id){ $from[] = " INNER JOIN $wpdb->term_relationships ". $taliases[ceil($i / 26)] . $taliases[($i % 26)] .' ON a.ID = '. $taliases[ceil($i / 26)] . $taliases[($i % 26)] .'.object_id '; $where[] = ' AND '. $taliases[ceil($i / 26)] . $taliases[($i % 26)] .'.term_taxonomy_id IN ('. implode($tt_id, ',') .') '; $i++; } } // it's a piece of cake to bake a pretty cake // bring this all together and find the right posts $orderby = ''; $keyword_select = ''; if( empty( $keyword_post_ids ) ){ $orderby = 'ORDER BY a.post_date_gmt DESC'; }else{ $keyword_select = 'AND a.ID IN ('. implode($keyword_post_ids, ',') .')' ; $limit = ''; } $post_ids = $wpdb->get_col('SELECT SQL_CALC_FOUND_ROWS a.ID '. implode($from) .' WHERE 1=1 '. implode($where) .' '. $keyword_select .' '. $author_id .' AND (a.post_type IN ("post", "page") AND (a.post_status IN ("publish", "private"))) GROUP BY a.ID '. $orderby .' '. $limit); if(count($post_ids) > 0){ $cache['count'] = $wpdb->get_var('SELECT FOUND_ROWS()'); if(empty($limit)){ count($post_ids); $post_ids_for_facets = array_slice(array_intersect($keyword_post_ids, $post_ids), 0, 150); $post_ids = array_slice(array_intersect($keyword_post_ids, $post_ids), ($paged - 1) * $posts_per_page, $posts_per_page); }else{ $post_ids_for_facets = $wpdb->get_col('SELECT SQL_CALC_FOUND_ROWS a.ID '. implode($from) .' WHERE 1=1 '. implode($where) .' '. $author_id .' AND (a.post_type IN ("post", "page") AND (a.post_status IN ("publish", "private"))) GROUP BY a.ID '. $orderby .' LIMIT '. ($paged - 1) * $posts_per_page .',150'); } $cache['facets'] = $wpdb->get_results("SELECT b.term_id, b.name, a.taxonomy, COUNT(c.term_taxonomy_id) as `count` FROM $wpdb->term_relationships c LEFT JOIN $wpdb->term_taxonomy a ON a.term_taxonomy_id = c.term_taxonomy_id LEFT JOIN $wpdb->terms b ON a.term_id = b.term_id WHERE c.object_id IN (". implode($post_ids_for_facets, ',') .") GROUP BY c.term_taxonomy_id ORDER BY `count` DESC LIMIT 1000"); $cache['posts'] = $post_ids; $cache['ordinals'] = array_flip($post_ids); }else{ $cache = array('count' => 0); } wp_cache_add( 'scrib_querycache_'. $key , $cache, 'default' ); } if(is_array($cache)){ $this->the_matching_posts = $cache['posts']; $this->the_matching_facets = $cache['facets']; $this->the_matching_posts_count = $cache['count']; $this->the_matching_posts_ordinals = $cache['ordinals']; add_filter('the_posts', array(&$this, 'sort_matching_posts')); return(TRUE); }else{ $this->the_matching_posts = FALSE; $this->the_matching_facets = FALSE; $this->the_matching_posts_count = 0; $this->the_matching_posts_ordinals = FALSE; return(FALSE); } } } public function sort_matching_posts($the_posts){ $GLOBALS["wp_query"]->found_posts = $GLOBALS["wp_query"]->post_count = $this->the_matching_posts_count; $GLOBALS["wp_query"]->max_num_pages = ceil( $this->the_matching_posts_count / $this->posts_per_page); //print_r($the_posts); //print_r($this->the_matching_posts_ordinals); // insert the ordinal into each post for sorting foreach($the_posts as $post){ //echo $post->ID . '='. $this->the_matching_posts_ordinals[$post->ID] .', '; $new_order[$this->the_matching_posts_ordinals[$post->ID]] = $post; } // now that the posts are re-keyed, sort them ksort($new_order); // This shuffle resets the keys on the array. // A function later in WP expects the array keys to be sequential, // and the output here might otherwise be non-sequential. array_unshift($new_order, 'Junk'); array_shift($new_order); //print_r($new_order); return($new_order); } public function search_terms(){ global $wp_query; $temp = array_map('stripslashes', (array_intersect_key($wp_query->query_vars, array_flip($this->taxonomies)))); $terms = FALSE; if(is_array($temp)){ $terms = array(); reset($temp); while (list($key, $val) = each($temp)) { $values = (explode('|', urldecode($val))); foreach($values as $val){ $terms[$key][] = $val; } } } if(!empty($wp_query->query_vars['s'])) $terms['keyword'] = explode('|', stripslashes(urldecode($wp_query->query_vars['s']))); $this->search_terms = $terms; return(array_filter($terms)); } public function posts_where($query){ // hide catalog entries from front page and rss feeds. global $wp_query; if($wp_query->is_home) return(" AND post_author <> {$this->options['catalog_author_id']}". $query); if($wp_query->is_feed && count($wp_query->query) < 2) return(" AND post_author <> {$this->options['catalog_author_id']}". $query); return($query); } public function the_query($query, $limit = NULL){ global $bsuite, $wp_query, $wpdb; if($wp_query->is_admin) return($query); //echo "
';
echo("post_title}\" class=\"summarylink\" id=\"summary-$id\">$image");
}
public function the_format($return = NULL) {
if($return){
return strip_tags($this->get_the_tag_list('format'));
}else{
echo strip_tags($this->get_the_tag_list('format'));
}
}
public function the_content($content){
// if(!$this->is_scrib)
// return($content);
$content = str_replace(array('ScribCatBase/subject/', 'ScribCatBase/author/'), array($this->options['browse_url'] .'/?subject=', $this->options['browse_url'] .'/?author='), $content);
return($content);
}
//
// Scriblio specific tokens (requires bsuite)
//
public function tokens_set($tokens){
// setup some tokens
$tokens['bookjacket'] = array(&$this, 'token_bookjacket');
$tokens['availability'] = array(&$this, 'token_availability');
$tokens['reviews'] = array(&$this, 'token_reviews');
$tokens['scrib_hit_count'] = array(&$this, 'token_hit_count');
$tokens['scrib_spellcheck'] = array(&$this, 'spelling_check_token');
return($tokens);
}
public function token_bookjacket($thing) {
// [[bookjacket|
]]
global $id;
return(''. $thing .'');
}
public function token_reviews($thing) {
// [[reviews|0738202444]]
if(function_exists('scrib_reviews')){
return(scrib_reviews($thing));
}else{
return('');
}
}
public function token_availability($thing) {
// [[availability|l1292675]]
if(function_exists('scrib_availability')){
return(scrib_availability($thing));
}else{
return('');
}
// return('click for location and availability');
// return('click for availability');
}
// end token-related functions
public function token_hit_count($thing) {
// [[scrib_hit_count]]
if(999 < $this->the_matching_posts_count)
return('more than 1000');
else
return($this->the_matching_posts_count);
}
public function spelling_init_table(){
global $wpdb;
set_time_limit(0);
ignore_user_abort(TRUE);
$interval = 250;
if( !isset( $_GET[ 'n' ] ) ) {
$n = 0;
$charset_collate = '';
if ( version_compare(mysql_get_server_info(), '4.1.0', '>=') ) {
if ( ! empty($wpdb->charset) )
$charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
if ( ! empty($wpdb->collate) )
$charset_collate .= " COLLATE $wpdb->collate";
}
// drop the old table
if($wpdb->get_var("SHOW TABLES LIKE '$this->spelling_table'"))
$wpdb->get_results("DROP TABLE $this->spelling_table");
// create the table
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta("
CREATE TABLE $this->spelling_table (
term_id bigint(20) NOT NULL default '0',
term_name varchar(55) NOT NULL default '',
term_metaphone varchar(55) NOT NULL default '',
term_count bigint(20) NOT NULL default '0',
PRIMARY KEY (term_id),
FULLTEXT KEY term_metaphone (term_metaphone)
) ENGINE=MyISAM $charset_collate ");
} else {
$n = (int) $_GET[ 'n' ] ;
}
// get the terms
$in_taxonomies = "'" . implode("', '", $this->taxonomies_for_spelling) . "'";
$terms = $wpdb->get_results("SELECT t.term_id, t.name, tt.count FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ($in_taxonomies) ORDER BY t.term_id LIMIT $n, $interval");
if( count( $terms ) ) {
echo '' . __('Rebuilding Scriblio spelling table. Please be patient.', 'Scrib') . " Working $interval terms, starting with $n .
'. __('Scriblio spelling table rebuilt.', 'bsuite') .'
'; ?> %%term%%'){ global $wpdb; $metaphone = array(); foreach(explode(' ', remove_accents($q)) as $part) $metaphone[] = metaphone($part); if( implode( $metaphone , ' ' )){ $term_ids = ($wpdb->get_col("SELECT term_id FROM $this->spelling_table WHERE MATCH (term_metaphone) AGAINST ('". implode($metaphone, ' ') ."') LIMIT 5")); if(!count($term_ids)) return(FALSE); $suggestion = array(); $in_taxonomies = "'" . implode("', '", $this->taxonomies_for_spelling) . "'"; foreach($term_ids as $term_id){ $term = $wpdb->get_row("SELECT t.name, tt.taxonomy FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy IN ($in_taxonomies) AND t.term_id = '$term_id' LIMIT 1"); $suggestion[] = str_replace(array('%%term%%','%%taxonomy%%','%%link%%'), array($term->name, $this->taxonomy_name[$term->taxonomy], $this->get_search_link(array($term->taxonomy => array($term->name)))), $template); // $suggestion[] = $this->taxonomy_name[$term->taxonomy] .': '. $term->name .''; } return($suggestion); } return(FALSE); } public function spelling_check_token(){ if($spelling = $this->spelling_check(implode($this->search_terms['keyword'], ' '))) return("
the_scope(); ?>
spelling_check(implode($this->search_terms['keyword'], ' '), '%%term%%')){ ?>