Log in

SiteGraph source

From Kenny Root

<?php //

This is a MediaWiki Extension. For more information about it, see the documentation in SiteGraph source Extension.

Important! Unless otherwise specified, this extension is released under GNU General Public License V3. If you choose to install it, you do so at your own risk and discretion.

/*
 * SiteGraph.php - A MediaWiki tag extension for adding site graphs based on GraphViz.
 * @author Kenneth L. Root
 * @version 1.0.0
 * @copyright Copyright (C) 2007-2009 Kenneth L. Root
 * @license GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
 * -----------------------------------------------------------------------
 * Description:
 *     This is a MediaWiki extension which a site graph utilizing the
 *     GraphViz plugin and program.
 *
 * Installation:
 *     1. Place this in a directory (SiteGraph) under $IP/extensions
 *     2. Enable the extension by adding this line to your LocalSettings.php:
 *        require_once('extensions/SiteGraph/SiteGraph.php');
 *
 * Usage:
 *     Once installed, you may utilize SiteGraph by adding the <sitegraph> tag.
 *
 * Example:
 *
 * <sitegraph type="digraph" layout="neato">
 * graph [
 *   center=true,
 *   fontname="Verdana",
 *   bgcolor="transparent",
 *   truecolor="true",
 *   fontsize=12,
 *   overlap="orthoyx",
 *   splines="true",
 *   pack="true",
 *   sep="0.1",
 *   dpi=62,
 *   ratio="compress",
 *   epsilon="0.001",
 * ];
 *
 * edge [
 *   fontsize=12,
 *   arrowsize=0.5,
 *   len=0.5
 * ];
 *
 * node [
 *   fontsize=12,
 *   shape="plaintext",
 *   height=0.25,
 *   width=0.25,
 *   fontcolor=blue,
 * ];
 * </sitegraph>
 *
 * Version Notes:
 *     version 1.0.0:
 *     Initial release.
 * -----------------------------------------------------------------------
 * Copyright (c) 2007-2009 Kenneth L. Root
 *
 *    This program is free software: 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 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * -----------------------------------------------------------------------
 */
 
if (!defined('MEDIAWIKI')) {
  die( "This file is part of MediaWiki and is not a valid entry point\n" );
}
 
$wgExtensionFunctions[] = 'SiteGraph_init';
$wgExtensionCredits['parserhook'][] = array(
  'name' => 'SiteGraph',
  'version' => '1.0.0',
  'author' => '[http://the-b.org/ Kenny Root]',
  'url' => 'http://the-b.org/SiteGraph',
  'description' => 'Create a sitemap graph through GraphViz.',
);
 
/**
 * Sets up the SiteGraph Parser hook and system messages
 */
function SiteGraph_init() {
  global $wgParser, $wgMessageCache;
  $wgParser->setHook( 'sitegraph', 'SiteGraph_render' );
}
 
function SiteGraph_render($text, $params = array(), &$parser) {
  global $wgContLang, $wgOut;
 
  $dbr = wfGetDB(DB_SLAVE);
  list($page, $pagelinks) = $dbr->tableNamesN('page', 'pagelinks');
 
  $type = "graph";
  if (array_key_exists('type', $params))
        $type = $params['type'];
 
  $layout = "dot";
  if (array_key_exists('layout', $params))
        $layout = $params['layout'];
 
  $html = array();
  $html[] = "<graphviz layout='$layout'>$type A {";
  $html[] = $text;
 
  $res = $dbr->query("SELECT
    page_namespace AS namespace,
    page_title AS title
    FROM $page
    WHERE page_namespace = ".NS_MAIN."
    AND page_is_redirect = 0");
  $num = $dbr->numRows($res);
 
  for ($i = 0; $i < $num && $row = $dbr->fetchObject($res); $i++) {
    $title = Title::makeTitleSafe($row->namespace, $row->title);
    $html[] = "\"". $row->title ."\" [label=\"" . htmlspecialchars($wgContLang->convert($title->getPrefixedText())) . "\" URL=\"/" . $row->title . "\"];";
  }
 
  $res = $dbr->query("SELECT
    page1.page_namespace AS namespace1,
    page1.page_title AS title1,
    page2.page_namespace AS namespace2,
    page2.page_title AS title2
    FROM page page1
    LEFT JOIN pagelinks link1 ON page1.page_id = link1.pl_from
    LEFT JOIN page page2 ON link1.pl_title = page2.page_title
    LEFT JOIN pagelinks link2 ON page2.page_id = link2.pl_from
    WHERE link2.pl_title = page1.page_title
    AND page1.page_title < page2.page_title
    AND (page1.page_namespace = ".NS_MAIN." OR page1.page_namespace >= 100)
    AND (page2.page_namespace = ".NS_MAIN." OR page2.page_namespace >= 100)
    AND page1.page_is_redirect = 0
    AND page2.page_is_redirect = 0");
  $num = $dbr->numRows($res);
 
  for ($i = 0; $i < $num && $row = $dbr->fetchObject($res); $i++) {
    $html[] = "\"". $row->title1 ."\" -> \"". $row->title2 ."\" [dir=\"both\"];";
  }
 
  $res = $dbr->query("SELECT DISTINCT
    page1.page_namespace AS namespace1,
    page1.page_title AS title1,
    page2.page_namespace AS namespace2,
    page2.page_title AS title2
    FROM page page1
    INNER JOIN pagelinks link1 ON page1.page_id = link1.pl_from
    INNER JOIN page page2 ON link1.pl_title = page2.page_title
    LEFT JOIN pagelinks link2 ON ((page2.page_id = link2.pl_from) AND (page1.page_title = link2.pl_title))
    WHERE link2.pl_from IS NULL
    AND page1.page_id <> page2.page_id
    AND (page1.page_namespace = 0 OR page1.page_namespace >= 102)
    AND (page2.page_namespace = 0 OR page2.page_namespace >= 102)
    AND page1.page_is_redirect = 0 AND page2.page_is_redirect = 0;");
  $num = $dbr->numRows($res);
 
  if ($type == "graph")
        $connector = "--";
  else
        $connector = "->";
 
  for ($i = 0; $i < $num && $row = $dbr->fetchObject($res); $i++) {
    $html[] = "\"". $row->title1 ."\" ". $connector ." \"". $row->title2 ."\";";
  }
 
  $html[] = "}</graphviz>";
 
  return '<!-- ENCODED_SITEGRAPH '. base64_encode(implode($html, "\n")) . ' -->';
}
 
if (!function_exists('processSiteGraphOutput')) {
    $wgHooks['ParserAfterTidy'][] = 'processSiteGraphOutput';
    function processSiteGraphOutput(&$out, &$text) {
        global $wgOut;
 
        # Find all hidden content and restore to normal
        $matches = array();
        $nmatch = preg_match_all(
            '/<!-- ENCODED_SITEGRAPH ([0-9a-zA-Z\\+]+=*) -->/esm',
            $text,
            $matches,
            PREG_SET_ORDER);
 
        for ($i = 0; $i < $nmatch; $i++) {
            $text = str_replace(
                $matches[$i][0],
                $wgOut->parse(base64_decode($matches[$i][1])),
                $text);
        }
        return true;
    }
}
 
//

?>

Cantonese
Kenny Root