path_web = '/'. PLUGINDIR .'/'. plugin_basename( dirname( __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('parse_query', array(&$this, 'parse_query'), 10); add_action('admin_menu', array(&$this, 'addmenus')); add_filter('bsuite_tokens', array(&$this, 'tokens_set')); add_filter('bsuite_suggestive_taxonomies', array(&$this, 'the_taxonomies_for_bsuite_suggestive'), 10, 2); add_filter('bsuite_link2me', array(&$this, 'link2me'), 10, 2); add_action('widgets_init', array(&$this, 'widgets_register')); add_shortcode('scrib_bookjacket', array(&$this, 'shortcode_bookjacket')); add_shortcode('scrib_availability', array(&$this, 'shortcode_availability')); add_shortcode('scrib_taglink', array(&$this, 'shortcode_taglink')); 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, $wp_rewrite; $this->suggest_table = $wpdb->prefix . 'scrib_suggest'; $slash = $wp_rewrite->use_trailing_slashes ? '' : '/'; $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']) . $slash; $this->options['browse_base'] = str_replace( $this->options['site_url'] , '', $this->options['browse_url'] ); $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', '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_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 taxonomies_register() { // define the Scrib taxonomies global $wpdb, $wp, $wp_rewrite; // get the taxonomies from the config or punt and read them from the DB $taxonomies = get_option('scrib'); $taxonomies = array_keys($taxonomies['taxonomies']); // register those taxonomies foreach($taxonomies as $taxonomy){ register_taxonomy( $taxonomy, 'post', array('rewrite' => FALSE, 'query_var' => FALSE )); $taxonomy = sanitize_title_with_dashes( $taxonomy ); $wp->add_query_var( $taxonomy ); $wp_rewrite->add_rewrite_tag( "%$taxonomy%", '([^/]+)', "$taxonomy=" ); $wp_rewrite->add_permastruct( $taxonomy, "{$this->options['browse_base']}$taxonomy/%$taxonomy%", FALSE ); } return($taxonomies); } public function taxonomies_getall() { global $wpdb; return( $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; $cache_key = md5( serialize( $this->search_terms ) . $paged ); $cache = wp_cache_get( $cache_key , 'scrib_search' ); 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 ){ $from = $where = array(); $what = ' a.ID '; $orderby = 'ORDER BY a.post_date_gmt DESC'; $keyword_select = ''; $from[] = " FROM $wpdb->posts a "; $limit_sql = 'LIMIT '. ($paged - 1) * $posts_per_page .', 1000'; // 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; } } if( !count( $keyword_post_ids )){ wp_cache_add( $cache_key , array('count' => 0), 'scrib_search' ); $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); } unset($search_terms['s']); }else{ $what = " a.ID, MATCH (b.content, b.title) AGAINST ('". $wpdb->escape(implode($this->search_terms['s'], ' ')) ."'$boolean) AS score "; $from[] = " INNER JOIN $bsuite->search_table b ON ( b.post_id = a.ID ) "; $where[] = " AND (MATCH (b.content, b.title) AGAINST ('". $wpdb->escape(implode($this->search_terms['s'], ' ')) ."'$boolean)) "; $orderby = ' ORDER BY score DESC '; unset($search_terms['s']); } } // 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' ); $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 if( isset( $this->search_terms['s'] ) && $this->options['sphinxsearch'] ){ $keyword_select = 'AND a.ID IN ('. implode($keyword_post_ids, ',') .')' ; $limit_sql = ''; $orderby = ''; } $post_ids = $wpdb->get_col('SELECT SQL_CALC_FOUND_ROWS '. $what . implode($from) .' WHERE 1=1 '. implode($where) .' '. $keyword_select .' AND (a.post_type IN ("post", "page") AND (a.post_status IN ("publish", "private"))) GROUP BY a.ID '. $orderby .' '. $limit_sql); if( count( $post_ids )){ if( isset( $this->search_terms['s'] ) && $this->options['sphinxsearch'] ){ $cache['ordinals'] = array_flip( $keyword_post_ids ); foreach($post_ids as $post_id) $new_order[$cache['ordinals'][$post_id]] = $post_id; ksort( $new_order ); $post_ids = array_values( $new_order ); } $cache['count'] = $wpdb->get_var( 'SELECT FOUND_ROWS()' ); $post_ids = array_slice( $post_ids, 0, $posts_per_page ); $cache['facets'] = $wpdb->get_results("SELECT b.term_id, b.name, a.taxonomy, COUNT(c.term_taxonomy_id) AS `count` FROM ( SELECT ". $what . implode($from) .' WHERE 1=1 '. implode($where) .' '. $keyword_select .' AND (a.post_type IN ("post", "page") AND (a.post_status IN ("publish", "private"))) GROUP BY a.ID '. $orderby .' '. $limit_sql . ") p INNER JOIN $wpdb->term_relationships c ON p.ID = c.object_id INNER JOIN $wpdb->term_taxonomy a ON a.term_taxonomy_id = c.term_taxonomy_id INNER JOIN $wpdb->terms b ON a.term_id = b.term_id 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' ); } 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_intersect_key($wp_query->query_vars, array_flip($this->taxonomies)); $terms = FALSE; if( count( $temp )){ $terms = array(); reset($temp); while (list($key, $val) = each($temp)) { $values = (explode('|', urldecode($val))); foreach($values as $val){ $terms[$key][] = $val; } } $this->is_browse = TRUE; $wp_query->is_search = TRUE; $wp_query->is_singular = FALSE; $wp_query->is_page = FALSE; $wp_query->is_home = FALSE; } if(!empty($wp_query->query_vars['s'])) $terms['s'] = 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); 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); // establish the query vars $this->search_terms(); if( !$wp_query->is_search ) // return immediately if this is not a search/browse request return($query); //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 parse_query( $the_wp_query ){ global $wp_query; $test_query = $the_wp_query->query; if( is_array( $test_query )){ $paged = (int) $test_query['paged'] ? (int) $test_query['paged'] : 1; unset( $test_query['paged'] ); } if( $test_query['pagename'] && count( $test_query ) == 1 && $test_query['pagename'] == $this->options['browse_name'] && !$this->parse_query_nonce){ $this->parse_query_nonce = TRUE; return( query_posts( array('category' => get_cat_name( $this->options['catalog_category_id'] ) , 'paged' => $paged ))); } return( $the_wp_query ); } public function editsearch() { global $wpdb, $wp_query, $bsuite; $search_terms = $this->search_terms; 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_author_filter( $content ){ if(!$this->is_scrib()) return($content); global $id; return( get_post_meta( $id, 'scrib_the_author', TRUE )); } public function author_link_filter( $content ){ if(!$this->is_scrib()) return($content); global $id; $tag->taxonomy = 'auth'; $tag->slug = urlencode( get_post_meta( $id, 'scrib_the_author_link', TRUE )); return( $this->get_tag_link( $tag )); } 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(){ global $id; return( array_shift( unserialize( get_post_meta( $id, 'scrib_the_bibkeys', TRUE )))); } public function the_gbs_id(){ $gbs_id = $this->gbs_id(); if( $gbs_id ) return( str_replace( array(':', ' '), '_', $gbs_id )); return( FALSE ); } public function shortcode_bookjacket( $arg, $content = '' ){ // [scrib_bookjacket][/scrib_bookjacket] global $id; if( !is_singular() ){ return(''. $content .''); }else{ preg_match( '/src="([^"]+)?"/', $content, $matches ); return( ''. $this->the_image( 'small', $id, FALSE ) .''); } } public function shortcode_availability( $arg ){ // [scrib_availability sourceid="ll1292675"] $arg = shortcode_atts( array( 'sourceid' => FALSE ), $arg ); if( function_exists( 'scrib_availability' ) ) return( scrib_availability( $arg['sourceid'] )); else return( '' ); } public function shortcode_taglink( $arg ){ // [scrib_taglink taxonomy="subj" value="stuff and things"] $arg = shortcode_atts( array( 'taxonomy' => FALSE, 'value' => FALSE ), $arg ); $tag->taxonomy = $arg['taxonomy']; $tag->slug = urlencode( $arg['value'] ); return( $this->get_tag_link( $tag )); } // // Scriblio specific tokens (requires bsuite) // public function tokens_set($tokens){ // setup some tokens $tokens['linkto'] = array(&$this, 'token_linkto'); $tokens['scrib_hit_count'] = array(&$this, 'token_hit_count'); return($tokens); } 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_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 = 1000; 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') .'

'; ?> 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_taxonomies_for_bsuite_suggestive( $taxonomies ) { if( $this->taxonomies_for_related ) return( $this->taxonomies_for_related ); else return( $taxonomies ); } 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, $linked = TRUE){ if( !$post_id ){ global $id; $post_id = $id; } if($size == 'large') $image_source = get_post_field( 'post_content', $post_id ); else $image_source = get_post_field( 'post_excerpt', $post_id ); preg_match( '/\[(scrib_bookjacket)\b(.*?)(?:(\/))?\](?:(.+?)\[\/\1\])?/', $image_source, $matches ); // fallback if no image if( !$matches[4] ) $matches[4] = ''; if( $linked ) return( ''. $matches[4] .'' ); else return( $matches[4] ); } 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; if( !empty( $_REQUEST['textthis'] ) && !empty( $wp_query->query_vars['p'] )){ if( !$textthis = $this->textthis() ) return( FALSE ); if(!ereg( '^'.__('Text This', 'Scrib'), $wp_query->post->post_title )) $wp_query->post->post_title = $wp_query->posts[0]->post_title = __('Text This', 'Scrib') .': '. $wp_query->post->post_title; $wp_query->post->post_content = $textthis; $wp_query->posts[0]->post_content = $textthis; $wp_query->post->comment_status = 'closed'; $wp_query->posts[0]->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; 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):

  • '; $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' => 2.15, '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'); $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 } } ?>