Ad Injection - Version 1.1.0.3

Version Description

  • First ad can now be started at or after a paragraph or character position.
  • Override ad positions on individual posts using <!--topad--> <!--randomad--> <!--bottomad-->
  • Separate old post restriction for widget ads.
  • Template ad examples in the 'Test ads' section.
  • Warning message improvements.
  • UI tweaks and other fixes.
Download this release

Release Info

Developer reviewmylife
Plugin Icon wp plugin Ad Injection
Version 1.1.0.3
Comparing to
See all releases

Code changes from version 1.1.0.2 to 1.1.0.3

Files changed (5) hide show
  1. ad-injection-admin.php +53 -7
  2. ad-injection-widget.php +4 -4
  3. ad-injection.php +104 -28
  4. readme.txt +46 -20
  5. ui-tab-main.php +102 -54
ad-injection-admin.php CHANGED
@@ -319,7 +319,7 @@ function adinj_top_message_box(){
319
  }
320
  if (adinj_mfunc_mode()){
321
  if (!is_supported_caching_plugin_active()){
322
- echo "<br /><b>Recommendation:</b> It looks like you don't have a supported caching plugin (WP Super Cache, W3 Total Cache or WP Cache) active. Therefore one of the <a href='#restrictions'>direct insertion modes</a> might be better for you.";
323
  }
324
  global $adinj_warning_msg_filewrite;
325
  if (!empty($adinj_warning_msg_filewrite)){
@@ -329,8 +329,17 @@ function adinj_top_message_box(){
329
  }
330
  global $adinj_warning_msg_chmod;
331
  if (!empty($adinj_warning_msg_chmod)){
332
- // TODO this adinj_warning_msg_chmod msg is no longer being shown
333
- echo '<br />Info: Some warnings were generated by chmod. See the <a href="?page=ad-injection&amp;tab=debug#debugging">debugging</a> section for more info.';
 
 
 
 
 
 
 
 
 
334
  }
335
  if ($ops['ads_enabled'] != 'on'){
336
  echo '<br /><font color="red">Warning: Ads are not enabled. You need to turn the ads on for everyone to see them.</font>';
@@ -339,7 +348,7 @@ function adinj_top_message_box(){
339
 
340
  } else if (!isset($_GET['tab'])){
341
  echo '<div id="message" class="updated below-h2"><p style="line-height:140%"><strong>';
342
- echo "22nd August 2011: Please check your ads after this update! I've attempted to make the settings less confusing by removing some duplicate ways to enable/disable ads. Instead of 'Disabled/Always show' options on the pull down boxes I now have an 'n/a' value to signify that the settings isn't being used. Ads can be disabled using the tick boxes instead. If you have disabled ads using the 'Disabled' option the correct tick boxes should now be checked. I've tested as much as I can but there is a risk with this update so do check your settings/ads. Also some parts of the UI will now dissapear if the 'All' boxes are ticked. Please contact me ASAP if you spot any bugs, or odd behaviour via the ".'<a href="'.adinj_feedback_url().'" target="_new">quick feedback form</a>.';
343
  echo '</strong></p></div>';
344
  }
345
  }
@@ -362,7 +371,7 @@ function adinj_side_donate_box(){
362
  <input type="hidden" name="currency_code" value="USD">
363
  <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted">
364
  <p>Amount:<br>
365
- <input class="omni_donate_field" type="text" name="amount" size="9" title="The amount you wish to donate" value="20">
366
  <select id="currency_code" name="currency_code">
367
  <option value="USD">U.S. Dollars</option>
368
  <option value="GBP">Pounds Sterling</option>
@@ -640,6 +649,10 @@ function adinj_max_num_ads($adtype, $pagetype){
640
  return 0;
641
  }
642
 
 
 
 
 
643
  function adinj_selection_box($name, $values, $type="", $selected_value=NULL){
644
  $associative = false;
645
  if (!array_key_exists(0, $values)){
@@ -727,7 +740,7 @@ HTML;
727
 
728
  function adinj_condition_tables($prefix, $show_setting){
729
  $ops = adinj_options();
730
- if (strlen($ops[$prefix.'category_condition_entries'])>0 || strlen($ops[$prefix.'tag_condition_entries'])>0 &&
731
  strlen($ops[$prefix.'author_condition_entries'])>0 || strlen($ops[$prefix.'id_condition_entries'])>0){
732
  $msg = "configured";
733
  } else {
@@ -947,7 +960,7 @@ function is_supported_caching_plugin_active(){
947
  //////////////////////////////////////////////////////////////////////////////
948
 
949
  function adinj_testads(){
950
- adinj_postbox_start(__("Test Adverts", 'adinj'), "testads", '95%');
951
  ?>
952
  <p>You can copy and paste these adverts into the boxes above to test your ad setup before switching to your real ads.</p>
953
 
@@ -1025,6 +1038,32 @@ function adinj_testads(){
1025
  <a href="http://www.advancedhtml.co.uk/">www.advancedhtml.co.uk</a>
1026
  </div><p></p>
1027
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1028
  <?php
1029
  adinj_postbox_end();
1030
  }
@@ -1229,6 +1268,10 @@ function adinj_upgrade_db(){
1229
  }
1230
  }
1231
 
 
 
 
 
1232
  // 3. Bump up db version number.
1233
  $new_options['db_version'] = $new_dbversion;
1234
 
@@ -1248,6 +1291,7 @@ function adinj_default_options(){
1248
  // Global settings
1249
  'ads_enabled' => 'off',
1250
  'ads_on_page_older_than' => '0',
 
1251
  'exclude_front' => '',
1252
  'exclude_home' => '',
1253
  'exclude_page' => '',
@@ -1296,6 +1340,8 @@ function adinj_default_options(){
1296
  'rnd_padding_top' => 'd',
1297
  'rnd_padding_bottom' => 'd',
1298
  'start_from_paragraph' => 'd',
 
 
1299
  'rnd_allow_ads_on_last_paragraph' => '',
1300
  'rnd_reselect_ad_per_position_in_post' => '',
1301
  'multiple_ads_at_same_position' => '',
319
  }
320
  if (adinj_mfunc_mode()){
321
  if (!is_supported_caching_plugin_active()){
322
+ echo "<br /><b>Recommendation:</b> It looks like you don't have a supported caching plugin (WP Super Cache, W3 Total Cache or WP Cache) active. Therefore <a href='#restrictions'>direct insertion modes</a> might be better for you.";
323
  }
324
  global $adinj_warning_msg_filewrite;
325
  if (!empty($adinj_warning_msg_filewrite)){
329
  }
330
  global $adinj_warning_msg_chmod;
331
  if (!empty($adinj_warning_msg_chmod)){
332
+ echo '<br />Info: Some warnings were generated by chmod. See the <a href="#warning_msg_chmod">warnings below</a> for more info.';
333
+ }
334
+ foreach (array('top', 'random', 'bottom', 'footer') as $type){
335
+ $adcount = adinj_count_live_ads($type, $ops);
336
+ if ($adcount > 0 && !adinj_ad_type_enabled($type)){
337
+ $adads = 'ad';
338
+ $isare = 'is';
339
+ $theyit = 'it is';
340
+ if ($adcount > 1) { $adads = 'ads'; $isare = 'are'; $theyit = 'they are'; }
341
+ echo "<br /><font color='red'>Warning: $adcount $type $adads $isare defined, but $theyit not enabled.</font>";
342
+ }
343
  }
344
  if ($ops['ads_enabled'] != 'on'){
345
  echo '<br /><font color="red">Warning: Ads are not enabled. You need to turn the ads on for everyone to see them.</font>';
348
 
349
  } else if (!isset($_GET['tab'])){
350
  echo '<div id="message" class="updated below-h2"><p style="line-height:140%"><strong>';
351
+ echo "29th August 2011: Lots of small new features and fixes in this update. I've added more options for selecting where random ads start; tags to allow ad positions to be hardcoded in selected posts; a separate 'older than' option for the widget ads; and more. See the changelog for more details. Please contact me ASAP if you spot any bugs, or odd behaviour via the ".'<a href="'.adinj_feedback_url().'" target="_new">quick feedback form</a>.';
352
  echo '</strong></p></div>';
353
  }
354
  }
371
  <input type="hidden" name="currency_code" value="USD">
372
  <input type="hidden" name="bn" value="PP-DonationsBF:btn_donateCC_LG.gif:NonHosted">
373
  <p>Amount:<br>
374
+ <input class="omni_donate_field" type="text" name="amount" size="9" title="The amount you wish to donate" value="10">
375
  <select id="currency_code" name="currency_code">
376
  <option value="USD">U.S. Dollars</option>
377
  <option value="GBP">Pounds Sterling</option>
649
  return 0;
650
  }
651
 
652
+ function adinj_ad_type_enabled($adtype){
653
+ return (adinj_max_num_ads($adtype, 'single') > 0 || adinj_max_num_ads($adtype, 'page') > 0 || adinj_max_num_ads($adtype, 'home') > 0 || adinj_max_num_ads($adtype, 'archive') > 0 || adinj_max_num_ads($adtype, 'front') > 0 || adinj_max_num_ads($adtype, '404') > 0 || adinj_max_num_ads($adtype, 'search') > 0);
654
+ }
655
+
656
  function adinj_selection_box($name, $values, $type="", $selected_value=NULL){
657
  $associative = false;
658
  if (!array_key_exists(0, $values)){
740
 
741
  function adinj_condition_tables($prefix, $show_setting){
742
  $ops = adinj_options();
743
+ if (strlen($ops[$prefix.'category_condition_entries'])>0 || strlen($ops[$prefix.'tag_condition_entries'])>0 ||
744
  strlen($ops[$prefix.'author_condition_entries'])>0 || strlen($ops[$prefix.'id_condition_entries'])>0){
745
  $msg = "configured";
746
  } else {
960
  //////////////////////////////////////////////////////////////////////////////
961
 
962
  function adinj_testads(){
963
+ adinj_postbox_start(__("Test Adverts and template ad examples", 'adinj'), "testads", '95%');
964
  ?>
965
  <p>You can copy and paste these adverts into the boxes above to test your ad setup before switching to your real ads.</p>
966
 
1038
  <a href="http://www.advancedhtml.co.uk/">www.advancedhtml.co.uk</a>
1039
  </div><p></p>
1040
 
1041
+
1042
+ <h4>Template ad examples</h4>
1043
+
1044
+ <p>Template ads allow any of the ads to be inserted anywhere in your theme. <b>*Don't*</b> try putting any of this code into one of the ad boxes - it is not an advert - it is code to load an advert directly your theme.</p>
1045
+
1046
+ <b>Simple examples for loading top, random, bottom or footer ads</b><br />
1047
+
1048
+ <p>If you are using mfunc mode (for caching plugins) you may need to include the ad framework loading code snippet below. You would have to include this snippet above the ad display code.</p>
1049
+
1050
+ <p><textarea onclick="javascript:this.focus();this.select();" style="min-height:50px;" cols="80" rows="1">
1051
+ &lt;?php if (function_exists('adinj_print_ad')){ adinj_print_ad('top'); } ?&gt;</textarea></p>
1052
+
1053
+ <p>You can load the 'top', 'random', 'bottom', and 'footer' ads.</p>
1054
+
1055
+ <p><textarea onclick="javascript:this.focus();this.select();" style="min-height:50px;" cols="80" rows="1">
1056
+ &lt;?php if (function_exists('adinj_print_ad')){ adinj_print_ad('hotel-ad.txt'); } ?&gt;</textarea></p>
1057
+
1058
+ <p>Or you can load ads stored as text files in the ad-injection-data directory (<?php echo ADINJ_AD_PATH; ?>/)</p>
1059
+
1060
+ <b>Ad framework loading code for mfunc mode with caching plugins + 1 random ad</b><br />
1061
+
1062
+ <p><textarea onclick="javascript:this.focus();this.select();" style="min-height:50px;" cols="110" rows="5">&lt;!--mfunc include_once('<?php echo ADINJ_PATH; ?>/adshow.php') --&gt;
1063
+ &lt;?php include_once('<?php echo ADINJ_PATH; ?>/adshow.php'); ?&gt;
1064
+ &lt;!--/mfunc--&gt;
1065
+ &lt;?php if (function_exists('adinj_print_ad')){ adinj_print_ad('random'); } ?&gt;</textarea></p>
1066
+
1067
  <?php
1068
  adinj_postbox_end();
1069
  }
1268
  }
1269
  }
1270
 
1271
+ if ($stored_dbversion < 15){
1272
+ $new_options['widgets_on_page_older_than'] = $stored_options['ads_on_page_older_than'];
1273
+ }
1274
+
1275
  // 3. Bump up db version number.
1276
  $new_options['db_version'] = $new_dbversion;
1277
 
1291
  // Global settings
1292
  'ads_enabled' => 'off',
1293
  'ads_on_page_older_than' => '0',
1294
+ 'widgets_on_page_older_than' => '0',
1295
  'exclude_front' => '',
1296
  'exclude_home' => '',
1297
  'exclude_page' => '',
1340
  'rnd_padding_top' => 'd',
1341
  'rnd_padding_bottom' => 'd',
1342
  'start_from_paragraph' => 'd',
1343
+ 'random_ads_after_mode' => 'at',
1344
+ 'random_ads_after_unit' => 'paragraph',
1345
  'rnd_allow_ads_on_last_paragraph' => '',
1346
  'rnd_reselect_ad_per_position_in_post' => '',
1347
  'multiple_ads_at_same_position' => '',
ad-injection-widget.php CHANGED
@@ -22,7 +22,7 @@ class Ad_Injection_Widget extends WP_Widget {
22
  }
23
 
24
  function widget( $args, $instance ) {
25
- if (adinj_ads_completely_disabled_from_page()) return;
26
 
27
  if ((is_front_page() && adinj_ticked('widget_exclude_front')) ||
28
  (is_home() && adinj_ticked('widget_exclude_home')) ||
@@ -243,8 +243,8 @@ class Ad_Injection_Widget extends WP_Widget {
243
  <?php $this->add_checkbox('exclude_page', $instance) ?>page - <?php echo $count_pages->publish; ?> single page(s)<br />
244
  <?php $this->add_checkbox('exclude_single', $instance) ?>single - <?php echo $count_posts->publish; ?> single post(s)<br />
245
  <?php $this->add_checkbox('exclude_archive', $instance) ?>archive - categories, tags, authors, dates<br />
246
- <?php $this->add_checkbox('exclude_search', $instance) ?>search (widgets only for now)<br />
247
- <?php $this->add_checkbox('exclude_404', $instance) ?>404 (widgets only for now)<br />
248
  <span style="font-size:10px;"><b>Notes:</b> Your home page is the page displaying your latest posts. It may be different to your front page if you have configured your front page to be a static page.</span><br />
249
  <span style="font-size:10px;">If you have <a href='options-reading.php'>set your front page</a> to be a static 'page' rather than your latest posts, the 'page' tick box will also apply to the front page.</span>
250
  </div>
@@ -299,7 +299,7 @@ class Ad_Injection_Widget extends WP_Widget {
299
 
300
  <br />
301
 
302
- <p>Other options to define who sees these adverts (by page age, IP, referrer) are on the main <a href='options-general.php?page=ad-injection.php'>Ad Injection settings page</a>. You can also set a global <a href='options-general.php?page=ad-injection.php#adsettings'>page type</a> restrictions for the widgets.</p>
303
 
304
  <?php
305
  }
22
  }
23
 
24
  function widget( $args, $instance ) {
25
+ if (adinj_ads_completely_disabled_from_page('widget')) return;
26
 
27
  if ((is_front_page() && adinj_ticked('widget_exclude_front')) ||
28
  (is_home() && adinj_ticked('widget_exclude_home')) ||
243
  <?php $this->add_checkbox('exclude_page', $instance) ?>page - <?php echo $count_pages->publish; ?> single page(s)<br />
244
  <?php $this->add_checkbox('exclude_single', $instance) ?>single - <?php echo $count_posts->publish; ?> single post(s)<br />
245
  <?php $this->add_checkbox('exclude_archive', $instance) ?>archive - categories, tags, authors, dates<br />
246
+ <?php $this->add_checkbox('exclude_search', $instance) ?>search<br />
247
+ <?php $this->add_checkbox('exclude_404', $instance) ?>404<br />
248
  <span style="font-size:10px;"><b>Notes:</b> Your home page is the page displaying your latest posts. It may be different to your front page if you have configured your front page to be a static page.</span><br />
249
  <span style="font-size:10px;">If you have <a href='options-reading.php'>set your front page</a> to be a static 'page' rather than your latest posts, the 'page' tick box will also apply to the front page.</span>
250
  </div>
299
 
300
  <br />
301
 
302
+ <p>Other options to define who sees these adverts (by page age, IP, referrer) are on the main <a href='options-general.php?page=ad-injection.php'>Ad Injection settings page</a>. You can also set a global <a href='options-general.php?page=ad-injection.php#global'>page type</a> restriction for the widgets.</p>
303
 
304
  <?php
305
  }
ad-injection.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Ad Injection
4
  Plugin URI: http://www.reviewmylife.co.uk/blog/2010/12/06/ad-injection-plugin-wordpress/
5
  Description: Injects any advert (e.g. AdSense) into your WordPress posts or widget area. Restrict who sees the ads by post length, age, referrer or IP. Cache compatible.
6
- Version: 1.1.0.2
7
  Author: reviewmylife
8
  Author URI: http://www.reviewmylife.co.uk/
9
  License: GPLv2
@@ -30,8 +30,9 @@ define('ADINJ_NO_CONFIG_FILE', 1);
30
  // 11 = options to disable rnd ad at bottom, and to get new ad for each rnd slot
31
  // 13 = post/page id restrictions
32
  // 14 = template ads
33
- // 15 = Remove duplicate 'Disabled' option from top/bottom ad section
34
- define('ADINJ_DB_VERSION', 15);
 
35
 
36
  // Files
37
  // TODO will these paths work on windows?
@@ -353,9 +354,13 @@ function read_ad_from_file($ad_path){
353
 
354
  // Based on: http://www.wprecipes.com/wordpress-hack-how-to-display-ads-on-old-posts-only
355
  // Only use for pages and posts. Not for archives, categories, home page, etc.
356
- function adinj_is_old_post(){
357
  $ops = adinj_options();
358
- $days = $ops['ads_on_page_older_than'];
 
 
 
 
359
  if ($days == 0) return true;
360
  if(is_single() || is_page()) {
361
  $current_date = time();
@@ -384,6 +389,9 @@ function adinj($content, $message){
384
  global $adinj_total_top_ads_used, $adinj_total_random_ads_used, $adinj_total_bottom_ads_used, $adinj_total_all_ads_used;
385
  $ops = adinj_options();
386
  $para = adinj_paragraph_to_start_ads();
 
 
 
387
  $mode = $ops['ad_insertion_mode'];
388
 
389
  $posttype = get_post_type() . ' (';
@@ -411,6 +419,7 @@ $message
411
  \$adinj_total_bottom_ads_used=$adinj_total_bottom_ads_used
412
  \$adinj_total_all_ads_used=$adinj_total_all_ads_used
413
  paragraphtostartads=$para (fyi: -1 is disabled)
 
414
  posttype=$posttype
415
  currentdate=$currentdate ($currentday)
416
  postdate=$postdate ($postday)
@@ -431,7 +440,7 @@ function adinj_excluded_by_tick_box($prefix){
431
  return false;
432
  }
433
 
434
- function adinj_ads_completely_disabled_from_page($content=NULL){
435
  $ops = adinj_options();
436
  if ($ops['ads_enabled'] == 'off' ||
437
  $ops['ads_enabled'] == ''){
@@ -456,7 +465,7 @@ function adinj_ads_completely_disabled_from_page($content=NULL){
456
  if (adinj_adverts_disabled_flag()) return "NOADS: adverts_disabled_flag";
457
 
458
  // no ads on old posts/pages if rule is enabled
459
- if((is_page() || is_single()) && !adinj_is_old_post()) return "NOADS: !is_old_post";
460
 
461
  if (!adinj_allowed_in_category('global', $ops)) return "NOADS: globally blocked from category";
462
  if (!adinj_allowed_in_tag('global', $ops)) return "NOADS: globally blocked from tag";
@@ -647,7 +656,7 @@ function adinj_content_hook($content){
647
  $adinj_total_bottom_ads_used = 0;
648
  }
649
 
650
- $reason = adinj_ads_completely_disabled_from_page($content);
651
  if ($reason !== false){
652
  return adinj($content, $reason);
653
  }
@@ -676,22 +685,37 @@ function adinj_content_hook($content){
676
  $length = 0;
677
  if ($ops['content_length_unit'] == 'all'){
678
  $length = strlen($content);
679
- if ($debug_on) $debug .= "\nnum chars: = $length (including HTML chars)";
680
  } else if ($ops['content_length_unit'] == 'viewable'){
681
  $length = strlen(strip_tags($content));
682
- if ($debug_on) $debug .= "\nnum chars: = $length (viewable chars only)";
683
  } else {
684
  $length = str_word_count_utf8(strip_tags($content));
685
- if ($debug_on) $debug .= "\nnum words: = $length";
686
  }
687
  # Insert top and bottom ads if necesary
688
- if (adinj_num_top_ads_to_insert($length) > 0){
689
- $content = $ad_include.adinj_ad_code_top().$content;
 
 
 
 
 
 
 
 
690
  $ad_include = "";
691
  ++$adinj_total_top_ads_used;
692
  }
693
- if (adinj_num_bottom_ads_to_insert($length) > 0){
694
- $content = $content.adinj_ad_code_bottom();
 
 
 
 
 
 
 
695
  ++$adinj_total_bottom_ads_used;
696
  }
697
 
@@ -702,8 +726,15 @@ function adinj_content_hook($content){
702
  $ad = adinj_ad_code_random();
703
  if (empty($ad)) return adinj($content, "no random ad defined");
704
 
 
 
 
 
 
 
705
  if (!$debug_on) $debugtags=false;
706
 
 
707
  $content_adfree_header = "";
708
  $content_adfree_footer = "";
709
 
@@ -714,6 +745,7 @@ function adinj_content_hook($content){
714
  if (count($split) == 2){
715
  $content_adfree_header = $split[0];
716
  $content = $split[1];
 
717
  }
718
 
719
  # Use the same naming convention for the end tag
@@ -727,6 +759,7 @@ function adinj_content_hook($content){
727
  if (count($split) == 2){
728
  $content_adfree_header = $split[0];
729
  $content = $split[1];
 
730
  }
731
 
732
  $split = adinj_split_by_tag($content, "<!--adend-->", $debugtags);
@@ -735,6 +768,28 @@ function adinj_content_hook($content){
735
  $content_adfree_footer = $split[1];
736
  }
737
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
738
  // TODO add note explaining that start tags are processed before the 'first
739
  // paragraph ad
740
 
@@ -745,7 +800,7 @@ function adinj_content_hook($content){
745
  if ($debug_on) $debug .= "\nTags=". htmlentities($debugtags);
746
 
747
  // Generate a list of all potential injection points
748
- if ($debug_on) $debug .= "\nPotential positions: ";
749
  $potential_inj_positions = array();
750
  $prevpos = -1;
751
  while(($prevpos = stripos($content, $paragraphmarker, $prevpos+1)) !== false){
@@ -757,25 +812,37 @@ function adinj_content_hook($content){
757
  if ($debug_on) $debug .= "\npotential_inj_positions:".sizeof($potential_inj_positions);
758
 
759
  if (sizeof($potential_inj_positions) == 0){
760
- return adinj($content, "Error: no potential inj positions");
761
  }
762
 
763
  if (!adinj_ticked('rnd_allow_ads_on_last_paragraph')){
764
  array_pop($potential_inj_positions);
 
 
 
765
  }
766
 
767
  $inj_positions = array();
768
 
769
- $startparagraph = adinj_paragraph_to_start_ads();
770
- if ($startparagraph > 0){
771
  $pos = NULL;
772
- for ($i=0; $i<$startparagraph; ++$i){
773
- // discard positions until we get to the starting paragraph
774
- $pos = array_shift($potential_inj_positions);
 
 
 
 
 
 
 
 
 
 
 
775
  }
776
- if ($pos != NULL){
777
- $inj_positions[] = $pos;
778
- --$num_rand_ads_to_insert;
779
  }
780
  }
781
 
@@ -806,7 +873,7 @@ function adinj_content_hook($content){
806
  }
807
 
808
  if (sizeof($inj_positions) == 0){
809
- return adinj($content_adfree_header.$content.$content_adfree_footer, "Error: No ad injection positions: " . $debug);
810
  }
811
  foreach($inj_positions as $pos){
812
  if ($debug_on) $debug = "$pos, $debug";
@@ -866,6 +933,15 @@ function adinj_split_by_tag($content, $tag, &$debugtags){
866
  return $ret;
867
  }
868
 
 
 
 
 
 
 
 
 
 
869
  function adinj_get_current_page_type_prefix(){
870
  if (is_home()) return 'home_';
871
  if (is_archive()) return 'archive_';
@@ -966,7 +1042,7 @@ function adinj_num_rand_ads_to_insert($content_length){
966
 
967
  function adinj_num_footer_ads_to_insert(){
968
  if (adinj_excluded_by_tick_box('footer_')) return 0;
969
- $reason = adinj_ads_completely_disabled_from_page($content);
970
  if ($reason !== false){
971
  return 0;
972
  }
@@ -1046,7 +1122,7 @@ function adinj_db_version($ops){
1046
 
1047
  // template ads
1048
  function adinj_print_ad($adname=''){
1049
- $reason = adinj_ads_completely_disabled_from_page("");
1050
  if ($reason !== false){
1051
  return;
1052
  }
3
  Plugin Name: Ad Injection
4
  Plugin URI: http://www.reviewmylife.co.uk/blog/2010/12/06/ad-injection-plugin-wordpress/
5
  Description: Injects any advert (e.g. AdSense) into your WordPress posts or widget area. Restrict who sees the ads by post length, age, referrer or IP. Cache compatible.
6
+ Version: 1.1.0.3
7
  Author: reviewmylife
8
  Author URI: http://www.reviewmylife.co.uk/
9
  License: GPLv2
30
  // 11 = options to disable rnd ad at bottom, and to get new ad for each rnd slot
31
  // 13 = post/page id restrictions
32
  // 14 = template ads
33
+ // 15 = remove duplicate 'Disabled' option from top/bottom ad section
34
+ // 16 = after paragraph options, older option for widget
35
+ define('ADINJ_DB_VERSION', 16);
36
 
37
  // Files
38
  // TODO will these paths work on windows?
354
 
355
  // Based on: http://www.wprecipes.com/wordpress-hack-how-to-display-ads-on-old-posts-only
356
  // Only use for pages and posts. Not for archives, categories, home page, etc.
357
+ function adinj_is_old_post($adtype){
358
  $ops = adinj_options();
359
+ if ($adtype == 'widget'){
360
+ $days = $ops['widgets_on_page_older_than'];
361
+ } else {
362
+ $days = $ops['ads_on_page_older_than'];
363
+ }
364
  if ($days == 0) return true;
365
  if(is_single() || is_page()) {
366
  $current_date = time();
389
  global $adinj_total_top_ads_used, $adinj_total_random_ads_used, $adinj_total_bottom_ads_used, $adinj_total_all_ads_used;
390
  $ops = adinj_options();
391
  $para = adinj_paragraph_to_start_ads();
392
+ $random_mode = $ops['random_ads_after_mode'];
393
+ if ($random_mode == 'after') $random_mode = 'at or after';
394
+ $random_unit = $ops['random_ads_after_unit'];
395
  $mode = $ops['ad_insertion_mode'];
396
 
397
  $posttype = get_post_type() . ' (';
419
  \$adinj_total_bottom_ads_used=$adinj_total_bottom_ads_used
420
  \$adinj_total_all_ads_used=$adinj_total_all_ads_used
421
  paragraphtostartads=$para (fyi: -1 is disabled)
422
+ random ads start $random_mode $random_unit $para (fyi: -1 is disabled)
423
  posttype=$posttype
424
  currentdate=$currentdate ($currentday)
425
  postdate=$postdate ($postday)
440
  return false;
441
  }
442
 
443
+ function adinj_ads_completely_disabled_from_page($adtype, $content=NULL){
444
  $ops = adinj_options();
445
  if ($ops['ads_enabled'] == 'off' ||
446
  $ops['ads_enabled'] == ''){
465
  if (adinj_adverts_disabled_flag()) return "NOADS: adverts_disabled_flag";
466
 
467
  // no ads on old posts/pages if rule is enabled
468
+ if((is_page() || is_single()) && !adinj_is_old_post($adtype)) return "NOADS: !is_old_post";
469
 
470
  if (!adinj_allowed_in_category('global', $ops)) return "NOADS: globally blocked from category";
471
  if (!adinj_allowed_in_tag('global', $ops)) return "NOADS: globally blocked from tag";
656
  $adinj_total_bottom_ads_used = 0;
657
  }
658
 
659
+ $reason = adinj_ads_completely_disabled_from_page('in-content', $content);
660
  if ($reason !== false){
661
  return adinj($content, $reason);
662
  }
685
  $length = 0;
686
  if ($ops['content_length_unit'] == 'all'){
687
  $length = strlen($content);
688
+ if ($debug_on) $debug .= "\nnum chars: $length (including HTML chars)";
689
  } else if ($ops['content_length_unit'] == 'viewable'){
690
  $length = strlen(strip_tags($content));
691
+ if ($debug_on) $debug .= "\nnum chars: $length (viewable chars only)";
692
  } else {
693
  $length = str_word_count_utf8(strip_tags($content));
694
+ if ($debug_on) $debug .= "\nnum words: $length";
695
  }
696
  # Insert top and bottom ads if necesary
697
+ if(stripos($content, "<!--topad-->") == false){
698
+ if (adinj_num_top_ads_to_insert($length) > 0){
699
+ $content = $ad_include.adinj_ad_code_top().$content;
700
+ $ad_include = "";
701
+ ++$adinj_total_top_ads_used;
702
+ }
703
+ } else {
704
+ if ($debug_on) $debug .= "\ntop ad position(s) fixed by 'topad' tag";
705
+ $content = str_replace('<!--topad-->', adinj_ad_code_top(), $content);
706
+ $content = $ad_include.$content;
707
  $ad_include = "";
708
  ++$adinj_total_top_ads_used;
709
  }
710
+
711
+ if(stripos($content, "<!--bottomad-->") == false){
712
+ if (adinj_num_bottom_ads_to_insert($length) > 0){
713
+ $content = $content.adinj_ad_code_bottom();
714
+ ++$adinj_total_bottom_ads_used;
715
+ }
716
+ } else {
717
+ if ($debug_on) $debug .= "\nbottom ad position(s) fixed by 'bottomad' tag";
718
+ $content = str_replace('<!--bottomad-->', adinj_ad_code_bottom(), $content);
719
  ++$adinj_total_bottom_ads_used;
720
  }
721
 
726
  $ad = adinj_ad_code_random();
727
  if (empty($ad)) return adinj($content, "no random ad defined");
728
 
729
+ if(stripos($content, "<!--randomad-->") !== false){
730
+ if ($debug_on) $debug .= "\nrandom ad position(s) fixed by 'randomad' tag";
731
+ $content = str_replace('<!--randomad-->', $ad, $content);
732
+ return adinj($content, "Fixed random ads" . $debug);
733
+ }
734
+
735
  if (!$debug_on) $debugtags=false;
736
 
737
+ $adstart_override = false;
738
  $content_adfree_header = "";
739
  $content_adfree_footer = "";
740
 
745
  if (count($split) == 2){
746
  $content_adfree_header = $split[0];
747
  $content = $split[1];
748
+ $adstart_override = true;
749
  }
750
 
751
  # Use the same naming convention for the end tag
759
  if (count($split) == 2){
760
  $content_adfree_header = $split[0];
761
  $content = $split[1];
762
+ $adstart_override = true;
763
  }
764
 
765
  $split = adinj_split_by_tag($content, "<!--adend-->", $debugtags);
768
  $content_adfree_footer = $split[1];
769
  }
770
 
771
+ if ($debug_on) $debug .= "\nContent length=". strlen($content);
772
+
773
+ $startposition = adinj_paragraph_to_start_ads();
774
+
775
+ if (!$adstart_override){
776
+ if ($ops['random_ads_after_unit'] == 'character' && $startposition > 0){
777
+ $split = adinj_split_by_index($content, $startposition);
778
+ if (count($split) == 2){
779
+ $content_adfree_header = $split[0];
780
+ $content = $split[1];
781
+ if ($ops['random_ads_after_mode'] == 'at'){
782
+ // Start ads at next paragraph
783
+ $startposition = 1;
784
+ } else {
785
+ $startposition = -1;
786
+ }
787
+ } else {
788
+ return adinj($content, "No random ads: content too short for 'start first ad at/after character $startposition' setting");
789
+ }
790
+ }
791
+ }
792
+
793
  // TODO add note explaining that start tags are processed before the 'first
794
  // paragraph ad
795
 
800
  if ($debug_on) $debug .= "\nTags=". htmlentities($debugtags);
801
 
802
  // Generate a list of all potential injection points
803
+ if ($debug_on) $debug .= "\nInitial potential positions: ";
804
  $potential_inj_positions = array();
805
  $prevpos = -1;
806
  while(($prevpos = stripos($content, $paragraphmarker, $prevpos+1)) !== false){
812
  if ($debug_on) $debug .= "\npotential_inj_positions:".sizeof($potential_inj_positions);
813
 
814
  if (sizeof($potential_inj_positions) == 0){
815
+ return adinj($content, "No random ads: no potential inj positions found in content");
816
  }
817
 
818
  if (!adinj_ticked('rnd_allow_ads_on_last_paragraph')){
819
  array_pop($potential_inj_positions);
820
+ if (sizeof($potential_inj_positions) == 0){
821
+ return adinj($content, "No random ads: no potential inj positions after removing last paragraph position");
822
+ }
823
  }
824
 
825
  $inj_positions = array();
826
 
827
+ if ($startposition > 0){
 
828
  $pos = NULL;
829
+ if ($ops['random_ads_after_mode'] == 'at'){
830
+ for ($i=0; $i<$startposition; ++$i){
831
+ // discard positions until we get to the starting paragraph
832
+ $pos = array_shift($potential_inj_positions);
833
+ }
834
+ if ($pos != NULL && $ops['random_ads_after_mode'] == 'at'){
835
+ $inj_positions[] = $pos;
836
+ --$num_rand_ads_to_insert;
837
+ }
838
+ } else { // mode == at or after
839
+ for ($i=0; $i<$startposition-1; ++$i){
840
+ // discard positions before the starting paragraph
841
+ array_shift($potential_inj_positions);
842
+ }
843
  }
844
+ if (sizeof($potential_inj_positions) == 0){
845
+ return adinj($content, "No random ads: no potential inj positions left after applying 'start ads at/after paragraph' $startposition setting");
 
846
  }
847
  }
848
 
873
  }
874
 
875
  if (sizeof($inj_positions) == 0){
876
+ return adinj($content_adfree_header.$content.$content_adfree_footer, "Error: No random ad injection positions: " . $debug);
877
  }
878
  foreach($inj_positions as $pos){
879
  if ($debug_on) $debug = "$pos, $debug";
933
  return $ret;
934
  }
935
 
936
+ function adinj_split_by_index($content, $index){
937
+ $ret = array();
938
+ if (strlen($content) > $index+4){ // +4 as there is no point splitting unless there is room for a </p> at end
939
+ $ret[0] = substr($content, 0, $index);
940
+ $ret[1] = substr($content, $index+1);
941
+ }
942
+ return $ret;
943
+ }
944
+
945
  function adinj_get_current_page_type_prefix(){
946
  if (is_home()) return 'home_';
947
  if (is_archive()) return 'archive_';
1042
 
1043
  function adinj_num_footer_ads_to_insert(){
1044
  if (adinj_excluded_by_tick_box('footer_')) return 0;
1045
+ $reason = adinj_ads_completely_disabled_from_page('footer', $content);
1046
  if ($reason !== false){
1047
  return 0;
1048
  }
1122
 
1123
  // template ads
1124
  function adinj_print_ad($adname=''){
1125
+ $reason = adinj_ads_completely_disabled_from_page('template', "");
1126
  if ($reason !== false){
1127
  return;
1128
  }
readme.txt CHANGED
@@ -4,17 +4,20 @@ Donate link: http://www.reviewmylife.co.uk/blog/2010/12/06/ad-injection-plugin-w
4
  Tags: ad injection, adsense, advert injection, advert, ad, injection, advertising, affiliate, inject, injection, insert, widget, widgets, sidebar, monetize, monetise, banner, Amazon, ClickBank, TradeDoubler, Google, adBrite, post, WordPress, automatically, plugin, Adsense Injection, free, blog, ad rotation, A:B testing, split testing, WP Super Cache, W3 Total Cache, WP Cache
5
  Requires at least: 2.8.6
6
  Tested up to: 3.2.1
7
- Stable tag: 1.1.0.2
8
 
9
  Injects any adverts (e.g. AdSense) into the WordPress posts or widget area. Restrict who sees ads by post length/age/referrer or IP. Cache compatible.
10
 
11
  == Description ==
12
 
13
- Ad Injection from [reviewmylife](http://www.reviewmylife.co.uk/ "reviewmylife") injects any kind of advert (e.g. Google AdSense, Amazon Associates, ClickBank, TradeDoubler, etc) into the existing content of your WordPress posts and pages. You can control the number of adverts based on the post length, and it can restrict who sees adverts by post age, visitor referrer and IP address. Adverts can be configured in the post (random, top, and bottom positions) or in any widget/sidebar area. There's support for A:B split testing / ad rotation. And the dynamic restrictions (by IP and referrer) work with WP Super Cache, W3 Total Cache and WP Cache.
14
 
15
  **New Features 1.1.x.x**
16
 
17
  * Template ads - you can now include ads anywhere in your theme template with some simple tags. You can load the top/random/bottom/footer ads, or you can load an ad from a text file on disk. Template ads inherit the same dynamic and global restrictions as for ads configured via the UI.
 
 
 
18
 
19
  **New Features 0.9.7.x**
20
 
@@ -33,7 +36,7 @@ Ad Injection from [reviewmylife](http://www.reviewmylife.co.uk/ "reviewmylife")
33
 
34
  = Automatic advert injection =
35
 
36
- The ads can be injected into existing posts without requiring any modification of the post. The injection can be done randomly between paragraphs, and there is an option to always inject the first advert at a specified paragraph (e.g. the first or second). Randomly positioning the adverts helps to reduce 'ad blindness'. Two additional adverts can be defined for the top and bottom of the content. Widget adverts can be defined as well.
37
 
38
  = Widget support =
39
 
@@ -49,7 +52,7 @@ The number of adverts can be set based on the length of the post. It is a good i
49
 
50
  = Search engines only mode (restrict by referrer) =
51
 
52
- You can specify that ads should only be shown to search engine visitors, or to visitors from defined referring websites - e.g. Facebook, Wikipedia, etc. This will give your regular visitors (who are unlikely to click your ads) a better experience of your site. You can define which search engines or referring sites see your adverts. A visitor who enters the site by one of these referrers will see ads for the next hour.
53
 
54
  = Ads on old posts only =
55
 
@@ -67,6 +70,10 @@ Ads can be included anywhere in your theme template with some simple tags. You c
67
 
68
  IP addresses of people who shouldn't see your ads can be defined. These could be the IP addresses of your friends, family, or even yourself.
69
 
 
 
 
 
70
  = Alternate content =
71
 
72
  This is content that is displayed when ads are blocked for the user. You could use this alternate content to show other content, some kind of layout filler, or even a different type of ad. I've added support for rotation of alternate content as well.
@@ -75,7 +82,18 @@ This is content that is displayed when ads are blocked for the user. You could u
75
 
76
  The advert code can be copied and pasted directly from your ad provider (Google AdSense, adBrite, ClickBank, etc) which will help you to comply with any terms of service (TOS) that state their ad code may not be modified.
77
 
78
- = Flexible ad positioning =
 
 
 
 
 
 
 
 
 
 
 
79
 
80
  Easy positioning options are provided for left, right, center, float left, and float right (or a random variant of these). Extra spacing can be set above and below the ad using the CSS margin and padding boxes. Or if that isn't flexible enough, you can write your own positioning code using HTML and CSS. And you can select which paragraph random ads should start from.
81
 
@@ -137,16 +155,17 @@ I used to use the excellent Adsense Injection by Dax Herrera, but found I needed
137
 
138
  = How is this plugin different to Adsense Injection by Dax Herrera? =
139
 
140
- One a basic level it can do the same job as Dax's excellent Adsense Injection. If you want it can just inject AdSense between paragraphs like his plugin does. I used to use his plugin, but found that I wanted a lot more features. Here are some of the extra features.
141
 
142
  * Inject any type of advert from any ad provider.
143
  * Restrict ad display by referrer (e.g. can restrict display to search engine visitors).
144
  * Can prevent specific IP addresses from seeing adverts.
145
  * Can define randomly positioned adverts, and adverts at the top, bottom and footer of the posts.
146
  * Add adverts to the widget area.
147
- * Adverts can be put anywhere in your theme template.
148
  * Ad rotation / split testing.
149
  * Restrict adverts by category, tag, author, post ID.
 
150
  * Vary number of adverts based on post length.
151
  * You can inject raw JavaScript and PHP.
152
  * Include ads anywhere in the theme template if you edit your theme's PHP.
@@ -362,7 +381,7 @@ Here is an example of how to load a text file ad from the ad-injection-data dire
362
 
363
  The `function_exists` condition ensures that the ads will silently dissapear if the plugin is deactivated rather than generating an error.
364
 
365
- If you are using template ads with a compatible caching plugin you will need to include adshow.php (once on the page) using mfunc tags. You will need to alter the code below to include the correct path.
366
 
367
  `<!--mfunc include_once('/home/public_html/wordpress/wp-content/plugins/ad-injection/adshow.php') -->
368
  <?php include_once('/home/public_html/wordpress/wp-content/plugins/ad-injection/adshow.php'); ?>
@@ -391,6 +410,14 @@ By default FeedWordPress prevents the syndicated post contents from being passed
391
 
392
  From the FeedWordPress settings page go to 'Posts & Links' and then in the 'Formatting' section set 'Formatting filters' to 'Expose syndicated posts to formatting filters'.
393
 
 
 
 
 
 
 
 
 
394
  = Will Ad Injection work with the multi-blog version of WordPress? =
395
 
396
  The multi-user version of WordPress are not supported - yet, however I have heard that some people have got it to work when using the 'direct' insertion mode. I hope to make it work properly with multi-blog versions of WordPress in the future.
@@ -487,6 +514,14 @@ If you do get any errors please use the 'Report a bug or give feedback' link on
487
 
488
  == Changelog ==
489
 
 
 
 
 
 
 
 
 
490
  = 1.1.0.2 =
491
  * Remove confusing Disabled/Enabled drop down options as all ads can be enabled/disabled from the tick boxes. Please check your ads after this update and report any problems!
492
  * Hide certain parts of the UI when the 'All' exclude boxes are ticked.
@@ -669,24 +704,15 @@ Fix 'Something badly wrong in num_rand_ads_to_insert' message that occurs on pag
669
 
670
  == Upgrade Notice ==
671
 
 
 
 
672
  = 1.1.0.2 =
673
  * Remove confusing Disabled/Enabled drop down options as all ads can be enabled/disabled from the tick boxes. Please check your ads after this update and report any problems!
674
 
675
  = 1.1.0.1 =
676
  * Template ads - you can now include ads anywhere in your theme template with some simple tags. UI usability improvements.
677
 
678
- = 0.9.7.11 =
679
- * Filter ads by post/page ID and other misc fixes.
680
-
681
- = 0.9.7.10 =
682
- * UI fix for WordPress 3.2 and fix for users who are running PHP with no UTF8 support.
683
-
684
- = 0.9.7.9 =
685
- * New options to disable last paragraph random ad, re-pick random ad for each position, and other minor fixes.
686
-
687
- = 0.9.7.8 =
688
- * Fix bug that prevented ads appearing on archive/home pages when used with certain plugins/themes.
689
-
690
  = 0.8.3 =
691
  First public release.
692
 
4
  Tags: ad injection, adsense, advert injection, advert, ad, injection, advertising, affiliate, inject, injection, insert, widget, widgets, sidebar, monetize, monetise, banner, Amazon, ClickBank, TradeDoubler, Google, adBrite, post, WordPress, automatically, plugin, Adsense Injection, free, blog, ad rotation, A:B testing, split testing, WP Super Cache, W3 Total Cache, WP Cache
5
  Requires at least: 2.8.6
6
  Tested up to: 3.2.1
7
+ Stable tag: 1.1.0.3
8
 
9
  Injects any adverts (e.g. AdSense) into the WordPress posts or widget area. Restrict who sees ads by post length/age/referrer or IP. Cache compatible.
10
 
11
  == Description ==
12
 
13
+ Ad Injection from [reviewmylife](http://www.reviewmylife.co.uk/ "reviewmylife") injects any kind of advert or other content (e.g. Google AdSense, Amazon Associates, ClickBank, TradeDoubler, etc) into the existing content of your WordPress posts and pages. You can control the number of adverts based on the post length, and it can restrict who sees adverts by post age, visitor referrer and IP address. Adverts can be configured in the post (random, top, and bottom positions) or in any widget/sidebar area. There's support for A:B split testing / ad rotation. And the dynamic restrictions (by IP and referrer) work with WP Super Cache, W3 Total Cache and WP Cache.
14
 
15
  **New Features 1.1.x.x**
16
 
17
  * Template ads - you can now include ads anywhere in your theme template with some simple tags. You can load the top/random/bottom/footer ads, or you can load an ad from a text file on disk. Template ads inherit the same dynamic and global restrictions as for ads configured via the UI.
18
+ * First ad can now be started at or after a paragraph or character position.
19
+ * Override ad positions on individual posts using &lt;!--topad--&gt; &lt;!--randomad--&gt; &lt;!--bottomad--&gt;
20
+ * Separate old post restriction for widget ads in case you want a different rule for the widget ads.
21
 
22
  **New Features 0.9.7.x**
23
 
36
 
37
  = Automatic advert injection =
38
 
39
+ The ads can be injected into existing posts without requiring any modification of the post. The injection can be done randomly between paragraphs, and there is an option to always inject the first advert at a specified paragraph (e.g. the first or second). Randomly positioning the adverts helps to reduce 'ad blindness'. Additional adverts can be defined for the top and bottom of the content, or the footer of the page. Widget adverts can be defined as well.
40
 
41
  = Widget support =
42
 
52
 
53
  = Search engines only mode (restrict by referrer) =
54
 
55
+ You can specify that ads should only be shown to search engine visitors, or to visitors from defined referring websites - e.g. Facebook, Wikipedia, Twitter, etc. This will give your regular visitors (who are unlikely to click your ads) a better experience of your site. You can define which search engines or referring sites see your adverts. A visitor who enters the site by one of these referrers will see ads for the next hour.
56
 
57
  = Ads on old posts only =
58
 
70
 
71
  IP addresses of people who shouldn't see your ads can be defined. These could be the IP addresses of your friends, family, or even yourself.
72
 
73
+ = Override ad positioning on individual posts =
74
+
75
+ If you need to override the top, random, or bottom ad positions on a specific post you can use these in-content tags to manually set the ad positions: &lt;!--topad--&gt; &lt;!--randomad--&gt; &lt;!--bottomad--&gt; &lt;!--adstart--&gt; &lt;!--adend--&gt; &lt;!--noads--&gt;
76
+
77
  = Alternate content =
78
 
79
  This is content that is displayed when ads are blocked for the user. You could use this alternate content to show other content, some kind of layout filler, or even a different type of ad. I've added support for rotation of alternate content as well.
82
 
83
  The advert code can be copied and pasted directly from your ad provider (Google AdSense, adBrite, ClickBank, etc) which will help you to comply with any terms of service (TOS) that state their ad code may not be modified.
84
 
85
+ = Inject anything! =
86
+
87
+ Although this plugin is usually used for injecting adverts it can in fact be used to inject anything. Here are some alternative uses for Ad Injection:
88
+
89
+ * Inject an email opt-in form at the bottom of each post.
90
+ * Insert a common header or footer block (e.g. copyright, disclaimers, website information).
91
+ * Add tracking scripts (e.g. Google Analytics) into your site.
92
+ * Use it to rotate random images or photos in your pages.
93
+ * Put some time limited temporary content at the top or bottom of each post (e.g. sales offer, or web site announcement).
94
+ * Inserting social networking buttons (e.g. Facebook, Twitter, Google +1) at the top or bottom of your posts.
95
+
96
+ = Flexible ad alignment =
97
 
98
  Easy positioning options are provided for left, right, center, float left, and float right (or a random variant of these). Extra spacing can be set above and below the ad using the CSS margin and padding boxes. Or if that isn't flexible enough, you can write your own positioning code using HTML and CSS. And you can select which paragraph random ads should start from.
99
 
155
 
156
  = How is this plugin different to Adsense Injection by Dax Herrera? =
157
 
158
+ One a basic level it can do the same job as Dax's Adsense Injection. If you want it can just inject AdSense between paragraphs like his plugin does. I used to use his plugin, but found that I wanted a lot more features. Here are some of the extra features.
159
 
160
  * Inject any type of advert from any ad provider.
161
  * Restrict ad display by referrer (e.g. can restrict display to search engine visitors).
162
  * Can prevent specific IP addresses from seeing adverts.
163
  * Can define randomly positioned adverts, and adverts at the top, bottom and footer of the posts.
164
  * Add adverts to the widget area.
165
+ * Adverts can be positioned anywhere in your theme template.
166
  * Ad rotation / split testing.
167
  * Restrict adverts by category, tag, author, post ID.
168
+ * Override ad positions for individual posts if necessary.
169
  * Vary number of adverts based on post length.
170
  * You can inject raw JavaScript and PHP.
171
  * Include ads anywhere in the theme template if you edit your theme's PHP.
381
 
382
  The `function_exists` condition ensures that the ads will silently dissapear if the plugin is deactivated rather than generating an error.
383
 
384
+ If you are using template ads with a compatible caching plugin you will need to include adshow.php (once on the page) using mfunc tags. You will need to alter the code below to include the correct path. If you look in the 'Test ads' section of the main settings page you should be able to find a version of this code customised for your web server.
385
 
386
  `<!--mfunc include_once('/home/public_html/wordpress/wp-content/plugins/ad-injection/adshow.php') -->
387
  <?php include_once('/home/public_html/wordpress/wp-content/plugins/ad-injection/adshow.php'); ?>
410
 
411
  From the FeedWordPress settings page go to 'Posts & Links' and then in the 'Formatting' section set 'Formatting filters' to 'Expose syndicated posts to formatting filters'.
412
 
413
+ **Shortcodes Ultimate**
414
+
415
+ Problem: Random ads don't show.
416
+
417
+ Reason: Shortcodes Ultimate disables the wpautop filter which adds the &lt;p&gt;&lt;/p&gt; tags to the page. It re-applies this filter at a priority of 99 which is after Ad Injection has run. Therefore when Ad Injection runs it can't find any &lt;/p&gt; tags which it needs to position the random adverts.
418
+
419
+ Potential solution?: I could change the priority of the plugin so it runs after Shortcodes Ultimate. What I'd prefer to do is to make the priority of Ad Injection configurable. I haven't yet investigated whether this is possible.
420
+
421
  = Will Ad Injection work with the multi-blog version of WordPress? =
422
 
423
  The multi-user version of WordPress are not supported - yet, however I have heard that some people have got it to work when using the 'direct' insertion mode. I hope to make it work properly with multi-blog versions of WordPress in the future.
514
 
515
  == Changelog ==
516
 
517
+ = 1.1.0.3 =
518
+ * First ad can now be started at or after a paragraph or character position.
519
+ * Override ad positions on individual posts using &lt;!--topad--&gt; &lt;!--randomad--&gt; &lt;!--bottomad--&gt;
520
+ * Separate old post restriction for widget ads.
521
+ * Template ad examples in the 'Test ads' section.
522
+ * Warning message improvements.
523
+ * UI tweaks and other fixes.
524
+
525
  = 1.1.0.2 =
526
  * Remove confusing Disabled/Enabled drop down options as all ads can be enabled/disabled from the tick boxes. Please check your ads after this update and report any problems!
527
  * Hide certain parts of the UI when the 'All' exclude boxes are ticked.
704
 
705
  == Upgrade Notice ==
706
 
707
+ = 1.1.0.3 =
708
+ * First ad can now be started at or after a paragraph or character position. Position override tags. Separate old post restriction for widget ads. Template ad examples in the 'Test ads' section. Warning message improvements. Other fixes.
709
+
710
  = 1.1.0.2 =
711
  * Remove confusing Disabled/Enabled drop down options as all ads can be enabled/disabled from the tick boxes. Please check your ads after this update and report any problems!
712
 
713
  = 1.1.0.1 =
714
  * Template ads - you can now include ads anywhere in your theme template with some simple tags. UI usability improvements.
715
 
 
 
 
 
 
 
 
 
 
 
 
 
716
  = 0.8.3 =
717
  First public release.
718
 
ui-tab-main.php CHANGED
@@ -16,42 +16,6 @@ function adinj_tab_main(){
16
 
17
 
18
  <?php adinj_postbox_start(__("Ad placement settings", 'adinj'), 'adsettings'); ?>
19
- <p><b><a name="pagetypefilters"></a>Exclude ads from page types</b></p>
20
- <?php
21
- $count_pages = wp_count_posts('page', 'readable');
22
- $count_posts = wp_count_posts('post', 'readable');
23
- ?>
24
-
25
-
26
- <table class="adinjstatustable">
27
- <tr>
28
- <td></td>
29
- <td><b>Single(<?php echo $count_posts->publish; ?>)</b></td>
30
- <td><b>Page(<?php echo $count_pages->publish; ?>)</b></td>
31
- <td><b>Home</b></td>
32
- <td><b>Archive</b></td>
33
- <td><b><a href="<?php echo get_bloginfo('url'); ?>" target="_new">Front</a></b></td>
34
- <td><b>404</b></td>
35
- <td><b>Search</b></td>
36
- </tr>
37
- <?php
38
- adinj_add_exclude_row('All ads');
39
- adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#topadplacement">Top</a>', 'top_');
40
- adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#randomadplacement">Random</a>', 'random_');
41
- adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#bottomadplacement">Bottom</a>', 'bottom_');
42
- adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#footeradplacement">Footer</a>', 'footer_');
43
- adinj_add_exclude_row('|_&nbsp;&nbsp;Widget', 'widget_');
44
- adinj_add_exclude_row('|_&nbsp;&nbsp;Template', 'template_');
45
- ?>
46
- <tr><td colspan="8"><span style="font-size:10px;">Go to the <a href="widgets.php">widget control panel</a> to set up any widgets. See the <a href="http://wordpress.org/extend/plugins/ad-injection/faq/" target="_new">FAQ</a> for how to set up template ads.</span></td></tr>
47
- </table>
48
-
49
- <p>
50
-
51
- </p>
52
-
53
- <p><span style="font-size:10px;"><b>Notes:</b> Your home page is the page displaying your latest posts. It may be different to your front page if you have configured your front page to be a static page. If you have <a href='options-reading.php'>set your front page</a> to be a static 'page' rather than your latest posts, the 'page' tick box will also apply to the front page.</span></p>
54
- <p><span style="font-size:10px;">Archive pages are the categories, tags, authors and date pages.</span></p>
55
 
56
  <p></p>
57
 
@@ -110,14 +74,41 @@ function adinj_tab_main(){
110
  ?>
111
  <tr><td colspan="4">
112
  <table class="adinjtable">
 
 
 
 
 
 
 
 
 
 
 
 
113
  <?php
114
- echo '<tr><td>';
115
- _e("Always put the first ad immediately after paragraph: ", 'adinj');
116
- echo '</td><td>';
117
- adinj_selection_box("start_from_paragraph", array('d',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), " ");
118
- echo '</td></tr>';
119
  ?>
 
120
  </table>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  </td></tr>
122
  <tr><td colspan="4">
123
  <br />
@@ -169,7 +160,7 @@ function adinj_tab_main(){
169
  <h3><a name="topadcode"></a>Top ad (below post title - this is not a 'header' ad) [<a href="#topadplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_top'>pool</a>]--></h3>
170
  <table border="0" class="adinjtable" width="95%">
171
  <tr><td>
172
- <textarea name="ad_code_top_1" rows="10" cols="60"><?php echo $ops['ad_code_top_1']; ?></textarea>
173
  <br />
174
  <p><span style="font-size:10px;"><b>Docs:</b> Try a <a href="#468x15">468x15</a> or <a href="#336x280">336x280</a> advert.</span></p>
175
  </td><td>
@@ -184,7 +175,7 @@ function adinj_tab_main(){
184
  <h3><a name="randomadcode"></a>Random ad (inserted randomly between paragraphs) [<a href="#randomadplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_random'>pool</a>]--></h3>
185
  <table border="0" class="adinjtable" width="95%">
186
  <tr><td>
187
- <textarea name="ad_code_random_1" rows="10" cols="60"><?php echo $ops['ad_code_random_1']; ?></textarea>
188
  <br />
189
  <p><span style="font-size:10px;"><b>Docs:</b> Try a <a href="#468x60">468x60</a> or <a href="#728x90">728x90</a> banner.</span></p>
190
  </td><td>
@@ -198,7 +189,7 @@ function adinj_tab_main(){
198
  <h3><a name="bottomadcode"></a>Bottom ad (below the post content) [<a href="#bottomadplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_bottom'>pool</a>]--></h3>
199
  <table border="0" class="adinjtable" width="95%">
200
  <tr><td>
201
- <textarea name="ad_code_bottom_1" rows="10" cols="60"><?php echo $ops['ad_code_bottom_1']; ?></textarea>
202
  <br />
203
  <p><span style="font-size:10px;"><b>Docs:</b> Try a <a href="#336x280">336x280</a> advert.</span></p>
204
  </td><td>
@@ -213,7 +204,7 @@ function adinj_tab_main(){
213
  <h3><a name="footeradcode"></a>Footer ad (put into 'the_footer' hook - not supported by all themes) [<a href="#footeradplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_footer'>pool</a>]--></h3>
214
  <table border="0" class="adinjtable" width="95%">
215
  <tr><td>
216
- <textarea name="ad_code_footer_1" rows="10" cols="60"><?php echo $ops['ad_code_footer_1']; ?></textarea>
217
  <br />
218
  Docs: footer ad information and troubleshooting
219
  <?php adinj_add_show_hide_section('footer_docs_'.uniqid(''), 'ui_footer_docs_show', 'ui_footer_docs_show', $ops); ?>
@@ -243,12 +234,17 @@ function adinj_tab_main(){
243
  adinj_docs();
244
 
245
  adinj_testads();
 
 
 
 
 
 
 
246
  }
247
 
248
  function adinj_global_settings_box($ops){
249
- adinj_postbox_start(__("Global settings", 'adinj'), 'global'); ?>
250
-
251
- <p>These settings apply to all ads (top, random, bottom, footer, and widget). They will override all other settings.</p>
252
 
253
  <input type="radio" name="ads_enabled" value="on" <?php if ($ops['ads_enabled']=='on') echo 'checked="checked"'; ?> /> <b>On: <?php _e('Ads enabled', 'adinj') ?></b><br />
254
  <input type="radio" name="ads_enabled" value="off" <?php if ($ops['ads_enabled']=='off' || $ops['ads_enabled']=='') echo 'checked="checked"'; ?> /> <b>Off</b><br />
@@ -271,15 +267,51 @@ function adinj_global_settings_box($ops){
271
  </script>
272
  <div id="test_mode_warning"><span style="font-size:10px;color:red;">Warning: Turn any caching plugin *off* before using test mode. If you leave the caching plugin on, the test adverts will be cached and shown to your real visitors.</span><br /></div>
273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  <style type="text/css">
275
  .adinjtable td { vertical-align: top; }
276
  </style>
277
-
278
  <table border="0" class="adinjtable">
279
  <tr>
280
- <td><p><?php _e("Only show ads on pages older than ", 'adinj') ?></p></td>
281
  <td>
282
- <p>
283
  <select name='ads_on_page_older_than'>
284
  <?php
285
  $older_than_days = array(0, 1, 2, 3, 5, 7, 10, 14, 21, 28, 40, 50);
@@ -289,9 +321,25 @@ function adinj_global_settings_box($ops){
289
  echo ">$older_than_days[$value]</option>";
290
  }
291
  ?>
292
- </select><?php _e(" (days)", 'adinj') ?> - only for single posts and pages</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
293
  </td></tr>
294
  </table>
 
 
 
295
  <?php
296
  adinj_condition_tables('global_', 'ui_conditions_show');
297
  //TODO sometimes OOM here - just before drop down list is loaded
@@ -351,9 +399,9 @@ function adinj_insertion_mode_box($ops){
351
  <h4><a name="dynamic"></a>Show ads only to visitors from these websites (dynamic feature)</h4>
352
 
353
  <blockquote>
354
- <?php adinj_add_checkbox('sevisitors_only') ?><?php _e("Only show ads to visitors from these websites (customise search engine or website referrers below if necessary).", 'adinj') ?><br />
355
  <textarea name="ad_referrers" rows="2" cols="70"><?php echo $ops['ad_referrers']; ?></textarea>
356
- <p>Comma separated list e.g.: <br /><code>.google., .bing., .yahoo., .ask., search?, search., facebook.com</code></p>
357
  </blockquote>
358
 
359
  <h4>Blocked IP addresses (dynamic feature)</h4>
16
 
17
 
18
  <?php adinj_postbox_start(__("Ad placement settings", 'adinj'), 'adsettings'); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  <p></p>
21
 
74
  ?>
75
  <tr><td colspan="4">
76
  <table class="adinjtable">
77
+ <tr><td>
78
+ <?php
79
+ _e("Always start the first ad ", 'adinj');
80
+ ?>
81
+ </td><td>
82
+ <input type="radio" name="random_ads_after_mode" value="at" <?php if ($ops['random_ads_after_mode']=='at') echo 'checked="checked"'; ?> /> <b>at</b><br />
83
+ <input type="radio" name="random_ads_after_mode" value="after" <?php if ($ops['random_ads_after_mode']=='after') echo 'checked="checked"'; ?> /> <b>at or after</b><br />
84
+ </td><td>
85
+ <input type="radio" name="random_ads_after_unit" value="paragraph" <?php if ($ops['random_ads_after_unit']=='paragraph') echo 'checked="checked"'; ?> /> <b>paragraph:</b><br />
86
+ <input type="radio" name="random_ads_after_unit" value="character" <?php if ($ops['random_ads_after_unit']=='character' || $ops['ads_enabled']=='') echo 'checked="checked"'; ?> /> <b>character:</b><br />
87
+ </td>
88
+ <td>
89
  <?php
90
+ adinj_selection_box("start_from_paragraph", array('d',1,2,3,4,5,100,200,300,500,750,1000,1500,2000,3000,4000,5000,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20), " ");
 
 
 
 
91
  ?>
92
+ </td></tr>
93
  </table>
94
+
95
+ <script type="text/javascript">
96
+ jQuery(document).ready(function(){
97
+ jQuery('input[name=random_ads_after_unit]:radio').change(function() {
98
+ if (jQuery('input[name=random_ads_after_unit]:checked').val() == "character"){
99
+ jQuery('#random_ads_after_warning').slideDown(300);
100
+ } else {
101
+ jQuery('#random_ads_after_warning').slideUp(300);
102
+ }
103
+ return true;
104
+ });
105
+ });
106
+ if ('<?php echo $ops['random_ads_after_unit'] ?>' == 'paragraph') {
107
+ document.write('<style type="text/css">#random_ads_after_warning { display: none; }</style>');
108
+ }
109
+ </script>
110
+ <div id="random_ads_after_warning"><span style="font-size:10px;color:red;">Note: If starting 'at character x', the start point will be the next paragraph.</span><br /></div>
111
+
112
  </td></tr>
113
  <tr><td colspan="4">
114
  <br />
160
  <h3><a name="topadcode"></a>Top ad (below post title - this is not a 'header' ad) [<a href="#topadplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_top'>pool</a>]--></h3>
161
  <table border="0" class="adinjtable" width="95%">
162
  <tr><td>
163
+ <textarea name="ad_code_top_1" rows="10" cols="70"><?php echo $ops['ad_code_top_1']; ?></textarea>
164
  <br />
165
  <p><span style="font-size:10px;"><b>Docs:</b> Try a <a href="#468x15">468x15</a> or <a href="#336x280">336x280</a> advert.</span></p>
166
  </td><td>
175
  <h3><a name="randomadcode"></a>Random ad (inserted randomly between paragraphs) [<a href="#randomadplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_random'>pool</a>]--></h3>
176
  <table border="0" class="adinjtable" width="95%">
177
  <tr><td>
178
+ <textarea name="ad_code_random_1" rows="10" cols="70"><?php echo $ops['ad_code_random_1']; ?></textarea>
179
  <br />
180
  <p><span style="font-size:10px;"><b>Docs:</b> Try a <a href="#468x60">468x60</a> or <a href="#728x90">728x90</a> banner.</span></p>
181
  </td><td>
189
  <h3><a name="bottomadcode"></a>Bottom ad (below the post content) [<a href="#bottomadplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_bottom'>pool</a>]--></h3>
190
  <table border="0" class="adinjtable" width="95%">
191
  <tr><td>
192
+ <textarea name="ad_code_bottom_1" rows="10" cols="70"><?php echo $ops['ad_code_bottom_1']; ?></textarea>
193
  <br />
194
  <p><span style="font-size:10px;"><b>Docs:</b> Try a <a href="#336x280">336x280</a> advert.</span></p>
195
  </td><td>
204
  <h3><a name="footeradcode"></a>Footer ad (put into 'the_footer' hook - not supported by all themes) [<a href="#footeradplacement">placement</a>] <!--[<a href='?page=ad-injection&amp;tab=adrotation#multiple_footer'>pool</a>]--></h3>
205
  <table border="0" class="adinjtable" width="95%">
206
  <tr><td>
207
+ <textarea name="ad_code_footer_1" rows="10" cols="70"><?php echo $ops['ad_code_footer_1']; ?></textarea>
208
  <br />
209
  Docs: footer ad information and troubleshooting
210
  <?php adinj_add_show_hide_section('footer_docs_'.uniqid(''), 'ui_footer_docs_show', 'ui_footer_docs_show', $ops); ?>
234
  adinj_docs();
235
 
236
  adinj_testads();
237
+
238
+ global $adinj_warning_msg_chmod;
239
+ if (!empty($adinj_warning_msg_chmod)){
240
+ echo '<a name="warning_msg_chmod"></a>';
241
+ echo '<br clear="all" />';
242
+ echo $adinj_warning_msg_chmod;
243
+ }
244
  }
245
 
246
  function adinj_global_settings_box($ops){
247
+ adinj_postbox_start(__("Global settings (apply to all ads)", 'adinj'), 'global'); ?>
 
 
248
 
249
  <input type="radio" name="ads_enabled" value="on" <?php if ($ops['ads_enabled']=='on') echo 'checked="checked"'; ?> /> <b>On: <?php _e('Ads enabled', 'adinj') ?></b><br />
250
  <input type="radio" name="ads_enabled" value="off" <?php if ($ops['ads_enabled']=='off' || $ops['ads_enabled']=='') echo 'checked="checked"'; ?> /> <b>Off</b><br />
267
  </script>
268
  <div id="test_mode_warning"><span style="font-size:10px;color:red;">Warning: Turn any caching plugin *off* before using test mode. If you leave the caching plugin on, the test adverts will be cached and shown to your real visitors.</span><br /></div>
269
 
270
+ <p><b><a name="pagetypefilters"></a>Exclude ads from page types (tick to remove ads)</b></p>
271
+ <?php
272
+ $count_pages = wp_count_posts('page', 'readable');
273
+ $count_posts = wp_count_posts('post', 'readable');
274
+ ?>
275
+
276
+
277
+ <table class="adinjstatustable">
278
+ <tr>
279
+ <td></td>
280
+ <td><b>Single(<?php echo $count_posts->publish; ?>)</b></td>
281
+ <td><b>Page(<?php echo $count_pages->publish; ?>)</b></td>
282
+ <td><b>Home</b></td>
283
+ <td><b>Archive</b></td>
284
+ <td><b><a href="<?php echo get_bloginfo('url'); ?>" target="_new">Front</a></b></td>
285
+ <td><b>404</b></td>
286
+ <td><b>Search</b></td>
287
+ </tr>
288
+ <?php
289
+ adinj_add_exclude_row('All ads');
290
+ adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#topadplacement">Top</a>', 'top_');
291
+ adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#randomadplacement">Random</a>', 'random_');
292
+ adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#bottomadplacement">Bottom</a>', 'bottom_');
293
+ adinj_add_exclude_row('|_&nbsp;&nbsp;<a href="#footeradplacement">Footer</a>', 'footer_');
294
+ adinj_add_exclude_row('|_&nbsp;&nbsp;Widget', 'widget_');
295
+ adinj_add_exclude_row('|_&nbsp;&nbsp;Template', 'template_');
296
+ ?>
297
+ <tr><td colspan="8"><span style="font-size:10px;">Go to the <a href="widgets.php">widget control panel</a> to set up any widgets. See the <a href="http://wordpress.org/extend/plugins/ad-injection/faq/" target="_new">FAQ</a> for how to set up template ads. There are some template ad examples in the <a href="#testads">test ads</a> section of this page.</span></td></tr>
298
+ </table>
299
+
300
+ <p>
301
+
302
+ </p>
303
+
304
+ <p><span style="font-size:10px;"><b>Notes:</b> Your home page is the page displaying your latest posts. It may be different to your front page if you have configured your front page to be a static page. If you have <a href='options-reading.php'>set your front page</a> to be a static 'page' rather than your latest posts, the 'page' tick box will also apply to the front page.</span></p>
305
+ <p><span style="font-size:10px;">Archive pages are the categories, tags, authors and date pages.</span></p>
306
+
307
  <style type="text/css">
308
  .adinjtable td { vertical-align: top; }
309
  </style>
310
+ <p></p>
311
  <table border="0" class="adinjtable">
312
  <tr>
313
+ <td><?php _e("Only show normal ads on pages older than ", 'adinj') ?></td>
314
  <td>
 
315
  <select name='ads_on_page_older_than'>
316
  <?php
317
  $older_than_days = array(0, 1, 2, 3, 5, 7, 10, 14, 21, 28, 40, 50);
321
  echo ">$older_than_days[$value]</option>";
322
  }
323
  ?>
324
+ </select><?php _e(" (days)", 'adinj') ?> - only for single posts and pages
325
+ </td></tr>
326
+ <tr>
327
+ <td><?php _e("Only show widget ads on pages older than ", 'adinj') ?></td>
328
+ <td>
329
+ <select name='widgets_on_page_older_than'>
330
+ <?php
331
+ for ($value=0; $value<sizeof($older_than_days); ++$value){
332
+ echo "<option value=\"$older_than_days[$value]\" ";
333
+ if($ops['widgets_on_page_older_than'] == $older_than_days[$value]) echo 'selected="selected"';
334
+ echo ">$older_than_days[$value]</option>";
335
+ }
336
+ ?>
337
+ </select><?php _e(" (days)", 'adinj') ?> - only for single posts and pages
338
  </td></tr>
339
  </table>
340
+
341
+ <p></p>
342
+
343
  <?php
344
  adinj_condition_tables('global_', 'ui_conditions_show');
345
  //TODO sometimes OOM here - just before drop down list is loaded
399
  <h4><a name="dynamic"></a>Show ads only to visitors from these websites (dynamic feature)</h4>
400
 
401
  <blockquote>
402
+ <?php adinj_add_checkbox('sevisitors_only') ?><?php _e("Only show ads to visitors from these websites (customise search engine or website referrers below). When a user visits from one of these referrers they will see ads <b>for the next hour</b> (sets a 1 hour cookie).", 'adinj') ?><br />
403
  <textarea name="ad_referrers" rows="2" cols="70"><?php echo $ops['ad_referrers']; ?></textarea>
404
+ <p>Comma separated list e.g.: <br /><code>.google., .bing., .yahoo., .ask., search?, search., facebook.com, t.co</code></p>
405
  </blockquote>
406
 
407
  <h4>Blocked IP addresses (dynamic feature)</h4>