diff --git a/wp-content/plugins/solr-for-wordpress/Apache/Solr/Response.php b/wp-content/plugins/solr-for-wordpress/Apache/Solr/Response.php index 673c50ab1429174f5ba20bcf1efc10c3e65c4968..49d015892bf6d28ef1a09d18083e391beb681d3a 100644 --- a/wp-content/plugins/solr-for-wordpress/Apache/Solr/Response.php +++ b/wp-content/plugins/solr-for-wordpress/Apache/Solr/Response.php @@ -124,8 +124,13 @@ class Apache_Solr_Response //Look for the Content-Type response header and determine type //and encoding from it (if possible - such as 'Content-Type: text/plain; charset=UTF-8') + //Check for a chunked response and de-chunk it if necessary foreach ($httpHeaders as $header) { + if (strncasecmp($header, 'Transfer-Encoding: chunked', 26) == 0) { + $rawResponse = $this->http_chunked_decode($rawResponse); + } + if (strncasecmp($header, 'Content-Type:', 13) == 0) { //split content type value into two parts if possible @@ -158,6 +163,47 @@ class Apache_Solr_Response $this->_collapseSingleValueArrays = (bool) $collapseSingleValueArrays; } + /** + * dechunk an http 'transfer-encoding: chunked' message + * + * @param string $chunk the encoded message + * @return string the decoded message. If $chunk wasn't encoded properly it will be returned unmodified. + */ + protected function http_chunked_decode($chunk) { + $pos = 0; + $len = strlen($chunk); + $dechunk = null; + + while(($pos < $len) + && ($chunkLenHex = substr($chunk,$pos, ($newlineAt = strpos($chunk,"\n",$pos+1))-$pos))) + { + if (! $this->is_hex($chunkLenHex)) { + trigger_error('Value is not properly chunk encoded', E_USER_WARNING); + return $chunk; + } + + $pos = $newlineAt + 1; + $chunkLen = hexdec(rtrim($chunkLenHex,"\r\n")); + $dechunk .= substr($chunk, $pos, $chunkLen); + $pos = strpos($chunk, "\n", $pos + $chunkLen) + 1; + } + return $dechunk; + } + + /** + * determine if a string can represent a number in hexadecimal + * + * @param string $hex + * @return boolean true if the string is a hex, otherwise false + */ + protected function is_hex($hex) { + // regex is for weenies + $hex = strtolower(trim(ltrim($hex,"0"))); + if (empty($hex)) { $hex = 0; }; + $dec = hexdec($hex); + return ($hex == dechex($dec)); + } + /** * Get the HTTP status code * @@ -276,4 +322,4 @@ class Apache_Solr_Response $this->_parsedData = $data; } -} \ No newline at end of file +} diff --git a/wp-content/plugins/solr-for-wordpress/Apache/Solr/Service.php b/wp-content/plugins/solr-for-wordpress/Apache/Solr/Service.php index f68b2ebeb08d6a378424c623abd14a368f700d10..2ec22d991454d1cfecd6a7886cff36d49ac8075f 100644 --- a/wp-content/plugins/solr-for-wordpress/Apache/Solr/Service.php +++ b/wp-content/plugins/solr-for-wordpress/Apache/Solr/Service.php @@ -737,6 +737,7 @@ class Apache_Solr_Service foreach ($document as $key => $value) { $key = htmlspecialchars($key, ENT_QUOTES, 'UTF-8'); + $key = preg_replace('/\pC/u', '', $key); // remove unicode Control chars. $fieldBoost = $document->getFieldBoost($key); if (is_array($value)) @@ -754,7 +755,8 @@ class Apache_Solr_Service } $multivalue = htmlspecialchars($multivalue, ENT_NOQUOTES, 'UTF-8'); - + $multivalue = preg_replace('/\pC/u', '', $multivalue); // remove unicode Control chars. + $xml .= '>' . $multivalue . '</field>'; } } @@ -768,6 +770,7 @@ class Apache_Solr_Service } $value = htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8'); + $value = preg_replace('/\pC/u', '', $value); // remove unicode Control chars. $xml .= '>' . $value . '</field>'; } @@ -894,6 +897,8 @@ class Apache_Solr_Service */ public function search($query, $offset = 0, $limit = 10, $params = array()) { + $searchurl = $this->_searchUrl; + if (!is_array($params)) { $params = array(); @@ -903,6 +908,11 @@ class Apache_Solr_Service // sending the version is important in case the format changes $params['version'] = self::SOLR_VERSION; + if ($params['qt'] && substr($params['qt'], 0, 1) === "/") { + $searchurl = $this->_constructUrl(substr($params['qt'], 1)); + unset($params['qt']); + } + // common parameters in this interface $params['wt'] = self::SOLR_WRITER; $params['json.nl'] = $this->_namedListTreatment; @@ -921,6 +931,6 @@ class Apache_Solr_Service // anywhere else the regex isn't expecting it $queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', $queryString); - return $this->_sendRawGet($this->_searchUrl . $this->_queryDelimiter . $queryString); + return $this->_sendRawGet($searchurl . $this->_queryDelimiter . $queryString); } } \ No newline at end of file diff --git a/wp-content/plugins/solr-for-wordpress/readme.txt b/wp-content/plugins/solr-for-wordpress/readme.txt index 7fcbe680cde611c8a0ea7818fc41f22137e65d2e..88e7c009a57588a7d07e374708dd0be62ee7f5f8 100644 --- a/wp-content/plugins/solr-for-wordpress/readme.txt +++ b/wp-content/plugins/solr-for-wordpress/readme.txt @@ -1,12 +1,12 @@ === Solr for WordPress === Contributors: mattweber Author URI: http://www.mattweber.org -Plugin URI: https://launchpad.net/solr4wordpress +Plugin URI: https://github.com/mattweber/solr-for-wordpress Donate link: http://www.mattweber.org Tags: solr, search, search results, search integration, custom search -Requires at least: 2.7.0 -Tested up to: 2.7.1 -Stable tag: 0.2.0 +Requires at least: 3.0 +Tested up to: 3.2.1 +Stable tag: 0.4.1 A WordPress plugin that replaces the default WordPress search with Solr. @@ -16,6 +16,8 @@ A WordPress plugin that replaces the default WordPress search with Solr. Featur * Index pages and posts * Enable faceting on fields such as tags, categories, author, and page type. +* Indexing and faceting on custom fields +* Multisite support * Treat the category facet as a taxonomy * Add special template tags so you can create your own custom result pages to match your theme. * Completely replaces default WordPress search, just install and configure. @@ -44,16 +46,25 @@ A WordPress plugin that replaces the default WordPress search with Solr. Featur = What version of WordPress does Solr for WordPress work with? = -Solr for WordPress works with WordPress 2.7.0 and greater. +Solr for WordPress works with WordPress 3.0 and greater. = What version of Solr is required. = -Solr 1.3 or greater. +Solr 1.4 or greater. -= Can I enabledis/disable specific facets. = += Can I enable/disable specific facets. = Yes, from the settings page. Uncheck the "Facet on FIELD" option, for the FIELD you don't want a facet for. += Do I need to run my own Solr server to use this plugin? = + +No, there are Solr hosting providers that will setup and manager Solr for you. As long as they allow custom schema's and support the +standard Solr http api, then the plugin should work. Some sites: + +http://www.mysolrserver.com/ +http://www.websolr.com/ +http://powcloud.com/ + = What is a taxonomy = A taxonomy is a hierarchal facet. This means that your subcategories will be treated as a child to the parent category instead of an individual facet. @@ -115,3 +126,7 @@ Login to the WordPress admin, select pages, click the page you want to exclude. 1. Configuration Page 2. Example of results page in default WordPress Theme + +== Credits == + +Dominique Bejean for custom field support. diff --git a/wp-content/plugins/solr-for-wordpress/schema.xml b/wp-content/plugins/solr-for-wordpress/schema.xml index 7137c5615576daddfb12e34aac80d07eb687f06c..037742872bf3fdfae364803a37addbd2b128f51e 100644 --- a/wp-content/plugins/solr-for-wordpress/schema.xml +++ b/wp-content/plugins/solr-for-wordpress/schema.xml @@ -29,8 +29,7 @@ <fieldType name="text" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> - <tokenizer class="solr.HTMLStripWhitespaceTokenizerFactory"/> - <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true"/> + <tokenizer class="solr.WhitespaceTokenizerFactory"/> <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/> <filter class="solr.LowerCaseFilterFactory"/> <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> @@ -39,7 +38,6 @@ <analyzer type="query"> <tokenizer class="solr.WhitespaceTokenizerFactory"/> <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> - <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true"/> <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/> <filter class="solr.LowerCaseFilterFactory"/> <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt"/> @@ -82,10 +80,17 @@ <fields> <field name="id" type="string" indexed="true" stored="true" required="true" /> + + <field name="blogid" type="string" indexed="true" stored="true"/> + <field name="blogdomain" type="string" indexed="true" stored="true"/> + <field name="blogpath" type="string" indexed="true" stored="true"/> + <field name="wp" type="string" indexed="true" stored="true"/> + <field name="permalink" type="string" indexed="true" stored="true"/> <field name="title" type="text_lws" indexed="true" stored="true"/> <field name="content" type="text" indexed="true" stored="true"/> <field name="numcomments" type="integer" indexed="true" stored="true"/> + <field name="comments" type="text" indexed="true" stored="true" multiValued="true"/> <field name="categories" type="string" indexed="true" stored="true" multiValued="true"/> <field name="categoriessrch" type="text_lws" indexed="true" stored="false" multiValued="true"/> @@ -96,10 +101,25 @@ <field name="author" type="string" indexed="true" stored="true"/> <field name="type" type="string" indexed="true" stored="true"/> + <!-- Date fields used for sorting and searching --> + <field name="date" type="date" indexed="true" stored="false"/> + <field name="modified" type="date" indexed="true" stored="false"/> + + <!-- Fields used to display the date --> + <field name="displaydate" type="string" indexed="false" stored="true"/> + <field name="displaymodified" type="string" indexed="false" stored="true"/> + + <!-- For spell checking, did you mean? --> + <field name="spell" type="textSpell" indexed="true" stored="true" multiValued="true"/> + <!-- composite field --> <field name="text" type="text" indexed="true" stored="false" multiValued="true"/> <!-- dynamic fields --> + <dynamicField name="*_str" type="string" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_srch" type="text_lws" indexed="true" stored="false" multiValued="true"/> + <dynamicField name="*_taxonomy" type="string" indexed="true" stored="true" multiValued="true"/> + <dynamicField name="*_i" type="sint" indexed="true" stored="true"/> <dynamicField name="*_s" type="string" indexed="true" stored="true"/> <dynamicField name="*_l" type="slong" indexed="true" stored="true"/> @@ -120,5 +140,7 @@ <copyField source="content" dest="text"/> <copyField source="tags" dest="tagssrch"/> <copyField source="categories" dest="categoriessrch"/> - + <copyField source="title" dest="spell"/> + <copyField source="content" dest="spell"/> + <copyField source="author" dest="spell"/> </schema> diff --git a/wp-content/plugins/solr-for-wordpress/solr-for-wordpress.php b/wp-content/plugins/solr-for-wordpress/solr-for-wordpress.php index c2f287c435e8bbefd9370e46e24f81f332aa8bb6..acbd3b95876a783f87808566734d2f47729ece36 100644 --- a/wp-content/plugins/solr-for-wordpress/solr-for-wordpress.php +++ b/wp-content/plugins/solr-for-wordpress/solr-for-wordpress.php @@ -1,15 +1,15 @@ <?php /* Plugin Name: Solr for WordPress -Plugin URI: https://launchpad.net/solr4wordpress +Plugin URI: http://wordpress.org/extend/plugins/solr-for-wordpress/ Donate link: http://www.mattweber.org Description: Indexes, removes, and updates documents in the Solr search engine. -Version: 0.2.0 +Version: 0.4.1 Author: Matt Weber Author URI: http://www.mattweber.org */ /* - Copyright (c) 2009 Matt Weber + Copyright (c) 2011 Matt Weber Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -31,20 +31,47 @@ Author URI: http://www.mattweber.org */ global $wp_version, $version; -$version = '0.2.0'; -$errmsg = __('Solr for WordPress requires WordPress 2.7 or greater. ', 'solr4wp'); -if (version_compare($wp_version, '2.7', '<')) { +$version = '0.4.1'; + +$errmsg = __('Solr for WordPress requires WordPress 3.0 or greater. ', 'solr4wp'); +if (version_compare($wp_version, '3.0', '<')) { exit ($errmsg); } require_once(dirname(__FILE__) . '/Apache/Solr/Service.php'); -function s4w_get_solr($ping = false) { +function s4w_get_option($option) { + $indexall = FALSE; + if (is_multisite()) { + $indexall = get_site_option('s4w_index_all_sites'); + } + + if ($indexall) { + return get_site_option($option); + } else { + return get_option($option); + } +} + +function s4w_update_option($option, $optval) { + $indexall = FALSE; + if (is_multisite()) { + $indexall = get_site_option('s4w_index_all_sites'); + } + + if ($indexall) { + update_site_option($option, $optval); + } else { + update_option($option, $optval); + } +} + +function s4w_get_solr($ping = FALSE) { # get the connection options - $host = get_option('s4w_solr_host'); - $port = get_option('s4w_solr_port'); - $path = get_option('s4w_solr_path'); + $host = s4w_get_option('s4w_solr_host'); + $port = s4w_get_option('s4w_solr_port'); + $path = s4w_get_option('s4w_solr_path'); # double check everything has been set if ( ! ($host and $port and $path) ) { @@ -64,46 +91,109 @@ function s4w_get_solr($ping = false) { return $solr; } -function s4w_build_document( $post_info ) { +function s4w_build_document( $post_info, $domain = NULL, $path = NULL) { + global $current_site, $current_blog; $doc = NULL; - $exclude_ids = get_option('s4w_exclude_pages'); - $categoy_as_taxonomy = get_option('s4w_cat_as_taxo'); + $exclude_ids = s4w_get_option('s4w_exclude_pages'); + $categoy_as_taxonomy = s4w_get_option('s4w_cat_as_taxo'); + $index_comments = s4w_get_option('s4w_index_comments'); + $index_custom_fields = s4w_get_option('s4w_index_custom_fields'); if ($post_info) { # check if we need to exclude this document - if ( in_array($post_info->ID, $exclude_ids) ) { + if (is_multisite() && in_array($current_blog->domain . $current_blog->path . $post_info->ID, $exclude_ids)) { + return NULL; + } else if ( !is_multisite() && in_array($post_info->ID, $exclude_ids) ) { return NULL; } $doc = new Apache_Solr_Document(); $auth_info = get_userdata( $post_info->post_author ); - $doc->setField( 'id', $post_info->ID ); - $doc->setField( 'permalink', get_permalink( $post_info->ID ) ); + # wpmu specific info + if (is_multisite()) { + + if ($domain == NULL) + $domain = $current_blog->domain; + + if ($path == NULL) + $path = $current_blog->path; + + $blogid = get_blog_id_from_url($domain, $path); + $doc->setField( 'id', $domain . $path . $post_info->ID ); + $doc->setField( 'permalink', get_blog_permalink($blogid, $post_info->ID)); + $doc->setField( 'blogid', $blogid ); + $doc->setField( 'blogdomain', $domain ); + $doc->setField( 'blogpath', $path ); + $doc->setField( 'wp', 'multisite'); + } else { + $doc->setField( 'id', $post_info->ID ); + $doc->setField( 'permalink', get_permalink( $post_info->ID ) ); + $doc->setField( 'wp', 'wp'); + } + + $numcomments = 0; + if ($index_comments) { + $comments = get_comments("status=approve&post_id={$post_info->ID}"); + foreach ($comments as $comment) { + $doc->addField( 'comments', $comment->comment_content ); + $numcomments += 1; + } + } + $doc->setField( 'title', $post_info->post_title ); $doc->setField( 'content', strip_tags($post_info->post_content) ); - $doc->setField( 'numcomments', $post_info->comment_count ); + $doc->setField( 'numcomments', $numcomments ); $doc->setField( 'author', $auth_info->display_name ); + $doc->setField( 'author_s', get_author_posts_url($auth_info->ID, $auth_info->user_nicename)); $doc->setField( 'type', $post_info->post_type ); + $doc->setField( 'date', s4w_format_date($post_info->post_date_gmt) ); + $doc->setField( 'modified', s4w_format_date($post_info->post_modified_gmt) ); + $doc->setField( 'displaydate', $post_info->post_date ); + $doc->setField( 'displaymodified', $post_info->post_modified ); $categories = get_the_category($post_info->ID); if ( ! $categories == NULL ) { foreach( $categories as $category ) { if ($categoy_as_taxonomy) { - $doc->addField('categories', get_category_parents($category->cat_ID, false, '^^')); + $doc->addField('categories', get_category_parents($category->cat_ID, FALSE, '^^')); } else { $doc->addField('categories', $category->cat_name); } } } + //get all the taxonomy names used by wp + $taxonomies = (array)get_taxonomies(array('_builtin'=>FALSE),'names'); + foreach($taxonomies as $parent) { + $terms = get_the_terms( $post_info->ID, $parent ); + if ((array) $terms === $terms) { + //we are creating *_taxonomy as dynamic fields using our schema + //so lets set up all our taxonomies in that format + $parent = $parent."_taxonomy"; + foreach ($terms as $term) { + $doc->addField($parent, $term->name); + } + } + } + $tags = get_the_tags($post_info->ID); if ( ! $tags == NULL ) { foreach( $tags as $tag ) { $doc->addField('tags', $tag->name); } } + + if (count($index_custom_fields)>0 && count($custom_fields = get_post_custom($post_info->ID))) { + foreach ( $index_custom_fields as $field_name ) { + $field = $custom_fields[$field_name]; + foreach ( $field as $key => $value ) { + $doc->addField($field_name . '_str', $value); + $doc->addField($field_name . '_srch', $value); + } + } + } } else { _e('Post Information is NULL', 'solr4wp'); } @@ -111,12 +201,39 @@ function s4w_build_document( $post_info ) { return $doc; } -function s4w_post( $documents ) { +function s4w_format_date( $thedate ) { + $datere = '/(\d{4}-\d{2}-\d{2})\s(\d{2}:\d{2}:\d{2})/'; + $replstr = '${1}T${2}Z'; + return preg_replace($datere, $replstr, $thedate); +} + +function s4w_post( $documents, $commit = TRUE, $optimize = FALSE) { try { $solr = s4w_get_solr(); if ( ! $solr == NULL ) { - $solr->addDocuments( $documents ); - $solr->commit(); + + if ($documents) { + $solr->addDocuments( $documents ); + } + + if ($commit) { + $solr->commit(); + } + + if ($optimize) { + $solr->optimize(); + } + } + } catch ( Exception $e ) { + echo $e->getMessage(); + } +} + +function s4w_optimize() { + try { + $solr = s4w_get_solr(); + if ( ! $solr == NULL ) { + $solr->optimize(); } } catch ( Exception $e ) { echo $e->getMessage(); @@ -147,12 +264,58 @@ function s4w_delete_all() { } } +function s4w_delete_blog($blogid) { + try { + $solr = s4w_get_solr(); + if ( ! $solr == NULL ) { + $solr->deleteByQuery( "blogid:{$blogid}" ); + $solr->commit(); + } + } catch ( Exception $e ) { + echo $e->getMessage(); + } +} + +function s4w_load_blog_all($blogid) { + global $wpdb; + $documents = array(); + $cnt = 0; + $batchsize = 10; + + $bloginfo = get_blog_details($blogid, FALSE); + + if ($bloginfo->public && !$bloginfo->archived && !$bloginfo->spam && !$bloginfo->deleted) { + $postids = $wpdb->get_results("SELECT ID FROM {$wpdb->base_prefix}{$blogid}_posts WHERE post_status = 'publish';"); + for ($idx = 0; $idx < count($postids); $idx++) { + $postid = $ids[$idx]; + $documents[] = s4w_build_document( get_blog_post($blogid, $postid->ID), $bloginfo->domain, $bloginfo->path ); + $cnt++; + if ($cnt == $batchsize) { + s4w_post($documents); + $cnt = 0; + $documents = array(); + } + } + + if ($documents) { + s4w_post($documents); + } + } +} + function s4w_handle_modified( $post_id ) { + global $current_blog; $post_info = get_post( $post_id ); - $index_pages = get_option('s4w_index_pages'); - $index_posts = get_option('s4w_index_posts'); + $index_pages = s4w_get_option('s4w_index_pages'); + $index_posts = s4w_get_option('s4w_index_posts'); if (($index_pages && $post_info->post_type == 'page') || ($index_posts && $post_info->post_type == 'post')) { + + # make sure this blog is not private or a spam if indexing on a multisite install + if (is_multisite() && ($current_blog->public != 1 || $current_blog->spam == 1 || $current_blog->archived == 1)) { + return; + } + $docs = array(); $doc = s4w_build_document( $post_info ); if ( $doc ) { @@ -163,57 +326,260 @@ function s4w_handle_modified( $post_id ) { } function s4w_handle_status_change( $post_id ) { + global $current_blog; $post_info = get_post( $post_id ); - $private_page = get_option('s4w_private_page'); - $private_post = get_option('s4w_private_post'); + $private_page = s4w_get_option('s4w_private_page'); + $private_post = s4w_get_option('s4w_private_post'); if ( ($private_page && $post_info->post_type == 'page') || ($private_post && $post_info->post_type == 'post') ) { if ( ($_POST['prev_status'] == 'publish' || $_POST['original_post_status'] == 'publish') && ($post_info->post_status == 'draft' || $post_info->post_status == 'private') ) { - s4w_delete( $post_info->ID ); + if (is_multisite()) { + s4w_delete( $current_blog->domain . $current_blog->path . $post_info->ID ); + } else { + s4w_delete( $post_info->ID ); + } } } } function s4w_handle_delete( $post_id ) { + global $current_blog; $post_info = get_post( $post_id ); - $delete_page = get_option('s4w_delete_page'); - $delete_post = get_option('s4w_delete_post'); + $delete_page = s4w_get_option('s4w_delete_page'); + $delete_post = s4w_get_option('s4w_delete_post'); if ( ($delete_page && $post_info->post_type == 'page') || ($delete_post && $post_info->post_type == 'post') ) { - s4w_delete( $post_info->ID ); + if (is_multisite()) { + s4w_delete( $current_blog->domain . $current_blog->path . $post_info->ID ); + } else { + s4w_delete( $post_info->ID ); + } } } -function s4w_load_all_posts() { +function s4w_handle_deactivate_blog($blogid) { + s4w_delete_blog($blogid); +} + +function s4w_handle_activate_blog($blogid) { + s4w_load_blog_all($blogid); +} + +function s4w_handle_archive_blog($blogid) { + s4w_delete_blog($blogid); +} + +function s4w_handle_unarchive_blog($blogid) { + s4w_load_blog_all($blogid); +} + +function s4w_handle_spam_blog($blogid) { + s4w_delete_blog($blogid); +} + +function s4w_handle_unspam_blog($blogid) { + s4w_load_blog_all($blogid); +} + +function s4w_handle_delete_blog($blogid) { + s4w_delete_blog($blogid); +} + +function s4w_handle_new_blog($blogid) { + s4w_load_blog_all($blogid); +} + +function s4w_load_all_posts($prev) { global $wpdb; - $posts = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post';" ); - if ( $posts ) { - $documents = array(); - foreach ( $posts as $post ) { - $documents[] = s4w_build_document( get_post($post->ID) ); + $documents = array(); + $cnt = 0; + $batchsize = 100; + $last = ""; + $found = FALSE; + $end = FALSE; + $percent = 0; + + if (is_multisite() && get_site_option('s4w_index_all_sites')) { + $bloglist = $wpdb->get_col("SELECT * FROM {$wpdb->base_prefix}blogs", 0); + foreach ($bloglist as $bloginfo) { + $postids = $wpdb->get_results("SELECT ID FROM {$wpdb->base_prefix}{$bloginfo->blog_id}_posts WHERE post_status = 'publish' AND post_type = 'post' ORDER BY ID;"); + $postcount = count($postids); + for ($idx = 0; $idx < $postcount; $idx++) { + + $postid = $postids[$idx]->ID; + $last = $postid; + $percent = (floatval($idx) / floatval($postcount)) * 100; + if ($prev && !$found) { + if ($postid === $prev) { + $found = TRUE; + } + + continue; + } + + if ($idx === $postcount - 1) { + $end = TRUE; + } + + $documents[] = s4w_build_document( get_blog_post($bloginfo->blog_id, $postid), $bloginfo->domain, $bloginfo->path ); + $cnt++; + if ($cnt == $batchsize) { + s4w_post( $documents, FALSE, FALSE); + $cnt = 0; + $documents = array(); + break; + } + } } - - s4w_post( $documents ); + } else { + $posts = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'post' ORDER BY ID;" ); + $postcount = count($posts); + for ($idx = 0; $idx < $postcount; $idx++) { + $postid = $posts[$idx]->ID; + $last = $postid; + $percent = (floatval($idx) / floatval($postcount)) * 100; + if ($prev && !$found) { + if ($postid === $prev) { + $found = TRUE; + } + + continue; + } + + if ($idx === $postcount - 1) { + $end = TRUE; + } + + $documents[] = s4w_build_document( get_post($postid) ); + $cnt++; + if ($cnt == $batchsize) { + s4w_post( $documents, FALSE, FALSE); + $cnt = 0; + $documents = array(); + break; + } + } + } + + if ( $documents ) { + s4w_post( $documents , FALSE, FALSE); + } + + if ($end) { + s4w_post(FALSE, TRUE, FALSE); + printf("{\"type\": \"post\", \"last\": \"%s\", \"end\": true, \"percent\": \"%.2f\"}", $last, $percent); + } else { + printf("{\"type\": \"post\", \"last\": \"%s\", \"end\": false, \"percent\": \"%.2f\"}", $last, $percent); } } -function s4w_load_all_pages() { +function s4w_load_all_pages($prev) { global $wpdb; - $pages = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'page';" ); - if ( $pages ) { - $documents = array(); - foreach ( $pages as $page ) { - $documents[] = s4w_build_document( get_post($page->ID) ); + $documents = array(); + $cnt = 0; + $batchsize = 100; + $last = ""; + $found = FALSE; + $end = FALSE; + $percent = 0; + + //if (is_multisite() && get_site_option('s4w_index_all_sites')) { + if (is_multisite() && FALSE) { + $bloglist = $wpdb->get_col("SELECT * FROM {$wpdb->base_prefix}blogs", 0); + foreach ($bloglist as $bloginfo) { + $postids = $wpdb->get_results("SELECT ID FROM {$wpdb->base_prefix}{$bloginfo->blog_id}_posts WHERE post_status = 'publish' AND post_type = 'page' ORDER BY ID;"); + $postcount = count($postids); + for ($idx = 0; $idx < $postcount; $idx++) { + $postid = $postids[$idx]->ID; + $last = $postid; + $percent = (floatval($idx) / floatval($postcount)) * 100; + if ($prev && !$found) { + if ($postid === $prev) { + $found = TRUE; + } + + continue; + } + + if ($idx === $postcount - 1) { + $end = TRUE; + } + + $documents[] = s4w_build_document( get_blog_post($bloginfo->blog_id, $postid), $bloginfo->domain, $bloginfo->path ); + $cnt++; + if ($cnt == $batchsize) { + s4w_post( $documents, FALSE, FALSE); + $cnt = 0; + $documents = array(); + break; + } + } + } + } else { + $pages = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'page' ORDER BY ID;" ); + $pagecount = count($pages); + for ($idx = 0; $idx < $pagecount; $idx++) { + $pageid = $pages[$idx]->ID; + $last = $pageid; + $percent = (floatval($idx) / floatval($pagecount)) * 100; + if ($prev && !$found) { + if ($pageid === $prev) { + $found = TRUE; + } + + continue; + } + + if ($idx === $pagecount - 1) { + $end = TRUE; + } + + $documents[] = s4w_build_document( get_post($pageid) ); + $cnt++; + if ($cnt == $batchsize) { + s4w_post( $documents, FALSE, FALSE); + $cnt = 0; + $documents = array(); + break; + } } - - s4w_post( $documents ); + } + + if ($documents) { + s4w_post( $documents, FALSE, FALSE); + } + + if ($end) { + s4w_post(FALSE, TRUE, FALSE); + printf("{\"type\": \"page\", \"last\": \"%s\", \"end\": true, \"percent\": \"%.2f\"}", $last, $percent); + } else { + printf("{\"type\": \"page\", \"last\": \"%s\", \"end\": false, \"percent\": \"%.2f\"}", $last, $percent); } } function s4w_search_form() { - $form = __('<form name="searchbox" method="get" id="searchbox" action=""><input type="text" id="qrybox" name="s" value="%s"/><input type="submit" id="searchbtn" /></form>', 'solr4wp'); - printf($form, stripslashes($_GET['s'])); + $sort = $_GET['sort']; + $order = $_GET['order']; + + + if ($sort == 'date') { + $sortval = __('<option value="score">Score</option><option value="date" selected="selected">Date</option><option value="modified">Last Modified</option>'); + } else if ($sort == 'modified') { + $sortval = __('<option value="score">Score</option><option value="date">Date</option><option value="modified" selected="selected">Last Modified</option>'); + } else { + $sortval = __('<option value="score" selected="selected">Score</option><option value="date">Date</option><option value="modified">Last Modified</option>'); + } + + if ($order == 'asc') { + $orderval = __('<option value="desc">Descending</option><option value="asc" selected="selected">Ascending</option>'); + } else { + $orderval = __('<option value="desc" selected="selected">Descending</option><option value="asc">Ascending</option>'); + } + + $form = __('<form name="searchbox" method="get" id="searchbox" action=""><input type="text" id="qrybox" name="s" value="%s"/><input type="submit" id="searchbtn" /><label for="sortselect" id="sortlabel">Sort By:</label><select name="sort" id="sortselect">%s</select><label for="orderselect" id="orderlabel">Order By:</label><select name="order" id="orderselect">%s</select></form>'); + + printf($form, htmlspecialchars(stripslashes($_GET['s'])), $sortval, $orderval); } function s4w_search_results() { @@ -221,12 +587,21 @@ function s4w_search_results() { $offset = $_GET['offset']; $count = $_GET['count']; $fq = $_GET['fq']; + $sort = $_GET['sort']; + $order = $_GET['order']; + $isdym = $_GET['isdym']; - $output_info = get_option('s4w_output_info'); - $output_pager = get_option('s4w_output_pager'); - $output_facets = get_option('s4w_output_facets'); - $results_per_page = get_option('s4w_num_results'); - $categoy_as_taxonomy = get_option('s4w_cat_as_taxo'); + $output_info = s4w_get_option('s4w_output_info'); + $output_pager = s4w_get_option('s4w_output_pager'); + $output_facets = s4w_get_option('s4w_output_facets'); + $results_per_page = s4w_get_option('s4w_num_results'); + $categoy_as_taxonomy = s4w_get_option('s4w_cat_as_taxo'); + $dym_enabled = s4w_get_option('s4w_enable_dym'); + $out = array(); + + if ( ! $qry ) { + $qry = ''; + } # set some default values if ( ! $offset ) { @@ -237,67 +612,113 @@ function s4w_search_results() { if ( ! $count ) { $count = $results_per_page; } - + if ( ! $fq ) { $fq = ''; } + if ( $sort && $order ) { + $sortby = $sort . ' ' . $order; + } else { + $sortby = ''; + $order = ''; + } + + if ( ! $isdym ) { + $isdym = 0; + } + $fqstr = ''; $fqitms = split('\|\|', stripslashes($fq)); + $selectedfacets = array(); foreach ($fqitms as $fqitem) { if ($fqitem) { $splititm = split(':', $fqitem, 2); + $selectedfacet = array(); + $selectedfacet['name'] = sprintf(__("%s:%s"), ucwords(preg_replace('/_str$/i', '', $splititm[0])), str_replace("^^", "/", $splititm[1])); + $removelink = ''; + foreach($fqitms as $fqitem2) { + if ($fqitem2 && !($fqitem2 === $fqitem)) { + $splititm2 = split(':', $fqitem2, 2); + $removelink = $removelink . urlencode('||') . $splititm2[0] . ':' . urlencode($splititm2[1]); + } + } + + if ($removelink) { + $selectedfacet['removelink'] = htmlspecialchars(sprintf(__("?s=%s&fq=%s"), urlencode($qry), $removelink)); + } else { + $selectedfacet['removelink'] = htmlspecialchars(sprintf(__("?s=%s"), urlencode($qry))); + } + $fqstr = $fqstr . urlencode('||') . $splititm[0] . ':' . urlencode($splititm[1]); + + $selectedfacets[] = $selectedfacet; } } if ($qry) { - $results = s4w_query( $qry, $offset, $count, $fqitms ); + $results = s4w_query( $qry, $offset, $count, $fqitms, $sortby ); + if ($results) { $response = $results->response; $header = $results->responseHeader; $teasers = get_object_vars($results->highlighting); + $didyoumean = $results->spellcheck->suggestions->collation; if ($output_info) { - $outinfo = __('<div id="resultinfo"><p>Found <em id="resultcnt">%d</em> results for <em id="resultqry">%s</em> in <em id="qrytime">%.3f</em> seconds.</p></div><div id="infoclear"></div>', 'solr4wp'); - printf($outinfo, $response->numFound, htmlspecialchars($qry), $header->QTime/1000); + $out['hits'] = sprintf(__("%d"), $response->numFound); + $out['qtime'] = sprintf(__("%.3f"), $header->QTime/1000); + + if ($didyoumean && !$isdym && $dym_enabled) { + $dymout = array(); + $dymout['term'] = htmlspecialchars($didyoumean); + $dymout['link'] = htmlspecialchars(sprintf(__("?s=%s&isdym=1"), urlencode($didyoumean))); + $out['dym'] = $dymout; + } } - + if ($output_pager) { # calculate the number of pages $numpages = ceil($response->numFound / $count); $currentpage = ceil($offset / $count) + 1; + $pagerout = array(); if ($numpages == 0) { $numpages = 1; } - print(__('<div id="resultpager"><ul>', 'solr4wp')); foreach (range(1, $numpages) as $pagenum) { if ( $pagenum != $currentpage ) { $offsetnum = ($pagenum - 1) * $count; - $itemout = __('<li><a href="?s=%s&offset=%d&count=%d">%d</a></li>', 'solr4wp'); - printf($itemout, urlencode($qry), $offsetnum, $count, $pagenum); + $pageritm = array(); + $pageritm['page'] = sprintf(__("%d"), $pagenum); + $pageritm['link'] = htmlspecialchars(sprintf(__("?s=%s&offset=%d&count=%d"), urlencode($qry), $offsetnum, $count)); + $pagerout[] = $pageritm; } else { - printf(__('<li>%d</li>', 'solr4wp'), $pagenum); + $pageritm = array(); + $pageritm['page'] = sprintf(__("%d"), $pagenum); + $pageritm['link'] = ""; + $pagerout[] = $pageritm; } } - print(__('</ul></div><div id="pagerclear"></div>', 'solr4wp')); + + $out['pager'] = $pagerout; } if ($output_facets) { # handle facets - print(__('<div id="facets"><ul class="facets">', 'solr4wp')); + $facetout = array(); + if($results->facet_counts) { - foreach ($results->facet_counts->facet_fields as $facetfield => $facet) { - if ( ! get_object_vars($facet) ) { continue; } - printf(__('<li class="facet"><h3>%s</h3><ul class="facetitems">', 'solr4wp'), ucwords($facetfield)); - + $facetinfo = array(); + $facetitms = array(); + $facetinfo['name'] = ucwords(preg_replace('/_str$/i', '', $facetfield)); + # categories is a taxonomy if ($categoy_as_taxonomy && $facetfield == 'categories') { # generate taxonomy and counts @@ -307,68 +728,125 @@ function s4w_search_results() { $taxo = s4w_gen_taxo_array($taxo, $taxovals); } - s4w_print_taxo($facet, $taxo, '', $fqstr, $facetfield); + $facetitms = s4w_get_output_taxo($facet, $taxo, '', $fqstr, $facetfield); } else { foreach ($facet as $facetval => $facetcnt) { - $faceturl = sprintf(__('?s=%s&fq=%s:%s%s', 'solr4wp'), $qry, $facetfield, urlencode('"' . $facetval . '"'), $fqstr); - printf(__('<li class="facetitem"><a href="%s">%s</a> (%d)</li>', 'solr4wp'), $faceturl, $facetval, $facetcnt); + $facetitm = array(); + $facetitm['count'] = sprintf(__("%d"), $facetcnt); + $facetitm['link'] = htmlspecialchars(sprintf(__('?s=%s&fq=%s:%s%s', 'solr4wp'), urlencode($qry), $facetfield, urlencode('"' . $facetval . '"'), $fqstr)); + $facetitm['name'] = $facetval; + $facetitms[] = $facetitm; } } - print(__('</ul></li>', 'solr4wp')); + + $facetinfo['items'] = $facetitms; + $facetout[$facetfield] = $facetinfo; } } + + $facetout['selected'] = $selectedfacets; + $out['facets'] = $facetout; } - print(__('</ul></div><div id="facetclear"></div>', 'solr4wp')); - print(__('<div id="results">', 'solr4wp')); - - if ($response->numFound == 0) { - printf(__('<div id="noresults">No Results Found</div>', 'solr4wp')); - } else { - + $resultout = array(); + + if ($response->numFound != 0) { foreach ( $response->docs as $doc ) { - print(__('<div class="result">', 'solr4wp')); - $titleout = __('<h2><a href="%s">%s</a></h2><h3>by <em id="resultauthor">%s</em> has a score of <em id="resultscore">%f</em></h3>', 'solr4wp'); - printf($titleout, $doc->permalink, $doc->title, $doc->author, $doc->score); + $resultinfo = array(); $docid = strval($doc->id); + $resultinfo['permalink'] = $doc->permalink; + $resultinfo['title'] = $doc->title; + $resultinfo['author'] = $doc->author; + $resultinfo['authorlink'] = htmlspecialchars($doc->author_s); + $resultinfo['numcomments'] = $doc->numcomments; + $resultinfo['date'] = $doc->displaydate; + + if ($doc->numcomments === 0) { + $resultinfo['comment_link'] = $doc->permalink . "#respond"; + } else { + $resultinfo['comment_link'] = $doc->permalink . "#comments"; + } + + $resultinfo['score'] = $doc->score; + $resultinfo['id'] = $docid; $docteaser = $teasers[$docid]; if ($docteaser->content) { - printf(__('<p>...%s...</p></div>', 'solr4wp'), implode('...', $docteaser->content)); + $resultinfo['teaser'] = sprintf(__("...%s..."), implode("...", $docteaser->content)); } else { $words = split(' ', $doc->content); $teaser = implode(' ', array_slice($words, 0, 30)); - printf(__('<p>%s...</p></div>', 'solr4wp'), $teaser); + $resultinfo['teaser'] = sprintf(__("%s..."), $teaser); } + $resultout[] = $resultinfo; } } - print(__('</div><div id="resultsclear"></div>', 'solr4wp')); + $out['results'] = $resultout; } - } -} + } else { + $out['hits'] = "0"; + } -function s4w_print_taxo($facet, $taxo, $prefix, $fqstr, $field) { + # pager and results count helpers + $out['query'] = htmlspecialchars($qry); + $out['offset'] = strval($offset); + $out['count'] = strval($count); + $out['firstresult'] = strval($offset + 1); + $out['lastresult'] = strval(min($offset + $count, $out['hits'])); + $out['sortby'] = $sortby; + $out['order'] = $order; + $out['sorting'] = array( + 'scoreasc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=score&order=asc', urlencode($qry), stripslashes($fq))), + 'scoredesc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=score&order=desc', urlencode($qry), stripslashes($fq))), + 'dateasc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=date&order=asc', urlencode($qry), stripslashes($fq))), + 'datedesc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=date&order=desc', urlencode($qry), stripslashes($fq))), + 'modifiedasc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=modified&order=asc', urlencode($qry), stripslashes($fq))), + 'modifieddesc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=modified&order=desc', urlencode($qry), stripslashes($fq))), + 'commentsasc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=numcomments&order=asc', urlencode($qry), stripslashes($fq))), + 'commentsdesc' => htmlspecialchars(sprintf('?s=%s&fq=%s&sort=numcomments&order=desc', urlencode($qry), stripslashes($fq))) + ); + return $out; +} + +function s4w_print_facet_items($items, $pre = "<ul>", $post = "</ul>", $before = "<li>", $after = "</li>", + $nestedpre = "<ul>", $nestedpost = "</ul>", $nestedbefore = "<li>", $nestedafter = "</li>") { + if (!$items) { + return; + } + printf(__("%s\n"), $pre); + foreach ($items as $item) { + printf(__("%s<a href=\"%s\">%s (%s)</a>%s\n"), $before, $item["link"], $item["name"], $item["count"], $after); + if ($item["items"]) { + s4w_print_facet_items($item["items"], $nestedpre, $nestedpost, $nestedbefore, $nestedafter, + $nestedpre, $nestedpost, $nestedbefore, $nestedafter); + } + } + printf(__("%s\n"), $post); +} + +function s4w_get_output_taxo($facet, $taxo, $prefix, $fqstr, $field) { $qry = stripslashes($_GET['s']); if (count($taxo) == 0) { return; } else { - if ($prefix) { - print (__('<li><ul class="facetchildren">', 'solr4wp')); - } - - foreach ($taxo as $taxoname => $taxoval) { + $facetitms = array(); + foreach ($taxo as $taxoname => $taxoval) { $newprefix = $prefix . $taxoname . '^^'; $facetvars = get_object_vars($facet); - $faceturl = sprintf(__('?s=%s&fq=%s:%s%s', 'solr4wp'), $qry, $field, urlencode('"' . $newprefix . '"'), $fqstr); - printf(__('<li class="facetitem"><a href="%s">%s</a> (%d)</li>', 'solr4wp'), $faceturl, $taxoname, $facetvars[$newprefix]); - s4w_print_taxo($facet, $taxoval, $newprefix, $fqstr, $field); + $facetitm = array(); + $facetitm['count'] = sprintf(__("%d"), $facetvars[$newprefix]); + $facetitm['link'] = htmlspecialchars(sprintf(__('?s=%s&fq=%s:%s%s', 'solr4wp'), $qry, $field, urlencode('"' . $newprefix . '"'), $fqstr)); + $facetitm['name'] = $taxoname; + $outitms = s4w_get_output_taxo($facet, $taxoval, $newprefix, $fqstr, $field); + if ($outitms) { + $facetitm['items'] = $outitms; + } + $facetitms[] = $facetitm; } - if ($prefix) { - print (__('</ul></li>', 'solr4wp')); - } + return $facetitms; } } @@ -384,32 +862,41 @@ function s4w_gen_taxo_array($in, $vals) { } } -function s4w_query( $qry, $offset, $count, $fq) { +function s4w_query( $qry, $offset, $count, $fq, $sortby) { $solr = s4w_get_solr(); $response = NULL; $facet_fields = array(); - $number_of_tags = get_option('s4w_max_display_tags'); + $number_of_tags = s4w_get_option('s4w_max_display_tags'); - if (get_option('s4w_facet_on_categories')) { + if (s4w_get_option('s4w_facet_on_categories')) { $facet_fields[] = 'categories'; } - $facet_on_tags = get_option('s4w_facet_on_tags'); + $facet_on_tags = s4w_get_option('s4w_facet_on_tags'); if ($facet_on_tags) { $facet_fields[] = 'tags'; } - if (get_option('s4w_facet_on_author')) { + if (s4w_get_option('s4w_facet_on_author')) { $facet_fields[] = 'author'; } - if (get_option('s4w_facet_on_type')) { + if (s4w_get_option('s4w_facet_on_type')) { $facet_fields[] = 'type'; } + $facet_on_custom_fields = s4w_get_option('s4w_facet_on_custom_fields'); + if (count($facet_on_custom_fields)>0) { + foreach ( $facet_on_custom_fields as $field_name ) { + $facet_fields[] = $field_name . '_str'; + } + } + if ( $solr ) { $params = array(); - $qry = $solr->escape($qry); + $params['defType'] = 'dismax'; + $params['qf'] = 'tagssrch^5 title^10 categoriessrch^5 content^3.5 comments^1.5'; // TODO : Add "_srch" custom fields ? + $params['pf'] = 'title^15 text^10'; $params['facet'] = 'true'; $params['facet.field'] = $facet_fields; $params['facet.mincount'] = '1'; @@ -419,13 +906,18 @@ function s4w_query( $qry, $offset, $count, $fq) { $params['hl.fl'] = 'content'; $params['hl.snippets'] = '3'; $params['hl.fragsize'] = '50'; + $params['sort'] = $sortby; + $params['spellcheck.onlyMorePopular'] = 'true'; + $params['spellcheck.extendedResults'] = 'false'; + $params['spellcheck.collate'] = 'true'; + $params['spellcheck.count'] = '1'; + $params['spellcheck'] = 'true'; if ($facet_on_tags) { $params['f.tags.facet.limit'] = $number_of_tags; } - $finalqry = 'tagssrch:' . $qry . '^4 title:' . $qry . '^3 categoriessrch:' . $qry . '^1.2 text:' . $qry . '^1'; - $response = $solr->search( $finalqry, $offset, $count, $params); + $response = $solr->search($qry, $offset, $count, $params); if ( ! $response->getHttpStatus() == 200 ) { $response = NULL; } @@ -435,11 +927,29 @@ function s4w_query( $qry, $offset, $count, $fq) { } function s4w_options_init() { + + $method = $_POST['method']; + if ($method === "load") { + $type = $_POST['type']; + $prev = $_POST['prev']; + + if ($type === 'post' ) { + s4w_load_all_posts($prev); + exit; + } else if ($type === 'page') { + s4w_load_all_pages($prev); + exit; + } else { + return; + } + } + register_setting( 's4w-options-group', 's4w_solr_host', 'wp_filter_nohtml_kses' ); register_setting( 's4w-options-group', 's4w_solr_port', 'absint' ); register_setting( 's4w-options-group', 's4w_solr_path', 'wp_filter_nohtml_kses' ); register_setting( 's4w-options-group', 's4w_index_pages', 'absint' ); - register_setting( 's4w-options-group', 's4w_index_posts', 'absint' ); + register_setting( 's4w-options-group', 's4w_index_posts', 'absint' ); + register_setting( 's4w-options-group', 's4w_index_comments', 'absint' ); register_setting( 's4w-options-group', 's4w_delete_page', 'absint' ); register_setting( 's4w-options-group', 's4w_delete_post', 'absint' ); register_setting( 's4w-options-group', 's4w_private_page', 'absint' ); @@ -447,7 +957,7 @@ function s4w_options_init() { register_setting( 's4w-options-group', 's4w_output_info', 'absint' ); register_setting( 's4w-options-group', 's4w_output_pager', 'absint' ); register_setting( 's4w-options-group', 's4w_output_facets', 'absint' ); - register_setting( 's4w-options-group', 's4w_exclude_pages', 's4w_filter_str2list_numeric' ); + register_setting( 's4w-options-group', 's4w_exclude_pages', 's4w_filter_str2list' ); register_setting( 's4w-options-group', 's4w_num_results', 'absint' ); register_setting( 's4w-options-group', 's4w_cat_as_taxo', 'absint' ); register_setting( 's4w-options-group', 's4w_max_display_tags', 'absint' ); @@ -455,14 +965,21 @@ function s4w_options_init() { register_setting( 's4w-options-group', 's4w_facet_on_tags', 'absint' ); register_setting( 's4w-options-group', 's4w_facet_on_author', 'absint' ); register_setting( 's4w-options-group', 's4w_facet_on_type', 'absint' ); + register_setting( 's4w-options-group', 's4w_index_all_sites', 'absint' ); + register_setting( 's4w-options-group', 's4w_enable_dym', 'absint' ); + register_setting( 's4w-options-group', 's4w_connect_type', 'wp_filter_nohtml_kses' ); + register_setting( 's4w-options-group', 's4w_index_custom_fields', 's4w_filter_str2list' ); + register_setting( 's4w-options-group', 's4w_facet_on_custom_fields', 's4w_filter_str2list' ); } function s4w_filter_str2list_numeric($input) { $final = array(); - foreach( split(',', $input) as $val ) { - $val = trim($val); - if ( is_numeric($val) ) { - $final[] = $val; + if ($input != "") { + foreach( split(',', $input) as $val ) { + $val = trim($val); + if ( is_numeric($val) ) { + $final[] = $val; + } } } @@ -471,19 +988,43 @@ function s4w_filter_str2list_numeric($input) { function s4w_filter_str2list($input) { $final = array(); - foreach( split(',', $input) as $val ) { - $final[] = trim($val); + if ($input != "") { + foreach( split(',', $input) as $val ) { + $final[] = trim($val); + } } return $final; } function s4w_filter_list2str($input) { - return implode(',', $input); + if (!is_array($input)) { + return ""; + } + + $outval = implode(',', $input); + if (!$outval) { + $outval = ""; + } + + return $outval; } function s4w_add_pages() { - add_options_page('Solr Options', 'Solr Options', 8, __FILE__, 's4w_options_page'); + $addpage = FALSE; + + if (is_multisite() && is_site_admin()) { + $indexall = get_site_option('s4w_index_all_sites'); + if (($indexall && is_main_blog()) || !$indexall) { + $addpage = TRUE; + } + } else if (!is_multisite() && is_admin()) { + $addpage = TRUE; + } + + if ($addpage) { + add_options_page('Solr Options', 'Solr Options', 8, __FILE__, 's4w_options_page'); + } } function s4w_options_page() { @@ -494,20 +1035,121 @@ function s4w_options_page() { } } +function s4w_admin_head() { + // include our default css + if (file_exists(dirname(__FILE__) . '/template/search.css')) { + printf(__("<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\" media=\"screen\" />\n"), plugins_url('/template/search.css', __FILE__)); + } +?> +<script type="text/javascript"> + var $j = jQuery.noConflict(); + + function switch1() { + if ($j('#solrconnect').is(':checked')) { + $j('#solr_admin_tab2').css('display', 'block'); + $j('#solr_admin_tab2_btn').addClass('solr_admin_on'); + } + } + + function doLoad($type, $prev) { + if ($prev == null) { + $j.post("options-general.php?page=solr-for-wordpress/solr-for-wordpress.php", {method: "load", type: $type}, handleResults, "json"); + } else { + $j.post("options-general.php?page=solr-for-wordpress/solr-for-wordpress.php", {method: "load", type: $type, prev: $prev}, handleResults, "json"); + } + } + + function handleResults(data) { + $j('#percentspan').text(data.percent + "%"); + if (!data.end) { + doLoad(data.type, data.last); + } else { + $j('#percentspan').remove(); + enableAll(); + } + } + + function disableAll() { + $j('[name=s4w_postload]').attr('disabled','disabled'); + $j('[name=s4w_deleteall]').attr('disabled','disabled'); + $j('[name=s4w_optimize]').attr('disabled','disabled'); + $j('[name=s4w_pageload]').attr('disabled','disabled'); + $j('[name=s4w_ping]').attr('disabled','disabled'); + $j('#settingsbutton').attr('disabled','disabled'); + } + + function enableAll() { + $j('[name=s4w_postload]').removeAttr('disabled'); + $j('[name=s4w_deleteall]').removeAttr('disabled'); + $j('[name=s4w_optimize]').removeAttr('disabled'); + $j('[name=s4w_pageload]').removeAttr('disabled'); + $j('[name=s4w_ping]').removeAttr('disabled'); + $j('#settingsbutton').removeAttr('disabled'); + } + + $percentspan = '<span style="font-size:1.2em;font-weight:bold;margin:20px;padding:20px" id="percentspan">0%</span>'; + + $j(document).ready(function() { + switch1(); + $j('[name=s4w_postload]').click(function() { + $j(this).after($percentspan); + disableAll(); + doLoad("post", null); + return FALSE; + }); + + $j('[name=s4w_pageload]').click(function() { + $j(this).after($percentspan); + disableAll(); + doLoad("page", null); + return FALSE; + }); + }); + +</script> <?php +} + function s4w_default_head() { // include our default css if (file_exists(dirname(__FILE__) . '/template/search.css')) { - include_once(dirname(__FILE__) . '/template/search.css'); + printf(__("<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\" media=\"screen\" />\n"), plugins_url('/template/search.css', __FILE__)); } } +function s4w_autosuggest_head() { + if (file_exists(dirname(__FILE__) . '/template/autocomplete.css')) { + printf(__("<link rel=\"stylesheet\" href=\"%s\" type=\"text/css\" media=\"screen\" />\n"), plugins_url('/template/autocomplete.css', __FILE__)); + } +?> +<script type="text/javascript"> + jQuery(document).ready(function($) { + $("#s").suggest("?method=autocomplete",{}); + $("#qrybox").suggest("?method=autocomplete",{}); + }); +</script> +<?php +} + function s4w_template_redirect() { + wp_enqueue_script('suggest'); + // not a search page; don't do anything and return // thanks to the Better Search plugin for the idea: http://wordpress.org/extend/plugins/better-search/ - if ( stripos($_SERVER['REQUEST_URI'], '?s=') == false ) { + $search = stripos($_SERVER['REQUEST_URI'], '?s='); + $autocomplete = stripos($_SERVER['REQUEST_URI'], '?method=autocomplete'); + + if ( ($search || $autocomplete) == FALSE ) { return; } + if ($autocomplete) { + $q = stripslashes($_GET['q']); + $limit = $_GET['limit']; + + s4w_autocomplete($q, $limit); + exit; + } + // If there is a template file then we use it if (file_exists(TEMPLATEPATH . '/s4w_search.php')) { // use theme file @@ -525,6 +1167,128 @@ function s4w_template_redirect() { exit; } +function s4w_mlt_widget() { + register_widget('s4w_MLTWidget'); +} + +class s4w_MLTWidget extends WP_Widget { + + function s4w_MLTWidget() { + $widget_ops = array('classname' => 'widget_s4w_mlt', 'description' => __( "Displays a list of pages similar to the page being viewed") ); + $this->WP_Widget('mlt', __('Similar'), $widget_ops); + } + + function widget( $args, $instance ) { + + extract($args); + $title = apply_filters('widget_title', empty($instance['title']) ? __('Similar') : $instance['title']); + $count = empty($instance['count']) ? 5 : $instance['count']; + if (!is_numeric($count)) { + $count = 5; + } + + $showauthor = $instance['showauthor']; + + $solr = s4w_get_solr(); + $response = NULL; + + if ((!is_single() && !is_page()) || !$solr) { + return; + } + + $params = array(); + $qry = 'permalink:' . $solr->escape(get_permalink()); + $params['fl'] = 'title,permalink,author'; + $params['mlt'] = 'true'; + $params['mlt.count'] = $count; + $params['mlt.fl'] = 'title,content'; + + $response = $solr->search($qry, 0, 1, $params); + if ( ! $response->getHttpStatus() == 200 ) { + return; + } + + echo $before_widget; + if ( $title ) + echo $before_title . $title . $after_title; + + $mltresults = $response->moreLikeThis; + foreach ($mltresults as $mltresult) { + $docs = $mltresult->docs; + echo "<ul>"; + foreach($docs as $doc) { + if ($showauthor) { + $author = " by {$doc->author}"; + } + echo "<li><a href=\"{$doc->permalink}\" title=\"{$doc->title}\">{$doc->title}</a>{$author}</li>"; + } + echo "</ul>"; + } + + echo $after_widget; + } + + function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $new_instance = wp_parse_args( (array) $new_instance, array( 'title' => '', 'count' => 5, 'showauthor' => 0) ); + $instance['title'] = strip_tags($new_instance['title']); + $cnt = strip_tags($new_instance['count']); + $instance['count'] = is_numeric($cnt) ? $cnt : 5; + $instance['showauthor'] = $new_instance['showauthor'] ? 1 : 0; + + return $instance; + } + + function form( $instance ) { + $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'count' => 5, 'showauthor' => 0) ); + $title = strip_tags($instance['title']); + $count = strip_tags($instance['count']); + $showauthor = $instance['showauthor'] ? 'checked="checked"' : ''; +?> + <p> + <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label> + <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>" /> + </p> + <p> + <label for="<?php echo $this->get_field_id('count'); ?>"><?php _e('Count:'); ?></label> + <input class="widefat" id="<?php echo $this->get_field_id('count'); ?>" name="<?php echo $this->get_field_name('count'); ?>" type="text" value="<?php echo esc_attr($count); ?>" /> + </p> + <p> + <label for="<?php echo $this->get_field_id('showauthor'); ?>"><?php _e('Show Author?:'); ?></label> + <input class="checkbox" type="checkbox" <?php echo $showauthor; ?> id="<?php echo $this->get_field_id('showauthor'); ?>" name="<?php echo $this->get_field_name('showauthor'); ?>" /> + </p> +<?php + } +} + +function s4w_autocomplete($q, $limit) { + $solr = s4w_get_solr(); + $response = NULL; + + if (!$solr) { + return; + } + + $params = array(); + $params['terms'] = 'true'; + $params['terms.fl'] = 'spell'; + $params['terms.lower'] = $q; + $params['terms.prefix'] = $q; + $params['terms.lower.incl'] = 'false'; + $params['terms.limit'] = $limit; + $params['qt'] = '/terms'; + + $response = $solr->search($q, 0, $limit, $params); + if ( ! $response->getHttpStatus() == 200 ) { + return; + } + + $terms = get_object_vars($response->terms->spell); + foreach($terms as $term => $count) { + printf("%s\n", $term); + } +} + add_action( 'template_redirect', 's4w_template_redirect', 1 ); add_action( 'publish_post', 's4w_handle_modified' ); add_action( 'publish_page', 's4w_handle_modified' ); @@ -532,5 +1296,19 @@ add_action( 'edit_post', 's4w_handle_status_change' ); add_action( 'delete_post', 's4w_handle_delete' ); add_action( 'admin_menu', 's4w_add_pages'); add_action( 'admin_init', 's4w_options_init'); +add_action( 'widgets_init', 's4w_mlt_widget'); +add_action( 'wp_head', 's4w_autosuggest_head'); +add_action( 'admin_head', 's4w_admin_head'); + +if (is_multisite()) { + add_action( 'deactivate_blog', 's4w_handle_deactivate_blog'); + add_action( 'activate_blog', 's4w_handle_activate_blog'); + add_action( 'archive_blog', 's4w_handle_archive_blog'); + add_action( 'unarchive_blog', 's4w_handle_unarchive_blog'); + add_action( 'make_spam_blog', 's4w_handle_spam_blog'); + add_action( 'unspam_blog', 's4w_handle_unspam_blog'); + add_action( 'delete_blog', 's4w_handle_delete_blog'); + add_action( 'wpmu_new_blog', 's4w_handle_new_blog'); +} ?> diff --git a/wp-content/plugins/solr-for-wordpress/solr-options-page.php b/wp-content/plugins/solr-for-wordpress/solr-options-page.php index b994337afb7c62b29b677bfcc8c195ae9dae8fb6..2cf0f84626fa9500d9f79ff8be614de05a87dcaf 100644 --- a/wp-content/plugins/solr-for-wordpress/solr-options-page.php +++ b/wp-content/plugins/solr-for-wordpress/solr-options-page.php @@ -21,38 +21,95 @@ THE SOFTWARE. */ -#set defaults -if (get_option('s4w_solr_initialized') != '1') { - update_option('s4w_solr_host', 'localhost'); - update_option('s4w_solr_port', '8983'); - update_option('s4w_solr_path', '/solr'); - update_option('s4w_index_pages', '1'); - update_option('s4w_index_posts', '1'); - update_option('s4w_delete_page', '1'); - update_option('s4w_delete_post', '1'); - update_option('s4w_private_page', '1'); - update_option('s4w_private_post', '1'); - update_option('s4w_output_info', '1'); - update_option('s4w_output_pager', '1'); - update_option('s4w_output_facets', '1'); - update_option('s4w_exclude_pages', array()); - update_option('s4w_num_results', '5'); - update_option('s4w_cat_as_taxo', '1'); - update_option('s4w_solr_initialized', '1'); - update_option('s4w_max_display_tags', '10'); - update_option('s4w_facet_on_categories', '1'); - update_option('s4w_facet_on_tags', '1'); - update_option('s4w_facet_on_author', '1'); - update_option('s4w_facet_on_type', '1'); +#set defaults if not initialized +if (s4w_get_option('s4w_solr_initialized') != '1') { + update_site_option('s4w_index_all_sites', '0'); + s4w_update_option('s4w_solr_host', 'localhost'); + s4w_update_option('s4w_solr_port', '8983'); + s4w_update_option('s4w_solr_path', '/solr'); + s4w_update_option('s4w_index_pages', '1'); + s4w_update_option('s4w_index_posts', '1'); + s4w_update_option('s4w_delete_page', '1'); + s4w_update_option('s4w_delete_post', '1'); + s4w_update_option('s4w_private_page', '1'); + s4w_update_option('s4w_private_post', '1'); + s4w_update_option('s4w_output_info', '1'); + s4w_update_option('s4w_output_pager', '1'); + s4w_update_option('s4w_output_facets', '1'); + //s4w_update_option('s4w_exclude_pages', array()); + s4w_update_option('s4w_exclude_pages', ''); + s4w_update_option('s4w_num_results', '5'); + s4w_update_option('s4w_cat_as_taxo', '1'); + s4w_update_option('s4w_solr_initialized', '1'); + s4w_update_option('s4w_max_display_tags', '10'); + s4w_update_option('s4w_facet_on_categories', '1'); + s4w_update_option('s4w_facet_on_taxonomy', '1'); + s4w_update_option('s4w_facet_on_tags', '1'); + s4w_update_option('s4w_facet_on_author', '1'); + s4w_update_option('s4w_facet_on_type', '1'); + s4w_update_option('s4w_enable_dym', '1'); + s4w_update_option('s4w_index_comments', '1'); + s4w_update_option('s4w_connect_type', 'solr'); + //s4w_update_option('s4w_index_custom_fields', array()); + //s4w_update_option('s4w_facet_on_custom_fields', array()); + s4w_update_option('s4w_index_custom_fields', ''); + s4w_update_option('s4w_facet_on_custom_fields', ''); +} + +wp_reset_vars(array('action')); + +# save form settings if we get the update action +# we do saving here instead of using options.php because we need to use +# s4w_update_option instead of update option. +if ($_POST['action'] == 'update') { + $options = array('s4w_solr_host', 's4w_solr_port', 's4w_solr_path', 's4w_index_pages', + 's4w_index_posts', 's4w_delete_page', 's4w_delete_post', 's4w_private_page', + 's4w_private_post', 's4w_output_info', 's4w_output_pager', 's4w_output_facets', + 's4w_exclude_pages', 's4w_num_results', 's4w_cat_as_taxo', 's4w_max_display_tags', + 's4w_facet_on_categories', 's4w_facet_on_tags', 's4w_facet_on_author', 's4w_facet_on_type', + 's4w_enable_dym', 's4w_index_comments', 's4w_connect_type', 's4w_index_all_sites', + 's4w_index_custom_fields', 's4w_facet_on_custom_fields', 's4w_facet_on_taxonomy'); + + foreach ( $options as $option ) { + $option = trim($option); + $value = null; + if ( isset($_POST[$option]) ) + $value = $_POST[$option]; + + if ( !is_array($value) ) $value = trim($value); + $value = stripslashes_deep($value); + + if ( $option == 's4w_index_all_sites') { + update_site_option($option, $value); + } else { + s4w_update_option($option, $value); + } + } + + ?> + <div id="message" class="updated fade"><p><strong><?php _e('Success!', 'solr4wp') ?></strong></p></div> + <?php } # checks if we need to check the checkbox function s4w_checkCheckbox( $theFieldname ) { - if( get_option( $theFieldname ) == '1'){ - echo 'checked="checked"'; + if ($theFieldname == 's4w_index_all_sites') { + if (get_site_option($theFieldname) == '1') { + echo 'checked="checked"'; + } + } else { + if( s4w_get_option( $theFieldname ) == '1'){ + echo 'checked="checked"'; + } } } +function s4w_checkConnectOption($connectType) { + if ( s4w_get_option('s4w_connect_type') === $connectType ) { + echo 'checked="checked"'; + } +} + # check for any POST settings if ($_POST['s4w_ping']) { if (s4w_get_solr(true)) { @@ -64,45 +121,47 @@ if ($_POST['s4w_ping']) { <div id="message" class="updated fade"><p><strong><?php _e('Ping Failed!', 'solr4wp') ?></strong></p></div> <?php } -} else if ($_POST['s4w_pageload']) { - s4w_load_all_pages(); -?> - <div id="message" class="updated fade"><p><strong><?php _e('Pages Loaded!', 'solr4wp') ?></strong></p></div> -<?php -} else if ($_POST['s4w_postload']) { - s4w_load_all_posts(); -?> - <div id="message" class="updated fade"><p><strong><?php _e('Posts Loaded!', 'solr4wp') ?></strong></p></div> -<?php } else if ($_POST['s4w_deleteall']) { s4w_delete_all(); ?> <div id="message" class="updated fade"><p><strong><?php _e('All Indexed Pages Deleted!', 'solr4wp') ?></strong></p></div> <?php +} else if ($_POST['s4w_optimize']) { + s4w_optimize(); +?> + <div id="message" class="updated fade"><p><strong><?php _e('Index Optimized!', 'solr4wp') ?></strong></p></div> +<?php } ?> <div class="wrap"> <h2><?php _e('Solr For WordPress', 'solr4wp') ?></h2> -<form method="post" action="options.php"> -<h3><?php _e('Connection Information', 'solr4wp') ?></h3> -<table class="form-table"> - <tr valign="top"> - <th scope="row"><?php _e('Solr Host', 'solr4wp') ?></th> - <td><input type="text" name="s4w_solr_host" value="<?php _e(get_option('s4w_solr_host'), 'solr4wp'); ?>" /></td> - </tr> - - <tr valign="top"> - <th scope="row"><?php _e('Solr Port', 'solr4wp') ?></th> - <td><input type="text" name="s4w_solr_port" value="<?php _e(get_option('s4w_solr_port'), 'solr4wp'); ?>" /></td> - </tr> +<form method="post" action="options-general.php?page=solr-for-wordpress/solr-for-wordpress.php"> +<h3><?php _e('Configure Solr', 'solr4wp') ?></h3> - <tr valign="top"> - <th scope="row"><?php _e('Solr Path', 'solr4wp') ?></th> - <td><input type="text" name="s4w_solr_path" value="<?php _e(get_option('s4w_solr_path'), 'solr4wp'); ?>" /></td> - </tr> -</table> +<div class="solr_admin clearfix"> + <div class="solr_adminR"> + <div class="solr_adminR2" id="solr_admin_tab2"> + <label><?php _e('Solr Host', 'solr4wp') ?></label> + <p><input type="text" name="s4w_solr_host" value="<?php _e(s4w_get_option('s4w_solr_host'), 'solr4wp'); ?>" /></p> + <label><?php _e('Solr Port', 'solr4wp') ?></label> + <p><input type="text" name="s4w_solr_port" value="<?php _e(s4w_get_option('s4w_solr_port'), 'solr4wp'); ?>" /></p> + <label><?php _e('Solr Path', 'solr4wp') ?></label> + <p><input type="text" name="s4w_solr_path" value="<?php _e(s4w_get_option('s4w_solr_path'), 'solr4wp'); ?>" /></p> + </div> + </div> + <ol> + <li id="solr_admin_tab1_btn" class="solr_admin_tab1"> + </li> + <li id="solr_admin_tab2_btn" class="solr_admin_tab2"> + <h4><input id="solrconnect" name="s4w_connect_type" type="radio" value="solr" <?php s4w_checkConnectOption('solr'); ?> onclick="switch1();" />Solr Server</h4> + <ol> + <li>Download, install and configure your own <a href="">Apache Solr 1.4</a> instance</li> + </ol> + </li> + </ol> +</div> <hr /> <h3><?php _e('Indexing Options', 'solr4wp') ?></h3> <table class="form-table"> @@ -128,8 +187,29 @@ if ($_POST['s4w_ping']) { </tr> <tr valign="top"> - <th scope="row"><?php _e('Excludes (comma-separated integer ids)', 'solr4wp') ?></th> - <td><input type="text" name="s4w_exclude_pages" value="<?php _e(s4w_filter_list2str(get_option('s4w_exclude_pages')), 'solr4wp'); ?>" /></td> + <th scope="row" style="width:200px;"><?php _e('Index Comments', 'solr4wp') ?></th> + <td style="width:10px;float:left;"><input type="checkbox" name="s4w_index_comments" value="1" <?php echo s4w_checkCheckbox('s4w_index_comments'); ?> /></td> + </tr> + + <?php + //is this a multisite installation + if (is_multisite() && is_main_site()) { + ?> + + <tr valign="top"> + <th scope="row" style="width:200px;"><?php _e('Index all Sites', 'solr4wp') ?></th> + <td style="width:10px;float:left;"><input type="checkbox" name="s4w_index_all_sites" value="1" <?php echo s4w_checkCheckbox('s4w_index_all_sites'); ?> /></td> + </tr> + <?php + } + ?> + <tr valign="top"> + <th scope="row"><?php _e('Index custom fields (comma separated names list)') ?></th> + <td><input type="text" name="s4w_index_custom_fields" value="<?php print( s4w_filter_list2str(s4w_get_option('s4w_index_custom_fields'), 'solr4wp')); ?>" /></td> + </tr> + <tr valign="top"> + <th scope="row"><?php _e('Excludes Posts or Pages (comma separated ids list)') ?></th> + <td><input type="text" name="s4w_exclude_pages" value="<?php print( s4w_filter_list2str(s4w_get_option('s4w_exclude_pages'), 'solr4wp')); ?>" /></td> </tr> </table> <hr /> @@ -162,22 +242,38 @@ if ($_POST['s4w_ping']) { <th scope="row" style="width:200px;float:left;margin-left:20px;"><?php _e('Type as Facet', 'solr4wp') ?></th> <td style="width:10px;float:left;"><input type="checkbox" name="s4w_facet_on_type" value="1" <?php echo s4w_checkCheckbox('s4w_facet_on_type'); ?> /></td> </tr> - + + <tr valign="top"> + <th scope="row" style="width:200px;"><?php _e('Taxonomy as Facet', 'solr4wp') ?></th> + <td style="width:10px;float:left;"><input type="checkbox" name="s4w_facet_on_taxonomy" value="1" <?php echo s4w_checkCheckbox('s4w_facet_on_taxonomy'); ?> /></td> + </tr> + + <tr valign="top"> + <th scope="row"><?php _e('Custom fields as Facet (comma separated ordered names list)') ?></th> + <td><input type="text" name="s4w_facet_on_custom_fields" value="<?php print( s4w_filter_list2str(s4w_get_option('s4w_facet_on_custom_fields'), 'solr4wp')); ?>" /></td> + </tr> + + <tr valign="top"> + <th scope="row" style="width:200px;"><?php _e('Enable Spellchecking', 'solr4wp') ?></th> + <td style="width:10px;float:left;"><input type="checkbox" name="s4w_enable_dym" value="1" <?php echo s4w_checkCheckbox('s4w_enable_dym'); ?> /></td> + </tr> + <tr valign="top"> <th scope="row"><?php _e('Number of Results Per Page', 'solr4wp') ?></th> - <td><input type="text" name="s4w_num_results" value="<?php _e(get_option('s4w_num_results'), 'solr4wp'); ?>" /></td> + <td><input type="text" name="s4w_num_results" value="<?php _e(s4w_get_option('s4w_num_results'), 'solr4wp'); ?>" /></td> </tr> <tr valign="top"> <th scope="row"><?php _e('Max Number of Tags to Display', 'solr4wp') ?></th> - <td><input type="text" name="s4w_max_display_tags" value="<?php _e(get_option('s4w_max_display_tags'), 'solr4wp'); ?>" /></td> + <td><input type="text" name="s4w_max_display_tags" value="<?php _e(s4w_get_option('s4w_max_display_tags'), 'solr4wp'); ?>" /></td> </tr> </table> <hr /> <?php settings_fields('s4w-options-group'); ?> <p class="submit"> -<input type="submit" class="button-primary" value="<?php _e('Save Changes', 'solr4wp') ?>" /> +<input type="hidden" name="action" value="update" /> +<input id="settingsbutton" type="submit" class="button-primary" value="<?php _e('Save Changes', 'solr4wp') ?>" /> </p> </form> @@ -200,6 +296,11 @@ if ($_POST['s4w_ping']) { <td><input type="submit" class="button-primary" name="s4w_postload" value="<?php _e('Execute', 'solr4wp') ?>" /></td> </tr> + <tr valign="top"> + <th scope="row"><?php _e('Optimize Index', 'solr4wp') ?></th> + <td><input type="submit" class="button-primary" name="s4w_optimize" value="<?php _e('Execute', 'solr4wp') ?>" /></td> + </tr> + <tr valign="top"> <th scope="row"><?php _e('Delete All', 'solr4wp') ?></th> <td><input type="submit" class="button-primary" name="s4w_deleteall" value="<?php _e('Execute', 'solr4wp') ?>" /></td> @@ -207,4 +308,4 @@ if ($_POST['s4w_ping']) { </table> </form> -</div> \ No newline at end of file +</div> diff --git a/wp-content/plugins/solr-for-wordpress/template/autocomplete.css b/wp-content/plugins/solr-for-wordpress/template/autocomplete.css new file mode 100644 index 0000000000000000000000000000000000000000..1346245d032b0d29a4f9a9aa6ef642bec676cc3c --- /dev/null +++ b/wp-content/plugins/solr-for-wordpress/template/autocomplete.css @@ -0,0 +1,27 @@ +.ac_results { + border: 1px solid gray; + background-color: white; + padding: 0; + margin: 0; + list-style: none; + position: absolute; + z-index: 10000; + display: none; +} + +.ac_results li { + padding: 2px 5px; + white-space: nowrap; + color: #101010; + text-align: left; +} + +.ac_over { + cursor: pointer; + background-color: #F0F0B8; +} + +.ac_match { + text-decoration: underline; + color: black; +} \ No newline at end of file diff --git a/wp-content/plugins/solr-for-wordpress/template/s4w_search.php b/wp-content/plugins/solr-for-wordpress/template/s4w_search.php index cc87c089047bac2030608cd9f37b4bcde73fc2f2..7504cbcc053eecb5def2091d6655346e8070de30 100644 --- a/wp-content/plugins/solr-for-wordpress/template/s4w_search.php +++ b/wp-content/plugins/solr-for-wordpress/template/s4w_search.php @@ -6,11 +6,155 @@ Template Name: Search <?php get_header(); ?> <div id="content"> - <div id="form"> - <?php s4w_search_form(); ?> - </div> - <div id="resultwrap"> - <?php s4w_search_results(); ?> - </div> + +<div class="solr clearfix"> + + <?php $results = s4w_search_results(); ?> + + <div class="solr1 clearfix"> + <div class="solr_search"> + <?php if ($results['qtime']) { + printf("<label class='solr_response'>Response time: <span id=\"qrytime\">{$results['qtime']}</span> s</label>"); + } ?> + + <form name="searchbox" method="get" id="searchbox" action=""> + <input id="qrybox" name="s" type="text" class="solr_field" value="<?php echo $results['query'] ?>"/><input id="searchbtn" type="submit" value="Search" /> + </form> + </div> + + <?php if($results['dym']) { + printf("<div class='solr_suggest'>Did you mean: <a href='%s'>%s</a> ?</div>", $results['dym']['link'], $results['dym']['term']); + } ?> + + </div> + + <div class="solr2"> + + <div class="solr_results_header clearfix"> + <div class="solr_results_headerL"> + + <?php if ($results['hits'] && $results['query'] && $results['qtime']) { + if ($results['firstresult'] === $results['lastresult']) { + printf("Displaying result %s of <span id='resultcnt'>%s</span> hits", $results['firstresult'], $results['hits']); + } else { + printf("Displaying results %s-%s of <span id='resultcnt'>%s</span> hits", $results['firstresult'], $results['lastresult'], $results['hits']); + } + } ?> + + </div> + <div class="solr_results_headerR"> + <ol class="solr_sort2"> + <li class="solr_sort_drop"><a href="<?php echo $results['sorting']['scoredesc'] ?>">Relevance<span></span></a></li> + <li><a href="<?php echo $results['sorting']['datedesc'] ?>">Newest</a></li> + <li><a href="<?php echo $results['sorting']['dateasc'] ?>">Oldest</a></li> + <li><a href="<?php echo $results['sorting']['commentsdesc'] ?>">Most Comments</a></li> + <li><a href="<?php echo $results['sorting']['commentsasc'] ?>">Least Comments</a></li> + </ol> + <div class="solr_sort">Sort by:</div> + </div> + </div> + + <div class="solr_results"> + + <?php if ($results['hits'] === "0") { + printf("<div class='solr_noresult'> + <h2>Sorry, no results were found.</h2> + <h3>Perhaps you mispelled your search query, or need to try using broader search terms.</h3> + <p>For example, instead of searching for 'Apple iPhone 3.0 3GS', try something simple like 'iPhone'.</p> + </div>\n"); + } else { + printf("<ol>\n"); + foreach($results['results'] as $result) { + printf("<li onclick=\"window.location='%s'\">\n", $result['permalink']); + printf("<h2><a href='%s'>%s</a></h2>\n", $result['permalink'], $result['title']); + printf("<p>%s <a href='%s'>(comment match)</a></p>\n", $result['teaser'], $result['comment_link']); + printf("<label> By <a href='%s'>%s</a> in %s %s - <a href='%s'>%s comments</a></label>\n", + $result['authorlink'], + $result['author'], + get_the_category_list( ', ', '', $result['id']), + date('m/d/Y', strtotime($result['date'])), + $result['comment_link'], + $result['numcomments']); + printf("</li>\n"); + } + printf("</ol>\n"); + } ?> + + <?php if ($results['pager']) { + printf("<div class='solr_pages'>"); + $itemlinks = array(); + $pagecnt = 0; + $pagemax = 10; + $next = ''; + $prev = ''; + $found = false; + foreach($results['pager'] as $pageritm) { + if ($pageritm['link']) { + if ($found && $next === '') { + $next = $pageritm['link']; + } else if ($found == false) { + $prev = $pageritm['link']; + } + + $itemlinks[] = sprintf("<a href='%s'>%s</a>", $pageritm['link'], $pageritm['page']); + } else { + $found = true; + $itemlinks[] = sprintf("<a class='solr_pages_on' href='%s'>%s</a>", $pageritm['link'], $pageritm['page']); + } + + $pagecnt += 1; + if ($pagecnt == $pagemax) { + break; + } + } + + if ($prev !== '') { + printf("<a href='%s'>Previous</a>", $prev); + } + + foreach ($itemlinks as $itemlink) { + echo $itemlink; + } + + if ($next !== '') { + printf("<a href='%s'>Next</a>", $next); + } + + printf("</div>\n"); + } ?> + + + </div> + </div> + + <div class="solr3"> + <ul class="solr_facets"> + + <li class="solr_active"> + <ol> + <?php if ($results['facets']['selected']) { + foreach( $results['facets']['selected'] as $selectedfacet) { + printf("<li><span></span><a href=\"%s\">%s<b>x</b></a></li>", $selectedfacet['removelink'], $selectedfacet['name']); + } + } ?> + </ol> + </li> + + <?php if ($results['facets'] && $results['hits'] != 1) { + foreach($results['facets'] as $facet) { + if (sizeof($facet["items"]) > 1) { #don't display facets with only 1 value + printf("<li>\n<h3>%s</h3>\n", $facet['name']); + s4w_print_facet_items($facet["items"], "<ol>", "</ol>", "<li>", "</li>", + "<li><ol>", "</ol></li>", "<li>", "</li>"); + printf("</li>\n"); + } + } + } ?> + + </ul> + </div> + +</div> + </div> -<?php get_footer(); ?> \ No newline at end of file +<?php get_footer(); ?> diff --git a/wp-content/plugins/solr-for-wordpress/template/search.css b/wp-content/plugins/solr-for-wordpress/template/search.css index 2d9e36cebfe286da139cf1783d123d10c87262db..d5f4e28f06296442016f6dabd2cba8e9931b9641 100644 --- a/wp-content/plugins/solr-for-wordpress/template/search.css +++ b/wp-content/plugins/solr-for-wordpress/template/search.css @@ -1,106 +1,367 @@ -<style type="text/css"> - #content { - margin: 0px 10px 0px 10px; - padding: 10px 15px 5px 15px; - } - - #form { - width: 700px; - margin: 0 250px 0 250px; - position: relative; - top: 30px; - z-index: 20; - } - - #resultwrap { - position: relative; - top: -40px; - } - - #resultinfo { - float: left; - } - - #resultinfo em#resultcnt, - #resultinfo em#resultqry, - #resultinfo em#qrytime { - font-weight: bold; - } - - #resultpager { - float: right; - } +#content { + width: auto !important; +} - #resultpager ul { - list-style: none; - } +*+ html clearfix { + display: inline-block !important; +} +*+ html ul,ol { + list-style-position: outside !important; +} - #resultpager ul li { - display: inline; - list-style-type: none; - padding: 5px; - } - - #pagerclear { - clear: both; - height: 10px; - } - - #facets { - float: right; - width: 150px; - padding: 3px; - } - #facets ul.facets { - list-style: none; - } - - #facets ul.facets li.facet ul.facetitems { - list-style: none; - margin-left: 5px; - padding: 5px 0px 5px 0px; - } +.solr * { + line-height: 1 !important; + padding: 0 !important; + margin: 0 !important; + text-align: left !important; +} +.solr ol, .solr ul, .solr ol li, .solr ul li { + background: none !important; + list-style-type: none !important; + overflow: hidden !important; /* IE7 */ +} +.solr h2 {font-size:16px !important;} +.solr h3 {font-size:14px !important;} +.solr { + font-size: 12px !important; + line-height: 1 !important; + margin: 0 !important; + padding: 20px !important; + width: auto !important; +} +div.solr1 { + border-bottom: 1px solid #cccccc !important; + padding: 0 0 6px !important; +} +div.solr_search { + clear: both !important; + padding: 0 0 12px !important; +} +div.solr_search input { + font-size: 18px !important; +} +.solr_field { + border: 1px solid #b7b7b7 !important; + border-top: 2px solid #999999 !important; + padding: 3px !important; + margin: 0 8px 0 0 !important; + width: 330px !important; +} +ol.solr_auto { + background: #ffffff !important; + border: 1px solid #b7b7b7 !important; + width: 336px !important; + padding: 6px 0 !important; + position: absolute !important; + clear: both !important; /* IE6 */ + z-index: 100 !important; +} +.solr_auto li { + padding: 2px 8px !important; +} +.solr_auto li:hover { + background: #efffb0 !important; +} +div.solr_suggest { + padding: 0 0 5px !important; +} +label.solr_response { + font-size: 10px !important; + color: #666666 !important; + float: right !important; + position: relative !important; + top: 13px !important; +} +div.solr3 { + float: left !important; + padding: 18px 2% 0 0 !important; + width: 23% !important; +} +.solr_active span { + border-top: 4px solid #ffffff !important; + border-left: 5px solid #999999 !important; + border-bottom: 4px solid #ffffff !important; + font-size: 0 !important; + line-height: 0 !important; + width: 0 !important; + margin: 0 4px 0 0 !important; + position: relative !important; + bottom: 4px !important; + zoom: 1 !important; /* IE7 */ +} +.solr_active b { + font-family: Arial, Verdana, Helvetica, sans-serif !important; + font-weight: bold !important; + color: #999999 !important; +} +.solr_active a { + text-decoration: none !important; +} +.solr_facets ol li { + padding: 3px 0 3px !important; +} +.solr_facets ol li ol { + padding: 3px 0 0 10px !important; +} +.solr_facets h3 { + padding: 10px 0 3px !important; +} +.solr_active ol li { + padding: 3px 0 !important; +} +.solr_active a { + color: #000000 !important; +} +div.solr2 { + float: right !important; + padding: 8px 0 0 !important; + width: 70% !important; +} +div.solr_results_header { + font-size: 10px !important; + color: #666666 !important; + padding: 0 0 4px !important; +} +div.solr_results_headerL { + width: 60% !important; + float: left !important; + padding: 0 0 0 12px !important; +} +div.solr_results_headerR { + width: 35% !important; + font-weight: bold !important; + float: right !important; +} +.solr_sort { + margin: 4px 4px 0 0 !important; + float: right !important; +} +ol.solr_sort2 { + background: #ffffff !important; + text-decoration: none !important; + border: 1px solid #cccccc !important; + padding: 2px 0 1px !important; + float: right !important; +} +.solr_sort2 li { + display: block !important; /* FF3 */ + padding: 2px 2px 2px 4px !important; +} +.solr_sort2 li:hover { + background: #efffb0 !important; +} +.solr_sort2 a { + text-decoration: none !important; +} +.solr_sort_drop span { + border-top: 4px solid #999999 !important; + border-right: 4px solid #ffffff !important; + border-left: 5px solid #ffffff !important; + font-size: 0 !important; + line-height: 0 !important; + width: 0 !important; + margin: 0 0 0 2px !important; + position: relative !important; + bottom: 1px !important; + zoom: 1 !important; /* IE7 */ +} - #facets ul.facets li.facet ul.facetitems li.facetitem { - list-style-type: disc; - } +.solr_results ol { + font-size: 12px !important; + padding: 0 0 14px !important; + clear: both !important; /* IE7 */ +} +.solr_results li { + border-bottom: 1px solid #e6e6e6 !important; + padding: 14px 12px !important; +} +.solr_results li:hover { + background: #efffb0 !important; +} +.solr_results img { + height: 50px !important; + border: 1px solid #cccccc !important; + float: right !important; + display: block; + margin: 0 0 0 5px !important; +} +.solr_results h2 { + font-weight: normal !important; + line-height: 1.1 !important; + padding: 0 0 5px !important; +} +.solr_results label { + font-size: 10px !important; + color: #666666 !important; + padding: 5px 0 0 !important; + display: block !important; +} +.solr_pages { + font-size: 14px !important; + font-weight: bold !important; + text-align: right !important; +} +.solr_pages a { + margin: 0 0 0 5px !important; +} +.solr_pages_on { + color: #000000 !important; +} +div.solr_noresult { + padding: 20px 5% 40px 0 !important; +} +.solr_noresult h2 { + font-weight: normal !important; + line-height: 1.2 !important; + padding: 0 0 14px !important; +} +.solr_noresult h3 { + font-weight: normal !important; + line-height: 1.2 !important; + padding: 0 0 14px !important; +} +.solr_noresult p { + font-weight: normal !important; + line-height: 1.2 !important; +} - #facets ul.facets li.facet .facetchildren { - list-style: none; - margin-left: 5px; - padding: 0px; - } - - #results { - float: left; - width: 550px; - } - - .result { - text-align: justify; - } - - .result h3 { - font-family: Arial, Helvetica, Sans-Serif; - font-size: 0.9em; - line-height: 1.5em; - font-weight: none; - margin: 0px; - color: #777; - } - - .result p em, - .result em#resultauthor, - .result em#resultscore, { - font-weight: bold; - } - - .result p em { - color: #06c; - } - - #resultclear { - clear: both; - } -</style> \ No newline at end of file + +.solr_HL { + background: #efffb0 !important; +} + +.solr_admin { + font-size: 14px; + color: #464646; + min-width: 800px; + padding: 0 0 20px; +} +.solr_admin h4 { + font-family: Georgia; + font-size: 20px; + font-style: italic; + font-weight: normal; + margin: 0; +} +.solr_admin h4 input { + margin-right: 3px; +} +.solr_admin h5 { + font-size: 14px; + padding: 0 0 12px; +} +.solr_admin ol { + list-style-type: none; + width: 35%; + float: right; + position: relative; + left: 1px; + margin-left: 0; +} +.solr_admin li { + color: #999999; + background: #eeeeee; + padding: 12px; + margin-bottom: 0; +} +.solr_admin ol li ol { + width: auto; + float: none; + left: 0; + padding: 5px 0 0 32px; +} + +.solr_admin ol li ol li { + font-size: 12px; + line-height: 1.2; + background: none; + list-style-type: disc; + list-style-position: outside; + padding: 1px 0; +} + +.solr_admin_tab1 { + border: 1px solid #cccccc; + -moz-border-radius-topleft:6px; + -webkit-border-top-left-radius:6px; +} + +.solr_admin_tab2 { + border-right: 1px solid #cccccc; + border-bottom: 1px solid #cccccc; + border-left: 1px solid #cccccc; + -moz-border-radius-bottomleft:6px; + -webkit-border-bottom-left-radius:6px; +} + +.solr_admin_tab2 h4 { + font-size: 18px; +} +.solr_adminR { + background: #ffffff; + float: right; + width: 65%; +} + +li.solr_admin_on { + color: #464646; + background: #ffffff; + border-right: 1px solid #eeeeee; +} + +li.solr_admin_on li { + color: #464646; +} + +.solr_adminR1, .solr_adminR2 { + border: 1px solid #cccccc; + -moz-border-radius-topright:6px; + -moz-border-radius-bottomright:6px; + -moz-border-radius-bottomleft:6px; + -webkit-border-top-right-radius:6px; + -webkit-border-bottom-right-radius:6px; + -webkit-border-bottom-left-radius:6px; + padding: 24px 32px; +} +.solr_adminR2 { + display: none; +} +.solr_adminR label { + display: block; + padding: 0 0 2px 3px; +} +.solr_adminR span { + font-size: 11px; + font-weight: bold; + color: #00CC00; + font: block; + padding: 0 0 2px 3px; +} +span.solr_admin_warning { + color: #FF9900; +} +.solr_adminR p { + padding: 0 0 10px; +} +.solr_adminR input[type=text] { + width: 220px; +} + +/*CLEARFIX*/ +.clearfix:after { + content: " "; + display: block; + height: 0; + clear: both; + visibility: hidden; + font-size: 0; +} +.clearfix { + display: block;/*the holly hack for a bug in IE6 for Windows*/ +} +* html .clearfix {height: 1%;}/* Hides from IE-mac \*/ +/* END CLEARFIX*/ +.clear { + clear: both; +}