Similar Posts – Best Related Posts Plugin for WordPress - Version 2.6.2.0

Version Description

Download this release

Release Info

Developer RobMarsh
Plugin Icon 128x128 Similar Posts – Best Related Posts Plugin for WordPress
Version 2.6.2.0
Comparing to
See all releases

Code changes from version 2.6.1.3 to 2.6.2.0

Files changed (5) hide show
  1. readme.txt +10 -2
  2. similar-posts-admin.php +56 -21
  3. similar-posts.php +100 -90
  4. similar-posts.pot +248 -0
  5. uninstall.php +11 -0
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: RobMarsh
3
  Donate link: http://rmarsh.com/donate/similar-posts/
4
  Tags: posts, related, similar, related posts, similar posts, tags, post-plugins
5
  Requires at least: 1.5
6
- Tested up to: 2.6.1
7
- Stable tag: 2.6.1.3
8
  Displays a list of posts similar to the current one based on content, title and/or tags.
9
 
10
  == Description ==
@@ -31,6 +31,14 @@ This plugin **requires** the latest version of the *Post-Plugin Library:* [downl
31
 
32
  == Version History ==
33
 
 
 
 
 
 
 
 
 
34
  * 2.6.1.3
35
  * fix - german language stemmer was crashing if mb_string fucntions not available
36
  * 2.6.1.2
3
  Donate link: http://rmarsh.com/donate/similar-posts/
4
  Tags: posts, related, similar, related posts, similar posts, tags, post-plugins
5
  Requires at least: 1.5
6
+ Tested up to: 2.6.2
7
+ Stable tag: 2.6.2.0
8
  Displays a list of posts similar to the current one based on content, title and/or tags.
9
 
10
  == Description ==
31
 
32
  == Version History ==
33
 
34
+ * 2.6.2.0
35
+ * fixed a problem with the stemming algorithm and overused words
36
+ * introduced a first stab at fuzzy matching
37
+ * new {imagealt} output tag -- rather like {imagesrc}
38
+ * {excerpt} can now trim to whole sentences
39
+ * content filter can now take parameter string
40
+ * widget can now take parameter string
41
+ * output can be appended to posts & feeds
42
  * 2.6.1.3
43
  * fix - german language stemmer was crashing if mb_string fucntions not available
44
  * 2.6.1.2
similar-posts-admin.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- // Admin stuff for Similar Posts Plugin, Version 2.6.1.3
4
 
5
  function similar_posts_option_menu() {
6
  add_options_page(__('Similar Posts Options', 'similar_posts'), __('Similar Posts', 'similar_posts'), 8, 'similar-posts', 'similar_posts_options_page');
@@ -40,6 +40,7 @@ function similar_posts_options_page(){
40
  $m->add_subpage('General', 'general', 'similar_posts_general_options_subpage');
41
  $m->add_subpage('Output', 'output', 'similar_posts_output_options_subpage');
42
  $m->add_subpage('Filter', 'filter', 'similar_posts_filter_options_subpage');
 
43
  $m->add_subpage('Other', 'other', 'similar_posts_other_options_subpage');
44
  $m->add_subpage('Manage the Index', 'index', 'similar_posts_index_options_subpage');
45
  $m->add_subpage('Report a Bug', 'bug', 'similar_posts_bug_subpage');
@@ -172,6 +173,39 @@ function similar_posts_filter_options_subpage(){
172
  <?php
173
  }
174
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  function similar_posts_other_options_subpage(){
176
  global $wpdb, $wp_version;
177
  $options = get_option('similar-posts');
@@ -179,7 +213,7 @@ function similar_posts_other_options_subpage(){
179
  check_admin_referer('similar-posts-update-options');
180
  if (defined('POC_CACHE_4')) poc_cache_flush();
181
  // Fill up the options with the values chosen...
182
- $options = ppl_options_from_post($options, array('content_filter', 'stripcodes', 'feed_active', 'term_extraction', 'num_terms', 'weight_title', 'weight_content', 'weight_tags', 'hand_links'));
183
  $wcontent = $options['weight_content'] + 0.0001;
184
  $wtitle = $options['weight_title'] + 0.0001;
185
  $wtags = $options['weight_tags'] + 0.0001;
@@ -202,9 +236,8 @@ function similar_posts_other_options_subpage(){
202
  ppl_display_weights($options);
203
  ppl_display_num_terms($options['num_terms']);
204
  ppl_display_term_extraction($options['term_extraction']);
205
- ppl_display_feed_active($options['feed_active']);
206
  ppl_display_hand_links($options['hand_links']);
207
- ppl_display_content_filter($options['content_filter']);
208
  ppl_display_stripcodes($options['stripcodes']);
209
  ?>
210
  </table>
@@ -233,7 +266,7 @@ function similar_posts_index_options_subpage(){
233
  $options['batch'] = ppl_check_cardinal($_POST['batch']);
234
  if ($options['batch'] === 0) $options['batch'] = 100;
235
  flush();
236
- $termcount = save_index_entries (($options['utf8']==='true'), ($options['use_stemmer']==='true'), $options['batch'], ($options['cjk']==='true'));
237
  update_option('similar-posts', $options);
238
  //show a message
239
  printf('<div class="updated fade"><p>'.__('Indexed %d posts.').'</p></div>', $termcount);
@@ -248,7 +281,7 @@ function similar_posts_index_options_subpage(){
248
  echo '<p>'.__('The options that affect the index can be set below.', 'similar_posts').'</p>';
249
  echo '<p>'.__('If you are using a language other than english you may find that the plugin mangles some characters since PHP is normally blind to multibyte characters. You can force the plugin to interpret extended characters as UTF-8 at the expense of a little speed but this facility is only available if your installation of PHP supports the mbstring functions.', 'similar_posts').'</p>';
250
  echo '<p>'.__('Languages like Chinese, Korean and Japanese pose a special difficulty for the full-text search algorithm. As an experiment I have introduced an option below to work around some of these issues. The text must be encoded as UTF-8. I would be very grateful for feedback from any users knowledgeable in these languages.', 'similar_posts').'</p>';
251
- echo '<p>'.__('Some related word forms should really be counted together, e.g., "follow", "follows", and "following". The plugin can use a "stemming" algorithm to reduce related forms to their root stem. It is worth experimenting to see if this improves the similarity of posts in your particular circumstances. Stemming algorithms are provided for english, german, spanish, french and italian but stemmers for other languages can be created: see the help for instructions. Note: stemming slows down the indexing more than a little.', 'similar_posts').'</p>';
252
  echo '<p>'.__('The indexing routine processes posts in batches of 100 by default. If you run into problems with limited memory you can opt to make the batches smaller.', 'similar_posts').'</p>';
253
  echo '<p>'.__('Note: the process of indexing may take a little while. On my modest machine 500 posts take between 5 seconds and 20 seconds (with stemming and utf-8 support). Don\'t worry if the screen fails to update until finished.', 'similar_posts').'</p>';
254
  ?>
@@ -273,11 +306,12 @@ function similar_posts_index_options_subpage(){
273
  </td>
274
  </tr>
275
  <tr valign="top">
276
- <th scope="row"><?php _e('Use a stemming algorithm?', 'similar_posts') ?></th>
277
  <td>
278
  <select name="use_stemmer" id="use_stemmer">
279
- <option <?php if($options['use_stemmer'] == 'false') { echo 'selected="selected"'; } ?> value="false">No</option>
280
- <option <?php if($options['use_stemmer'] == 'true') { echo 'selected="selected"'; } ?> value="true">Yes</option>
 
281
  </select>
282
  </td>
283
  </tr>
@@ -301,15 +335,7 @@ function similar_posts_bug_subpage(){
301
  }
302
 
303
  function similar_posts_remove_subpage(){
304
- function eradicate() {
305
- global $wpdb, $table_prefix;
306
- delete_option('similar-posts');
307
- delete_option('similar-posts-feed');
308
- delete_option('widget_rrm_similar_posts');
309
- $table_name = $table_prefix . 'similar_posts';
310
- $wpdb->query("DROP TABLE `$table_name`");
311
- }
312
- ppl_plugin_eradicate_form('eradicate', str_replace('-admin', '', __FILE__));
313
  }
314
 
315
  function similar_posts_for_feed_options_page(){
@@ -505,7 +531,7 @@ function similar_posts_feed_remove_subpage(){
505
  }
506
 
507
  // sets up the index for the blog
508
- function save_index_entries ($utf8=false, $use_stemmer=false, $batch=100, $cjk=false) {
509
  global $wpdb, $table_prefix;
510
  //$t0 = microtime(true);
511
  $table_name = $table_prefix.'similar_posts';
@@ -611,7 +637,16 @@ function similar_posts_install() {
611
  $options = (array) get_option('similar-posts');
612
  // check each of the option values and, if empty, assign a default (doing it this long way
613
  // lets us add new options in later versions)
614
- if (!isset($options['feed_active'])) $options['feed_active'] = 'false';
 
 
 
 
 
 
 
 
 
615
  if (!isset($options['limit'])) $options['limit'] = 5;
616
  if (!isset($options['skip'])) $options['skip'] = 0;
617
  if (!isset($options['age'])) {$options['age']['direction'] = 'none'; $options['age']['length'] = '0'; $options['age']['duration'] = 'month';}
@@ -665,7 +700,7 @@ function similar_posts_install() {
665
 
666
  // initial creation of the index, if the table is empty
667
  $num_index_posts = $wpdb->get_var("SELECT COUNT(*) FROM `$table_name`");
668
- if ($num_index_posts == 0) save_index_entries (($options['utf8'] === 'true'), false, $options['batch'], ($options['cjk'] === 'true'));
669
 
670
  // deactivate legacy Similar Posts Feed if present
671
  $current = get_option('active_plugins');
1
  <?php
2
 
3
+ // Admin stuff for Similar Posts Plugin, Version 2.6.2.0
4
 
5
  function similar_posts_option_menu() {
6
  add_options_page(__('Similar Posts Options', 'similar_posts'), __('Similar Posts', 'similar_posts'), 8, 'similar-posts', 'similar_posts_options_page');
40
  $m->add_subpage('General', 'general', 'similar_posts_general_options_subpage');
41
  $m->add_subpage('Output', 'output', 'similar_posts_output_options_subpage');
42
  $m->add_subpage('Filter', 'filter', 'similar_posts_filter_options_subpage');
43
+ $m->add_subpage('Placement', 'placement', 'similar_posts_placement_options_subpage');
44
  $m->add_subpage('Other', 'other', 'similar_posts_other_options_subpage');
45
  $m->add_subpage('Manage the Index', 'index', 'similar_posts_index_options_subpage');
46
  $m->add_subpage('Report a Bug', 'bug', 'similar_posts_bug_subpage');
173
  <?php
174
  }
175
 
176
+ function similar_posts_placement_options_subpage(){
177
+ global $wpdb, $wp_version;
178
+ $options = get_option('similar-posts');
179
+ if (isset($_POST['update_options'])) {
180
+ check_admin_referer('similar-posts-update-options');
181
+ if (defined('POC_CACHE_4')) poc_cache_flush();
182
+ // Fill up the options with the values chosen...
183
+ $options = ppl_options_from_post($options, array('content_filter', 'widget_parameters', 'widget_condition', 'feed_on', 'feed_priority', 'feed_parameters', 'append_on', 'append_priority', 'append_parameters', 'append_condition'));
184
+ update_option('similar-posts', $options);
185
+ // Show a message to say we've done something
186
+ echo '<div class="updated fade"><p>' . __('Options saved', 'similar_posts') . '</p></div>';
187
+ }
188
+ //now we drop into html to display the option page form
189
+ ?>
190
+ <div class="wrap">
191
+ <h2><?php _e('Placement Settings', 'similar_posts'); ?></h2>
192
+ <form method="post" action="">
193
+ <div class="submit"><input type="submit" name="update_options" value="<?php _e('Save Placement Settings', 'similar_posts') ?>" /></div>
194
+ <table class="optiontable form-table">
195
+ <?php
196
+ ppl_display_append($options);
197
+ ppl_display_feed($options);
198
+ ppl_display_widget($options);
199
+ ppl_display_content_filter($options['content_filter']);
200
+ ?>
201
+ </table>
202
+ <div class="submit"><input type="submit" name="update_options" value="<?php _e('Save Placement Settings', 'similar_posts') ?>" /></div>
203
+ <?php if (function_exists('wp_nonce_field')) wp_nonce_field('similar-posts-update-options'); ?>
204
+ </form>
205
+ </div>
206
+ <?php
207
+ }
208
+
209
  function similar_posts_other_options_subpage(){
210
  global $wpdb, $wp_version;
211
  $options = get_option('similar-posts');
213
  check_admin_referer('similar-posts-update-options');
214
  if (defined('POC_CACHE_4')) poc_cache_flush();
215
  // Fill up the options with the values chosen...
216
+ $options = ppl_options_from_post($options, array('stripcodes', 'feed_active', 'term_extraction', 'num_terms', 'weight_title', 'weight_content', 'weight_tags', 'hand_links'));
217
  $wcontent = $options['weight_content'] + 0.0001;
218
  $wtitle = $options['weight_title'] + 0.0001;
219
  $wtags = $options['weight_tags'] + 0.0001;
236
  ppl_display_weights($options);
237
  ppl_display_num_terms($options['num_terms']);
238
  ppl_display_term_extraction($options['term_extraction']);
 
239
  ppl_display_hand_links($options['hand_links']);
240
+ ppl_display_feed_active($options['feed_active']);
241
  ppl_display_stripcodes($options['stripcodes']);
242
  ?>
243
  </table>
266
  $options['batch'] = ppl_check_cardinal($_POST['batch']);
267
  if ($options['batch'] === 0) $options['batch'] = 100;
268
  flush();
269
+ $termcount = save_index_entries (($options['utf8']==='true'), $options['use_stemmer'], $options['batch'], ($options['cjk']==='true'));
270
  update_option('similar-posts', $options);
271
  //show a message
272
  printf('<div class="updated fade"><p>'.__('Indexed %d posts.').'</p></div>', $termcount);
281
  echo '<p>'.__('The options that affect the index can be set below.', 'similar_posts').'</p>';
282
  echo '<p>'.__('If you are using a language other than english you may find that the plugin mangles some characters since PHP is normally blind to multibyte characters. You can force the plugin to interpret extended characters as UTF-8 at the expense of a little speed but this facility is only available if your installation of PHP supports the mbstring functions.', 'similar_posts').'</p>';
283
  echo '<p>'.__('Languages like Chinese, Korean and Japanese pose a special difficulty for the full-text search algorithm. As an experiment I have introduced an option below to work around some of these issues. The text must be encoded as UTF-8. I would be very grateful for feedback from any users knowledgeable in these languages.', 'similar_posts').'</p>';
284
+ echo '<p>'.__('Some related word forms should really be counted together, e.g., "follow", "follows", and "following". By default, Similar Posts treats such differences strictly but has two other algorithms which are more relaxed: <em>stemming</em> and <em>fuzzy matching</em>. The stemming algorithm tries to reduce related forms to their root stem. Stemming algorithms are provided for english, german, spanish, french and italian but stemmers for other languages can be created: see the help for instructions. Fuzzy matching uses the "metaphone" algorithm to handle word variations. Note: both stemming and fuzzy matching slow down the indexing more than a little. It is worth experimenting with the three possibilities to see what improves the similarity of posts in your particular circumstances.', 'similar_posts').'</p>';
285
  echo '<p>'.__('The indexing routine processes posts in batches of 100 by default. If you run into problems with limited memory you can opt to make the batches smaller.', 'similar_posts').'</p>';
286
  echo '<p>'.__('Note: the process of indexing may take a little while. On my modest machine 500 posts take between 5 seconds and 20 seconds (with stemming and utf-8 support). Don\'t worry if the screen fails to update until finished.', 'similar_posts').'</p>';
287
  ?>
306
  </td>
307
  </tr>
308
  <tr valign="top">
309
+ <th scope="row"><?php _e('Treat Related Word Variations:', 'similar_posts') ?></th>
310
  <td>
311
  <select name="use_stemmer" id="use_stemmer">
312
+ <option <?php if($options['use_stemmer'] == 'false') { echo 'selected="selected"'; } ?> value="false">Strictly</option>
313
+ <option <?php if($options['use_stemmer'] == 'true') { echo 'selected="selected"'; } ?> value="true">By Stem</option>
314
+ <option <?php if($options['use_stemmer'] == 'fuzzy') { echo 'selected="selected"'; } ?> value="fuzzy">Fuzzily</option>
315
  </select>
316
  </td>
317
  </tr>
335
  }
336
 
337
  function similar_posts_remove_subpage(){
338
+ ppl_plugin_eradicate_form(str_replace('-admin', '', __FILE__));
 
 
 
 
 
 
 
 
339
  }
340
 
341
  function similar_posts_for_feed_options_page(){
531
  }
532
 
533
  // sets up the index for the blog
534
+ function save_index_entries ($utf8=false, $use_stemmer='false', $batch=100, $cjk=false) {
535
  global $wpdb, $table_prefix;
536
  //$t0 = microtime(true);
537
  $table_name = $table_prefix.'similar_posts';
637
  $options = (array) get_option('similar-posts');
638
  // check each of the option values and, if empty, assign a default (doing it this long way
639
  // lets us add new options in later versions)
640
+ if (!isset($options['feed_active'])) $options['feed_active'] = 'false'; // deprecated
641
+ if (!isset($options['widget_condition'])) $options['widget_condition'] = '';
642
+ if (!isset($options['widget_parameters'])) $options['widget_parameters'] = '';
643
+ if (!isset($options['feed_on'])) $options['feed_on'] = 'false';
644
+ if (!isset($options['feed_priority'])) $options['feed_priority'] = '10';
645
+ if (!isset($options['feed_parameters'])) $options['feed_parameters'] = 'prefix=<strong>'.__('Similar Posts', 'similar-posts').':</strong><ul class="similar-posts">&suffix=</ul>';
646
+ if (!isset($options['append_on'])) $options['append_on'] = 'false';
647
+ if (!isset($options['append_priority'])) $options['append_priority'] = '10';
648
+ if (!isset($options['append_parameters'])) $options['append_parameters'] = 'prefix=<h3>'.__('Similar Posts', 'similar-posts').':</h3><ul class="similar-posts">&suffix=</ul>';
649
+ if (!isset($options['append_condition'])) $options['append_condition'] = 'is_single()';
650
  if (!isset($options['limit'])) $options['limit'] = 5;
651
  if (!isset($options['skip'])) $options['skip'] = 0;
652
  if (!isset($options['age'])) {$options['age']['direction'] = 'none'; $options['age']['length'] = '0'; $options['age']['duration'] = 'month';}
700
 
701
  // initial creation of the index, if the table is empty
702
  $num_index_posts = $wpdb->get_var("SELECT COUNT(*) FROM `$table_name`");
703
+ if ($num_index_posts == 0) save_index_entries (($options['utf8'] === 'true'), 'false', $options['batch'], ($options['cjk'] === 'true'));
704
 
705
  // deactivate legacy Similar Posts Feed if present
706
  $current = get_option('active_plugins');
similar-posts.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name:Similar Posts
4
  Plugin URI: http://rmarsh.com/plugins/similar-posts/
5
  Description: Displays a <a href="options-general.php?page=similar-posts.php">highly configurable</a> list of related posts. Similarity can be based on any combination of word usage in the content, title, or tags. Don't be disturbed if it takes a few moments to complete the installation -- the plugin is indexing your posts. <a href="http://rmarsh.com/plugins/post-options/">Instructions and help online</a>. Requires the latest version of the <a href="http://wordpress.org/extend/plugins/post-plugin-library/">Post-Plugin Library</a> to be installed.
6
- Version: 2.6.1.3
7
  Author: Rob Marsh, SJ
8
  Author URI: http://rmarsh.com/
9
  */
@@ -22,7 +22,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
  GNU General Public License for more details: http://www.gnu.org/licenses/gpl.txt
23
  */
24
 
25
- $similar_posts_version = $similar_posts_feed_version= '2.6.1.3';
26
 
27
  /*
28
  Template Tag: Displays the posts most similar to the current post.
@@ -142,6 +142,7 @@ class SimilarPosts {
142
  $sql .= "WHERE ".implode(' AND ', $where);
143
  if ($check_custom) $sql .= " GROUP BY $wpdb->posts.ID";
144
  $sql .= " ORDER BY score DESC LIMIT $limit";
 
145
  $results = $wpdb->get_results($sql);
146
  } else {
147
  $results = false;
@@ -274,11 +275,6 @@ function sp_terms_by_textrank($ID, $num_terms = 20) {
274
  return $res;
275
  }
276
 
277
- // do not try and use this function directly -- it is automatically installed when the option is set to show similar posts in feeds
278
- function similar_posts_for_feed($content) {
279
- return (is_feed()) ? $content . SimilarPosts::execute('', '<li>{link}</li>', 'similar-posts-feed') : $content;
280
- }
281
-
282
  function sp_save_index_entry($postID) {
283
  global $wpdb, $table_prefix;
284
  $table_name = $table_prefix . 'similar_posts';
@@ -288,9 +284,8 @@ function sp_save_index_entry($postID) {
288
  $options = get_option('similar-posts');
289
  $utf8 = ($options['utf8'] === 'true');
290
  $cjk = ($options['cjk'] === 'true');
291
- $use_stemmer = ($options['use_stemmer'] === 'true');
292
- $content = sp_get_post_terms($post['post_content'], $utf8, $use_stemmer, $cjk);
293
- $title = sp_get_title_terms($post['post_title'], $utf8, $use_stemmer, $cjk);
294
  $tags = sp_get_tag_terms($postID, $utf8);
295
  //check to see if the field is set
296
  $pid = $wpdb->get_var("SELECT pID FROM $table_name WHERE pID=$postID limit 1");
@@ -366,55 +361,45 @@ function sp_cjk_digrams($string) {
366
  function sp_get_post_terms($text, $utf8, $use_stemmer, $cjk) {
367
  global $overusedwords;
368
  if ($utf8) {
369
- if ($use_stemmer) {
370
- mb_regex_encoding('UTF-8');
371
- mb_internal_encoding('UTF-8');
372
- $wordlist = mb_split("\W+", sp_mb_clean_words($text));
373
- $words = '';
374
- reset($wordlist);
375
- while (list($n, $word) = each($wordlist)) {
376
- if ( mb_strlen($word) > 3) {
377
- $stem = sp_mb_str_pad(stem($word), 4, '_');
378
- if (!isset($overusedwords[$stem])) {
379
- $words .= $stem . ' ';
380
- }
381
- }
382
- }
383
- } else {
384
- mb_regex_encoding('UTF-8');
385
- mb_internal_encoding('UTF-8');
386
- $wordlist = mb_split("\W+", sp_mb_clean_words($text));
387
- $words = '';
388
- reset($wordlist);
389
- while (list($n, $word) = each($wordlist)) {
390
- if ( mb_strlen($word) > 3 && !isset($overusedwords[$word])) {
391
- $words .= $word . ' ';
392
- }
393
  }
394
- }
395
  } else {
396
- if ($use_stemmer) {
397
- $wordlist = str_word_count(sp_clean_words($text), 1);
398
- $words = '';
399
- reset($wordlist);
400
- while (list($n, $word) = each($wordlist)) {
401
- if ( strlen($word) > 3) {
402
- $stem = str_pad(stem($word), 4, '_');
403
- if (!isset($overusedwords[$stem])) {
404
- $words .= $stem . ' ';
405
- }
406
- }
407
- }
408
- } else {
409
- $wordlist = str_word_count(sp_clean_words($text), 1);
410
- $words = '';
411
- reset($wordlist);
412
- while (list($n, $word) = each($wordlist)) {
413
- if (strlen($word) > 3 && !isset($overusedwords[$word])) {
414
- $words .= $word . ' ';
415
- }
416
  }
417
- }
418
  }
419
  if ($cjk) $words = sp_cjk_digrams($words);
420
  return $words;
@@ -425,43 +410,41 @@ $tinywords = array('the' => 1, 'and' => 1, 'of' => 1, 'a' => 1, 'for' => 1, 'on'
425
  function sp_get_title_terms($text, $utf8, $use_stemmer, $cjk) {
426
  global $tinywords;
427
  if ($utf8) {
428
- if ($use_stemmer) {
429
- mb_regex_encoding('UTF-8');
430
- mb_internal_encoding('UTF-8');
431
- $wordlist = mb_split("\W+", sp_mb_clean_words($text));
432
- $words = '';
433
- foreach ($wordlist as $word) {
434
- if (!isset($tinywords[$word])) {
 
435
  $words .= sp_mb_str_pad(stem($word), 4, '_') . ' ';
436
- }
437
- }
438
- } else {
439
- mb_regex_encoding('UTF-8');
440
- mb_internal_encoding('UTF-8');
441
- $wordlist = mb_split("\W+", sp_mb_clean_words($text));
442
- $words = '';
443
- foreach ($wordlist as $word) {
444
- if (!isset($tinywords[$word])) {
445
  $words .= sp_mb_str_pad($word, 4, '_') . ' ';
446
- }
447
  }
448
- }
449
  } else {
450
- if ($use_stemmer) {
451
- $wordlist = str_word_count(sp_clean_words($text), 1);
452
- $words = '';
453
- foreach ($wordlist as $word) {
454
- if (!isset($tinywords[$word])) {
 
455
  $words .= str_pad(stem($word), 4, '_') . ' ';
456
- }
457
- }
458
- } else {
459
- $wordlist = str_word_count(sp_clean_words($text), 1);
460
- $words = '';
461
- foreach ($wordlist as $word) {
462
- if (!isset($tinywords[$word])) {
463
  $words .= str_pad($word, 4, '_') . ' ';
464
- }
465
  }
466
  }
467
  }
@@ -505,7 +488,18 @@ function widget_rrm_similar_posts_init() {
505
  function widget_rrm_similar_posts($args) {
506
  extract($args);
507
  $options = get_option('widget_rrm_similar_posts');
508
- $condition = ($options['condition']) ? $options['condition'] : 'true' ;
 
 
 
 
 
 
 
 
 
 
 
509
  $condition = (stristr($condition, "return")) ? $condition : "return ".$condition;
510
  $condition = rtrim($condition, '; ') . ' || is_admin();';
511
  if (eval($condition)) {
@@ -516,7 +510,9 @@ function widget_rrm_similar_posts_init() {
516
  $number = 1;
517
  else if ( $number > 15 )
518
  $number = 15;
519
- $output = SimilarPosts::execute('limit='.$number);
 
 
520
  if ($output) {
521
  echo $before_widget;
522
  echo $before_title.$title.$after_title;
@@ -575,13 +571,27 @@ require_once($languagedir.'stopwords.php');
575
  global $overusedwords;
576
  $overusedwords = array_flip($overusedwords);
577
 
 
 
 
 
 
578
  function similar_posts_init () {
579
  global $overusedwords, $wp_db_version;
580
  load_plugin_textdomain('similar_posts');
581
 
582
  $options = get_option('similar-posts');
583
- if ($options['content_filter'] === 'true' && function_exists('ppl_register_content_filter')) ppl_register_content_filter('SimilarPosts');
584
  if ($options['feed_active'] === 'true') add_filter('the_content', 'similar_posts_for_feed');
 
 
 
 
 
 
 
 
 
 
585
 
586
  //install the actions to keep the index up to date
587
  add_action('save_post', 'sp_save_index_entry', 1);
3
  Plugin Name:Similar Posts
4
  Plugin URI: http://rmarsh.com/plugins/similar-posts/
5
  Description: Displays a <a href="options-general.php?page=similar-posts.php">highly configurable</a> list of related posts. Similarity can be based on any combination of word usage in the content, title, or tags. Don't be disturbed if it takes a few moments to complete the installation -- the plugin is indexing your posts. <a href="http://rmarsh.com/plugins/post-options/">Instructions and help online</a>. Requires the latest version of the <a href="http://wordpress.org/extend/plugins/post-plugin-library/">Post-Plugin Library</a> to be installed.
6
+ Version: 2.6.2.0
7
  Author: Rob Marsh, SJ
8
  Author URI: http://rmarsh.com/
9
  */
22
  GNU General Public License for more details: http://www.gnu.org/licenses/gpl.txt
23
  */
24
 
25
+ $similar_posts_version = $similar_posts_feed_version= '2.6.2.0';
26
 
27
  /*
28
  Template Tag: Displays the posts most similar to the current post.
142
  $sql .= "WHERE ".implode(' AND ', $where);
143
  if ($check_custom) $sql .= " GROUP BY $wpdb->posts.ID";
144
  $sql .= " ORDER BY score DESC LIMIT $limit";
145
+ //echo $sql;
146
  $results = $wpdb->get_results($sql);
147
  } else {
148
  $results = false;
275
  return $res;
276
  }
277
 
 
 
 
 
 
278
  function sp_save_index_entry($postID) {
279
  global $wpdb, $table_prefix;
280
  $table_name = $table_prefix . 'similar_posts';
284
  $options = get_option('similar-posts');
285
  $utf8 = ($options['utf8'] === 'true');
286
  $cjk = ($options['cjk'] === 'true');
287
+ $content = sp_get_post_terms($post['post_content'], $utf8, $options['use_stemmer'], $cjk);
288
+ $title = sp_get_title_terms($post['post_title'], $utf8, $options['use_stemmer'], $cjk);
 
289
  $tags = sp_get_tag_terms($postID, $utf8);
290
  //check to see if the field is set
291
  $pid = $wpdb->get_var("SELECT pID FROM $table_name WHERE pID=$postID limit 1");
361
  function sp_get_post_terms($text, $utf8, $use_stemmer, $cjk) {
362
  global $overusedwords;
363
  if ($utf8) {
364
+ mb_regex_encoding('UTF-8');
365
+ mb_internal_encoding('UTF-8');
366
+ $wordlist = mb_split("\W+", sp_mb_clean_words($text));
367
+ $words = '';
368
+ reset($wordlist);
369
+ while (list($n, $word) = each($wordlist)) {
370
+ if ( mb_strlen($word) > 3 && !isset($overusedwords[$word])) {
371
+ switch ($use_stemmer) {
372
+ case 'true':
373
+ $words .= sp_mb_str_pad(stem($word), 4, '_') . ' ';
374
+ break;
375
+ case 'fuzzy':
376
+ $words .= sp_mb_str_pad(metaphone($word), 4, '_') . ' ';
377
+ break;
378
+ case 'false':
379
+ default:
380
+ $words .= $word . ' ';
381
+ }
 
 
 
 
 
 
382
  }
383
+ }
384
  } else {
385
+ $wordlist = str_word_count(sp_clean_words($text), 1);
386
+ $words = '';
387
+ reset($wordlist);
388
+ while (list($n, $word) = each($wordlist)) {
389
+ if ( strlen($word) > 3 && !isset($overusedwords[$word])) {
390
+ switch ($use_stemmer) {
391
+ case 'true':
392
+ $words .= str_pad(stem($word), 4, '_') . ' ';
393
+ break;
394
+ case 'fuzzy':
395
+ $words .= str_pad(metaphone($word), 4, '_') . ' ';
396
+ break;
397
+ case 'false':
398
+ default:
399
+ $words .= $word . ' ';
400
+ }
 
 
 
 
401
  }
402
+ }
403
  }
404
  if ($cjk) $words = sp_cjk_digrams($words);
405
  return $words;
410
  function sp_get_title_terms($text, $utf8, $use_stemmer, $cjk) {
411
  global $tinywords;
412
  if ($utf8) {
413
+ mb_regex_encoding('UTF-8');
414
+ mb_internal_encoding('UTF-8');
415
+ $wordlist = mb_split("\W+", sp_mb_clean_words($text));
416
+ $words = '';
417
+ foreach ($wordlist as $word) {
418
+ if (!isset($tinywords[$word])) {
419
+ switch ($use_stemmer) {
420
+ case 'true':
421
  $words .= sp_mb_str_pad(stem($word), 4, '_') . ' ';
422
+ break;
423
+ case 'fuzzy':
424
+ $words .= sp_mb_str_pad(metaphone($word), 4, '_') . ' ';
425
+ break;
426
+ case 'false':
427
+ default:
 
 
 
428
  $words .= sp_mb_str_pad($word, 4, '_') . ' ';
429
+ }
430
  }
431
+ }
432
  } else {
433
+ $wordlist = str_word_count(sp_clean_words($text), 1);
434
+ $words = '';
435
+ foreach ($wordlist as $word) {
436
+ if (!isset($tinywords[$word])) {
437
+ switch ($use_stemmer) {
438
+ case 'true':
439
  $words .= str_pad(stem($word), 4, '_') . ' ';
440
+ break;
441
+ case 'fuzzy':
442
+ $words .= str_pad(metaphone($word), 4, '_') . ' ';
443
+ break;
444
+ case 'false':
445
+ default:
 
446
  $words .= str_pad($word, 4, '_') . ' ';
447
+ }
448
  }
449
  }
450
  }
488
  function widget_rrm_similar_posts($args) {
489
  extract($args);
490
  $options = get_option('widget_rrm_similar_posts');
491
+ $opt = get_option('similar-posts');
492
+ $widget_condition = $opt['widget_condition'];
493
+ // the condition specified in the widget control overrides the placement setting screen
494
+ if ($options['condition']) {
495
+ $condition = $options['condition'];
496
+ } else {
497
+ if ($widget_condition) {
498
+ $condition = $widget_condition;
499
+ } else {
500
+ $condition = 'true';
501
+ }
502
+ }
503
  $condition = (stristr($condition, "return")) ? $condition : "return ".$condition;
504
  $condition = rtrim($condition, '; ') . ' || is_admin();';
505
  if (eval($condition)) {
510
  $number = 1;
511
  else if ( $number > 15 )
512
  $number = 15;
513
+ $options = get_option('recent-posts');
514
+ $widget_parameters = $options['widget_parameters'];
515
+ $output = SimilarPosts::execute('limit='.$number.'&'.$widget_parameters);
516
  if ($output) {
517
  echo $before_widget;
518
  echo $before_title.$title.$after_title;
571
  global $overusedwords;
572
  $overusedwords = array_flip($overusedwords);
573
 
574
+ // do not try and use this function directly -- it is automatically installed when the option is set to show similar posts in feeds // moreover it is deprecated and going soon
575
+ function similar_posts_for_feed($content) {
576
+ return (is_feed()) ? $content . SimilarPosts::execute('', '<li>{link}</li>', 'similar-posts-feed') : $content;
577
+ }
578
+
579
  function similar_posts_init () {
580
  global $overusedwords, $wp_db_version;
581
  load_plugin_textdomain('similar_posts');
582
 
583
  $options = get_option('similar-posts');
 
584
  if ($options['feed_active'] === 'true') add_filter('the_content', 'similar_posts_for_feed');
585
+ if ($options['content_filter'] === 'true' && function_exists('ppl_register_content_filter')) ppl_register_content_filter('SimilarPosts');
586
+ if ($options['feed_on'] === 'true' && function_exists('ppl_register_post_filter')) ppl_register_post_filter('feed', 'similar-posts', 'SimilarPosts');
587
+ if ($options['append_condition']) {
588
+ $condition = $options['append_condition'];
589
+ } else {
590
+ $condition = 'true';
591
+ }
592
+ $condition = (stristr($condition, "return")) ? $condition : "return ".$condition;
593
+ $condition = rtrim($condition, '; ') . ';';
594
+ if ($options['append_on'] === 'true' && function_exists('ppl_register_post_filter')) ppl_register_post_filter('append', 'similar-posts', 'SimilarPosts', $condition);
595
 
596
  //install the actions to keep the index up to date
597
  add_action('save_post', 'sp_save_index_entry', 1);
similar-posts.pot ADDED
@@ -0,0 +1,248 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SOME DESCRIPTIVE TITLE.
2
+ # Copyright (C) YEAR Rob Marsh, SJ
3
+ # This file is distributed under the same license as the PACKAGE package.
4
+ # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
+ #
6
+ #, fuzzy
7
+ msgid ""
8
+ msgstr ""
9
+ "Project-Id-Version: PACKAGE VERSION\n"
10
+ "Report-Msgid-Bugs-To: http://wordpress.org/tag/similar-posts\n"
11
+ "POT-Creation-Date: 2008-09-09 13:52+0000\n"
12
+ "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
+ "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
+ "Language-Team: LANGUAGE <LL@li.org>\n"
15
+ "MIME-Version: 1.0\n"
16
+ "Content-Type: text/plain; charset=CHARSET\n"
17
+ "Content-Transfer-Encoding: 8bit\n"
18
+
19
+ #: similar-posts-admin.php:6
20
+ msgid "Similar Posts Options"
21
+ msgstr ""
22
+
23
+ #: similar-posts-admin.php:6 similar-posts-admin.php:645
24
+ #: similar-posts-admin.php:648 similar-posts.php:506
25
+ msgid "Similar Posts"
26
+ msgstr ""
27
+
28
+ #: similar-posts-admin.php:12
29
+ msgid "Similar Posts Feed Options"
30
+ msgstr ""
31
+
32
+ #: similar-posts-admin.php:12
33
+ msgid "Similar Posts Feed"
34
+ msgstr ""
35
+
36
+ #: similar-posts-admin.php:34
37
+ msgid "Similar Posts "
38
+ msgstr ""
39
+
40
+ #: similar-posts-admin.php:36 similar-posts-admin.php:345
41
+ msgid "help and instructions"
42
+ msgstr ""
43
+
44
+ #: similar-posts-admin.php:38
45
+ #, php-format
46
+ msgid "Please install the %sPost Plugin Library%s plugin."
47
+ msgstr ""
48
+
49
+ #: similar-posts-admin.php:66 similar-posts-admin.php:106
50
+ #: similar-posts-admin.php:151 similar-posts-admin.php:186
51
+ #: similar-posts-admin.php:226 similar-posts-admin.php:367
52
+ #: similar-posts-admin.php:407 similar-posts-admin.php:452
53
+ #: similar-posts-admin.php:494
54
+ msgid "Options saved"
55
+ msgstr ""
56
+
57
+ #: similar-posts-admin.php:71 similar-posts-admin.php:372
58
+ msgid "General Settings"
59
+ msgstr ""
60
+
61
+ #: similar-posts-admin.php:73 similar-posts-admin.php:89
62
+ #: similar-posts-admin.php:374 similar-posts-admin.php:390
63
+ msgid "Save General Settings"
64
+ msgstr ""
65
+
66
+ #: similar-posts-admin.php:111 similar-posts-admin.php:412
67
+ msgid "Output Settings"
68
+ msgstr ""
69
+
70
+ #: similar-posts-admin.php:113 similar-posts-admin.php:134
71
+ #: similar-posts-admin.php:414 similar-posts-admin.php:435
72
+ msgid "Save Output Settings"
73
+ msgstr ""
74
+
75
+ #: similar-posts-admin.php:156 similar-posts-admin.php:457
76
+ msgid "Filter Settings"
77
+ msgstr ""
78
+
79
+ #: similar-posts-admin.php:158 similar-posts-admin.php:169
80
+ #: similar-posts-admin.php:459 similar-posts-admin.php:470
81
+ msgid "Save Filter Settings"
82
+ msgstr ""
83
+
84
+ #: similar-posts-admin.php:191
85
+ msgid "Placement Settings"
86
+ msgstr ""
87
+
88
+ #: similar-posts-admin.php:193 similar-posts-admin.php:202
89
+ msgid "Save Placement Settings"
90
+ msgstr ""
91
+
92
+ #: similar-posts-admin.php:231 similar-posts-admin.php:499
93
+ msgid "Other Settings"
94
+ msgstr ""
95
+
96
+ #: similar-posts-admin.php:233 similar-posts-admin.php:244
97
+ #: similar-posts-admin.php:501 similar-posts-admin.php:511
98
+ msgid "Save Other Settings"
99
+ msgstr ""
100
+
101
+ #: similar-posts-admin.php:272
102
+ #, php-format
103
+ msgid "Indexed %d posts."
104
+ msgstr ""
105
+
106
+ #: similar-posts-admin.php:279
107
+ msgid "Manage Index"
108
+ msgstr ""
109
+
110
+ #: similar-posts-admin.php:280
111
+ msgid ""
112
+ "Similar Posts maintains a special index to help search for related posts. "
113
+ "The index is created when the plugin is activated and then kept up-to-date "
114
+ "automatically when posts are added, edited, or deleted."
115
+ msgstr ""
116
+
117
+ #: similar-posts-admin.php:281
118
+ msgid "The options that affect the index can be set below."
119
+ msgstr ""
120
+
121
+ #: similar-posts-admin.php:282
122
+ msgid ""
123
+ "If you are using a language other than english you may find that the plugin "
124
+ "mangles some characters since PHP is normally blind to multibyte characters. "
125
+ "You \tcan force the plugin to interpret extended characters as UTF-8 at the "
126
+ "expense of a little speed but this facility is only available if your "
127
+ "installation of PHP supports the mbstring functions."
128
+ msgstr ""
129
+
130
+ #: similar-posts-admin.php:283
131
+ msgid ""
132
+ "Languages like Chinese, Korean and Japanese pose a special difficulty for "
133
+ "the full-text search algorithm. As an experiment I have introduced an option "
134
+ "below to work around some of these issues. The text must be encoded as UTF-"
135
+ "8. I would be very grateful for feedback from any users knowledgeable in "
136
+ "these languages."
137
+ msgstr ""
138
+
139
+ #: similar-posts-admin.php:284
140
+ msgid ""
141
+ "Some related word forms should really be counted together, e.g., \"follow\", "
142
+ "\"follows\", and \"following\". By default, Similar Posts treats such "
143
+ "differences strictly but has two other algorithms which are more relaxed: "
144
+ "<em>stemming</em> and <em>fuzzy matching</em>. The stemming algorithm tries "
145
+ "to reduce related forms to their root stem. Stemming algorithms are provided "
146
+ "for english, german, spanish, french and italian but stemmers for other "
147
+ "languages can be created: see the help for instructions. Fuzzy matching uses "
148
+ "the \"metaphone\" algorithm to handle word variations. Note: both stemming "
149
+ "and fuzzy matching slow down the indexing more than a little. It is worth "
150
+ "experimenting with the three possibilities to see what improves the "
151
+ "similarity of posts in your particular circumstances."
152
+ msgstr ""
153
+
154
+ #: similar-posts-admin.php:285
155
+ msgid ""
156
+ "The indexing routine processes posts in batches of 100 by default. If you "
157
+ "run into problems with limited memory you can opt to make the batches "
158
+ "smaller."
159
+ msgstr ""
160
+
161
+ #: similar-posts-admin.php:286
162
+ msgid ""
163
+ "Note: the process of indexing may take a little while. On my modest machine "
164
+ "500 posts take between 5 seconds and 20 seconds (with stemming and utf-8 "
165
+ "support). Don't worry if the screen fails to update until finished."
166
+ msgstr ""
167
+
168
+ #: similar-posts-admin.php:291
169
+ msgid "Handle extended characters?"
170
+ msgstr ""
171
+
172
+ #: similar-posts-admin.php:300
173
+ msgid "Treat as Chinese, Korean, or Japanese?"
174
+ msgstr ""
175
+
176
+ #: similar-posts-admin.php:309
177
+ msgid "Treat Related Word Variations:"
178
+ msgstr ""
179
+
180
+ #: similar-posts-admin.php:319
181
+ msgid "Batch size:"
182
+ msgstr ""
183
+
184
+ #: similar-posts-admin.php:324
185
+ msgid "Recreate Index"
186
+ msgstr ""
187
+
188
+ #: similar-posts-admin.php:343
189
+ msgid "Similar Posts Feed "
190
+ msgstr ""
191
+
192
+ #: similar-posts-admin.php:604 similar-posts-admin.php:660
193
+ msgid "None Found"
194
+ msgstr ""
195
+
196
+ #: similar-posts.php:57
197
+ msgid "Post-Plugin Library missing"
198
+ msgstr ""
199
+
200
+ #: similar-posts.php:538
201
+ msgid "Title:"
202
+ msgstr ""
203
+
204
+ #: similar-posts.php:539
205
+ msgid "Number of posts to show:"
206
+ msgstr ""
207
+
208
+ #: similar-posts.php:539
209
+ msgid "(at most 15)"
210
+ msgstr ""
211
+
212
+ #: similar-posts.php:540
213
+ #, php-format
214
+ msgid "Show only if page: (e.g., %sis_single()%s)"
215
+ msgstr ""
216
+
217
+ #: similar-posts.php:545 similar-posts.php:546
218
+ msgid "Similar Posts +"
219
+ msgstr ""
220
+
221
+ #. Plugin Name of an extension
222
+ msgid "Similar Posts"
223
+ msgstr ""
224
+
225
+ #. Plugin URI of an extension
226
+ msgid "http://rmarsh.com/plugins/similar-posts/"
227
+ msgstr ""
228
+
229
+ #. Description of an extension
230
+ msgid ""
231
+ "Displays a <a href=\"options-general.php?page=similar-posts.php\">highly "
232
+ "configurable</a> list of related posts. Similarity can be based on any "
233
+ "combination of word usage in the content, title, or tags. Don't be disturbed "
234
+ "if it takes a few moments to complete the installation -- the plugin is "
235
+ "indexing your posts. <a "
236
+ "href=\"http://rmarsh.com/plugins/post-options/\">Instructions and help "
237
+ "online</a>. Requires the latest version of the <a "
238
+ "href=\"http://wordpress.org/extend/plugins/post-plugin-library/\">Post-Plugin "
239
+ "Library</a> to be installed."
240
+ msgstr ""
241
+
242
+ #. Author of an extension
243
+ msgid "Rob Marsh, SJ"
244
+ msgstr ""
245
+
246
+ #. Author URI of an extension
247
+ msgid "http://rmarsh.com/"
248
+ msgstr ""
uninstall.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if (defined('ABSPATH') && defined('WP_UNINSTALL_PLUGIN')
3
+ && strtolower(WP_UNINSTALL_PLUGIN) === 'similar-posts/similar-posts.php') {
4
+ global $wpdb, $table_prefix;
5
+ delete_option('similar-posts');
6
+ delete_option('similar-posts-feed');
7
+ delete_option('widget_rrm_similar_posts');
8
+ $table_name = $table_prefix . 'similar_posts';
9
+ $wpdb->query("DROP TABLE `$table_name`");
10
+ }
11
+ ?>