Advertisement
Guest User

index.php

a guest
Jun 20th, 2014
303
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 56.69 KB | None | 0 0
  1. <?php
  2. ini_set('memory_limit','500M');
  3. $time = microtime(1);
  4. require_once( 'core.php' );
  5. require_once( 'RateLimit.php' );
  6. $sitenotice = array();
  7. require_once( 'sitenotice.php' );
  8. require_once( 'blacklist.php' );
  9. $globalopt = 'optin';
  10. $localopt = array( 'optin' => array(),
  11.                    'optout' => array(),
  12.                    'noopt' => array( 'enwiki' ) );
  13. $optoverride = array( 'Cyberpower678' => '2795450270d6b5aa2f8d25d923eafb99',
  14.                       'A930913' => '7333ae0e128403bdf234abcfa4abb508',
  15. );    //Encrypted passwords to override the opt requirement.
  16. $maintainance = false;   //Take the site down for maintainance
  17.  
  18. if( isset( $_GET['maintenenceoverride'] ) && $_GET['maintenenceoverride'] ) $maintainance = false;
  19. function printStartPage( $noticeTitle = null, $noticeContent = null ) {
  20.     ?></head>
  21. <body>
  22. <div class="hero-unit pagination-centered">
  23.     <h1>User Analysis Tool</h1><br><?php printSiteNotice();
  24.     if( !is_null( $noticeTitle ) && !is_null( $noticeContent ) ) echo "    <div class=\"alert  alert-error\"><h4>$noticeTitle:</h4>  $noticeContent</div>"; ?>
  25.     <div id="form">
  26.     <p>This tool has been designed as a replacement for X!'s Edit Counter.  It currently produces identical results, but more features will be available in the future.</p>
  27.     <p>Please leave comments and feedback to <a href="//en.wikipedia.org/wiki/User%20talk:Cyberpower678">Cyberpower678</a>.  It would be greatly appreciated.</p>
  28.     <form name="input" action="index.php" method="get">
  29.         <label for="u">User name: <input type="text" id="user" name="user" placeholder="Jimbo Wales" value="<?php if( isset( $_GET['user'] ) ) echo $_GET['user']; ?>"></label>
  30.         <label for="p">Project: http://<input type="text" id="project" name="project" placeholder="en.wikipedia"  value="<?php if( isset( $_GET['project'] ) ) echo $_GET['project']; ?>">.org</label>
  31.         <input type="submit" value="Submit" class="btn btn-large btn-primary" id="init">
  32.         <hr>
  33.         <h3>Options:</h3>
  34.         <label for="t">Restrict most edited pages to <input type="text" id="toplimit" name="toplimit" value="<?php if( isset( $_GET['toplimit'] ) ) echo $_GET['toplimit']; else echo "10"; ?>"> (values < 1 imply infinity)</label>
  35.     </form>
  36. </div>
  37. </div><?php
  38.     die();  
  39. }
  40. function printStart() {?><!--
  41.  
  42. User Analysis Tool
  43. Copyright (C) 2014 Cyberpower678
  44.  
  45. en.wikipedia.org/wiki/User:Cyberpower678
  46. tools.wmflabs.org/supercount/
  47.  
  48. This program is free software: you can redistribute it and/or modify
  49. it under the terms of the GNU General Public License as published by
  50. the Free Software Foundation, either version 3 of the License, or
  51. (at your option) any later version.
  52.  
  53. This program is distributed in the hope that it will be useful,
  54. but WITHOUT ANY WARRANTY; without even the implied warranty of
  55. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  56. GNU General Public License for more details.
  57.  
  58. You should have received a copy of the GNU General Public License
  59. along with this program.  If not, see <http://www.gnu.org/licenses/>.
  60.  
  61. -->
  62. <!DOCTYPE html>
  63. <html>
  64. <head>
  65. <meta charset="utf-8"><?php echo "<title>User Analysis ".( (isset( $_GET['user'] ) && $_GET['user']) && (isset( $_GET['project'] ) && $_GET['project']) ? " for ".str_replace( "|", " & ", $_GET['user'] ) : "Tool" )."</title>";?>
  66.  
  67. <link href="//tools.wmflabs.org/supercount/bootstrap-combined.min.css" rel="stylesheet">
  68. <script type="text/javascript" src="//tools.wmflabs.org/static/res/jquery/2.1.0/jquery.js"></script>
  69. <script type="text/javascript" src="//tools.wmflabs.org/static/res/bootstrap/3.1.1/js/bootstrap.js"></script>
  70.  
  71.  
  72. <script type="text/javascript" src="//tools.wmflabs.org/static/res/raphael/2.1.2/raphael.js"></script>
  73. <!-- g.Raphael - JavaScript charting library
  74. (the main script needs to be up-to-date) -->
  75. <script type="text/javascript" src="//tools.wmflabs.org/static/res/g.raphael/0.5.1/g.raphael.js"></script>
  76. <script type="text/javascript" src="//tools.wmflabs.org/static/res/g.raphael/0.5.1/g.bar.js"></script>
  77. <script type="text/javascript" src="//tools.wmflabs.org/static/res/g.raphael/0.5.1/g.pie.js"></script>
  78. <script>
  79. jQuery(function($) {
  80.      $('div.btn-group[data-toggle-name]').each(function(){
  81.             var group   = $(this);
  82.             var form    = group.parents('form').eq(0);
  83.             var name    = $(this).attr('data-toggle-name');
  84.             var hidden  = $('input[name="' + name + '"]', form);
  85.             var type    = group.attr('data-toggle');
  86.             var check   = (hidden.val() != '') ? hidden.val().split(',') : [];
  87.             $('button', group).each(function() {
  88.                 var button = $(this);
  89.                 button.live('click', function() {
  90.                     switch(type) {
  91.                         case 'buttons-checkbox':
  92.                             if(check.indexOf(button.val()) == -1){
  93.                                 button.addClass('active');
  94.                                 check.push(button.val());
  95.                             }else{
  96.                                 check.splice(check.indexOf(button.val()),1);
  97.                                 button.removeClass('active');
  98.                             }
  99.                             hidden.val(check.toString());
  100.                             break;
  101.                         case 'button':
  102.                             if(button.val() == hidden.val()) {
  103.                                 button.removeClass('active');
  104.                                 hidden.val(0);
  105.                             } else {
  106.                                 button.addClass('active');
  107.                                 hidden.val(1);
  108.                             }
  109.                             break;
  110.                         default:
  111.                             hidden.val(button.val());
  112.                             break;
  113.                     }
  114.                 });
  115.                 switch(type) {
  116.                     case 'buttons-checkbox':
  117.                         for (i=0;i<check.length;i++) {
  118.                             if(button.val() == check[i]) {
  119.                                 button.addClass('active');
  120.                             }
  121.                         }
  122.                         break;
  123.                     default:
  124.                         if(button.val() == hidden.val()) {
  125.                             button.addClass('active');
  126.                         }
  127.                         break;
  128.                 }
  129.  
  130.             });
  131.     });
  132. });</script>
  133.  
  134. <style type="text/css">
  135. body{
  136.     padding:1em;
  137. }
  138. .mw-plusminus-pos{
  139.     color:#006400;
  140. }
  141. .mw-plusminus-neg{
  142.     color:#8b0000;
  143. }
  144. .mw-plusminus-null{
  145.     color:#aaa;
  146. }
  147. .hero-unit+.nav-tabs{
  148.     display:none;
  149. }
  150. footer{
  151.     float:left;
  152.     position:static;
  153.     bottom:1em;
  154.     display:none;
  155. }
  156. #ns-chart svg path.selected{
  157.     stroke-width:3px!important;
  158. }
  159. #punchcard svg circle{
  160.     fill:#444!important;
  161. }
  162. #punchcard svg circle.day-hover{
  163.     fill:#4183C4!important;
  164.     z-index:9999!important;
  165. }
  166. </style>
  167.  
  168. <?php }
  169. if( $maintainance ) {
  170.     printStart();
  171.     printStartPage( "Down for maintenence", "Whoops sorry about that.  My owner is working on improvements for me.  Please come back later." );
  172. }
  173. if( enforceBlacklist( $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'] ) ) {
  174.     printStart();
  175.     printStartPage( "Blacklisted", "You have been disallowed access to the tool for excessive queries, or are a bot.  Please use the API." );
  176. }
  177. if( (!isset( $_GET['user'] ) || !$_GET['user']) || (!isset( $_GET['project'] ) || !$_GET['project']) ) {
  178.     printStart();
  179.     if( isset( $_GET['user'] ) && !$_GET['user'] ) printStartPage( "Missing user", "I can only work right if you give me a username." );
  180.     elseif( isset( $_GET['project'] ) && !$_GET['project'] ) printStartPage( "Missing project", "Again, I can only work right if you also give me a project to look at." );
  181.     else printStartPage();
  182. } else {
  183.     $wiki = API::getWikiCode( "https://{$_GET['project']}.org/w/api.php" );
  184.     if( !$wiki ) {
  185.         printStart();
  186.         printStartPage( "Connection Failed", "For some reason, I can't connect to https://{$_GET['project']}.org.  Did you type the project in correctly?" );  
  187.     }
  188.     ini_set("display_errors", 0);
  189.     $rldb = openConnection();
  190.     ini_set("display_errors", 0);
  191.     if( $rldb && enforceLimit( $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], 4, $rldb ) ) {
  192.         closeConnection( $rldb );
  193.         header( "HTTP/1.1 429 Too Many Requests", true, 429 );
  194.         printStart();
  195.         printStartPage( "Query Limit Exceeded", "You have exceeded the maximum rate limit.  Please wait 1 minute." );    
  196.     } elseif( $rldb ) addHit( $_SERVER['REMOTE_ADDR'], $_SERVER['HTTP_USER_AGENT'], $_GET['user'], $_GET['project'], false, $rldb );
  197.     if( $rldb ) $servicedRequests = getRequestsServiced( $rldb );
  198.     else $servicedRequests = "unknown";
  199.     $colors = array(
  200.       0 => 'FF5555',
  201.       1 => '55FF55',
  202.       2 => 'FFEE22',
  203.       3 => 'FF55FF',
  204.       4 => '5555FF',
  205.       5 => '55FFFF',
  206.       6 => 'C00000',
  207.       7 => '0000C0',
  208.       8 => '008800',
  209.       9 => '00C0C0',
  210.       10 => 'FFAFAF',
  211.       11 => '808080',
  212.       12 => '00C000',
  213.       13 => '404040',
  214.       14 => 'C0C000',
  215.       15 => 'C000C0',
  216.       90 => '991100',
  217.       91 => '99FF00',
  218.       92 => '000000',
  219.       93 => '777777',
  220.       100 => '75A3D1',
  221.       101 => 'A679D2',
  222.       102 => '660000',
  223.       103 => '000066',
  224.       104 => 'FAFFAF',
  225.       105 => '408345',
  226.       106 => '5c8d20',
  227.       107 => 'e1711d',
  228.       108 => '94ef2b',
  229.       109 => '756a4a',
  230.       110 => '6f1dab',
  231.       111 => '301e30',
  232.       112 => '5c9d96',
  233.       113 => 'a8cd8c',
  234.       114 => 'f2b3f1',
  235.       115 => '9b5828',
  236.       116 => '002288',
  237.       117 => '0000CC',
  238.       118 => '99FFFF',
  239.       119 => '99BBFF',
  240.       120 => 'FF99FF',
  241.       121 => 'CCFFFF',
  242.       122 => 'CCFF00',
  243.       123 => 'CCFFCC',
  244.       200 => '33FF00',
  245.       201 => '669900',
  246.       202 => '666666',
  247.       203 => '999999',
  248.       204 => 'FFFFCC',
  249.       205 => 'FF00CC',
  250.       206 => 'FFFF00',
  251.       207 => 'FFCC00',
  252.       208 => 'FF0000',
  253.       209 => 'FF6600',
  254.       250 => '6633CC',
  255.       251 => '6611AA',
  256.       252 => '66FF99',
  257.       253 => '66FF66',
  258.       446 => '06DCFB',
  259.       447 => '892EE4',
  260.       460 => '99FF66',
  261.       461 => '99CC66',
  262.       470 => 'CCCC33',
  263.       471 => 'CCFF33',
  264.       480 => '6699FF',
  265.       481 => '66FFFF',
  266.       490 => '995500',
  267.       491 => '998800',
  268.       710 => 'FFCECE',
  269.       711 => 'FFC8F2',
  270.       828 => 'F7DE00',
  271.       829 => 'BABA21',
  272.       866 => 'FFFFFF',
  273.       867 => 'FFCCFF',
  274.       1198 => 'FF34B3',
  275.       1199 => '8B1C62',
  276.     );
  277.     ini_set("display_errors", 0);
  278.     $db = mysqli_connect( $wiki.".labsdb", "s51780", "aidohngeijamadoo", $wiki."_p" );
  279.     ini_set("display_errors", 1);
  280.     if( !$db ) $db = null;
  281.     $thisopt = null;
  282.     foreach( $localopt as $opt=>$wikis ) {
  283.         if( in_array( $wiki, $wikis ) ) $thisopt = $opt;
  284.     }
  285.     if( $thisopt == null ) $thisopt = $globalopt;
  286.     $optstatus = null;
  287.     switch( $thisopt ) {
  288.         case 'optin':
  289.         $optstatus = isOptedIn( $_GET['user'], "https://{$_GET['project']}.org/w/api.php" );
  290.         break;
  291.         case 'optout':
  292.         $optstatus = !isOptedOut( $_GET['user'], "https://{$_GET['project']}.org/w/api.php" );
  293.         break;
  294.         case 'noopt':
  295.         $optstatus = true;
  296.         break;
  297.     }
  298.     $optinoverride = false;
  299.     if( isset( $_GET['optinoverride'] ) && in_array( md5( md5( $_GET['optinoverride'] ) ), $optoverride ) ) {
  300.         $optinoverride = true;
  301.         $overridekey = array_search( md5( md5( $_GET['optinoverride'] ) ), $optoverride );
  302.         if( $rldb ) mysqli_query( $rldb, "INSERT INTO overrides (`timestamp`, `ip`, `ua`, `user`, `project`, `key`, `optinstatus`, `API`) VALUES ('".time()."','".mysqli_escape_string( $rldb, $_SERVER['REMOTE_ADDR'] )."','".mysqli_escape_string( $rldb, $_SERVER['HTTP_USER_AGENT'] )."', '".mysqli_escape_string( $rldb, $_GET['user'] )."', '".mysqli_escape_string( $rldb, $_GET['project'] )."', '".mysqli_escape_string( $rldb, $overridekey )."', '".mysqli_escape_string( $rldb, ($optstatus ? '1' : '0' ) )."', '0');" );
  303.         //echo mysqli_error( $rldb );
  304.         $optstatus = true;  
  305.     }
  306.     if( $rldb ) closeConnection( $rldb );
  307.     printStart();
  308.     $API = new API( $_GET['user'], array( 'wikiid' => $wiki, 'apiurl' => "https://{$_GET['project']}.org/w/api.php" ), $optstatus, ( isset( $_GET['fullstats'] ) && $_GET['fullstats'] ? ($optinoverride ? true : isPrivateOptedIn( $_GET['user'], "https://{$_GET['project']}.org/w/api.php" )) : false ), $db, "revision_userindex", "archive_userindex", "recentchanges_userindex" );
  309.     $existance = $API->get_exists();
  310.     if( !$existance['nonexist'] ) {
  311.         $data = $API->get_stats( array(), (isset( $_GET['toplimit'] ) ? $_GET['toplimit'] : 10), (isset( $_GET['fullstats'] ) ? $_GET['fullstats'] : false) );
  312.         $data = $API->get_replag( $data );
  313.         $data = $API->get_usergroups( $data );
  314.         if( !isset( $data['messages']['APIfailures'] ) ) $data = $API->get_namespaces( $data );
  315.         if( !is_null( $db ) ) mysqli_close( $db );
  316.         ?><script>
  317.                 window.onload = function () { <?php
  318.         if( isset( $data['namespace_totals'] ) && $data['namespace_totals'] && isset( $data['namespaces'] ) ) {
  319.             $nsContribs = array();
  320.             $nsNames = array();
  321.             $nsColors = array();
  322.             foreach( $data['namespace_totals'] as $id=>$tcount ) {
  323.                 $nsContribs[] = $tcount;
  324.                 if( $id == 0 ) $nsNames[] = "Main: ".number_format( $tcount, 0, '.', ',' )." (%%.%%)";
  325.                 else $nsNames[] = $data['namespaces'][$id]['*'].": ".number_format( $tcount, 0, '.', ',' )." (%%.%%)";    
  326.             }
  327.             arsort( $data['namespace_totals'] );
  328.             foreach( $data['namespace_totals'] as $id=>$tcount ) {
  329.                 $nsColors[] = $colors[$id];
  330.             }
  331.             ?>
  332.                 var nsColorsM = {<?php
  333.                 $i = 0;
  334.                 foreach( $data['namespaces'] as $tid => $tns ) {
  335.                     if( $tid == -2 || $tid == -1 ) {
  336.                         $i++;
  337.                         continue;
  338.                     }
  339.                     echo "'#".$colors[$tid]."' : '".( $tid == 0 ? "Main" : $tns['*'] )."'";
  340.                     if( $i < count( $data['namespaces'] ) - 1 ) echo ", ";
  341.                     $i++;
  342.                 }?>};
  343.                 var nsCanvas = Raphael("ns-chart", 600, 400),
  344.                     nsChart = nsCanvas.piechart(170, 200, 150, [<?php echo implode( ", ", $nsContribs ); ?>], { legend: [<?php echo "\"".implode( "\", \"", $nsNames )."\""; ?>], legendpos: "east", colors: [<?php echo "\"#".implode( "\", \"#", $nsColors )."\""; ?>], minpercent: 0});
  345.  
  346.                 nsChart.hover(function () {
  347.                     this.sector.stop();
  348.                     this.sector.scale(1.1, 1.1, this.cx, this.cy);
  349.  
  350.                     if (this.label) {
  351.                         this.label[0].stop();
  352.                         this.label[0].attr({ r: 7.5 });
  353.                         this.label[1].attr({ "font-weight": 800 });
  354.                     }
  355.                 }, function () {
  356.                     this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
  357.  
  358.                     if (this.label) {
  359.                         this.label[0].animate({ r: 5 }, 500, "bounce");
  360.                         this.label[1].attr({ "font-weight": 400 });
  361.                     }
  362.                 });
  363.                 nsChart.click(function () {
  364.                     this.sector.stop();
  365.                     this.sector.attr({transform:'s1 1 ' + this.cx + ' ' + this.cy });
  366.                     if(this.sector[0].classList.contains('selected')){
  367.                         this.sector[0].classList.remove('selected');
  368.                         $('#low-stats').hide('fast');
  369.                         nsCanvas.canvas.setAttribute('width',600);
  370.                     }
  371.                     else{
  372.                         nsCanvas.canvas.setAttribute('width',340);
  373.                         nsChart.each(function(){
  374.                             this.sector.attr({transform:'s1 1 ' + this.cx + ' ' + this.cy });
  375.                             this.sector[0].classList.remove('selected');
  376.                         });
  377.                         this.sector.scale(1.1, 1.1, this.cx, this.cy);
  378.                         this.sector[0].classList.add('selected');    
  379.                         $('#low-stats')
  380.                         .empty()
  381.                         .append($('<h5>').text('All Percentages'))
  382.                         .append( '<ul><?php foreach( $data['namespace_totals'] as $id=>$tcount ) {if( $id == 0 ) echo "<li>Main: ".number_format( $tcount, 0, '.', ',' )." (".round( $tcount/$data['liveedits']*100, 2 )."%)</li>"; else echo "<li>".$data['namespaces'][$id]['*'].": ".number_format( $tcount, 0, '.', ',' )." (".round( $tcount/$data['liveedits']*100, 2 )."%)</li>";} ?></ul>'
  383.                         ).show('fast');
  384.                     }
  385.                 } ) ;
  386.             <?php
  387.             if( isset( $data['monthly_counts'] ) ) {
  388.                 $mSize = 24.5*count( $data['monthly_counts'] );
  389.                 $nsData = array();
  390.                 $nsColors = array();
  391.                 $axisLabels = array();
  392.                 $axisData = array();
  393.                 foreach( $data['namespaces'] as $id=>$tdata ) {
  394.                     if( $id < 0 ) continue;
  395.                     foreach( $data['monthly_counts'] as $tmonth=>$tcount ) {
  396.                        if( !in_array( $tmonth, $axisLabels ) ) {
  397.                            $axisLabels[] = $tmonth;
  398.                            $axisData[] = $tcount['total'];
  399.                        }
  400.                        $nsData[$id][$tmonth] = ( isset( $tcount[$id] ) ? $tcount[$id] : 0 );
  401.                     }
  402.                     $nsColors[] = $colors[$id];  
  403.                 }
  404.                 $axisLabels = array_reverse( $axisLabels );
  405.                 $axisData = array_reverse( $axisData ); ?>
  406.                 var axisData=['<?php echo implode( "', '", $axisData ); ?>'],
  407.                     nsData=[<?php $i = 0; foreach( $nsData as $tdata ) { echo "[". implode( ", ", $tdata )."]"; if( $i < count($nsData) - 1 ) echo ","; $i++; } ?>];
  408.                 var nsColors=[<?php echo "\"#".implode( "\", \"#", $nsColors )."\""; ?>],
  409.                     axisLabels=['<?php echo implode( "', '", $axisLabels ); ?>'],
  410.                     mSize = <?php echo $mSize; ?>,
  411.                     monthsCanvas = Raphael('month-chart',1200,mSize),
  412.                     fin2 = function () {
  413.                         this.flag = monthsCanvas.popup(this.bar.x, this.bar.y, nsColorsM[this.bar.attrs.fill]+': '+this.bar.value || '0', 'right').insertBefore(this);
  414.                     },
  415.                     fout = function () {
  416.                         this.flag.animate({opacity: 0}, 100, function () {this.remove();});
  417.                     };
  418.                     monthsChart = monthsCanvas.hbarchart(75, 0, 850, mSize, nsData, { stacked: true, colors: nsColors }).hover(fin2, fout);
  419.                     var aY = monthsChart.bars[0][monthsChart.bars[0].length -1].y;
  420.                     var aH = aY - monthsChart.bars[0][0].y;
  421.                     console.log(aY+'\n'+aH);
  422.                     console.log(monthsChart.bars[0]);
  423.                     Raphael.g.axis(45, aY+1.8, (aH || (aY+1.8)*10), 0, axisLabels.length, axisLabels.length-1, 1, axisLabels, ' ', null, monthsCanvas)
  424.                     .text.attr({'font-weight':'bold'});
  425.                     Raphael.g.axis(78, aY+1.8, (aH || (aY+1.8)*10), 0, axisData.length, axisData.length-1, 1, axisData, ' ', null, monthsCanvas)
  426. .text.attr({'text-anchor':'right'});
  427.                     $("tspan").each(function(){this.setAttribute("dy",0);})
  428.             <?php }
  429.         }
  430.         if( isset( $data['total_namespace_totals'] ) && $data['total_namespace_totals']  && isset( $data['namespaces'] ) ) {
  431.             $nsContribs = array();
  432.             $nsNames = array();
  433.             $nsColors = array();
  434.             foreach( $data['total_namespace_totals'] as $id=>$tcount ) {
  435.                 $nsContribs[] = $tcount;
  436.                 if( $id == 0 ) $nsNames[] = "Main: ".number_format( $tcount, 0, '.', ',' )." (%%.%%)";
  437.                 else $nsNames[] = $data['namespaces'][$id]['*'].": ".number_format( $tcount, 0, '.', ',' )." (%%.%%)";    
  438.             }
  439.             arsort( $data['total_namespace_totals'] );
  440.             foreach( $data['total_namespace_totals'] as $id=>$tcount ) {
  441.                 $nsColors[] = $colors[$id];
  442.             }
  443.             ?>
  444.                 var nsColorsM = {<?php
  445.                 $i = 0;
  446.                 foreach( $data['namespaces'] as $tid => $tns ) {
  447.                     if( $tid == -2 || $tid == -1 ) {
  448.                         $i++;
  449.                         continue;
  450.                     }
  451.                     echo "'#".$colors[$tid]."' : '".( $tid == 0 ? "Main" : $tns['*'] )."'";
  452.                     if( $i < count( $data['namespaces'] ) - 1 ) echo ", ";
  453.                     $i++;
  454.                 }?>};
  455.                 var nsCanvasTotal = Raphael("ns-chart-total", 600, 400),
  456.                     nsChartTotal = nsCanvasTotal.piechart(170, 200, 150, [<?php echo implode( ", ", $nsContribs ); ?>], { legend: [<?php echo "\"".implode( "\", \"", $nsNames )."\""; ?>], legendpos: "east", colors: [<?php echo "\"#".implode( "\", \"#", $nsColors )."\""; ?>], minpercent: 0});
  457.  
  458.                 nsChartTotal.hover(function () {
  459.                     this.sector.stop();
  460.                     this.sector.scale(1.1, 1.1, this.cx, this.cy);
  461.  
  462.                     if (this.label) {
  463.                         this.label[0].stop();
  464.                         this.label[0].attr({ r: 7.5 });
  465.                         this.label[1].attr({ "font-weight": 800 });
  466.                     }
  467.                 }, function () {
  468.                     this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
  469.  
  470.                     if (this.label) {
  471.                         this.label[0].animate({ r: 5 }, 500, "bounce");
  472.                         this.label[1].attr({ "font-weight": 400 });
  473.                     }
  474.                 });
  475.                 nsChartTotal.click(function () {
  476.                     this.sector.stop();
  477.                     this.sector.attr({transform:'s1 1 ' + this.cx + ' ' + this.cy });
  478.                     if(this.sector[0].classList.contains('selected')){
  479.                         this.sector[0].classList.remove('selected');
  480.                         $('#low-stats-total').hide('fast');
  481.                         nsCanvas.canvas.setAttribute('width',600);
  482.                     }
  483.                     else{
  484.                         nsCanvasTotal.canvas.setAttribute('width',340);
  485.                         nsChartTotal.each(function(){
  486.                             this.sector.attr({transform:'s1 1 ' + this.cx + ' ' + this.cy });
  487.                             this.sector[0].classList.remove('selected');
  488.                         });
  489.                         this.sector.scale(1.1, 1.1, this.cx, this.cy);
  490.                         this.sector[0].classList.add('selected');    
  491.                         $('#low-stats-total')
  492.                         .empty()
  493.                         .append($('<h5>').text('All Percentages'))
  494.                         .append( '<ul><?php foreach( $data['total_namespace_totals'] as $id=>$tcount ) {if( $id == 0 ) echo "<li>Main: ".number_format( $tcount, 0, '.', ',' )." (".round( $tcount/$data['totaledits']*100, 2 )."%)</li>"; else echo "<li>".$data['namespaces'][$id]['*'].": ".number_format( $tcount, 0, '.', ',' )." (".round( $tcount/$data['totaledits']*100, 2 )."%)</li>";} ?></ul>'
  495.                         ).show('fast');
  496.                     }
  497.                 } ) ;
  498.             <?php
  499.             if( isset( $data['total_monthly_counts'] ) ) {
  500.                 $mSize = 24.5*count( $data['total_monthly_counts'] );
  501.                 $nsData = array();
  502.                 $nsColors = array();
  503.                 $axisLabels = array();
  504.                 $axisData = array();
  505.                 foreach( $data['namespaces'] as $id=>$tdata ) {
  506.                     if( $id < 0 ) continue;
  507.                     foreach( $data['total_monthly_counts'] as $tmonth=>$tcount ) {
  508.                        if( !in_array( $tmonth, $axisLabels ) ) {
  509.                            $axisLabels[] = $tmonth;
  510.                            $axisData[] = $tcount['total'];
  511.                        }
  512.                        $nsData[$id][$tmonth] = ( isset( $tcount[$id] ) ? $tcount[$id] : 0 );
  513.                     }
  514.                     $nsColors[] = $colors[$id];  
  515.                 }
  516.                 $axisLabels = array_reverse( $axisLabels );
  517.                 $axisData = array_reverse( $axisData ); ?>
  518.                 var axisData=['<?php echo implode( "', '", $axisData ); ?>'],
  519.                     nsData=[<?php $i = 0; foreach( $nsData as $tdata ) { echo "[". implode( ", ", $tdata )."]"; if( $i < count($nsData) - 1 ) echo ","; $i++; } ?>];
  520.                 var nsColors=[<?php echo "\"#".implode( "\", \"#", $nsColors )."\""; ?>],
  521.                     axisLabels=['<?php echo implode( "', '", $axisLabels ); ?>'],
  522.                     mSize = <?php echo $mSize; ?>,
  523.                     monthsCanvasTotal = Raphael('month-chart-total',1200,mSize),
  524.                     fin2 = function () {
  525.                         this.flag = monthsCanvasTotal.popup(this.bar.x, this.bar.y, nsColorsM[this.bar.attrs.fill]+': '+this.bar.value || '0', 'right').insertBefore(this);
  526.                     },
  527.                     fout = function () {
  528.                         this.flag.animate({opacity: 0}, 100, function () {this.remove();});
  529.                     };
  530.                     monthsChartTotal = monthsCanvasTotal.hbarchart(75, 0, 850, mSize, nsData, { stacked: true, colors: nsColors }).hover(fin2, fout);
  531.                     var aY = monthsChartTotal.bars[0][Total.bars[0].length -1].y;
  532.                     var aH = aY - monthsChartTotal.bars[0][0].y;
  533.                     console.log(aY+'\n'+aH);
  534.                     console.log(monthsChartTotal.bars[0]);
  535.                     Raphael.g.axis(45, aY+1.8, (aH || (aY+1.8)*10), 0, axisLabels.length, axisLabels.length-1, 1, axisLabels, ' ', null, monthsCanvasTotal)
  536.                     .text.attr({'font-weight':'bold'});
  537.                     Raphael.g.axis(78, aY+1.8, (aH || (aY+1.8)*10), 0, axisData.length, axisData.length-1, 1, axisData, ' ', null, monthsCanvasTotal)
  538. .text.attr({'text-anchor':'right'});
  539.                     $("tspan").each(function(){this.setAttribute("dy",0);})
  540.             <?php }
  541.         }
  542.         if( isset( $data['deleted_namespace_totals'] ) && $data['deleted_namespace_totals']  && isset( $data['namespaces'] ) ) {
  543.             $nsContribs = array();
  544.             $nsNames = array();
  545.             $nsColors = array();
  546.             foreach( $data['deleted_namespace_totals'] as $id=>$tcount ) {
  547.                 $nsContribs[] = $tcount;
  548.                 if( $id == 0 ) $nsNames[] = "Main: ".number_format( $tcount, 0, '.', ',' )." (%%.%%)";
  549.                 else $nsNames[] = $data['namespaces'][$id]['*'].": ".number_format( $tcount, 0, '.', ',' )." (%%.%%)";    
  550.             }
  551.             arsort( $data['deleted_namespace_totals'] );
  552.             foreach( $data['deleted_namespace_totals'] as $id=>$tcount ) {
  553.                 $nsColors[] = $colors[$id];
  554.             }
  555.             ?>
  556.                 var nsColorsM = {<?php
  557.                 $i = 0;
  558.                 foreach( $data['namespaces'] as $tid => $tns ) {
  559.                     if( $tid == -2 || $tid == -1 ) {
  560.                         $i++;
  561.                         continue;
  562.                     }
  563.                     echo "'#".$colors[$tid]."' : '".( $tid == 0 ? "Main" : $tns['*'] )."'";
  564.                     if( $i < count( $data['namespaces'] ) - 1 ) echo ", ";
  565.                     $i++;
  566.                 }?>};
  567.                 var nsCanvasDeleted = Raphael("ns-chart-deleted", 600, 400),
  568.                     nsChartDeleted = nsCanvasDeleted.piechart(170, 200, 150, [<?php echo implode( ", ", $nsContribs ); ?>], { legend: [<?php echo "\"".implode( "\", \"", $nsNames )."\""; ?>], legendpos: "east", colors: [<?php echo "\"#".implode( "\", \"#", $nsColors )."\""; ?>], minpercent: 0});
  569.  
  570.                 nsChartDeleted.hover(function () {
  571.                     this.sector.stop();
  572.                     this.sector.scale(1.1, 1.1, this.cx, this.cy);
  573.  
  574.                     if (this.label) {
  575.                         this.label[0].stop();
  576.                         this.label[0].attr({ r: 7.5 });
  577.                         this.label[1].attr({ "font-weight": 800 });
  578.                     }
  579.                 }, function () {
  580.                     this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
  581.  
  582.                     if (this.label) {
  583.                         this.label[0].animate({ r: 5 }, 500, "bounce");
  584.                         this.label[1].attr({ "font-weight": 400 });
  585.                     }
  586.                 });
  587.                 nsChartDeleted.click(function () {
  588.                     this.sector.stop();
  589.                     this.sector.attr({transform:'s1 1 ' + this.cx + ' ' + this.cy });
  590.                     if(this.sector[0].classList.contains('selected')){
  591.                         this.sector[0].classList.remove('selected');
  592.                         $('#low-stats-deleted').hide('fast');
  593.                         nsCanvas.canvas.setAttribute('width',600);
  594.                     }
  595.                     else{
  596.                         nsCanvasDeleted.canvas.setAttribute('width',340);
  597.                         nsChartDeleted.each(function(){
  598.                             this.sector.attr({transform:'s1 1 ' + this.cx + ' ' + this.cy });
  599.                             this.sector[0].classList.remove('selected');
  600.                         });
  601.                         this.sector.scale(1.1, 1.1, this.cx, this.cy);
  602.                         this.sector[0].classList.add('selected');    
  603.                         $('#low-stats-deleted')
  604.                         .empty()
  605.                         .append($('<h5>').text('All Percentages'))
  606.                         .append( '<ul><?php foreach( $data['deleted_namespace_totals'] as $id=>$tcount ) {if( $id == 0 ) echo "<li>Main: ".number_format( $tcount, 0, '.', ',' )." (".round( $tcount/$data['deletededits']*100, 2 )."%)</li>"; else echo "<li>".$data['namespaces'][$id]['*'].": ".number_format( $tcount, 0, '.', ',' )." (".round( $tcount/$data['deletededits']*100, 2 )."%)</li>";} ?></ul>'
  607.                         ).show('fast');
  608.                     }
  609.                 } ) ;
  610.             <?php
  611.             if( isset( $data['deleted_monthly_counts'] ) ) {
  612.                 $mSize = 24.5*count( $data['deleted_monthly_counts'] );
  613.                 $nsData = array();
  614.                 $nsColors = array();
  615.                 $axisLabels = array();
  616.                 $axisData = array();
  617.                 foreach( $data['namespaces'] as $id=>$tdata ) {
  618.                     if( $id < 0 ) continue;
  619.                     foreach( $data['deleted_monthly_counts'] as $tmonth=>$tcount ) {
  620.                        if( !in_array( $tmonth, $axisLabels ) ) {
  621.                            $axisLabels[] = $tmonth;
  622.                            $axisData[] = $tcount['total'];
  623.                        }
  624.                        $nsData[$id][$tmonth] = ( isset( $tcount[$id] ) ? $tcount[$id] : 0 );
  625.                     }
  626.                     $nsColors[] = $colors[$id];  
  627.                 }
  628.                 $axisLabels = array_reverse( $axisLabels );
  629.                 $axisData = array_reverse( $axisData ); ?>
  630.                 var axisData=['<?php echo implode( "', '", $axisData ); ?>'],
  631.                     nsData=[<?php $i = 0; foreach( $nsData as $tdata ) { echo "[". implode( ", ", $tdata )."]"; if( $i < count($nsData) - 1 ) echo ","; $i++; } ?>];
  632.                 var nsColors=[<?php echo "\"#".implode( "\", \"#", $nsColors )."\""; ?>],
  633.                     axisLabels=['<?php echo implode( "', '", $axisLabels ); ?>'],
  634.                     mSize = <?php echo $mSize; ?>,
  635.                     monthsCanvasDeleted = Raphael('month-chart-deleted',1200,mSize),
  636.                     fin2 = function () {
  637.                         this.flag = monthsCanvasDeleted.popup(this.bar.x, this.bar.y, nsColorsM[this.bar.attrs.fill]+': '+this.bar.value || '0', 'right').insertBefore(this);
  638.                     },
  639.                     fout = function () {
  640.                         this.flag.animate({opacity: 0}, 100, function () {this.remove();});
  641.                     };
  642.                     monthsChartDeleted = monthsCanvasDeleted.hbarchart(75, 0, 850, mSize, nsData, { stacked: true, colors: nsColors }).hover(fin2, fout);
  643.                     var aY = monthsChartDeleted.bars[0][monthsChartDeleted.bars[0].length -1].y;
  644.                     var aH = aY - monthsChartDeleted.bars[0][0].y;
  645.                     console.log(aY+'\n'+aH);
  646.                     console.log(monthsChartDeleted.bars[0]);
  647.                     Raphael.g.axis(45, aY+1.8, (aH || (aY+1.8)*10), 0, axisLabels.length, axisLabels.length-1, 1, axisLabels, ' ', null, monthsCanvasDeleted)
  648.                     .text.attr({'font-weight':'bold'});
  649.                     Raphael.g.axis(78, aY+1.8, (aH || (aY+1.8)*10), 0, axisData.length, axisData.length-1, 1, axisData, ' ', null, monthsCanvasDeleted)
  650. .text.attr({'text-anchor':'right'});
  651.                     $("tspan").each(function(){this.setAttribute("dy",0);})
  652.             <?php }
  653.         }?>
  654.             };
  655.         </script>
  656.             <style>
  657.             body {background-color:#EEEEEE;}</style>
  658.             </head>
  659.             <body><div class="pagination-centered">
  660.     <h1>User Analysis for <?php echo str_replace( "|", " & ", $_GET['user'] );?></h1><br>
  661.     </div><?php printSiteNotice();
  662.         if( $optinoverride ) {
  663.             ?><div class="alert  alert-error"><h4>WARNING:</h4>  You are using a valid override key assigned to <?php echo $overridekey; ?>.  Please note that every override is logged and abuse will result in termination of the key.  You have been warned.<br>
  664.         </div><?php  
  665.         }
  666.         if( !$existance['allexist'] && isset( $existance['notauser'] ) ) {
  667.             ?><div class="alert  alert-error"><h4>Non-existent user:</h4>  The user(s), <?php echo implode( ", ", $existance['notauser'] );?> do not seem to exist and have been excluded from the analysis.<br>
  668.         </div><?php    
  669.         }
  670.         if( isset( $data['messages'] ) ) {
  671.             if( isset( $data['messages']['DBfailures'] ) ) {
  672.                 ?><div class="alert  alert-error"><h4>Database Failure:</h4>  For some reason, I'm having issues with the databases.  As a result, <?php echo implode( ", ", $data['messages']['DBfailures'] );?>.  Please contact <a href="//en.wikipedia.org/wiki/User%20talk:Cyberpower678">Cyberpower678</a> if the issue persists.<br>
  673.         </div><?php
  674.             }
  675.             if( isset( $data['messages']['APIfailures'] ) ) {
  676.                 ?><div class="alert  alert-error"><h4>API Failure:</h4>  For some reason, I'm having issues with the API.  As a result, <?php echo implode( ", ", $data['messages']['APIfailures'] );?>.  Please contact <a href="//en.wikipedia.org/wiki/User%20talk:Cyberpower678">Cyberpower678</a> if the issue persists.<br>
  677.         </div><?php
  678.             }
  679.             if( isset( $data['messages']['memoryoverflow'] ) ) {
  680.                 ?><div class="alert  alert-error"><h4>Memory Overflow:</h4>  In an attempt to ensure this tool doesn't crash on you due to memory contraints, not all data was processed.  As a result, <?php echo implode( ", ", $data['messages']['memoryoverflow'] );?>.  Please contact <a href="//en.wikipedia.org/wiki/User%20talk:Cyberpower678">Cyberpower678</a> if you feel there is an error.<br>
  681.         </div><?php
  682.             }
  683.             if( isset( $data['messages']['optinrequired'] ) && $thisopt == 'optin' ) {
  684.                 ?><div class="alert alert-block alert-info"><h4>Not Opted In:</h4>  <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) echo "One of the users"; else echo "This user"; ?> is not opted in.  As a result, <?php echo implode( ", ", $data['messages']['optinrequired'] );?>.<br>
  685.                 <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) {?>Please make sure each user is opted in by following the FAQ.</div> <?php } else {?> Please add content to <a href="//<?php echo $_GET['project']; ?>.org/wiki/User:<?php echo $_GET['user']; ?>/EditCounterOptIn.js">User:<?php echo $_GET['user']; ?>/EditCounterOptIn.js</a> to opt in locally or add content to <a href="//meta.wikimedia.org/wiki/User:<?php echo $_GET['user']; ?>/EditCounterGlobalOptIn.js">User:<?php echo $_GET['user']; ?>/EditCounterGlobalOptIn.js</a> to optin globally.</div>
  686.             <?php }
  687.             } elseif( isset( $data['messages']['optinrequired'] ) && $thisopt == 'optout' ) {
  688.                 ?><div class="alert alert-block alert-info"><h4>Not Opted In:</h4>  <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) echo "One of the users"; else echo "This user"; ?> has opted out.  As a result, <?php echo implode( ", ", $data['messages']['optinrequired'] );?>.<br>
  689.                 <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) {?>Please make sure each user is opted in by following the FAQ.</div> <?php } else {?> Please blank <a href="//<?php echo $_GET['project']; ?>.org/wiki/User:<?php echo $_GET['user']; ?>/EditCounterOptOut.js">User:<?php echo $_GET['user']; ?>/EditCounterOptOut.js</a> and blank <a href="//meta.wikimedia.org/wiki/User:<?php echo $_GET['user']; ?>/EditCounterGlobalOptOut.js">User:<?php echo $_GET['user']; ?>/EditCounterGlobalOptOut.js</a> to opt back in.</div>
  690.             <?php }
  691.             }
  692.             if( isset( $data['messages']['privateoptinrequired'] ) ) {
  693.                 ?><div class="alert alert-block alert-info"><h4>Not Opted In:</h4>  <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) echo "One of the users"; else echo "This user"; ?> is not opted in to non-public data.  As a result, <?php echo implode( ", ", $data['messages']['privateoptinrequired'] );?>.<br>
  694.                 <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) {?>Please make sure each user is opted in by following the FAQ.</div> <?php } else {?> Please add content to <a href="//<?php echo $_GET['project']; ?>.org/wiki/User:<?php echo $_GET['user']; ?>/EditCounterPrivateOptIn.js">User:<?php echo $_GET['user']; ?>/EditCounterPrivateOptIn.js</a> to optin locally or add content to <a href="//meta.wikimedia.org/wiki/User:<?php echo $_GET['user']; ?>/EditCounterGlobalPrivateOptIn.js">User:<?php echo $_GET['user']; ?>/EditCounterGlobalPrivateOptIn.js</a> to optin globally.</div>
  695.             <?php }
  696.             }
  697.         }
  698.         if( $thisopt == 'optout' && !isset( $data['messages']['optinrequired'] ) ) {
  699.             ?><div class="alert alert-block alert-info"><h4>Opt Out Wiki:</h4>  All data is automatically available.</div>  <?php if( count( explode( '|', $_GET['user'] ) ) > 1 ) { echo ""; } else {?> To opt out please create User:<?php echo $_GET['user']; ?>/EditCounterOptOut.js on your local wiki or create User:<?php echo $_GET['user']; ?>/EditCounterGlobalOptOut.js on meta.wikimedia.org.</div>
  700.         <?php }
  701.         }
  702.         if( isset( $data['replag'] ) && $data['replag'] > 60 ) {?><div class="alert  alert-error"><h4>High Replication Lag:</h4>  Oh dear.  The database appears to be lagging behind.  I won't be able to present you with information newer than <?php echo round( $data['replag'], 0 ); ?> seconds.</div><?php } ?>
  703.     <ul class="nav nav-tabs">
  704.     <li class="active"><a href="#overview" data-toggle="tab">Overview</a></li>
  705.     <?php if( $optstatus ) {?><li><a href="#monthly" data-toggle="tab">Monthly Stats</a></li><?php }
  706.         if( $optstatus ) {?><li><a href="#top" data-toggle="tab">Top Edited Pages</a></li><?php }
  707.         ?><li><a href="#future" data-toggle="tab">Future Plans</a></li>
  708.         <li><a href="#faq" data-toggle="tab">FAQ</a></li>
  709.         <?php if( isset( $_GET['debug'] ) && $_GET['debug'] ) { ?><li><a href="#debug" data-toggle="tab">Debugging Purposes</a></li><?php } ?></ul><?php
  710.         ?><div class="tab-content">
  711.     <div class="tab-pane active container-fluid" id="overview">
  712.         <h3>Overview:</h3>
  713.         <?php if( isset( $data['namespace_totals'] ) && isset( $data['deleted_namespace_totals'] ) && isset( $data['total_namespace_totals'] ) ) {
  714.             ?><ul class="nav nav-tabs">
  715.             <li class="active"><a href="#overviewtotal" data-toggle="tab">All Edits</a></li>
  716.             <li><a href="#overviewlive" data-toggle="tab">Live Only</a></li>
  717.             <li><a href="#overviewdeleted" data-toggle="tab">Deleted Only</a></li></ul>
  718.         <div class="tab-content">
  719.             <div class="tab-pane active container-fluid" id="overviewtotal">
  720.             <?php printTotalOverview(); ?>
  721.             </div>
  722.             <div class="tab-pane container-fluid" id="overviewlive">
  723.             <?php printLiveOverview(); ?>
  724.             </div>
  725.             <div class="tab-pane container-fluid" id="overviewdeleted">
  726.             <?php printDeletedOverview(); ?>
  727.             </div>
  728.         </div>
  729.         <?php }
  730.         else printGeneralOverview();
  731.         echo "</div>"; //close tab
  732.         if( !isset( $data['messages']['optinrequired'] ) ) {
  733. ?>  <div class="tab-pane container-fluid" id="monthly">
  734.         <h3>Monthly Namespace Edit Breakdown:</h3>
  735.         <ul class="nav nav-tabs">
  736.         <li><a href="#legend" data-toggle="tab">Namespaces</a></li>
  737.         <li class="active"><a href="#monthchart" data-toggle="tab">Monthly Chart</a></li>
  738.         <li><a href="#monthtable" data-toggle="tab">Monthly Tables</a></li>
  739.         </ul>
  740.         <div class="tab-content">
  741.         <div class="tab-pane container-fluid" id="monthtable">
  742.         <?php  
  743.         foreach( $data['monthly_counts'] as $tmonth=>$tcount ) {
  744.             echo "          <div class=\"span4\">\n<div class=\"table-responsive\">\n<table class=\"table table-bordered\">";
  745.             echo "<thead>\n";
  746.             echo "<tr>\n          <th>$tmonth</th>\n          <th>Namespace</th>\n          <th>Edit count</th>\n          <th>Percentage</th>\n        </tr>\n      </thead>\n      <tbody>\n";
  747.             foreach( $tcount as $tid=>$tdata ) {
  748.                 if( $tid !== 'total' ) {
  749.                     echo "        <tr>\n          <td bgcolor=\"#{$colors[$tid]}\"> </td>\n";
  750.                     echo "          <td>".( $tid == 0 ? "Main" : $data['namespaces'][$tid]['*'] )."</td>\n";
  751.                     echo "          <td>$tdata</td>\n";
  752.                     echo "          <td>".( $tcount['total'] == 0 ? "0%" : round( $tdata/$tcount['total']*100, 2 )."%" )."</td>\n        </tr>\n";
  753.                 }  
  754.             }
  755.             echo "        <tr>\n          <td> </td>\n";
  756.             echo "          <td>Total</td>\n";
  757.             echo "          <td>{$tcount['total']}</td>\n";
  758.             echo "          <td>".( $tcount['total'] == 0 ? "0%" : "100%" )."</td>\n        </tr>\n      </tbody>\n    </table>\n</div>\n</div>\n";
  759.         } ?></div>
  760.         <div class="tab-pane container-fluid" id="legend"><div class="span3" style="float:left"><table class="table table-bordered">
  761.       <thead>
  762.         <tr>
  763.             <th columnspan="2"><b>Legend</b></th>
  764.         </tr>
  765.         <tr>
  766.           <th>Color</th>
  767.           <th>Namespace</th>
  768.         </tr>
  769.       </thead>
  770.       <tbody> <?php foreach( $data['namespaces'] as $tid=>$tnamespace ) {
  771.           if( $tid == -2 || $tid == -1 ) continue;
  772.           echo "        <tr>\n";
  773.           echo "          <td bgcolor=\"#{$colors[$tid]}\"></td>\n";
  774.           echo "          <td>".( $tid == 0 ? "Main" : $tnamespace['*'] )."</td>\n";
  775.           echo "        </tr>\n";
  776.       } ?>
  777.       </tbody>
  778.     </table></div></div>
  779.         <div class="tab-pane active container-fluid" id="monthchart"><div class="span4"><div id="month-chart"></div></div></div>
  780.         </div>
  781.     </div>
  782.     <div class="tab-pane container-fluid" id="top">
  783.         <h3>Top <?php echo (isset( $_GET['toplimit'] ) ? ( $_GET['toplimit'] > 0 ? $_GET['toplimit'] : "" ) : "10"); ?> Most Edited Pages by Namespace:</h3><?php foreach( $data['top_pages'] as $tid=>$tlist ) {
  784.             echo "<h4>".( $tid == 0 ? "Main" : $data['namespaces'][$tid]['*'] )."</h4>\n<ol>\n";
  785.             foreach( $tlist as $tpage=>$tcount ) {
  786.                 echo "<li><a href=\"//{$_GET['project']}.org/wiki/".$data['namespaces'][$tid]['*'].":$tpage\">".str_replace( '_', ' ', $tpage )."</a> &mdash; $tcount</li>\n";  
  787.             }
  788.             echo "</ol>\n";
  789.         } ?>
  790.     </div><?php
  791.         }
  792. ?>  <div class="tab-pane container-fluid" id="future">
  793.         <h3>What's to be added to the tool:</h3>
  794.         <ol>
  795.         <li>Articles created list</li>
  796.         <li>Edit summary analysis</li>
  797.         <li>Edit analysis</li>
  798.         <li>Files uploaded</li>
  799.         <li>Treemap view of namespace breakdown</li>
  800.         <li>Logged statistics</li></ol><br>
  801.         If you would like to see more features added, please feel free to suggest it to <a href="//en.wikipedia.org/wiki/User talk:Cyberpower678">Cyberpower678</a>.
  802.     </div>
  803.     <div class="tab-pane container-fluid" id="faq">
  804.         <h3>Frequently Asked Questions:</h3>
  805.         <ol>
  806.         <li><b>Why do some of the tabs not show up for certain users?</b>
  807.         <dl><dd>A: This is because some users have chosen not to opt in to additional statistics, or have chosen to opt out.  Only they can choose whether they want that information public or not.</dd></dl></li>
  808.         <li><b>Why was X!'s Edit Counter replaced with this tool?</b>
  809.         <dl><dd>A: X!'s edit counter was old.  On top of that, it used old PHP functions that were deprecated and leaked memory.  This is partially responsible for the outages happening on xtools.  The code had a lot of hacky fixes in it as well.  At this point a complete rewrite was a more favorable option.</dd></dl></li>
  810.         <li><b>What is the opt requirement for this wiki?</b>
  811.         <dl><dd>A: <?php echo "For {$_GET['project']}.org, to view detailed statistics, ";
  812.         switch( $thisopt ) {
  813.             case 'optin':
  814.             echo "the user must be opted in.";
  815.             break;
  816.             case 'optout':
  817.             echo "the user is already opted in but can choose to opt out.";
  818.             break;
  819.             case 'noopt':
  820.             echo "no optin is required.";
  821.             break;
  822.         }?></dd></dl></li>
  823.         <li><b><?php switch( $thisopt ) {
  824.             case 'optin':
  825.             echo "How do I opt in to this wiki to allow additional data to be displayed?";
  826.             break;
  827.             case 'optout':
  828.             echo "How can I opt out of this wiki to suppress additional data from be displayed?";
  829.             break;
  830.             case 'noopt':
  831.             echo "Why can't I choose to opt in or opt out to control what data can be displayed?";
  832.             break;
  833.         }?></b>
  834.         <dl><dd>A: <?php switch( $thisopt ) {
  835.             case 'optin':
  836.             echo "To opt in to this wiki, simply create User:{$_GET['user']}/EditCounterOptIn.js.  Alternatively, creating User:{$_GET['user']}/EditCounterGlobalOptIn.js on meta.wikimedia.org will opt in for all wikimedia wikis supporting optin.";
  837.             break;
  838.             case 'optout':
  839.             echo "To opt out to this wiki, simply create User:{$_GET['user']}/EditCounterOptOut.js.  Alternatively, creating User:{$_GET['user']}/EditCounterGlobalOptOut.js on meta.wikimedia.org will opt out for all wikimedia wikis supporting optout.";
  840.             break;
  841.             case 'noopt':
  842.             echo "This specific wiki has no support for optin or optout.";
  843.             break;
  844.         }?></dd></dl></li>
  845.         <li><b>Some optin requirements are different for certain wikis.  Why?</b>
  846.         <dl><dd>A: That is because the local consensus wishes to have it that way.  If you feel your wiki would favor to change the opt requirements, all you have to do is initiate a Request for Comments on that wiki and notify <a href="//en.wikipedia.org/wiki/User_talk:Cyberpower678">Cyberpower678</a> of the discussion.  When starting a request for comments, please allow users to choose one of three options.  Require opt-in, require opt-out, or no opt requirement at all.</dd></li>
  847.         <li><b>Some namespace percentages are small and have been grouped with the "Others" section of the piechart.  How do I view the namespaces?</b>
  848.         <dl><dd>A: Click on any wedge to view a complete list.  Click on the same wedge to hide it.</dd></dl></li>
  849.         </ol>
  850.     </div>
  851.     <?php if( isset( $_GET['debug'] ) && $_GET['debug'] ) { ?><div class="tab-pane container-fluid" id="debug"><h3>Debugging page:</h3><pre><?php print_r( $data ); ?></pre></div><?php }
  852.         echo "</div>"; //close tab content
  853.         echo "This tool has serviced $servicedRequests requests to date.";
  854.     } else {
  855.         printStart();
  856.         if( !is_null( $db ) ) mysqli_close( $db );
  857.         printStartPage( "Not a user", "Call me silly, but ".( count( explode( '|', $_GET['user'] ) ) > 1  ? "these users don't" : "this user doesn't")." seem to exist.");
  858.     }  
  859. }?>
  860. </body>
  861. </html><?php
  862.  
  863. function printSiteNotice() {
  864.     global $sitenotice;
  865.     if( !empty( $sitenotice ) ) {
  866.         if( isset( $sitenotice['danger'] ) ) {
  867.             echo "\n<div class=\"alert alert-danger\">\n<h4>Important Alerts:</h4>  <ul><li>".implode( "</li>\n<li>", $sitenotice['danger'] )."</li></ul></div>";  
  868.         }
  869.         if( isset( $sitenotice['warning'] ) ) {
  870.             echo "\n<div class=\"alert alert-warning\">\n<h4>Alerts:</h4>  <ul><li>".implode( "</li>\n<li>", $sitenotice['warning'] )."</li></ul></div>";  
  871.         }
  872.         if( isset( $sitenotice['info'] ) ) {
  873.             echo "\n<div class=\"alert alert-info\">\n<h4>Useful Info:</h4>  <ul><li>".implode( "</li>\n<li>", $sitenotice['info'] )."</li></ul></div>";  
  874.         }
  875.         if( isset( $sitenotice['success'] ) ) {
  876.             echo "\n<div class=\"alert alert-success\">\n<h4>Not so important info:</h4>  <ul><li>".implode( "</li>\n<li>", $sitenotice['success'] )."</li></ul></div>";  
  877.         }
  878.     }
  879. }
  880.  
  881. function isOptedIn( $tuser, $api ) {
  882.     $HTTP = new HTTP();
  883.     $opt = true;
  884.     foreach( explode( '|', $tuser ) as $user) {
  885.         $x = unserialize( $HTTP->get( $api, array( 'action'=>'query', 'prop'=>'revisions', 'titles'=>"User:$user/EditCounterOptIn.js", 'rvprop'=>'content', 'format'=>'php' ) ) );
  886.         foreach( $x['query']['pages'] as $page ) {
  887.             if( !isset( $page['revisions'] ) ) {
  888.                 $x = unserialize( $HTTP->get( 'https://meta.wikimedia.org/w/api.php', array( 'action'=>'query', 'prop'=>'revisions', 'titles'=>"User:$user/EditCounterGlobalOptIn.js", 'rvprop'=>'content', 'format'=>'php' ) ) );
  889.                 foreach( $x['query']['pages'] as $page ) {
  890.                     if( !isset( $page['revisions'] ) ) {
  891.                         $opt = false;
  892.                     }
  893.                 }
  894.             }
  895.         }
  896.         if( $x === false ) $opt = false;
  897.     }
  898.     return $opt;
  899. }
  900. function isOptedOut( $tuser, $api ) {
  901.     $HTTP = new HTTP();
  902.     $opt = true;
  903.     foreach( explode( '|', $tuser ) as $user) {
  904.         $x = unserialize( $HTTP->get( $api, array( 'action'=>'query', 'prop'=>'revisions', 'titles'=>"User:$user/EditCounterOptOut.js", 'rvprop'=>'content', 'format'=>'php' ) ) );
  905.         foreach( $x['query']['pages'] as $page ) {
  906.             if( !isset( $page['revisions'] ) ) {
  907.                 $x = unserialize( $HTTP->get( 'https://meta.wikimedia.org/w/api.php', array( 'action'=>'query', 'prop'=>'revisions', 'titles'=>"User:$user/EditCounterGlobalOptOut.js", 'rvprop'=>'content', 'format'=>'php' ) ) );
  908.                 foreach( $x['query']['pages'] as $page ) {
  909.                     if( !isset( $page['revisions'] ) ) {
  910.                         $opt = false;
  911.                     }
  912.                 }
  913.             }
  914.         }
  915.         if( $x === false ) $opt = false;
  916.     }
  917.     return $opt;
  918. }
  919. function isPrivateOptedIn( $tuser, $api ) {
  920.     $HTTP = new HTTP();
  921.     $opt = true;
  922.     foreach( explode( '|', $tuser ) as $user) {
  923.         $x = unserialize( $HTTP->get( $api, array( 'action'=>'query', 'prop'=>'revisions', 'titles'=>"User:$user/EditCounterPrivateOptIn.js", 'rvprop'=>'content', 'format'=>'php' ) ) );
  924.         foreach( $x['query']['pages'] as $page ) {
  925.             if( !isset( $page['revisions'] ) ) {
  926.                 $x = unserialize( $HTTP->get( 'https://meta.wikimedia.org/w/api.php', array( 'action'=>'query', 'prop'=>'revisions', 'titles'=>"User:$user/EditCounterGlobalPrivateOptIn.js", 'rvprop'=>'content', 'format'=>'php' ) ) );
  927.                 foreach( $x['query']['pages'] as $page ) {
  928.                     if( !isset( $page['revisions'] ) ) {
  929.                         $opt = false;
  930.                     }
  931.                 }
  932.             }
  933.         }
  934.         if( $x === false ) $opt = false;
  935.     }
  936.     return $opt;
  937. }
  938.  
  939. function printGeneralOverview() {
  940.     global $data, $time; ?>
  941.     <div id="general" class="span<?php echo ( isset( $data['namespace_totals'] ) && isset( $data['deleted_namespace_totals'] ) && isset( $data['total_namespace_totals'] ) ? "4" : "3" );?>" style="float:left"><?php
  942.     echo "First edit: {$data['firstedit']}<br>User groups: ".implode( ", ", $data['usergroups'] )."<br>Unique Pages Edited: ".number_format( $data['unique_count'], 0, '.', ',' )."<br>Average edits per page: ".number_format( round( ( $data['unique_count'] == 0 ? 0 : $data['liveedits']/$data['unique_count'] ), 2 ), 2, '.', ',' );
  943.     echo "<br>Live edits: ".number_format( $data['liveedits'], 0, '.', ',' )."<br>Deleted edits: ".number_format( $data['deletededits'], 0, '.', ',' )."<br><b>Total edits (including deleted): ".number_format( $data['totaledits'], 0, '.', ',' )."</b><br>Executed in ".round( microtime( 1 )-$time, 2 )." seconds.";                                                        
  944.     ?></div>
  945.         <div class = "span4">
  946.             <div id="ns-chart"></div>
  947.         </div>
  948.         <div class = "span4" id="low-stats"></div>
  949.         <?php
  950. }
  951. function printLiveOverview() {
  952.     global $data, $time; ?>
  953.     <div id="general" class="span<?php echo ( isset( $data['namespace_totals'] ) && isset( $data['deleted_namespace_totals'] ) && isset( $data['total_namespace_totals'] ) ? "4" : "3" );?>" style="float:left"><?php
  954.     echo "First edit: {$data['firstedit']}<br>User groups: ".implode( ", ", $data['usergroups'] )."<br>Unique Pages Edited: ".number_format( $data['unique_count'], 0, '.', ',' )."<br>Average edits per page: ".number_format( round( ( $data['unique_count'] == 0 ? 0 : $data['liveedits']/$data['unique_count'] ), 2 ), 2, '.', ',' );
  955.     echo "<br>Live edits: ".number_format( $data['liveedits'], 0, '.', ',' )."<br>Executed in ".round( microtime( 1 )-$time, 2 )." seconds.";                                                        
  956.     ?></div>
  957.         <div class = "span4">
  958.             <div id="ns-chart"></div>
  959.         </div>
  960.         <div class = "span4" id="low-stats"></div>
  961.         <?php
  962. }
  963. function printTotalOverview() {
  964.     global $data, $time; ?>
  965.     <div id="general" class="span<?php echo ( isset( $data['namespace_totals'] ) && isset( $data['deleted_namespace_totals'] ) && isset( $data['total_namespace_totals'] ) ? "4" : "3" );?>" style="float:left"><?php
  966.     echo "First edit: {$data['true_firstedit']}<br>User groups: ".implode( ", ", $data['usergroups'] )."<br>Unique Pages Edited: ".number_format( $data['total_unique_count'], 0, '.', ',' )."<br>Average edits per page: ".number_format( round( ( $data['total_unique_count'] == 0 ? 0 : $data['totaledits']/$data['total_unique_count'] ), 2 ), 2, '.', ',' );
  967.     echo "<br><b>Total edits (including deleted): ".number_format( $data['totaledits'], 0, '.', ',' )."</b><br>Executed in ".round( microtime( 1 )-$time, 2 )." seconds.";                                                        
  968.     ?></div>
  969.         <div class = "span4">
  970.             <div id="ns-chart-total"></div>
  971.         </div>
  972.         <div class = "span4" id="low-stats-total"></div>
  973.         <?php
  974. }
  975. function printDeletedOverview() {
  976.     global $data, $time; ?>
  977.     <div id="general" class="span<?php echo ( isset( $data['namespace_totals'] ) && isset( $data['deleted_namespace_totals'] ) && isset( $data['total_namespace_totals'] ) ? "4" : "3" );?>" style="float:left"><?php
  978.     echo "First edit: {$data['deleted_firstedit']}<br>User groups: ".implode( ", ", $data['usergroups'] )."<br>Unique Pages Edited: ".number_format( $data['deleted_unique_count'], 0, '.', ',' )."<br>Average edits per page: ".number_format( round( ( $data['deleted_unique_count'] == 0 ? 0 : $data['deletededits']/$data['deleted_unique_count'] ), 2 ), 2, '.', ',' );
  979.     echo "<br>Deleted edits: ".number_format( $data['deletededits'], 0, '.', ',' )."<br>Executed in ".round( microtime( 1 )-$time, 2 )." seconds.";                                                        
  980.     ?></div>
  981.         <div class = "span4">
  982.             <div id="ns-chart-deleted"></div>
  983.         </div>
  984.         <div class = "span4" id="low-stats-deleted"></div>
  985.         <?php
  986. }
  987.  
  988. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement