<?php if (!defined('PmWiki')) exit();
/*  Copyright 2004-2022 Patrick R. Michaud (pmichaud@pobox.com)
    This file is part of PmWiki; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published
    by the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.  See pmwiki.php for full details.

    This file does simple reference counting on pages in a PmWiki site.
    Simply activate this script using
        include_once('scripts/refcount.php');
    in the config.php file and then use ?action=refcount to bring up
    the reference count form.  The output is a table where each row
    of the table contains a page name or link reference, the number
    of (non-RecentChanges) pages that contain links to the page,
    the number of RecentChanges pages with links to the page, and the
    total number of references in all pages.
    
    Script maintained by Petko YOTOV www.pmwiki.org/petko
*/

SDV($PageRefCountFmt,"<h2 class='wikiaction'>Reference Count Results</h2>");
SDV($RefCountTimeFmt," <small>%Y-%b-%d %H:%M</small>");
SDV($HandleActions['refcount'], 'HandleRefCount');

function PrintRefCount($pagename) {
  global $GroupPattern,$NamePattern,$PageRefCountFmt,$RefCountTimeFmt, $ScriptUrl;
  $pagelist = ListPages();
  $grouplist = array();
  foreach($pagelist as $pname) {
    if (!preg_match("/^($GroupPattern)[\\/.]($NamePattern)$/",$pname,$m))
      continue;
    $grouplist[$m[1]]=$m[1];
  }
  asort($grouplist);
  $grouplist = array_merge(array('all' => 'all groups'),$grouplist);

  $wlist = array('all','missing','existing','orphaned');
  $tlist = isset($_REQUEST['tlist']) ? $_REQUEST['tlist'] : array('all');
  $flist = isset($_REQUEST['flist']) ? $_REQUEST['flist'] : array('all');
  $whichrefs = @$_REQUEST['whichrefs'];
  $showrefs = (@$_REQUEST['showrefs']=='checked')? "checked='checked'" : '';
  $submit = @$_REQUEST['submit'];

  echo FmtPageName($PageRefCountFmt,$pagename);
  echo FmtPageName("<form method='post' action='{\$PageUrl}'><input type='hidden' name='action' value='refcount'/>
    <table cellspacing='10'><tr><td valign='top'>Show
    <br/><select name='whichrefs'>",$pagename);
  foreach($wlist as $w)
    echo "<option ",($whichrefs==$w) ? 'selected="selected"' : ''," value='$w'>$w</option>\n";
  echo "</select></td><td valign='top'> page names in group<br/>
    <select name='tlist[]' multiple='multiple' size='4'>";
  foreach($grouplist as $g=>$t)
    echo "<option ",in_array($g,$tlist) ? 'selected="selected"' : ''," value='$g'>$t</option>\n";
  echo "</select></td><td valign='top'> referenced from pages in<br/>
    <select name='flist[]' multiple='multiple' size='4'>";
  foreach($grouplist as $g=>$t)
    echo "<option ",in_array($g,$flist) ? 'selected="selected"' : ''," value='$g'>$t</option>\n";
  echo "</select></td></tr></table>
    <p><input type='checkbox' name='showrefs' id='chk_showrefs' value='checked' $showrefs/>
      <label for='chk_showrefs'>Display referencing pages</label>
    </p><p><input type='submit' name='submit' value='Search'/></p></form><hr/>";

  if ($submit) {
    foreach($pagelist as $pname) {
      $ref = array();
      $page = ReadPage($pname, READPAGE_CURRENT); 
      if (!$page) continue;
      $tref[$pname]['time'] = $page['time'];
      if (!in_array('all',$flist) &&
          !in_array(FmtPageName('$Group',$pname),$flist)) continue;
      $rc = preg_match('/RecentChanges$/',$pname);
      foreach(explode(',',strval(@$page['targets'])) as $r) {
        if ($r=='') continue;
        if ($rc) @$tref[$r]['rc']++;
        else { @$tref[$r]['page']++; @$pref[$r][$pname]++; }
      }
    }
    uasort($tref,'RefCountCmp');
    echo "<table class='refcount'>
      <tr><th></th><th colspan='2'>Referring pages</th></tr>
      <tr><th>Name / Time</th><th>All</th><th>R.C.</th></tr>";
    reset($tref);
    foreach($tref as $p=>$c) {
      if (!in_array('all',$tlist) &&
          !in_array(FmtPageName('$Group',$p),$tlist)) continue;
      if ($whichrefs=='missing' && PageExists($p)) continue;
      elseif ($whichrefs=='existing' && !PageExists($p)) continue;
      elseif ($whichrefs=='orphaned' &&
        (@$tref[$p]['page']>0 || !PageExists($p))) continue;
      echo "<tr><td valign='top'>",LinkPage($pagename, '', $p, '', $p);
      if (@$tref[$p]['time']) echo PSFT($RefCountTimeFmt,$tref[$p]['time']);
      if ($showrefs && is_array(@$pref[$p])) {
        foreach($pref[$p] as $pr=>$pc) 
          echo "<dd>", LinkPage($pagename, '', $pr, '', $pr);
      }
      echo "</td>";
      echo "<td align='center' valign='top'>",@$tref[$p]['page']+0,"</td>";
      echo "<td align='center' valign='top'>",@$tref[$p]['rc']+0,"</td>";
      echo "</tr>";
    }
    echo "</table>";
  }
}


function RefCountCmp($ua,$ub) {
  if (@($ua['page']!=$ub['page'])) return @($ub['page']-$ua['page']);
  if (@($ua['rc']!=$ub['rc'])) return @($ub['rc']-$ua['rc']);
  return @($ub['time']-$ua['time']);
}



function HandleRefCount($pagename, $auth='read') {
  global $HandleRefCountFmt,$PageStartFmt,$PageEndFmt;
  $page = RetrieveAuthPage($pagename, $auth, true, READPAGE_CURRENT);
  if (!$page) Abort('?unauthorized');
  PCache($pagename, $page);
  SDV($HandleRefCountFmt,array(&$PageStartFmt,
    'function:PrintRefCount',&$PageEndFmt));
  PrintFmt($pagename,$HandleRefCountFmt);
}

