SEO Smart Links - Version 2.2

Version Description

  • Added option to exclude certain posts and pages from automatic linking (credits to Gabriel Paladino)
Download this release

Release Info

Developer freediver
Plugin Icon 128x128 SEO Smart Links
Version 2.2
Comparing to
See all releases

Code changes from version 2.1 to 2.2

Files changed (2) hide show
  1. readme.txt +12 -21
  2. seo-links.php +553 -540
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: freediver
3
Donate link: https://www.networkforgood.org/donation/MakeDonation.aspx?ORGID2=520781390
4
Tags: Post, posts, comments, links, seo, google, automatic
5
Requires at least: 2.3
6
- Tested up to: 2.7
7
Stable tag: trunk
8
9
SEO Smart Links provides automatic SEO benefits for your site in addition to custom keyword lists, nofollow and much more.
@@ -19,31 +19,22 @@ Further SEO Smart links allows you to set up your own keywords and set of matchi
19
20
Everything happens completely transparent, and you can edit the options from the administration settings panel.
21
22
- What is new:
23
24
25
- v2.1
26
- - Performance optimization and new option to link to cats and tags with used at least n times (thanks Dominik Deobald!)
27
28
-
29
- v2.0
30
- - Added the option for case sensitive matching
31
-
32
- v1.9.3
33
- - Various improvements and bug fixes
34
-
35
- v1.8.0
36
- - Added support for non-english characters (Unicode)
37
- - Added support for keyword synonyms (in keywords section of the settings screen)
38
39
- v1.7.1
40
- - More performance optimizations
41
- - External links now work correctly for blogs on sites
42
-
43
- v1.7
44
- - Performance optimization of the plugin. SEO Smart Links causes much lesser strain on the server.
45
46
- Plugin by Vladimir Prelovac. Need help with <a href="http://www.prelovac.com/vladimir/services">WordPress SEO</a>?
47
48
== Credits ==
49
3
Donate link: https://www.networkforgood.org/donation/MakeDonation.aspx?ORGID2=520781390
4
Tags: Post, posts, comments, links, seo, google, automatic
5
Requires at least: 2.3
6
+ Tested up to: 2.8.4
7
Stable tag: trunk
8
9
SEO Smart Links provides automatic SEO benefits for your site in addition to custom keyword lists, nofollow and much more.
19
20
Everything happens completely transparent, and you can edit the options from the administration settings panel.
21
22
23
+ == Changelog ==
24
25
+ = 2.2 =
26
+ * Added option to exclude certain posts and pages from automatic linking (credits to Gabriel Paladino)
27
28
+ = 2.1 =
29
+ * Performance optimization and new option to link to cats and tags with used at least n times (thanks Dominik Deobald!)
30
31
32
+ = 2.0 =
33
+ * Added the option for case sensitive matching
34
+
35
+ = 1.8.0 =
36
+ * Added support for non-english characters (Unicode)
37
+ * Added support for keyword synonyms (in keywords section of the settings screen)
38
39
== Credits ==
40
seo-links.php CHANGED
@@ -1,541 +1,554 @@
1
- <?php
2
-
3
- /*
4
- Plugin Name: SEO Smart Links
5
- Version: 2.1
6
- Plugin URI: http://www.prelovac.com/vladimir/wordpress-plugins/seo-smart-links
7
- Author: Vladimir Prelovac</a>
8
- Author URI: http://www.prelovac.com/vladimir
9
- Description: SEO Smart Links provides automatic SEO benefits for your site in addition to custom keyword lists, nofollow and much more.
10
- */
11
-
12
- // todo It's possible to have option for case insensitive ?
13
- // $count in preg_replace, max links towards same url
14
- // If possible I'd be interested in having the plugin to not autolink keywords within (ie H1, H2 etc)
15
-
16
- // Avoid name collisions.
17
- if ( !class_exists('SEOLinks') ) :
18
-
19
- class SEOLinks {
20
-
21
- // Name for our options in the DB
22
- var $SEOLinks_DB_option = 'SEOLinks';
23
- var $SEOLinks_options;
24
-
25
- // Initialize WordPress hooks
26
- function SEOLinks() {
27
- $options = $this->get_options();
28
- if ($options)
29
- {
30
- if ($options['post'] || $options['page'])
31
- add_filter('the_content', array(&$this, 'SEOLinks_the_content_filter'), 10);
32
- if ($options['comment'])
33
- add_filter('comment_text', array(&$this, 'SEOLinks_comment_text_filter'), 10);
34
- }
35
-
36
- add_action( 'create_category', array(&$this, 'SEOLinks_delete_cache'));
37
- add_action( 'edit_category', array(&$this,'SEOLinks_delete_cache'));
38
- add_action( 'edit_post', array(&$this,'SEOLinks_delete_cache'));
39
- add_action( 'save_post', array(&$this,'SEOLinks_delete_cache'));
40
- // Add Options Page
41
- add_action('admin_menu', array(&$this, 'SEOLinks_admin_menu'));
42
-
43
- }
44
-
45
- function SEOLinks_process_text($text, $mode)
46
- {
47
-
48
- global $wpdb, $post;
49
-
50
- $options = $this->get_options();
51
-
52
- $links=0;
53
-
54
-
55
-
56
-
57
- if ($options['onlysingle'] && !(is_single() || is_page()))
58
- return $text;
59
-
60
- if (!$mode)
61
- {
62
- if ($post->post_type=='post' && !$options['post'])
63
- return $text;
64
- else if ($post->post_type=='page' && !$options['page'])
65
- return $text;
66
-
67
- if (($post->post_type=='page' && !$options['pageself']) || ($post->post_type=='post' && !$options['postself'])) {
68
-
69
- $thistitle=$options['casesens'] ? $post->post_title : strtolower($post->post_title);
70
- $thisurl=trailingslashit(get_permalink($post->ID));
71
- }
72
- else {
73
- $thistitle='';
74
- $thisurl='';
75
- }
76
-
77
- }
78
-
79
-
80
- $maxlinks=($options['maxlinks']>0) ? $options['maxlinks'] : 0;
81
- $maxsingle=($options['maxsingle']>0) ? $options['maxsingle'] : -1;
82
- $minusage = ($options['minusage']>0) ? $options['minusage'] : 1;
83
-
84
- $arrignore=$this->explode_trim(",", ($options['ignore']));
85
-
86
- // $reg_post = $options['casesens'] ? '/(?!(?:[^<]+>|[^>]+<\/a>))($name)/msU' : '/(?!(?:[^<]+>|[^>]+<\/a>))($name)/imsU';
87
- // $reg = $options['casesens'] ? '/(?!(?:[^<]+>|[^>]+<\/a>))\b($name)\b/msU' : '/(?!(?:[^<]+>|[^>]+<\/a>))\b($name)\b/imsU';
88
- $reg_post = $options['casesens'] ? '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))($name)/msU' : '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))($name)/imsU';
89
- $reg = $options['casesens'] ? '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))\b($name)\b/msU' : '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))\b($name)\b/imsU';
90
- $strpos_fnc = $options['casesens'] ? 'strpos' : 'stripos';
91
-
92
- $text = " $text ";
93
-
94
- // custom keywords
95
- if (!empty($options['customkey']))
96
- {
97
- $kw_array = array();
98
-
99
- // thanks PK for the suggestion
100
- foreach (explode("\n", $options['customkey']) as $line) {
101
- $chunks = array_map('trim', explode(",", $line));
102
- $total_chuncks = count($chunks);
103
- if($total_chuncks > 2) {
104
- $i = 0;
105
- $url = $chunks[$total_chuncks-1];
106
- while($i < $total_chuncks-1) {
107
- if (!empty($chunks[$i])) $kw_array[$chunks[$i]] = $url;
108
- $i++;
109
- }
110
- } else {
111
- list($keyword, $url) = array_map('trim', explode(",", $line, 2));
112
- if (!empty($keyword)) $kw_array[$keyword] = $url;
113
- }
114
- }
115
-
116
- /*foreach (explode("\n", $options['customkey']) as $line) {
117
- list($keyword, $url) = array_map('trim', explode(",", $line, 2));
118
- if (!empty($keyword)) $kw_array[$keyword] = $url;
119
- }*/
120
-
121
- foreach ($kw_array as $name=>$url)
122
- {
123
-
124
- if ((!$maxlinks || ($links < $maxlinks)) && (trailingslashit($url)!=$thisurl) && !in_array( $options['casesens'] ? $name : strtolower($name), $arrignore))
125
- {
126
- if ($strpos_fnc($text, $name) !== false) { // credit to Dominik Deobald
127
- $name= preg_quote($name, '/');
128
-
129
- $replace="<a title=\"$1\" href=\"$url\">$1</a>";
130
- $regexp=str_replace('$name', $name, $reg);
131
- //$regexp="/(?!(?:[^<]+>|[^>]+<\/a>))(?<!\p{L})($name)(?!\p{L})/imsU";
132
- $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
133
- if ($newtext!=$text) {
134
- $links++;
135
- $text=$newtext;
136
- }
137
- }
138
- }
139
- }
140
- }
141
-
142
-
143
- // posts and pages
144
- if ($options['lposts'] || $options['lpages'])
145
- {
146
- if ( !$posts = wp_cache_get( 'seo-links-posts', 'seo-smart-links' ) ) {
147
- $query="SELECT post_title, ID, post_type FROM $wpdb->posts WHERE post_status = 'publish' AND LENGTH(post_title)>3 ORDER BY LENGTH(post_title) DESC";
148
- $posts = $wpdb->get_results($query);
149
-
150
- wp_cache_add( 'seo-links-posts', $posts, 'seo-smart-links', 86400 );
151
- }
152
-
153
-
154
- foreach ($posts as $postitem)
155
- {
156
- if ((($options['lposts'] && $postitem->post_type=='post') || ($options['lpages'] && $postitem->post_type=='page')) &&
157
- (!$maxlinks || ($links < $maxlinks)) && (($options['casesens'] ? $postitem->post_title : strtolower($postitem->post_title))!=$thistitle) && (!in_array( ($options['casesens'] ? $postitem->post_title : strtolower($postitem->post_title)), $arrignore)) )
158
- {
159
- if ($strpos_fnc($text, $postitem->post_title) !== false) { // credit to Dominik Deobald
160
- $name = preg_quote($postitem->post_title, '/');
161
-
162
- $regexp=str_replace('$name', $name, $reg_post);
163
-
164
-
165
- $replace='<a title="$1" href="$$url$quot;>$1</a>';
166
-
167
- $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
168
- if ($newtext!=$text) {
169
- $url = get_permalink($postitem->ID);
170
- $links++;
171
- $text=str_replace('$$url$#x27;, $url, $newtext);
172
- }
173
- }
174
- }
175
- }
176
- }
177
-
178
- // categories
179
- if ($options['lcats'])
180
- {
181
- if ( !$categories = wp_cache_get( 'seo-links-categories', 'seo-smart-links' ) ) {
182
-
183
- $query="SELECT $wpdb->terms.name, $wpdb->terms.term_id FROM $wpdb->terms LEFT JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE $wpdb->term_taxonomy.taxonomy = 'category' AND LENGTH($wpdb->terms.name)>3 AND $wpdb->term_taxonomy.count >= $minusage ORDER BY LENGTH($wpdb->terms.name) DESC";
184
- $categories = $wpdb->get_results($query);
185
-
186
- wp_cache_add( 'seo-links-categories', $categories, 'seo-smart-links',86400 );
187
- }
188
-
189
- foreach ($categories as $cat)
190
- {
191
- if ((!$maxlinks || ($links < $maxlinks)) && !in_array( $options['casesens'] ? $cat->name : strtolower($cat->name), $arrignore) )
192
- {
193
- if ($strpos_fnc($text, $cat->name) !== false) { // credit to Dominik Deobald
194
- $name= preg_quote($cat->name, '/');
195
- $regexp=str_replace('$name', $name, $reg); ;
196
- $replace='<a title="$1" href="$$url$quot;>$1</a>';
197
-
198
- $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
199
- if ($newtext!=$text) {
200
- $url = (get_category_link($cat->term_id));
201
- $links++;
202
- $text=str_replace('$$url$#x27;, $url, $newtext);
203
- }
204
- }
205
- }
206
- }
207
- }
208
-
209
- // tags
210
- if ($options['ltags'])
211
- {
212
- if ( !$tags = wp_cache_get( 'seo-links-tags', 'seo-smart-links' ) ) {
213
-
214
- $query="SELECT $wpdb->terms.name, $wpdb->terms.term_id FROM $wpdb->terms LEFT JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE $wpdb->term_taxonomy.taxonomy = 'post_tag' AND LENGTH($wpdb->terms.name)>3 AND $wpdb->term_taxonomy.count >= $minusage ORDER BY LENGTH($wpdb->terms.name) DESC";
215
- $tags = $wpdb->get_results($query);
216
-
217
- wp_cache_add( 'seo-links-tags', $tags, 'seo-smart-links',86400 );
218
- }
219
-
220
- foreach ($tags as $tag)
221
- {
222
- if ((!$maxlinks || ($links < $maxlinks)) && !in_array( $options['casesens'] ? $tag->name : strtolower($tag->name), $arrignore) )
223
- {
224
- if ($strpos_fnc($text, $tag->name) !== false) { // credit to Dominik Deobald
225
- $name = preg_quote($tag->name, '/');
226
- $regexp=str_replace('$name', $name, $reg); ;
227
- $replace='<a title="$1" href="$$url$quot;>$1</a>';
228
-
229
- $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
230
- if ($newtext!=$text) {
231
- $url = (get_tag_link($tag->term_id));
232
- $links++;
233
- $text=str_replace('$$url$#x27;, $url, $newtext);
234
- }
235
- }
236
- }
237
- }
238
- }
239
-
240
- return trim( $text );
241
-
242
- }
243
-
244
- function SEOLinks_the_content_filter($text) {
245
-
246
- $result=$this->SEOLinks_process_text($text, 0);
247
-
248
- $options = $this->get_options();
249
- $link=parse_url(get_bloginfo('wpurl'));
250
- $host='http://'.$link['host'];
251
-
252
- if ($options['blanko'])
253
- $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a target="_blank"\\1', $result); // credit to Kaf Oseo
254
-
255
- if ($options['nofolo'])
256
- $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a rel="nofollow"\\1', $result);
257
- return $result;
258
- }
259
-
260
- function SEOLinks_comment_text_filter($text) {
261
- $result = $this->SEOLinks_process_text($text, 1);
262
-
263
- $options = $this->get_options();
264
- $link=parse_url(get_bloginfo('wpurl'));
265
- $host='http://'.$link['host'];
266
-
267
- if ($options['blanko'])
268
- $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a target="_blank"\\1', $result); // credit to Kaf Oseo
269
-
270
- if ($options['nofolo'])
271
- $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a rel="nofollow"\\1', $result);
272
-
273
- return $result;
274
- }
275
-
276
- function explode_trim($separator, $text)
277
- {
278
- $arr = explode($separator, $text);
279
-
280
- $ret = array();
281
- foreach($arr as $e)
282
- {
283
- $ret[] = trim($e);
284
- }
285
- return $ret;
286
- }
287
-
288
- // Handle our options
289
- function get_options() {
290
-
291
- $options = array(
292
- 'post' => 'on',
293
- 'postself' => '',
294
- 'page' => 'on',
295
- 'pageself' => '',
296
- 'comment' => '',
297
- 'lposts' => 'on',
298
- 'lpages' => 'on',
299
- 'lcats' => '',
300
- 'ltags' => '',
301
- 'ignore' => 'about,',
302
- 'maxlinks' => 3,
303
- 'maxsingle' => 1,
304
- 'minusage' => 1,
305
- 'customkey' => '',
306
- 'nofoln' =>'',
307
- 'nofolo' =>'',
308
- 'blankn' =>'',
309
- 'blanko' =>'',
310
- 'onlysingle' => 'on',
311
- 'casesens' =>''
312
-
313
- );
314
-
315
- $saved = get_option($this->SEOLinks_DB_option);
316
-
317
-
318
- if (!empty($saved)) {
319
- foreach ($saved as $key => $option)
320
- $options[$key] = $option;
321
- }
322
-
323
- if ($saved != $options)
324
- update_option($this->SEOLinks_DB_option, $options);
325
-
326
- return $options;
327
-
328
- }
329
-
330
-
331
-
332
- // Set up everything
333
- function install() {
334
- $SEOLinks_options = $this->get_options();
335
-
336
-
337
- }
338
-
339
- function handle_options()
340
- {
341
-
342
- $options = $this->get_options();
343
- if ( isset($_POST['submitted']) ) {
344
-
345
- check_admin_referer('seo-smart-links');
346
-
347
- $options['post']=$_POST['post'];
348
- $options['postself']=$_POST['postself'];
349
- $options['page']=$_POST['page'];
350
- $options['pageself']=$_POST['pageself'];
351
- $options['comment']=$_POST['comment'];
352
- $options['lposts']=$_POST['lposts'];
353
- $options['lpages']=$_POST['lpages'];
354
- $options['lcats']=$_POST['lcats'];
355
- $options['ltags']=$_POST['ltags'];
356
- $options['ignore']=$_POST['ignore'];
357
- $options['maxlinks']=(int) $_POST['maxlinks'];
358
- $options['maxsingle']=(int) $_POST['maxsingle'];
359
- $options['minusage']=(int) $_POST['minusage']; // credit to Dominik Deobald
360
- $options['customkey']=$_POST['customkey'];
361
- $options['nofoln']=$_POST['nofoln'];
362
- $options['nofolo']=$_POST['nofolo'];
363
- $options['blankn']=$_POST['blankn'];
364
- $options['blanko']=$_POST['blanko'];
365
- $options['onlysingle']=$_POST['onlysingle'];
366
- $options['casesens']=$_POST['casesens'];
367
-
368
-
369
- update_option($this->SEOLinks_DB_option, $options);
370
- $this->SEOLinks_delete_cache(0);
371
- echo '<div class="updated fade"><p>Plugin settings saved.</p></div>';
372
- }
373
-
374
-
375
-
376
-
377
- $action_url = $_SERVER['REQUEST_URI'];
378
-
379
- $post=$options['post']=='on'?'checked':'';
380
- $postself=$options['postself']=='on'?'checked':'';
381
- $page=$options['page']=='on'?'checked':'';
382
- $pageself=$options['pageself']=='on'?'checked':'';
383
- $comment=$options['comment']=='on'?'checked':'';
384
- $lposts=$options['lposts']=='on'?'checked':'';
385
- $lpages=$options['lpages']=='on'?'checked':'';
386
- $lcats=$options['lcats']=='on'?'checked':'';
387
- $ltags=$options['ltags']=='on'?'checked':'';
388
- $ignore=$options['ignore'];
389
- $maxlinks=$options['maxlinks'];
390
- $maxsingle=$options['maxsingle'];
391
- $minusage=$options['minusage'];
392
- $customkey=stripslashes($options['customkey']);
393
- $nofoln=$options['nofoln']=='on'?'checked':'';
394
- $nofolo=$options['nofolo']=='on'?'checked':'';
395
- $blankn=$options['blankn']=='on'?'checked':'';
396
- $blanko=$options['blanko']=='on'?'checked':'';
397
- $onlysingle=$options['onlysingle']=='on'?'checked':'';
398
- $casesens=$options['casesens']=='on'?'checked':'';
399
-
400
- if (!is_numeric($minusage)) $minusage = 1;
401
-
402
- $nonce=wp_create_nonce( 'seo-smart-links');
403
-
404
- $imgpath=trailingslashit(get_option('siteurl')). 'wp-content/plugins/seo-automatic-links/i';
405
- echo <<<END
406
-
407
- <div class="wrap" style="max-width:950px !important;">
408
- <h2>SEO Smart Links</h2>
409
-
410
- <div id="poststuff" style="margin-top:10px;">
411
-
412
- <div id="sideblock" style="float:right;width:220px;margin-left:10px;">
413
- <h2>Information</h2>
414
- <div id="dbx-content" style="text-decoration:none;">
415
- <img src="$imgpath/home.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/wordpress-plugins/seo-smart-links"> SEO Smart Links Home</a><br />
416
- <img src="$imgpath/rate.png"><a style="text-decoration:none;" href="http://wordpress.org/extend/plugins/seo-automatic-links/"> Rate this plugin</a><br />
417
- <img src="$imgpath/help.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/forum"> Support and Help</a><br />
418
- <br />
419
- <a style="text-decoration:none;" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2567254"><img src="$imgpath/paypal.gif"></a>
420
- <br /><br />
421
- <img src="$imgpath/more.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/wordpress-plugins"> Cool WordPress Plugins</a><br />
422
- <img src="$imgpath/twit.png"><a style="text-decoration:none;" href="http://twitter.com/vprelovac"> Follow updates on Twitter</a><br />
423
- <img src="$imgpath/idea.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/services"> Need a WordPress Expert?</a>
424
- </div>
425
- </div>
426
-
427
- <div id="mainblock" style="width:710px">
428
-
429
- <div class="dbx-content">
430
- <form name="SEOLinks" action="$action_url" method="post">
431
- <input type="hidden" id="_wpnonce" name="_wpnonce" value="$nonce" />
432
- <input type="hidden" name="submitted" value="1" />
433
- <h2>Overview</h2>
434
-
435
- <p>SEO Smart Links can automatically link keywords and phrases in your posts and comments with corresponding posts, pages, categories and tags on your blog.</p>
436
- <p>Further SEO Smart links allows you to set up your own keywords and set of matching URLs.</p>
437
- <p>Finally SEO Smart links allows you to set nofollow attribute and open links in new window.</p>
438
-
439
- <h2>Internal Links</h2>
440
- <p>SEO Smart Links can process your posts, pages and comments in search for keywords to automatically interlink.</p>
441
- <input type="checkbox" name="post" $post/><label for="post"> Posts</label>
442
- <ul>&nbsp;<input type="checkbox" name="postself" $postself/><label for="postself"> Allow links to self</label></ul>
443
- <br />
444
- <input type="checkbox" name="page" $page/><label for="page"> Pages</label>
445
- <ul>&nbsp;<input type="checkbox" name="pageself" $pageself/><label for="pageself"> Allow links to self</label></ul>
446
- <br />
447
- <input type="checkbox" name="comment" $comment /><label for="comment"> Comments</label> (may slow down performance) <br>
448
-
449
- <h4>Target</h4>
450
- <p>The targets SEO Smart links should consider. The match will be based on post/page title or category/tag name, case insensitive.</p>
451
- <input type="checkbox" name="lposts" $lposts /><label for="lposts"> Posts</label> <br>
452
- <input type="checkbox" name="lpages" $lpages /><label for="lpages"> Pages</label> <br>
453
- <input type="checkbox" name="lcats" $lcats /><label for="lcats"> Categories</label> (may slow down performance) <br>
454
- <input type="checkbox" name="ltags" $ltags /><label for="ltags"> Tags</label> (may slow down performance) <br>
455
- <br>
456
- Link tags and categories that have been used at least <input type="text" name="minusage" size="2" value="$minusage"/> times.
457
- <br>
458
-
459
- <h2>Settings</h2>
460
- <p>To reduce database load you can choose to have SEO SMART links work only on single posts and pages (for example not on main page or archives).</p>
461
- <input type="checkbox" name="onlysingle" $onlysingle /><label for="onlysingle"> Process only single posts and pages</label> <br>
462
-
463
- <p>Set whether matching should be case sensitive.</p>
464
- <input type="checkbox" name="casesens" $casesens /><label for="casesens"> Case sensitive matching</label> <br>
465
-
466
- <h4>Ignore keywords</h4>
467
- <p>You may wish to ignore certain words or phrases from automatic linking. Seperate them by comma.</p>
468
- <input type="text" name="ignore" size="90" value="$ignore"/>
469
- <br><br>
470
-
471
-
472
- <h4>Custom Keywords</h4>
473
- <p>Here you can enter manually the extra keywords you want to automaticaly link. Use comma to seperate keywords and add target url at the end. Use a new line for new url and set of keywords. You can have these keywords link to any url, not only your site.</p>
474
- <p>Example:<br />
475
- vladimir prelovac, http://www.prelovac.com/vladimir<br />
476
- cars, car, autos, auto, http://mycarblog.com/<br />
477
- </p>
478
-
479
- <textarea name="customkey" id="customkey" rows="10" cols="90" >$customkey</textarea>
480
- <br><br>
481
-
482
- <h4>Limits</h4>
483
- <p>You can limit the maximum number of links SEO Smart Links will generate per post. Set to 0 for no limit. </p>
484
- Max Links: <input type="text" name="maxlinks" size="2" value="$maxlinks"/>
485
- <p>You can also limit maximum number of links created with the same keyword. Set to 0 for no limit. </p>
486
- Max Single: <input type="text" name="maxsingle" size="2" value="$maxsingle"/>
487
- <br><br>
488
-
489
- <h4>External Links</h4>
490
- <p>SEO Smart links can open external links in new window and add nofollow attribute.</p>
491
-
492
-
493
- <input type="checkbox" name="nofolo" $nofolo /><label for="nofolo"> Add nofollow attribute</label> <br>
494
-
495
-
496
- <input type="checkbox" name="blanko" $blanko /><label for="blanko"> Open in new window</label> <br>
497
-
498
-
499
- <div class="submit"><input type="submit" name="Submit" value="Update options" class="button-primary" /></div>
500
- </form>
501
- </div>
502
-
503
- <br/><br/><h3>&nbsp;</h3>
504
- </div>
505
-
506
- </div>
507
-
508
- <h5>WordPress plugin by <a href="http://www.prelovac.com/vladimir/">Vladimir Prelovac</a></h5>
509
- </div>
510
- END;
511
-
512
-
513
- }
514
-
515
- function SEOLinks_admin_menu()
516
- {
517
- add_options_page('SEO Smart Links Options', 'SEO Smart Links', 8, basename(__FILE__), array(&$this, 'handle_options'));
518
- }
519
-
520
- function SEOLinks_delete_cache($id) {
521
- wp_cache_delete( 'seo-links-categories', 'seo-smart-links' );
522
- wp_cache_delete( 'seo-links-tags', 'seo-smart-links' );
523
- wp_cache_delete( 'seo-links-posts', 'seo-smart-links' );
524
- }
525
- //add_action( 'comment_post', 'SEOLinks_delete_cache');
526
- //add_action( 'wp_set_comment_status', 'SEOLinks_delete_cache');
527
-
528
-
529
- }
530
-
531
- endif;
532
-
533
- if ( class_exists('SEOLinks') ) :
534
-
535
- $SEOLinks = new SEOLinks();
536
- if (isset($SEOLinks)) {
537
- register_activation_hook( __FILE__, array(&$SEOLinks, 'install') );
538
- }
539
- endif;
540
-
541
?>
1
+ <?php
2
+
3
+ /*
4
+ Plugin Name: SEO Smart Links
5
+ Version: 2.2
6
+ Plugin URI: http://www.prelovac.com/vladimir/wordpress-plugins/seo-smart-links
7
+ Author: Vladimir Prelovac</a>
8
+ Author URI: http://www.prelovac.com/vladimir
9
+ Description: SEO Smart Links provides automatic SEO benefits for your site in addition to custom keyword lists, nofollow and much more.
10
+ */
11
+
12
+ // todo It's possible to have option for case insensitive ?
13
+ // $count in preg_replace, max links towards same url
14
+ // If possible I'd be interested in having the plugin to not autolink keywords within (ie H1, H2 etc)
15
+
16
+ // Avoid name collisions.
17
+ if ( !class_exists('SEOLinks') ) :
18
+
19
+ class SEOLinks {
20
+
21
+ // Name for our options in the DB
22
+ var $SEOLinks_DB_option = 'SEOLinks';
23
+ var $SEOLinks_options;
24
+
25
+ // Initialize WordPress hooks
26
+ function SEOLinks() {
27
+ $options = $this->get_options();
28
+ if ($options)
29
+ {
30
+ if ($options['post'] || $options['page'])
31
+ add_filter('the_content', array(&$this, 'SEOLinks_the_content_filter'), 10);
32
+ if ($options['comment'])
33
+ add_filter('comment_text', array(&$this, 'SEOLinks_comment_text_filter'), 10);
34
+ }
35
+
36
+ add_action( 'create_category', array(&$this, 'SEOLinks_delete_cache'));
37
+ add_action( 'edit_category', array(&$this,'SEOLinks_delete_cache'));
38
+ add_action( 'edit_post', array(&$this,'SEOLinks_delete_cache'));
39
+ add_action( 'save_post', array(&$this,'SEOLinks_delete_cache'));
40
+ // Add Options Page
41
+ add_action('admin_menu', array(&$this, 'SEOLinks_admin_menu'));
42
+
43
+ }
44
+
45
+ function SEOLinks_process_text($text, $mode)
46
+ {
47
+
48
+ global $wpdb, $post;
49
+
50
+ $options = $this->get_options();
51
+
52
+ $links=0;
53
+
54
+
55
+
56
+
57
+ if ($options['onlysingle'] && !(is_single() || is_page()))
58
+ return $text;
59
+
60
+ $arrignorepost=$this->explode_trim(",", ($options['ignorepost']));
61
+
62
+ if (is_page($arrignorepost) || is_single($arrignorepost)) {
63
+ return $text;
64
+ }
65
+
66
+ if (!$mode)
67
+ {
68
+ if ($post->post_type=='post' && !$options['post'])
69
+ return $text;
70
+ else if ($post->post_type=='page' && !$options['page'])
71
+ return $text;
72
+
73
+ if (($post->post_type=='page' && !$options['pageself']) || ($post->post_type=='post' && !$options['postself'])) {
74
+
75
+ $thistitle=$options['casesens'] ? $post->post_title : strtolower($post->post_title);
76
+ $thisurl=trailingslashit(get_permalink($post->ID));
77
+ }
78
+ else {
79
+ $thistitle='';
80
+ $thisurl='';
81
+ }
82
+
83
+ }
84
+
85
+
86
+ $maxlinks=($options['maxlinks']>0) ? $options['maxlinks'] : 0;
87
+ $maxsingle=($options['maxsingle']>0) ? $options['maxsingle'] : -1;
88
+ $minusage = ($options['minusage']>0) ? $options['minusage'] : 1;
89
+
90
+ $arrignore=$this->explode_trim(",", ($options['ignore']));
91
+
92
+ // $reg_post = $options['casesens'] ? '/(?!(?:[^<]+>|[^>]+<\/a>))($name)/msU' : '/(?!(?:[^<]+>|[^>]+<\/a>))($name)/imsU';
93
+ // $reg = $options['casesens'] ? '/(?!(?:[^<]+>|[^>]+<\/a>))\b($name)\b/msU' : '/(?!(?:[^<]+>|[^>]+<\/a>))\b($name)\b/imsU';
94
+ $reg_post = $options['casesens'] ? '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))($name)/msU' : '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))($name)/imsU';
95
+ $reg = $options['casesens'] ? '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))\b($name)\b/msU' : '/(?!(?:[^<\[]+[>\]]|[^>\]]+<\/a>))\b($name)\b/imsU';
96
+ $strpos_fnc = $options['casesens'] ? 'strpos' : 'stripos';
97
+
98
+ $text = " $text ";
99
+
100
+ // custom keywords
101
+ if (!empty($options['customkey']))
102
+ {
103
+ $kw_array = array();
104
+
105
+ // thanks PK for the suggestion
106
+ foreach (explode("\n", $options['customkey']) as $line) {
107
+ $chunks = array_map('trim', explode(",", $line));
108
+ $total_chuncks = count($chunks);
109
+ if($total_chuncks > 2) {
110
+ $i = 0;
111
+ $url = $chunks[$total_chuncks-1];
112
+ while($i < $total_chuncks-1) {
113
+ if (!empty($chunks[$i])) $kw_array[$chunks[$i]] = $url;
114
+ $i++;
115
+ }
116
+ } else {
117
+ list($keyword, $url) = array_map('trim', explode(",", $line, 2));
118
+ if (!empty($keyword)) $kw_array[$keyword] = $url;
119
+ }
120
+ }
121
+
122
+ /*foreach (explode("\n", $options['customkey']) as $line) {
123
+ list($keyword, $url) = array_map('trim', explode(",", $line, 2));
124
+ if (!empty($keyword)) $kw_array[$keyword] = $url;
125
+ }*/
126
+
127
+ foreach ($kw_array as $name=>$url)
128
+ {
129
+
130
+ if ((!$maxlinks || ($links < $maxlinks)) && (trailingslashit($url)!=$thisurl) && !in_array( $options['casesens'] ? $name : strtolower($name), $arrignore))
131
+ {
132
+ if ($strpos_fnc($text, $name) !== false) { // credit to Dominik Deobald
133
+ $name= preg_quote($name, '/');
134
+
135
+ $replace="<a title=\"$1\" href=\"$url\">$1</a>";
136
+ $regexp=str_replace('$name', $name, $reg);
137
+ //$regexp="/(?!(?:[^<]+>|[^>]+<\/a>))(?<!\p{L})($name)(?!\p{L})/imsU";
138
+ $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
139
+ if ($newtext!=$text) {
140
+ $links++;
141
+ $text=$newtext;
142
+ }
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+
149
+ // posts and pages
150
+ if ($options['lposts'] || $options['lpages'])
151
+ {
152
+ if ( !$posts = wp_cache_get( 'seo-links-posts', 'seo-smart-links' ) ) {
153
+ $query="SELECT post_title, ID, post_type FROM $wpdb->posts WHERE post_status = 'publish' AND LENGTH(post_title)>3 ORDER BY LENGTH(post_title) DESC";
154
+ $posts = $wpdb->get_results($query);
155
+
156
+ wp_cache_add( 'seo-links-posts', $posts, 'seo-smart-links', 86400 );
157
+ }
158
+
159
+
160
+ foreach ($posts as $postitem)
161
+ {
162
+ if ((($options['lposts'] && $postitem->post_type=='post') || ($options['lpages'] && $postitem->post_type=='page')) &&
163
+ (!$maxlinks || ($links < $maxlinks)) && (($options['casesens'] ? $postitem->post_title : strtolower($postitem->post_title))!=$thistitle) && (!in_array( ($options['casesens'] ? $postitem->post_title : strtolower($postitem->post_title)), $arrignore)) )
164
+ {
165
+ if ($strpos_fnc($text, $postitem->post_title) !== false) { // credit to Dominik Deobald
166
+ $name = preg_quote($postitem->post_title, '/');
167
+
168
+ $regexp=str_replace('$name', $name, $reg_post);
169
+
170
+
171
+ $replace='<a title="$1" href="$$url$quot;>$1</a>';
172
+
173
+ $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
174
+ if ($newtext!=$text) {
175
+ $url = get_permalink($postitem->ID);
176
+ $links++;
177
+ $text=str_replace('$$url$#x27;, $url, $newtext);
178
+ }
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ // categories
185
+ if ($options['lcats'])
186
+ {
187
+ if ( !$categories = wp_cache_get( 'seo-links-categories', 'seo-smart-links' ) ) {
188
+
189
+ $query="SELECT $wpdb->terms.name, $wpdb->terms.term_id FROM $wpdb->terms LEFT JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE $wpdb->term_taxonomy.taxonomy = 'category' AND LENGTH($wpdb->terms.name)>3 AND $wpdb->term_taxonomy.count >= $minusage ORDER BY LENGTH($wpdb->terms.name) DESC";
190
+ $categories = $wpdb->get_results($query);
191
+
192
+ wp_cache_add( 'seo-links-categories', $categories, 'seo-smart-links',86400 );
193
+ }
194
+
195
+ foreach ($categories as $cat)
196
+ {
197
+ if ((!$maxlinks || ($links < $maxlinks)) && !in_array( $options['casesens'] ? $cat->name : strtolower($cat->name), $arrignore) )
198
+ {
199
+ if ($strpos_fnc($text, $cat->name) !== false) { // credit to Dominik Deobald
200
+ $name= preg_quote($cat->name, '/');
201
+ $regexp=str_replace('$name', $name, $reg); ;
202
+ $replace='<a title="$1" href="$$url$quot;>$1</a>';
203
+
204
+ $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
205
+ if ($newtext!=$text) {
206
+ $url = (get_category_link($cat->term_id));
207
+ $links++;
208
+ $text=str_replace('$$url$#x27;, $url, $newtext);
209
+ }
210
+ }
211
+ }
212
+ }
213
+ }
214
+
215
+ // tags
216
+ if ($options['ltags'])
217
+ {
218
+ if ( !$tags = wp_cache_get( 'seo-links-tags', 'seo-smart-links' ) ) {
219
+
220
+ $query="SELECT $wpdb->terms.name, $wpdb->terms.term_id FROM $wpdb->terms LEFT JOIN $wpdb->term_taxonomy ON $wpdb->terms.term_id = $wpdb->term_taxonomy.term_id WHERE $wpdb->term_taxonomy.taxonomy = 'post_tag' AND LENGTH($wpdb->terms.name)>3 AND $wpdb->term_taxonomy.count >= $minusage ORDER BY LENGTH($wpdb->terms.name) DESC";
221
+ $tags = $wpdb->get_results($query);
222
+
223
+ wp_cache_add( 'seo-links-tags', $tags, 'seo-smart-links',86400 );
224
+ }
225
+
226
+ foreach ($tags as $tag)
227
+ {
228
+ if ((!$maxlinks || ($links < $maxlinks)) && !in_array( $options['casesens'] ? $tag->name : strtolower($tag->name), $arrignore) )
229
+ {
230
+ if ($strpos_fnc($text, $tag->name) !== false) { // credit to Dominik Deobald
231
+ $name = preg_quote($tag->name, '/');
232
+ $regexp=str_replace('$name', $name, $reg); ;
233
+ $replace='<a title="$1" href="$$url$quot;>$1</a>';
234
+
235
+ $newtext = preg_replace($regexp, $replace, $text, $maxsingle);
236
+ if ($newtext!=$text) {
237
+ $url = (get_tag_link($tag->term_id));
238
+ $links++;
239
+ $text=str_replace('$$url$#x27;, $url, $newtext);
240
+ }
241
+ }
242
+ }
243
+ }
244
+ }
245
+
246
+ return trim( $text );
247
+
248
+ }
249
+
250
+ function SEOLinks_the_content_filter($text) {
251
+
252
+ $result=$this->SEOLinks_process_text($text, 0);
253
+
254
+ $options = $this->get_options();
255
+ $link=parse_url(get_bloginfo('wpurl'));
256
+ $host='http://'.$link['host'];
257
+
258
+ if ($options['blanko'])
259
+ $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a target="_blank"\\1', $result); // credit to Kaf Oseo
260
+
261
+ if ($options['nofolo'])
262
+ $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a rel="nofollow"\\1', $result);
263
+ return $result;
264
+ }
265
+
266
+ function SEOLinks_comment_text_filter($text) {
267
+ $result = $this->SEOLinks_process_text($text, 1);
268
+
269
+ $options = $this->get_options();
270
+ $link=parse_url(get_bloginfo('wpurl'));
271
+ $host='http://'.$link['host'];
272
+
273
+ if ($options['blanko'])
274
+ $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a target="_blank"\\1', $result); // credit to Kaf Oseo
275
+
276
+ if ($options['nofolo'])
277
+ $result = preg_replace('%<a(\s+.*?href=\S(?!' . $host . '))%i', '<a rel="nofollow"\\1', $result);
278
+
279
+ return $result;
280
+ }
281
+
282
+ function explode_trim($separator, $text)
283
+ {
284
+ $arr = explode($separator, $text);
285
+
286
+ $ret = array();
287
+ foreach($arr as $e)
288
+ {
289
+ $ret[] = trim($e);
290
+ }
291
+ return $ret;
292
+ }
293
+
294
+ // Handle our options
295
+ function get_options() {
296
+
297
+ $options = array(
298
+ 'post' => 'on',
299
+ 'postself' => '',
300
+ 'page' => 'on',
301
+ 'pageself' => '',
302
+ 'comment' => '',
303
+ 'lposts' => 'on',
304
+ 'lpages' => 'on',
305
+ 'lcats' => '',
306
+ 'ltags' => '',
307
+ 'ignore' => 'about,',
308
+ 'ignorepost' => 'contact',
309
+ 'maxlinks' => 3,
310
+ 'maxsingle' => 1,
311
+ 'minusage' => 1,
312
+ 'customkey' => '',
313
+ 'nofoln' =>'',
314
+ 'nofolo' =>'',
315
+ 'blankn' =>'',
316
+ 'blanko' =>'',
317
+ 'onlysingle' => 'on',
318
+ 'casesens' =>''
319
+
320
+ );
321
+
322
+ $saved = get_option($this->SEOLinks_DB_option);
323
+
324
+
325
+ if (!empty($saved)) {
326
+ foreach ($saved as $key => $option)
327
+ $options[$key] = $option;
328
+ }
329
+
330
+ if ($saved != $options)
331
+ update_option($this->SEOLinks_DB_option, $options);
332
+
333
+ return $options;
334
+
335
+ }
336
+
337
+
338
+
339
+ // Set up everything
340
+ function install() {
341
+ $SEOLinks_options = $this->get_options();
342
+
343
+
344
+ }
345
+
346
+ function handle_options()
347
+ {
348
+
349
+ $options = $this->get_options();
350
+ if ( isset($_POST['submitted']) ) {
351
+
352
+ check_admin_referer('seo-smart-links');
353
+
354
+ $options['post']=$_POST['post'];
355
+ $options['postself']=$_POST['postself'];
356
+ $options['page']=$_POST['page'];
357
+ $options['pageself']=$_POST['pageself'];
358
+ $options['comment']=$_POST['comment'];
359
+ $options['lposts']=$_POST['lposts'];
360
+ $options['lpages']=$_POST['lpages'];
361
+ $options['lcats']=$_POST['lcats'];
362
+ $options['ltags']=$_POST['ltags'];
363
+ $options['ignore']=$_POST['ignore'];
364
+ $options['ignorepost']=$_POST['ignorepost'];
365
+ $options['maxlinks']=(int) $_POST['maxlinks'];
366
+ $options['maxsingle']=(int) $_POST['maxsingle'];
367
+ $options['minusage']=(int) $_POST['minusage']; // credit to Dominik Deobald
368
+ $options['customkey']=$_POST['customkey'];
369
+ $options['nofoln']=$_POST['nofoln'];
370
+ $options['nofolo']=$_POST['nofolo'];
371
+ $options['blankn']=$_POST['blankn'];
372
+ $options['blanko']=$_POST['blanko'];
373
+ $options['onlysingle']=$_POST['onlysingle'];
374
+ $options['casesens']=$_POST['casesens'];
375
+
376
+
377
+ update_option($this->SEOLinks_DB_option, $options);
378
+ $this->SEOLinks_delete_cache(0);
379
+ echo '<div class="updated fade"><p>Plugin settings saved.</p></div>';
380
+ }
381
+
382
+
383
+
384
+
385
+ $action_url = $_SERVER['REQUEST_URI'];
386
+
387
+ $post=$options['post']=='on'?'checked':'';
388
+ $postself=$options['postself']=='on'?'checked':'';
389
+ $page=$options['page']=='on'?'checked':'';
390
+ $pageself=$options['pageself']=='on'?'checked':'';
391
+ $comment=$options['comment']=='on'?'checked':'';
392
+ $lposts=$options['lposts']=='on'?'checked':'';
393
+ $lpages=$options['lpages']=='on'?'checked':'';
394
+ $lcats=$options['lcats']=='on'?'checked':'';
395
+ $ltags=$options['ltags']=='on'?'checked':'';
396
+ $ignore=$options['ignore'];
397
+ $ignorepost=$options['ignorepost'];
398
+ $maxlinks=$options['maxlinks'];
399
+ $maxsingle=$options['maxsingle'];
400
+ $minusage=$options['minusage'];
401
+ $customkey=stripslashes($options['customkey']);
402
+ $nofoln=$options['nofoln']=='on'?'checked':'';
403
+ $nofolo=$options['nofolo']=='on'?'checked':'';
404
+ $blankn=$options['blankn']=='on'?'checked':'';
405
+ $blanko=$options['blanko']=='on'?'checked':'';
406
+ $onlysingle=$options['onlysingle']=='on'?'checked':'';
407
+ $casesens=$options['casesens']=='on'?'checked':'';
408
+
409
+ if (!is_numeric($minusage)) $minusage = 1;
410
+
411
+ $nonce=wp_create_nonce( 'seo-smart-links');
412
+
413
+ $imgpath=trailingslashit(get_option('siteurl')). 'wp-content/plugins/seo-automatic-links/i';
414
+ echo <<<END
415
+
416
+ <div class="wrap" style="max-width:950px !important;">
417
+ <h2>SEO Smart Links</h2>
418
+
419
+ <div id="poststuff" style="margin-top:10px;">
420
+
421
+ <div id="sideblock" style="float:right;width:220px;margin-left:10px;">
422
+ <h2>Information</h2>
423
+ <div id="dbx-content" style="text-decoration:none;">
424
+ <img src="$imgpath/home.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/wordpress-plugins/seo-smart-links"> SEO Smart Links Home</a><br />
425
+ <img src="$imgpath/rate.png"><a style="text-decoration:none;" href="http://wordpress.org/extend/plugins/seo-automatic-links/"> Rate this plugin</a><br />
426
+ <img src="$imgpath/help.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/forum"> Support and Help</a><br />
427
+ <br />
428
+ <a style="text-decoration:none;" href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=2567254"><img src="$imgpath/paypal.gif"></a>
429
+ <br /><br />
430
+ <img src="$imgpath/more.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/wordpress-plugins"> Cool WordPress Plugins</a><br />
431
+ <img src="$imgpath/twit.png"><a style="text-decoration:none;" href="http://twitter.com/vprelovac"> Follow updates on Twitter</a><br />
432
+ <img src="$imgpath/idea.png"><a style="text-decoration:none;" href="http://www.prelovac.com/vladimir/services"> Need a WordPress Expert?</a>
433
+ </div>
434
+ </div>
435
+
436
+ <div id="mainblock" style="width:710px">
437
+
438
+ <div class="dbx-content">
439
+ <form name="SEOLinks" action="$action_url" method="post">
440
+ <input type="hidden" id="_wpnonce" name="_wpnonce" value="$nonce" />
441
+ <input type="hidden" name="submitted" value="1" />
442
+ <h2>Overview</h2>
443
+
444
+ <p>SEO Smart Links can automatically link keywords and phrases in your posts and comments with corresponding posts, pages, categories and tags on your blog.</p>
445
+ <p>Further SEO Smart links allows you to set up your own keywords and set of matching URLs.</p>
446
+ <p>Finally SEO Smart links allows you to set nofollow attribute and open links in new window.</p>
447
+
448
+ <h2>Internal Links</h2>
449
+ <p>SEO Smart Links can process your posts, pages and comments in search for keywords to automatically interlink.</p>
450
+ <input type="checkbox" name="post" $post/><label for="post"> Posts</label>
451
+ <ul>&nbsp;<input type="checkbox" name="postself" $postself/><label for="postself"> Allow links to self</label></ul>
452
+ <br />
453
+ <input type="checkbox" name="page" $page/><label for="page"> Pages</label>
454
+ <ul>&nbsp;<input type="checkbox" name="pageself" $pageself/><label for="pageself"> Allow links to self</label></ul>
455
+ <br />
456
+ <input type="checkbox" name="comment" $comment /><label for="comment"> Comments</label> (may slow down performance) <br>
457
+
458
+ <h4>Target</h4>
459
+ <p>The targets SEO Smart links should consider. The match will be based on post/page title or category/tag name, case insensitive.</p>
460
+ <input type="checkbox" name="lposts" $lposts /><label for="lposts"> Posts</label> <br>
461
+ <input type="checkbox" name="lpages" $lpages /><label for="lpages"> Pages</label> <br>
462
+ <input type="checkbox" name="lcats" $lcats /><label for="lcats"> Categories</label> (may slow down performance) <br>
463
+ <input type="checkbox" name="ltags" $ltags /><label for="ltags"> Tags</label> (may slow down performance) <br>
464
+ <br>
465
+ Link tags and categories that have been used at least <input type="text" name="minusage" size="2" value="$minusage"/> times.
466
+ <br>
467
+
468
+ <h2>Settings</h2>
469
+ <p>To reduce database load you can choose to have SEO SMART links work only on single posts and pages (for example not on main page or archives).</p>
470
+ <input type="checkbox" name="onlysingle" $onlysingle /><label for="onlysingle"> Process only single posts and pages</label> <br>
471
+
472
+ <p>Set whether matching should be case sensitive.</p>
473
+ <input type="checkbox" name="casesens" $casesens /><label for="casesens"> Case sensitive matching</label> <br>
474
+
475
+ <h4>Ignore Posts and Pages</h4>
476
+ <p>You may wish to forbid automatic linking on certain posts or pages. Seperate them by comma. (id, slug or name)</p>
477
+ <input type="text" name="ignorepost" size="90" value="$ignorepost"/>
478
+ <br>
479
+
480
+ <h4>Ignore keywords</h4>
481
+ <p>You may wish to ignore certain words or phrases from automatic linking. Seperate them by comma.</p>
482
+ <input type="text" name="ignore" size="90" value="$ignore"/>
483
+ <br><br>
484
+
485
+ <h4>Custom Keywords</h4>
486
+ <p>Here you can enter manually the extra keywords you want to automaticaly link. Use comma to seperate keywords and add target url at the end. Use a new line for new url and set of keywords. You can have these keywords link to any url, not only your site.</p>
487
+ <p>Example:<br />
488
+ vladimir prelovac, http://www.prelovac.com/vladimir<br />
489
+ cars, car, autos, auto, http://mycarblog.com/<br />
490
+ </p>
491
+
492
+ <textarea name="customkey" id="customkey" rows="10" cols="90" >$customkey</textarea>
493
+ <br><br>
494
+
495
+ <h4>Limits</h4>
496
+ <p>You can limit the maximum number of links SEO Smart Links will generate per post. Set to 0 for no limit. </p>
497
+ Max Links: <input type="text" name="maxlinks" size="2" value="$maxlinks"/>
498
+ <p>You can also limit maximum number of links created with the same keyword. Set to 0 for no limit. </p>
499
+ Max Single: <input type="text" name="maxsingle" size="2" value="$maxsingle"/>
500
+ <br><br>
501
+
502
+ <h4>External Links</h4>
503
+ <p>SEO Smart links can open external links in new window and add nofollow attribute.</p>
504
+
505
+
506
+ <input type="checkbox" name="nofolo" $nofolo /><label for="nofolo"> Add nofollow attribute</label> <br>
507
+
508
+
509
+ <input type="checkbox" name="blanko" $blanko /><label for="blanko"> Open in new window</label> <br>
510
+
511
+
512
+ <div class="submit"><input type="submit" name="Submit" value="Update options" class="button-primary" /></div>
513
+ </form>
514
+ </div>
515
+
516
+ <br/><br/><h3>&nbsp;</h3>
517
+ </div>
518
+
519
+ </div>
520
+
521
+ <h5>WordPress plugin by <a href="http://www.prelovac.com/vladimir/">Vladimir Prelovac</a></h5>
522
+ </div>
523
+ END;
524
+
525
+
526
+ }
527
+
528
+ function SEOLinks_admin_menu()
529
+ {
530
+ add_options_page('SEO Smart Links Options', 'SEO Smart Links', 8, basename(__FILE__), array(&$this, 'handle_options'));
531
+ }
532
+
533
+ function SEOLinks_delete_cache($id) {
534
+ wp_cache_delete( 'seo-links-categories', 'seo-smart-links' );
535
+ wp_cache_delete( 'seo-links-tags', 'seo-smart-links' );
536
+ wp_cache_delete( 'seo-links-posts', 'seo-smart-links' );
537
+ }
538
+ //add_action( 'comment_post', 'SEOLinks_delete_cache');
539
+ //add_action( 'wp_set_comment_status', 'SEOLinks_delete_cache');
540
+
541
+
542
+ }
543
+
544
+ endif;
545
+
546
+ if ( class_exists('SEOLinks') ) :
547
+
548
+ $SEOLinks = new SEOLinks();
549
+ if (isset($SEOLinks)) {
550
+ register_activation_hook( __FILE__, array(&$SEOLinks, 'install') );
551
+ }
552
+ endif;
553
+
554
?>