Plugin Directory

Changeset 584842


Ignore:
Timestamp:
08/13/2012 12:31:54 PM (14 years ago)
Author:
pbackx
Message:

New 1.3 version

Location:
adherder/trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • adherder/trunk/adherder.php

    r465264 r584842  
    44Plugin URI: http://grasshopperherder.com/
    55Description: Displays call to actions, tracks their performance and optimizes placement
    6 Version: 1.2
     6Version: 1.3
    77Author: Tristan Kromer, Peter Backx
    88Author URI: http://grasshopperherder.com/
     
    5555    add_action('admin_menu', 'adherder_admin_menu');
    5656    add_action('admin_init', 'adherder_admin_init');
    57     add_action('contextual_help', 'adherder_help', 10, 3);
    5857}
    5958
  • adherder/trunk/includes/admin.php

    r465264 r584842  
    2525    // add options and reporting menu items.
    2626    $reportsMenu = add_submenu_page('edit.php?post_type=adherder_ad', 'Ad Herder reports', 'Reports', 'edit_posts', 'co-reporting-menu', 'adherder_reporting_page');
    27     add_submenu_page('edit.php?post_type=adherder_ad', 'AdHerder Options', 'Options', 'manage_options', 'adherder_options', 'adherder_options_page');
     27    $optionsMenu = add_submenu_page('edit.php?post_type=adherder_ad', 'AdHerder Options', 'Options', 'manage_options', 'adherder_options', 'adherder_options_page');
    2828
    2929    // customize the columns in the admin interface
     
    3535    // add JavaScript for reporting only
    3636    add_action('load-'.$reportsMenu, 'adherder_report_scripts');
    37     add_action('admin_print_styles-post-new.php', 'adherder_help_styles');
     37    add_action('admin_print_styles', 'adherder_help_styles');
     38   
     39    add_action('load-'.$reportsMenu, 'adherder_help_switch');
     40    add_action('load-'.$optionsMenu, 'adherder_help_switch');
     41}
     42
     43function adherder_help_switch() {
     44    $screen = get_current_screen();
     45    //old style of help menu
     46    if(!method_exists($screen, 'add_help_tab')) {
     47        add_action('contextual_help', 'adherder_help', 10, 3);
     48    } else {
     49        $screen->add_help_tab(array(
     50            'id' => 'adherder-help',
     51            'title' => 'FAQ',
     52            'callback' => adherder_help_new
     53        ));
     54    }
    3855}
    3956
    4057function adherder_help($contextual_help, $screen_id, $screen) {
    41     if($screen_id == 'adherder_ad') {
     58    if(strstr($screen_id,'adherder_ad')) {
    4259        include(plugin_dir_path(__FILE__).'/../template/help.php');
    4360        return '';
    4461    }
    4562    return $contextual_help;
     63}
     64
     65function adherder_help_new() {
     66    include(plugin_dir_path(__FILE__).'/../template/help.php');
    4667}
    4768
     
    157178
    158179function adherder_options_page() {
    159   include(plugin_dir_path(__FILE__).'/../template/options.php');
     180    include(plugin_dir_path(__FILE__).'/../template/options.php');
    160181}
    161182
     
    178199function adherder_reporting_page() {
    179200  $message = '';
    180   if(isset($_POST['adherder_switch_status'])) {
    181     $ad_id   = $_POST['adherder_switch_ad_id'];
    182     $ad_post = get_post($ad_id);
    183     if($ad_post && $ad_post->post_type == 'adherder_ad') {
    184       $post_update       = array();
    185       $post_update['ID'] = $ad_id;
    186       $post_changed      = false;
    187       if($ad_post->post_status == 'publish') {
    188         $post_update['post_status'] = 'pending';
    189         $post_changed = true;
    190       } else if($ad_post->post_status == 'pending') {
    191         $post_update['post_status'] = 'publish';
    192         $post_changed = true;
    193       } else {
    194         $message = 'The call id is not in status pending or publish, status was not updated.';
    195       }
    196       if($post_changed) {
    197         wp_update_post($post_update);
    198       }
    199     } else {
    200       $message = 'The ad id you entered is incorrect.';
    201     }
     201  if(isset($_POST['adherder_bulk_action'])) {
     202    $ad_ids = explode(',',$_POST['adherder_bulk_ad_ids']);
     203    $action = $_POST['adherder_bulk_action'];
     204    foreach ($ad_ids as $ad_id) {
     205        if($action === 'publish' || $action === 'pending') {
     206            $ad_post = get_post($ad_id);
     207            if($ad_post && $ad_post->post_type == 'adherder_ad') {
     208                $post_update       = array();
     209                $post_update['ID'] = $ad_id;
     210                $post_changed      = false;
     211                if($ad_post->post_status == 'publish' && $action === 'pending') {
     212                    $post_update['post_status'] = 'pending';
     213                    $post_changed = true;
     214                } else if($ad_post->post_status == 'pending' && $action === 'publish') {
     215                    $post_update['post_status'] = 'publish';
     216                    $post_changed = true;
     217                }
     218                if($post_changed) {
     219                    wp_update_post($post_update);
     220                }
     221            } else {
     222                $message .= "Ad id $ad_id is incorrect.<br/>";
     223            }
     224        }
     225        if($action === 'in_report' || $action === 'not_in_report') {
     226            $ad_in_report = get_post_meta($ad_id, 'adherder_in_report', true);
     227            update_post_meta($ad_id, 'adherder_in_report', ($action === 'in_report' ? 1 : 0));
     228        }
     229        if($action === 'clear_data') {
     230            $ad_post = get_post($ad_id);
     231            if($ad_post && $ad_post->post_type == 'adherder_ad') {
     232                adherder_database_clean_for_post($ad_id);
     233                update_post_meta($ad_id, 'adherder_impressions', 0);
     234                update_post_meta($ad_id, 'adherder_clicks', 0);
     235                $message = 'Cleared all data for ad with id ' . $ad_id;
     236            }
     237        }
     238    }
    202239  }
    203   if(isset($_POST['adherder_clear_history'])) {
    204     $ad_id   = $_POST['adherder_clear_ad_id'];
    205     $ad_post = get_post($ad_id);
    206     if($ad_post && $ad_post->post_type == 'adherder_ad') {
    207       adherder_database_clean_for_post($ad_id);
    208       update_post_meta($ad_id, 'adherder_impressions', 0);
    209       update_post_meta($ad_id, 'adherder_clicks', 0);
    210       $message = 'Cleared all data for ad with id ' . $ad_id;
    211     } else {
    212       $message = 'Id ' . $ad_id . ' is not a valid ad id';
    213     }
    214   }
    215   if(isset($_POST['adherder_cleanup_old_data'])) {
    216     adherder_database_clean();
    217     $message = 'Older impression data cleared';
    218   }
     240/*  if(isset($_POST['adherder_cleanup_old_data'])) {
     241        adherder_database_clean();
     242        $message = 'Older impression data cleared';
     243        return array();
     244    } */
    219245  $reports = adherder_database_find_reports();
    220246  include(plugin_dir_path(__FILE__).'/../template/report.php');
  • adherder/trunk/includes/database.php

    r456242 r584842  
    104104      id, post_title, post_status,
    105105      IFNULL((select meta_value from wp_postmeta where post_id = id and meta_key = 'adherder_impressions'),0) as impressions,
    106       IFNULL((select meta_value from wp_postmeta where post_id = id and meta_key = 'adherder_clicks'), 0) as clicks
     106      IFNULL((select meta_value from wp_postmeta where post_id = id and meta_key = 'adherder_clicks'), 0) as clicks,
     107      IFNULL((select meta_value from wp_postmeta where post_id = id and meta_key = 'adherder_in_report'), 0) as in_report
    107108      FROM wp_posts p WHERE post_type = 'adherder_ad'");
    108109    foreach($reports as $report) {
    109110      $conversion = 0;
     111      $confidence = 0;
    110112      if($report->impressions != '0') {
    111113        $conversion = ($report->clicks * 100) / $report->impressions;
    112114        $conversion = round($conversion, 2);
     115        if($conversion > 100) {
     116            $conversion = 100; // filter out edge cases
     117        }
     118       
     119        $confidence = sqrt(($conversion * (100 - $conversion)) / $report->impressions);
     120        $confidence = round($confidence, 2);
    113121      }
    114122      $report->conversion = $conversion;
     123      $report->confidence = $confidence;
    115124    }
     125   
     126    //calculate relevance
     127    foreach($reports as $report) {
     128        if(!$report->in_report) {
     129            $report->relevant = "null";
     130            $report->min = "null";
     131            $report->max = "null";
     132            $report->opening = "null";
     133            $report->closing = "null";
     134            continue;
     135        }
     136        $relevant = true;
     137        foreach($reports as $comp_report) {
     138            if($report->id == $comp_report->id || !$comp_report->in_report) {
     139                continue;
     140            }
     141            $diff      = abs($comp_report->conversion - $report->conversion);
     142            $conf_diff = $comp_report->confidence + $report->confidence;
     143           
     144            if($diff <= $conf_diff) {
     145                $relevant = false;
     146            }
     147        }
     148        $report->relevant = $relevant ? "true" : "false";
     149       
     150        $report->min = $report->conversion - $report->confidence;
     151        $report->max = $report->conversion + $report->confidence;
     152        if($relevant) {
     153            $report->opening = $report->min;
     154            $report->closing = $report->max;
     155        } else {
     156            $report->opening = $report->max;
     157            $report->closing = $report->min;
     158        }
     159    }
    116160    return $reports;
    117161}
  • adherder/trunk/readme.txt

    r465266 r584842  
    55Tags: plugin, widget, automatic, ad, manage
    66Requires at least: 3.0
    7 Tested up to: 3.2.1
    8 Stable tag: 1.2
     7Tested up to: 3.4.1
     8Stable tag: 1.3
    99
    1010== Description ==
     
    121121== Changelog ==
    122122
     123= Version 1.3 =
     124
     125* Added confidence & relevance calculations for selected items
     126* Now possible to customize the items that are in the report
     127* Simplified managment & reporting interface
     128* Bulk actions on ads (ctr-click to select multiple)
     129
    123130= Version 1.2 =
    124131
  • adherder/trunk/template/options.php

    r456242 r584842  
    2828        <input name="Submit" type="submit" value="Save Changes" class="button-primary" />
    2929    </form>
     30    <!-- form id="adherder_cleanup_old_data" method="post" action="edit.php?post_type=adherder_ad&page=adherder_options" style="float: left; width: 70%">
     31        <p>If ad serving becomes sluggish, you may want to remove all data older than 30 days.</p>
     32        <input type="submit" name="adherder_cleanup_old_data" value="Clean up old tracking data" class="button-secondary" />
     33    </form -->
    3034</div>
  • adherder/trunk/template/report.php

    r456242 r584842  
    2727   
    2828    <div id="dashboard">
    29         <table>
    30             <tr>
    31                 <td style="width: 300px; vertical-align: top;">
     29        <div style="display:none;">
     30                    <div id="control-report"></div>
    3231                    <div id="control-status"></div>
    33                     <div id="control-impressions"></div>
    34                     <div id="control-clicks"></div>
    35                 </td>
    36                 <td>
    37                     <div id="chart-report"></div>
    38                 </td>
    39             </tr>
    40             <tr>
    41                 <td colspan="2">
    42                     <div id="chart-legend"></div>
    43                 </td>
    44             </tr>
    45         </table>
     32        </div>
     33        <div>
     34            <div id="chart-report"></div>
     35        </div>
     36        <div>
     37            <div class="tablenav top">
     38            <div class="alignleft actions">
     39            <select>
     40                <option value="none">Bulk Actions</option>
     41                <option value="publish">Publish</option>
     42                <option value="pending">Unpublish</option>
     43                <option value="in_report">Include in report</option>
     44                <option value="not_in_report">Remove from report</option>
     45                <option value="clear_data">Clear data</option>
     46            </select>
     47            <button class="button-secondary apply-bulk" >Apply</button><br/>
     48            </div>
     49            <div class="alignleft actions">
     50            <select>
     51                <option value="report">Report</option>
     52                <option value="all">All</option>
     53                <option value="published">Published</option>
     54                <option value="unpublished">Unpublished</option>
     55            </select>
     56            <button class="button-secondary apply-filter" >Filter</button><br/>
     57            </div>
     58            </div>         
     59           
     60            <div id="chart-legend"></div>
     61
     62            <div class="tablenav bottom">
     63            <div class="alignleft actions">
     64            <select>
     65                <option value="none">Bulk Actions</option>
     66                <option value="publish">Publish</option>
     67                <option value="pending">Unpublish</option>
     68                <option value="in_report">Include in report</option>
     69                <option value="not_in_report">Remove from report</option>
     70                <option value="clear_data">Clear data</option>
     71            </select>
     72            <button class="button-secondary apply-bulk" >Apply</button><br/>
     73            </div>
     74            </div>
     75        </div>
    4676    </div>
    4777   
    48     <form id="adherder_switch_status" method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
    49         <input type="hidden" name="adherder_switch_ad_id" id="adherder_switch_ad_id" />
    50         <input type="hidden" name="adherder_switch_status" />
    51     </form>
    52     <form id="adherder_clear_history" method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
    53         <input type="hidden" name="adherder_clear_ad_id" id="adherder_clear_ad_id" />
    54         <input type="hidden" name="adherder_clear_history" />
    55     </form>
    56     <form id="adherder_cleanup_old_data" method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
    57         <p><input type="submit" name="adherder_cleanup_old_data" value="Clean up old impression tracking data" class="button-secondary" /></p>
     78    <form id="adherder_bulk_action_form" method="post" action="<?php echo $_SERVER["REQUEST_URI"]; ?>">
     79        <input type="hidden" name="adherder_bulk_ad_ids" id="adherder_bulk_ad_ids" />
     80        <input type="hidden" name="adherder_bulk_action" id="adherder_bulk_action" />
    5881    </form>
    5982   
     
    6184      google.load("visualization", "1.1", {packages:["corechart", "table", "controls"]});
    6285      google.setOnLoadCallback(drawChart);
    63       var table, data;
     86      var table, data, reportPicker, statusPicker;
    6487      function drawChart() {
    6588        data = new google.visualization.DataTable();
     
    7093        data.addColumn('number', 'Clicks');
    7194        data.addColumn('number', 'Conversion %');
    72         data.addColumn('string', 'Status (click to switch)');
    73         data.addColumn('string', 'Clear history');
     95        data.addColumn('number', 'Confidence %');
     96        data.addColumn('boolean', 'Relevant?');
     97        data.addColumn('string', 'In Report Data?');
     98        data.addColumn('number', 'min');
     99        data.addColumn('number', 'max');
     100        data.addColumn('number', 'opening');
     101        data.addColumn('number', 'closing');
    74102        data.addRows(<?php echo count($reports); ?>);
    75103        <?php
     
    82110          echo "data.setValue(" . $count . ", 4,  " . $report->clicks . ");\n";
    83111          echo "data.setValue(" . $count . ", 5,  " . $report->conversion . ");\n";
    84           $switchValue = "";
    85           switch($report->post_status) {
    86             case 'publish' : $switchValue = 'Online'; break;
    87             case 'pending' : $switchValue = 'Offline'; break;
    88           }
    89           if($switchValue != "") {
    90             $switchValue = '<a href="#" class="button-secondary" onclick="switchStatus(' . $report->id . ')">' . $switchValue . '</a>';
    91           }
    92           echo "data.setValue(" . $count . ", 6,  '" . $switchValue . "');\n";
    93           $clearValue = '<a class="button-secondary" href="#" onclick="clearHistory(' . $report->id . ')">remove data</a>';
    94           echo "data.setValue(" . $count . ", 7,  '" . $clearValue . "');\n";
    95          
     112          echo "data.setValue(" . $count . ", 6,  " . $report->confidence . ");\n";
     113          echo "data.setValue(" . $count . ", 7,  " . $report->relevant . ");\n";
     114          echo "data.setValue(" . $count . ", 8, '" . ($report->in_report?"Yes":"No") . "');\n";
     115          echo "data.setValue(" . $count . ", 9,  " . $report->min . ");\n";
     116          echo "data.setValue(" . $count . ",10,  " . $report->max . ");\n";
     117          echo "data.setValue(" . $count . ",11,  " . $report->opening . ");\n";
     118          echo "data.setValue(" . $count . ",12,  " . $report->closing . ");\n";
    96119          $count++;
    97120        } ?>
    98121
    99         var statusPicker = new google.visualization.ControlWrapper({
     122        reportPicker = new google.visualization.ControlWrapper({
     123            'controlType': 'CategoryFilter',
     124            'containerId': 'control-report',
     125            'options'    : {
     126                'filterColumnLabel': 'In Report Data?',
     127                'ui': {
     128                    'labelStacking'  : 'vertical',
     129                    'allowTyping'    : false,
     130                }
     131            },
     132            'state': { 'selectedValues' : ['Yes'] }
     133        });
     134
     135        statusPicker = new google.visualization.ControlWrapper({
    100136          'controlType': 'CategoryFilter',
    101137          'containerId': 'control-status',
     
    105141              'labelStacking'  : 'vertical',
    106142              'allowTyping'    : false,
    107               'allowMultiple'  : false
    108143            }
    109           },
    110           'state': { 'selectedValues' : ['publish'] }
    111         });
    112 
    113         var impressionsSlider = new google.visualization.ControlWrapper({
    114           'controlType': 'NumberRangeFilter',
    115           'containerId': 'control-impressions',
    116           'options': {
    117             'filterColumnLabel': 'Impressions',
    118             'ui': {'labelStacking': 'vertical'}
    119144          }
    120145        });
    121146
    122         var clicksSlider = new google.visualization.ControlWrapper({
    123           'controlType': 'NumberRangeFilter',
    124           'containerId': 'control-clicks',
    125           'options': {
    126             'filterColumnLabel': 'Clicks',
    127             'ui': {'labelStacking': 'vertical'}
    128           }
    129         });
    130 
     147        var in_report_rows = data.getFilteredRows([{column: 8, value: 'Yes'}]);
    131148        var chart = new google.visualization.ChartWrapper({
    132           'chartType'  : 'ColumnChart',
     149          'chartType'  : 'CandlestickChart',
     150          'dataTable'  : data,
    133151          'containerId': 'chart-report',
    134152          'options'    : {
     
    136154            'height'   : 240,
    137155            'title'    : 'Ad engagement',
     156            'legend'   : 'none',
     157            'candlestick': {
     158              'fallingColor' : {
     159                'fill'   : '#FF0000',
     160                'stroke' : '#FF0000',
     161              },
     162              'risingColor' : {
     163                'fill'   : '#00FF00',
     164                'stroke' : '#00FF00',
     165              },
     166            },
    138167          },
    139168          'view'       : {
    140             'columns'  : [0, 3, 4]
     169            'columns'  : [0, 9, 11, 12, 10],
     170            'rows'     : in_report_rows
    141171          }
    142172        });
     
    147177          'options'    : {
    148178            'allowHtml'     : true
     179          },
     180          'view'       : {
     181            'columns'  : [0, 1, 2, 3, 4, 5, 6, 7]
    149182          }
    150183        });
    151184
    152185        new google.visualization.Dashboard(document.getElementById('dashboard'))
    153           .bind([statusPicker, impressionsSlider, clicksSlider], [table, chart])
     186          .bind([reportPicker, statusPicker], [table])
    154187          .draw(data);
     188         
     189        chart.draw();
    155190      }
    156       function switchStatus(callId) {
    157         if(!callId) return;
    158         jQuery('#adherder_switch_ad_id').val(callId);
    159         jQuery('#adherder_switch_status').submit();
    160       }
    161       function clearHistory(callId) {
    162         if(!callId) return;
    163         jQuery('#adherder_clear_ad_id').val(callId);
    164         jQuery('#adherder_clear_history').submit();
    165       }
     191      jQuery(document).ready(function($) {
     192          $('.apply-bulk').click(function() {
     193              var action = $(this).prev().val();
     194              $('#adherder_bulk_action').val(action);
     195              if("none" != action) {
     196                  var selection = table.getChart().getSelection();
     197                  if(selection.length != 0) {
     198                      var ids = "";
     199                      $.each(selection, function(i, obj) {
     200                          if(i!=0) {
     201                              ids += ',';
     202                          }
     203                          ids += table.getDataTable().getValue(obj.row,0);
     204                      });
     205                      $('#adherder_bulk_ad_ids').val(ids);
     206                      $('#adherder_bulk_action_form').submit();
     207                  }
     208              }
     209          });
     210         
     211            $('.apply-filter').click(function() {
     212                var filter = $(this).prev().val();
     213                switch(filter) {
     214                    case "report":
     215                        reportPicker.setState({'selectedValues':['Yes']});
     216                        statusPicker.setState({'selectedValues':[]});
     217                        break;
     218                    case "all":
     219                        reportPicker.setState({'selectedValues':[]});
     220                        statusPicker.setState({'selectedValues':[]});
     221                        break;
     222                    case "published":
     223                        reportPicker.setState({'selectedValues':[]});
     224                        statusPicker.setState({'selectedValues':['publish']});
     225                        break;
     226                    case "unpublished":
     227                        reportPicker.setState({'selectedValues':[]});
     228                        statusPicker.setState({'selectedValues':['pending']});
     229                        break;
     230                }
     231                reportPicker.draw();
     232                statusPicker.draw();
     233            });
     234      });
    166235</script>
    167236</div>
Note: See TracChangeset for help on using the changeset viewer.