path_web = '/'. PLUGINDIR .'/'. substr( plugin_basename(__FILE__), 0, strpos( plugin_basename(__FILE__), '/' )); // register and queue javascripts wp_register_script( 'jquery-suggest', $this->path_web . '/js/jquery.suggest.js', array('jquery','dimensions'), '20080422' ); wp_enqueue_script( 'jquery-suggest' ); wp_register_script( 'scrib-googlebook', $this->path_web . '/js/scrib.googlebook.js', array('jquery'), '20080422' ); wp_enqueue_script( 'scrib-googlebook' ); // register WordPress hooks add_filter('posts_where', array(&$this, 'posts_where'), 10); add_filter('posts_request', array(&$this, 'the_query'), 10); add_filter('query_vars', array(&$this, 'query_vars'), 11); add_action('admin_menu', array(&$this, 'addmenus')); add_filter('bsuite_tokens', array(&$this, 'tokens_set')); add_filter('bsuite_suggestive_tags', array(&$this, 'the_tags_for_bsuite_suggestive'), 10, 2); add_filter('bsuite_link2me', array(&$this, 'link2me'), 10, 2); add_action('widgets_init', array(&$this, 'widgets_register')); add_filter('the_content_rss', array(&$this, 'the_content_filter'), 1); add_filter('get_the_excerpt', array(&$this, 'the_content_filter'), 1); add_filter('the_content', array(&$this, 'the_content_filter'), 1); add_filter('the_excerpt', array(&$this, 'the_content_filter'), 1); // add_filter('the_author', array(&$this, 'the_author_filter'), 1); // add_filter('author_link', array(&$this, 'author_link_filter'), 1); add_filter('the_title', array(&$this, 'gbs_aggregator'), 1); add_action('wp_footer', array(&$this, 'wp_footer_js')); add_filter('template_redirect', array(&$this, 'textthis_redirect'), 11); register_activation_hook(__FILE__, array(&$this, 'activate')); add_action('init', array(&$this, 'init')); // end register WordPress hooks } function init(){ global $wpdb; $this->suggest_table = $wpdb->prefix . 'scrib_suggest'; $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_suggest = $this->options['taxonomies_for_suggest']; $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( 's' => 'Keyword', 'scope' => 'Scope', 'auth' => 'Author', 'format' => 'Format', 'isbn' => 'ISBN', 'sourceid' => 'Source ID', 'subj' => 'Subject', 'title' => 'Title'), 'taxonomies_for_related' => array('auth', 'subj'), 'taxonomies_for_suggest' => 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', array( 'search-title' => 'Searching', 'search-text-top' => 'Your search found [[scrib_hit_count]] items with all of the following terms:', 'search-text-bottom' => 'Click [x] to remove a term, or use the facets in the sidebar to narrow your search. What are facets? Results sorted by keyword relevance.', 'browse-title' => 'Browsing New Titles', 'browse-text-top' => 'We have [[scrib_hit_count]] items with all of the following terms:', 'browse-text-bottom' => 'Click [x] to remove a term, or use the facets in the sidebar to narrow your search. What are facets? Results sorted by the date added to the collection.', 'default-title' => 'Browsing New Titles', 'default-text' => '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', array( 'title' => 'Searching In' )); if(!get_option('widget_scrib_facets')) update_option('widget_scrib_facets', array( 'number' => 9, 1 => array( 'title' => 'Narrow by Subject', 'facets' => 'subj', 'count' => '25', 'show_search' => 'on', 'format' => 'cloud'), 2 => array( 'title' => 'More in Subject', 'facets' => 'subj', 'count' => '0', 'show_singular' => 'on', 'format' => 'list'), 3 => array( 'title' => 'Format', 'facets' => 'format', 'count' => '25', 'show_search' => 'on', 'format' => 'list'), 4 => array( 'title' => 'Author', 'facets' => 'auth', 'count' => '9', 'show_singular' => 'on', 'show_browse' => 'on', 'format' => 'list') )); } 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') && !$reset){ $taxonomies = get_option('scrib'); $taxonomies = array_keys($taxonomies['taxonomies']); }else{ $taxonomies = $this->taxonomies_getall(); update_option('Scrib_taxonomies', $facets); } // register those taxonomies foreach($taxonomies as $taxonomy){ if($taxonomy == 's' || $taxonomy == 'scope') 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('s', '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; // a little work around for the /related/ queries if( $bsuite->bsuggestive_to ) $wp_query->query_vars['paged'] = (int) $_REQUEST['paged']; // 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; $cache_key = md5( serialize( $this->search_terms ) . $paged ); $cache = wp_cache_get( $cache_key , 'scrib_search_'. $cache_key{1} ); if ( isset($cache['count']) && $cache['count'] === 0 ){ $this->the_matching_posts = FALSE; $this->the_matching_post_counts = $cache['post_counts']; $this->the_matching_facets = FALSE; $this->the_matching_posts_count = 0; $this->the_matching_posts_ordinals = FALSE; return(FALSE); } if( !$cache ){ // handle the /related/ queries if( $bsuite->bsuggestive_to ){ if( count( $bsuite->bsuggestive_getposts( $bsuite->bsuggestive_to ))){ $cache['posts'] = array_slice( $bsuite->bsuggestive_getposts( $bsuite->bsuggestive_to ), ( $paged - 1 ) * $posts_per_page, $posts_per_page ); $cache['count'] = count( $cache['posts'] ); $cache['ordinals'] = array_flip( $cache['posts'] ); $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( $bsuite->bsuggestive_getposts( $bsuite->bsuggestive_to ), ',' ) .") GROUP BY c.term_taxonomy_id ORDER BY `count` DESC LIMIT 1000" ); }else{ $cache = array( 'count' => 0 ); } wp_cache_add( $cache_key , $cache, 'scrib_search_'. $cache_key{1} ); $this->the_matching_posts = $cache['posts']; $this->the_matching_facets = $cache['facets']; $this->the_matching_posts_count = count( $bsuite->bsuggestive_getposts( $bsuite->bsuggestive_to )); $this->the_matching_posts_ordinals = $cache['ordinals']; add_filter('the_posts', array(&$this, 'sort_matching_posts')); return(TRUE); } $from[] = " FROM $wpdb->posts a "; // the scope $author_id = ''; if($search_terms['scope'][0] == 'catalog') $author_id = 'AND a.post_author = '. (int) $this->options['catalog_author_id']; if($search_terms['scope'][0] == 'blog') $author_id = 'AND a.post_author <> '. (int) $this->options['catalog_author_id']; unset($search_terms['scope']); // the keywords if(!empty($search_terms['s'])){ $boolean = ''; if(ereg('"|\+|\-|\(|\<|\>|\*', $this->search_terms['s'])) $boolean = ' IN BOOLEAN MODE'; if($this->options['sphinxsearch'] && empty($boolean)){ // get the sphinx client library & configuration require_once(ABSPATH . PLUGINDIR .'/'. plugin_basename(dirname(__FILE__)) .'/includes/sphinxapi.php'); require_once(ABSPATH . PLUGINDIR .'/'. plugin_basename(dirname(__FILE__)) .'/conf_sphinx.php'); // init sphinx & apply the config $sphinx = new SphinxClient (); $sphinx->SetServer ( $sphinx_host, $sphinx_port ); $sphinx->SetLimits ( $sphinx_recstart, $sphinx_reclimit, $sphinx_recoffset ); $sphinx->SetWeights ( $sphinx_weights); $sphinx->SetMatchMode ( $sphinx_matchmode ); $sphinx->SetSortMode ( $sphinx_sortmode, $sphinx_sortby ); // searching the catalog or blog posts or all if($wp_query->query_vars['scope'] == 'catalog') $sphinx->SetFilter ( 'type', array ( 1 ) ); if($wp_query->query_vars['scope'] == 'blog') $sphinx->SetFilter ( 'type', array ( 0 ) ); // do the search $res = $sphinx->Query ( implode($this->search_terms['s'], ' '), $sphinx_index ); if ( is_array($res['matched']) ){ //print_r(array_keys($res['matched'])); //print_r($res['matched']); $keyword_post_ids = array_keys($res['matched']); if (SAVEQUERIES) { unset( $res['matches'] ); unset( $res['matched'] ); $wpdb->queries[] = $res; } } unset($search_terms['s']); }else{ $keyword_post_ids = $wpdb->get_col(" SELECT a.ID, MATCH (b.content, b.title) AGAINST ('". $wpdb->escape(implode($this->search_terms['s'], ' ')) ."'$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['s'], ' ')) ."'$boolean)) $author_id AND (post_status IN ('publish', 'private')) ORDER BY score DESC LIMIT 1000 "); unset($search_terms['s']); } if( 1 > count( $keyword_post_ids )){ wp_cache_add( $cache_key , array('count' => 0), 'scrib_search_'. $cache_key{1} ); $this->the_matching_posts = FALSE; $this->the_matching_post_counts = $matching_post_counts; $this->the_matching_facets = FALSE; $this->the_matching_posts_count = 0; $this->the_matching_posts_ordinals = FALSE; return(FALSE); } } // the other facets if(!empty($search_terms)){ foreach($search_terms as $taxonomy => $values){ foreach($values as $key => $value){ if(!$tt_ids[] = $this->is_term ( $value, $taxonomy )) $matching_post_counts[$taxonomy][$key] = 0; else $matching_post_counts[$taxonomy][$key] = $wpdb->get_var("SELECT COUNT(term_taxonomy_id) FROM $wpdb->term_relationships WHERE term_taxonomy_id IN (". implode($this->is_term ( $value, $taxonomy ) , ',' ) .')' ); if($matching_post_counts[$taxonomy][$key] < 1){ wp_cache_add( $cache_key , array( 'count' => 0, 'post_counts' => $matching_post_counts ), 'scrib_search_'. $cache_key{1} ); $this->the_matching_posts = FALSE; $this->the_matching_post_counts = $matching_post_counts; $this->the_matching_facets = FALSE; $this->the_matching_posts_count = 0; $this->the_matching_posts_ordinals = FALSE; return(FALSE); } } } } $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); $cache['post_counts'] = $matching_post_counts; }else{ $cache = array('count' => 0); } wp_cache_add( $cache_key , $cache, 'scrib_search_'. $cache_key{1} ); } if(is_array($cache)){ $this->the_matching_posts = $cache['posts']; $this->the_matching_post_counts = $matching_post_counts; $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_post_counts = $matching_post_counts; $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['s'] = explode('|', stripslashes(urldecode($wp_query->query_vars['s']))); if($this->is_browse && empty($terms)){ $terms['scope'][] = 'catalog'; $this->autoscoped = TRUE; } $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); if($wp_query->is_admin && !isset( $wp_query->query['author'] )) return(" AND post_author <> {$this->options['catalog_author_id']}". $query); return($query); } public function the_query($query, $limit = NULL){ global $bsuite, $wp_query, $wpdb; //error_log( $query ."\r\r". print_r( $wp_query->query_vars, TRUE ) ); //echo "

$query

"; //print_r($wp_query); if( $wp_query->is_admin ) return($query); //echo "

$query

"; //print_r($wp_query); // is this a browse page thing? if($wp_query->query['pagename'] && ($wp_query->query['pagename'] == $this->options['browse_name'])) { $this->is_browse = TRUE; $wp_query->is_search = TRUE; $wp_query->is_singular = FALSE; $wp_query->is_page = FALSE; } if(!$wp_query->is_search) // return immediately if this is not a search/browse request return($query); // establish the query vars $this->search_terms(); //print_r($this->taxonomies); //print_r($this->search_terms); // figure out if we have matching posts, and which ones they are $this->get_matching_posts(); if(is_array($this->the_matching_posts)) $query = "SELECT * FROM $wpdb->posts WHERE 1=1 AND ID IN (" . implode($this->the_matching_posts, ', ') . ') AND post_status IN ("publish", "private")'; else $query = "SELECT * FROM $wpdb->posts WHERE 1=2"; //print_r($wp_query); //echo "

$query

"; $this->the_query_string = $query; return($query); } public function the_scope() { echo ''; } public function editsearch() { global $wpdb, $wp_query, $bsuite; $search_terms = $this->search_terms; unset($search_terms['scope']); if(!empty($search_terms)){ echo ''; } } public function parse_content(){ global $post, $bsuite; if ( !$ret = wp_cache_get( (int) $post->ID, 'scrib_parsedcontent' )) { $xml = $bsuite->makeXMLTree($post->post_content); foreach( $xml['ul'][0]['li'] as $val ){ switch ($val['class']) { case 'attribution': $ret['attribution'] = $val['cdata']; break; case 'isbn': $ret['isbn'] = $val['ul'][0]['li']; if( !isset( $ret['gbs_id'] )) $ret['gbs_id'] = 'ISBN:'.$val['ul'][0]['li'][0]; break; case 'lccn': $ret['lccn'] = $val['ul'][0]['li']; if( !isset( $ret['gbs_id'] )) $ret['gbs_id'] = 'LCCN:'.$val['ul'][0]['li'][0]; break; } } wp_cache_add( (int) $post->ID, $ret, 'scrib_parsedcontent' , 864000 ); } return($ret); // if the cache is still warm, then we return this } public function the_content_filter($content){ if(!$this->is_scrib()) return($content); $content = str_replace(array('ScribCatBase/subj/', 'ScribCatBase/auth/', 'ScribCatBase/subject/', 'ScribCatBase/author/'), array($this->options['browse_url'] .'?subj=', $this->options['browse_url'] .'?auth=', $this->options['browse_url'] .'?subject=', $this->options['browse_url'] .'?author='), $content); return($content); } public function the_author_filter($content){ if(!$this->is_scrib()) return($content); $author = $this->parse_content(); if( isset( $author['attribution'][0])) return( $author['attribution'][0] ); return( $content ); } public function author_link_filter($content){ if(!$this->is_scrib()) return($content); return($content); } public function wp_footer_js(){ $this->suggest_js(); $this->gbs_link(); } public function gbs_aggregator($content){ if(!$this->is_scrib()) return($content); /* old way, but hurts performance $gbs_id = $this->parse_content(); $this->gbs_ids[] = $gbs_id['gbs_id']; */ $this->gbs_ids[] = $this->gbs_id(); return($content); } public function gbs_link(){ if( count( $this->gbs_ids )) echo ''; } public function gbs_id(){ $isbn = $this->get_the_tags(); if( $isbn = array_shift( $isbn['isbn'] )) return('ISBN:'. $isbn->name); else return( FALSE ); } public function the_gbs_id(){ $gbs_id = $this->gbs_id(); if( $gbs_id ) return( str_replace( array(':', ' '), '_', $gbs_id )); return( FALSE ); } // // 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['linkto'] = array(&$this, 'token_linkto'); $tokens['scrib_hit_count'] = array(&$this, 'token_hit_count'); 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_linkto($thing) { if( $post_id = reset( get_objects_in_term( is_term( $thing ), 'sourceid' ))){ return( ''. $this->the_image('small', $post_id) .'' ); } } 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 suggest_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->suggest_table'")) $wpdb->get_results("DROP TABLE $this->suggest_table"); // create the table require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta(" CREATE TABLE $this->suggest_table ( term_id bigint(20) NOT NULL default '0', term_name varchar(55) NOT NULL default '', term_rank bigint(20) NOT NULL default '0', PRIMARY KEY (term_id), KEY term_name (term_name(3)) ) ENGINE=MyISAM $charset_collate "); } else { $n = (int) $_GET[ 'n' ] ; } // get the terms $in_taxonomies = "'" . implode("', '", $this->taxonomies_for_suggest) . "'"; $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 search suggest table. Please be patient.', 'Scrib') . " Working $interval terms, starting with $n .

"; // insert the terms foreach($terms as $term){ $term->rank = (56 - strlen($term->name)) * $term->count; if(is_term($term->name, 'hint')) $term->rank = $term->rank * 10; // could also add ranking based on usage (clicks/checkouts/comment counts) of the related items $term->name = ereg_replace('[^a-z|0-9| ]', '', str_replace(array('-','_'), ' ', strtolower(remove_accents($term->name)))); $values[] = "($term->term_id, '$term->name', $term->rank)"; } $wpdb->get_results("INSERT DELAYED INTO $this->suggest_table (term_id, term_name, term_rank) VALUES ". implode($values, ",\n") ." ;"); ?>

'. __('Scriblio search suggest table rebuilt.', 'bsuite') .'

'; ?> autoscoped ) unset($input['scope']); $tags = FALSE; reset($input); while (list($key, $val) = each($input)) { $tags[$key] = implode('|', $val); } if (!empty($tags['s'])) { $keywords = $tags['s']; unset($tags['s']); $taglink = $this->options['search_url'] . urlencode($keywords) .'?'. http_build_query($tags); }else{ $taglink = $this->options['browse_url'] .'?'. http_build_query($tags); } return trim($taglink, '?'); } public function get_tag_link( $tag ) { global $wp_rewrite; $taglink = $this->options['browse_url'] . '?' . $tag->taxonomy . '=' . $tag->slug; // return apply_filters('tag_link', $taglink, $tag_id); return $taglink; } public function the_tags_for_bsuite_suggestive( $tags, $post_id ) { $post_id = (int) $post_id; if ( !$post_id ) return($tags); if($terms = wp_get_object_terms($post_id, $this->taxonomies_for_related)){ foreach ( $terms as $term ){ $tags[] = $term->name; } return($tags); }else{ return($tags); } } public function get_the_tags( $id = 0 ) { global $post, $wp_taxonomies; $id = (int) $id; if ( !$id ) $id = (int) $post->ID; $terms = wp_get_object_terms( $id, array_intersect( array_keys( $wp_taxonomies ), $this->taxonomies )); foreach ( $terms as $term ) $tags[$term->taxonomy][$term->term_id] = $term; // $tags = apply_filters( 'get_the_tags', $tags ); if ( empty( $tags ) ) return false; return $tags; } public function get_the_tag_list( $facets = FALSE, $before = '', $sep = '', $after = '' ) { $tags = $this->get_the_tags(); if ( empty( $tags ) ) return false; if ( $facets === FALSE ) $facets = $this->taxonomies; if ( !is_array($facets) ) $facets = explode(',', $facets); $tag_list = $before; foreach ( $tags as $taxonomy ){ foreach ( $taxonomy as $tag ){ if(in_array($tag->taxonomy, $facets)) $tag_links[] = ''; } } if(empty($tag_links)) return(FALSE); $tag_links = join( $sep, $tag_links ); // $tag_links = apply_filters( 'the_tags', $tag_links ); $tag_list .= $tag_links; $tag_list .= $after; return $tag_list; } public function the_tags( $facets = FALSE, $before = 'Tags: ', $sep = ', ', $after = '' ) { echo $this->get_the_tag_list($facets, $before, $sep, $after); } public function tag_cloud( $args = '' ) { $defaults = array( 'smallest' => 8, 'largest' => 33, 'unit' => 'pt', 'number' => 45, 'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC', 'exclude' => '', 'include' => '' ); $args = wp_parse_args( $args, $defaults ); if ( empty($this->the_matching_facets) ) return; $return = $this->generate_tag_cloud( $this->the_matching_facets, $args ); // Here's where those top tags get sorted according to $args //echo apply_filters( 'wp_tag_cloud', $return, $args ); return $return; } public function &generate_tag_cloud( $tags, $args = '' ) { global $wp_rewrite; $defaults = array( 'smallest' => 8, 'largest' => 22, 'unit' => 'pt', 'number' => 45, 'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC', 'facets' => $this->taxonomies ); $args = wp_parse_args( $args, $defaults ); extract($args); if(!is_array($facets)) $facets = explode(',', $facets); if ( !$tags ) return; $counts = $tag_links = $selected = array(); foreach ( (array) $tags as $tag ) { if(!in_array($tag->taxonomy, $facets)) continue; $counts[$tag->name] = $tag->count; if(in_array($tag->name, $this->search_terms[$tag->taxonomy])){ $selected[$tag->name] = ' selected'; $tag_links[$tag->name] = $this->get_search_link( $this->search_terms ); }else{ $selected[$tag->name] = ''; $tag_links[$tag->name] = $this->get_search_link( array_merge_recursive($this->search_terms, array($tag->taxonomy => array($tag->name))) ); } $tag_ids[$tag->name] = $tag->term_id; } if ( !$counts ) return; asort($counts); if($number > 0) $counts = array_slice($counts, -$number, $number, TRUE); $min_count = min($counts); $spread = max($counts) - $min_count; if ( $spread <= 0 ) $spread = 1; $font_spread = $largest - $smallest; if ( $font_spread <= 0 ) $font_spread = 1; $font_step = $font_spread / $spread; // SQL cannot save you; this is a second (potentially different) sort on a subset of data. if ( 'name' == $orderby ) uksort($counts, 'strnatcasecmp'); else asort($counts); if ( 'DESC' == $order ) $counts = array_reverse( $counts, true ); $a = array(); $rel = ( is_object($wp_rewrite) && $wp_rewrite->using_permalinks() ) ? ' rel="tag"' : ''; foreach ( $counts as $tag => $count ) { $tag_id = $tag_ids[$tag]; $tag_link = clean_url($tag_links[$tag]); $tag_link = $tag_links[$tag]; // $tag = str_replace(' ', ' ', wp_specialchars( $tag )); $tag = wp_specialchars( $tag ); $a[] = "$tag" ; } switch ( $format ) : case 'array' : $return =& $a; break; case 'list' : $return = "\n"; break; default : $return = join("\n", $a); break; endswitch; return $return; // return apply_filters( 'wp_generate_tag_cloud', $return, $tags, $args ); } public function is_scrib(){ global $post; if($post->post_author == $this->options['catalog_author_id']) return(TRUE); else return(FALSE); } public function spellcheck(){ // using Y! Spellcheck Service if(empty($this->search_terms['s'])) //short circuit if there's no keyword search return(FALSE); $cache_key = md5( implode( ' ', $this->search_terms['s'] ) ); $cache = wp_cache_get( $cache_key , 'scrib_spellcheck' ); if( is_array( $cache['ResultSet'] ) && empty( $cache['ResultSet']['Result'] )) return( FALSE ); if( !$cache ){ // The POST URL and parameters $request = 'http://search.yahooapis.com/WebSearchService/V1/spellingSuggestion'; $postargs = http_build_query(array( 'appid' => 'ArwZj6XV34Gifv47B08dHuxjnSHlaEIdGNdM50aIUemwvo_Nmj4_UpqqlTCqHzdngqws', 'output' => 'php', 'query' => implode( ' ', $this->search_terms['s'] ) )); // Get the curl session object $session = curl_init($request); // Set the POST options. curl_setopt($session, CURLOPT_POST, true); curl_setopt($session, CURLOPT_POSTFIELDS, $postargs); curl_setopt($session, CURLOPT_HEADER, FALSE); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); // Do the POST and then close the session $cache = array(); $cache = unserialize( curl_exec( $session )); curl_close( $session ); wp_cache_add( $cache_key , $cache, 'scrib_spellcheck' ); } if( !isset( $cache['ResultSet']['Result'] )) return( FALSE ); return( ''. $cache['ResultSet']['Result'] .'' ); } public function the_image($size = 'small', $post_id = NULL) { if( !$post_id ){ global $id; $post_id = $id; } if($size == 'large') $image = get_post_field( 'post_content', $post_id ); else $image = get_post_field( 'post_excerpt', $post_id ); preg_match('/\[\[bookjacket\|([^\]]*)\]\]/', $image, $matches); unset($image); $image = str_replace('ScribBase/', get_settings('siteurl') . '/', $matches[1]); // fallback if no image if(!$image) $image = ''; return(''. $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 link2me( $things, $post_id ){ $things[] = array('code' => $this->the_image( 'small', $post_id ), 'name' => 'Embed Small' ); $things[] = array('code' => $this->the_image( 'large', $post_id ), 'name' => 'Embed Large' ); return( $things ); } function the_related_bookjackets($before = '
  • ', $after = '
  • ') { global $post, $bsuite; $report = FALSE; $id = (int) $post->ID; if ( !$id ) return FALSE; $posts = array_slice($bsuite->bsuggestive_getposts($id), 0, 10); if($posts){ $report = ''; foreach($posts as $post_id){ $url = get_permalink($post_id); $linktext = trim( substr( strip_tags(get_the_title($post_id)), 0, 45)); if( $linktext <> get_the_title($post_id) ) $linktext .= '...'; $report .= $before . $this->the_image('small', $post_id) . "

    $linktext

    ". $after; } } return($report); } public function textthis(){ global $post; /* get the SMS config */ require_once(ABSPATH . PLUGINDIR .'/'. plugin_basename(dirname(__FILE__)) .'/conf_sms.php'); /* prepare the SMS message */ $sms[] = $scribsms_content_pre . "\n"; $sms[] = strlen( $post->post_title ) > 30 ? trim( substr( $post->post_title, 0, 30 )) . '...' : trim( substr( $post->post_title, 0, 30 )); if( ( $sourceid = wp_get_object_terms( $post->ID, 'sourceid' )) && ( count( wp_get_object_terms( $post->ID, 'sourceid' )))); $sms[] = scrib_availability( $sourceid[0]->name ) . "\n"; $sms[] = get_permalink( $post->ID ) . "\n"; $sms = substr( implode( array_filter( array_map( 'trim', $sms )), "\n" ), 0, 450 ); /* create the replacement post content */ $content = '
    '; /* send the message if we have a destination phone number */ if( isset( $_POST['textthis_smsto'] ) && strlen( ereg_replace( '[^0-9]', '', $_POST['textthis_smsto'] )) == 11 ){ $mysms = new bSuite_sms( $scribsms_api_id, $scribsms_user, $scribsms_pass ); if( $mysms->send( $sms, ereg_replace( '[^0-9]', '', $_POST['textthis_smsto'] ))) $content .= '

    Success! Your message was sent to '. ereg_replace( '[^0-9]', '', $_REQUEST['textthis_smsto'] ) .'.

    '; else $content .= '

    Error: there was an error sending the message.

    '; //print_r( $mysms ); //echo $mysms->querymsg( $mysms->last_id ); }else if( isset( $_REQUEST['textthis_smsto'] )){ $content .= '

    Error: please enter a complete phone number.

    '; } /* create the form to input the destination number */ $content .= '

    Send information about this item as an SMS text message.

    Message Preview

    '. $sms .'

    Please Note

    Sending messages is free, but your mobile service provider may charge you to receive the messages. Please check your plan details before continuing.

    Unfortunately, you cannot reply to any SMS text messages you receive using this service.

    Messaging services are provided by Clickatell and are subject to their privacy policy.

    '; return( $content ); } function textthis_redirect(){ global $wp_query, $post_cache; if( !empty( $_REQUEST['textthis'] ) && !empty( $wp_query->query_vars['p'] )){ if( !$textthis = $this->textthis() ) return( FALSE ); if(!ereg('^'.__('Text This', 'Scrib'), $post_cache[1][$wp_query->query_vars['p']]->post_title)) $post_cache[1][$wp_query->query_vars['p']]->post_title = __('Text This', 'Scrib') .': '. $post_cache[1][$wp_query->query_vars['p']]->post_title; $post_cache[1][$wp_query->query_vars['p']]->post_content = $textthis; $post_cache[1][$wp_query->query_vars['p']]->comment_status = 'closed'; } } // end sharelinks related functions public function widget_editsearch($args) { if(!is_search()) return; global $wp_query; extract($args); $options = get_option('widget_scrib_searchedit'); $search_title = $options['search-title']; $search_text_top = apply_filters( 'widget_text', $options['search-text-top'] ); $search_text_bottom = apply_filters( 'widget_text', $options['search-text-bottom'] ); $browse_title = $options['browse-title']; $browse_text_top = apply_filters( 'widget_text', $options['browse-text-top'] ); $browse_text_bottom = apply_filters( 'widget_text', $options['browse-text-bottom'] ); $default_title = $options['default-title']; $default_text = apply_filters( 'widget_text', $options['default-text'] ); $search_terms = $this->search_terms; unset($search_terms['scope']); echo $before_widget; if( $this->is_browse && empty( $search_terms )) { if ( !empty( $default_title ) ) echo $before_title . $default_title . $after_title; if ( !empty( $default_text ) ) echo '
    ' . $default_text . '
    '; }else if( $this->is_browse ) { if ( !empty( $browse_title ) ) echo $before_title . $browse_title . $after_title; if ( !empty( $browse_text_top ) ) echo '
    ' . $browse_text_top . '
    '; $this->editsearch(); if ( !empty( $browse_text_bottom ) ) echo '
    ' . $browse_text_bottom . '
    '; }else{ if ( !empty( $search_title ) ) echo $before_title . $search_title . $after_title; if ( !empty( $search_text_top ) ) echo '
    ' . $search_text_top . '
    '; $this->editsearch(); if ( !empty( $search_text_bottom ) ) echo '
    ' . $search_text_bottom . '
    '; } echo $after_widget; } public function widget_editsearch_control() { $options = $newoptions = get_option('widget_scrib_searchedit'); if ( $_POST['widget_scrib_searchedit-submit'] ) { $newoptions['search-title'] = strip_tags(stripslashes($_POST['widget_scrib_searchedit-search-title'])); $newoptions['search-text-top'] = stripslashes($_POST["widget_scrib_searchedit-search-text-top"]); $newoptions['search-text-bottom'] = stripslashes($_POST["widget_scrib_searchedit-search-text-bottom"]); $newoptions['browse-title'] = strip_tags(stripslashes($_POST['widget_scrib_searchedit-browse-title'])); $newoptions['browse-text-top'] = stripslashes($_POST["widget_scrib_searchedit-browse-text-top"]); $newoptions['browse-text-bottom'] = stripslashes($_POST["widget_scrib_searchedit-browse-text-bottom"]); $newoptions['default-title'] = strip_tags(stripslashes($_POST['widget_scrib_searchedit-default-title'])); $newoptions['default-text'] = stripslashes($_POST["widget_scrib_searchedit-default-text"]); if ( !current_user_can('unfiltered_html') ){ $newoptions['search-text-top'] = stripslashes(wp_filter_post_kses($newoptions['search-text-top'])); $newoptions['search-text-bottom'] = stripslashes(wp_filter_post_kses($newoptions['search-text-bottom'])); $newoptions['browse-text-top'] = stripslashes(wp_filter_post_kses($newoptions['browse-text-top'])); $newoptions['browse-text-bottom'] = stripslashes(wp_filter_post_kses($newoptions['browse-text-bottom'])); $newoptions['default-text'] = stripslashes(wp_filter_post_kses($newoptions['default-text'])); } } if ( $options != $newoptions ) { $options = $newoptions; update_option('widget_scrib_searchedit', $options); } $search_title = attribute_escape( $options['search-title'] ); $search_text_top = format_to_edit($options['search-text-top']); $search_text_bottom = format_to_edit($options['search-text-bottom']); $browse_title = attribute_escape( $options['browse-title'] ); $browse_text_top = format_to_edit($options['browse-text-top']); $browse_text_bottom = format_to_edit($options['browse-text-bottom']); $default_title = attribute_escape( $options['default-title'] ); $default_text = format_to_edit($options['default-text']); ?>

    Search display:

    Browse display (no keywords):

    Default display (no terms):

    bsuggestive_to ) return; global $wp_query; extract($args); $options = get_option('widget_scrib_scope'); $title = $options['title']; $text_top = apply_filters( 'widget_text', $options['text-top'] ); $text_bottom = apply_filters( 'widget_text', $options['text-bottom'] ); $title_no_terms = $options['title-no-terms']; $text_no_terms = apply_filters( 'widget_text', $options['text-no-terms'] ); ?>
    the_scope(); ?>

  • '; $single_between = '
  • '; $single_after = '
  • '; $search_before = ''; $search_after = ''; $search_options = array( 'smallest' => .9998, 'largest' => .9999, 'unit' => 'em', 'number' => $options[$number]['count'], 'format' => 'list', 'orderby' => 'count', 'order' => 'DESC', 'facets' => $options[$number]['facets']); }else{ $single_before = '
    '; $single_between = ', '; $single_after = '
    '; $search_before = '
    '; $search_after = '
    '; $search_options = array( 'smallest' => 1, 'largest' => 3, 'unit' => 'em', 'number' => $options[$number]['count'], 'format' => 'flat', 'orderby' => 'name', 'order' => 'ASC', 'facets' => $options[$number]['facets']); } if(is_singular() && $options[$number]['show_singular'] && $facets = $this->get_the_tag_list($options[$number]['facets'], $single_before, $single_between, $single_after)){ // actually, it's all done here, just display it below }else if(is_search() && $options[$number]['show_search'] && $facets = $this->tag_cloud($search_options)){ $facets = $search_before . $facets . $search_after; }else{ return; } ?>

    " name="widget_scrib_facets-submit-" value="1" /> 29 ) $number = 29; if ( $number < 1 ) $number = 1; $newoptions['number'] = $number; } if ( $options != $newoptions ) { $options = $newoptions; update_option('widget_scrib_facets', $options); $this->widget_facets_register($options['number']); } } function widget_facets_page() { $options = $newoptions = get_option('widget_scrib_facets'); ?>

    29 ) $number = 29; $dims = array('width' => 460, 'height' => 350); $class = array('classname' => 'widget_scrib_facets'); for ($i = 1; $i <= 29; $i++) { $name = sprintf(__('Scrib Facets %d'), $i); $id = "widget_scrib_facets-$i"; // Never never never translate an id wp_register_sidebar_widget($id, $name, $i <= $number ? array(&$this, 'widget_facets') : /* unregister */ '', $class, $i); wp_register_widget_control($id, $name, $i <= $number ? array(&$this, 'widget_facets_control') : /* unregister */ '', $dims, $i); } add_action('sidebar_admin_setup', array(&$this, 'widget_facets_setup')); add_action('sidebar_admin_page', array(&$this, 'widget_facets_page')); } public function widgets_register(){ $class['classname'] = 'widget_scrib_searchedit'; wp_register_sidebar_widget('widget_scrib_searchedit', __('Scrib Search Editor'), array(&$this, 'widget_editsearch'), $class); wp_register_widget_control('widget_scrib_searchedit', __('Scrib Search Editor'), array(&$this, 'widget_editsearch_control'), 'width=460&height=600'); $class['classname'] = 'widget_scrib_scope'; wp_register_sidebar_widget('widget_scrib_scope', __('Scrib Scope Selector'), array(&$this, 'widget_scope'), $class); wp_register_widget_control('widget_scrib_scope', __('Scrib Scope Selector'), array(&$this, 'widget_scope_control'), 'width=460&height=100'); $this->widget_facets_register(); } } // now instantiate this object $scrib = & new Scrib; // some template functions... function is_browse() { global $scrib; return( $scrib->is_browse ); } function is_scrib( $post_id = '' ) { global $scrib; return( $scrib->is_scrib($post_id) ); } function scrib_the_related(){ global $scrib; echo $scrib->the_related_bookjackets(); } if(!function_exists('scrib_availability')){ function scrib_availability($sourceid){ global $scrib; return(''); // this function can be used to get the current availability of an item from the ILS, // though, because of the differences between ILS and their local configuration, // it is up to the local site to develop their own code. // // Example code can be found at http://about.scriblio.net/wiki/scrib_availability } } ?>