Extension:C Style Wiki Includes

From MediaWiki.org

Jump to: navigation, search
Manual on MediaWiki Extensions
List of MediaWiki Extensions
C Style Wiki Includes

Release status: beta

Implementation Extended syntax
Description Allows including HTML, WikiText, or PlainText using an #include tag.
Author(s) Daniel Friesen (Dantman Talk)
Version unknown
MediaWiki 1.8.x, 1.9x
Download Wiki-Tools.com or this page
Added rights cwikiinclude_html

[edit] Rationale and Features

I saw one user on my wiki add an amusing line on their user page instead of a #REDIRECT to another userpage... They basically used a C Style include with an interwiki link to their normal Userpage.

That gave me the idea to setup real C style includes. HTML, WikiText, and then decided to add Text.

I'll have to thank the ProtectSection extension, because I used their extension as a base to know what functions to use and how to make adding unsafe ones fail when not added by a privileged user.

[edit] Usage and Installation

Full information on the C Style Wiki Includes extension can be found at Wiki-Tools.com.

[edit] Code

The site's being taken down and every thing's being done from scratch... So here's the code... Dantman

<?php
# 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 2 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# http://www.gnu.org/copyleft/gpl.html
 
/**
 * @author Daniel Friesen <dan_the_man@telus.net>
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 */
 
if( !defined( 'MEDIAWIKI' ) ) die( "This is an extension to the MediaWiki package and cannot be run standalone." );
 
// Two new permissions
$wgAvailableRights[] = 'cwikiinclude';
 
$wgExtensionFunctions[] = 'efCWikiIncludeSetup';
 
// Register hooks
$wgHooks['ParserAfterTidy'][] = 'efCWikiAfterParse';
$wgHooks['EditFilter'][] = 'efCheckCWikiInclude';
$wgHooks['ParserBeforeStrip'][] = 'efCWikiBeforeParse';
 
$wgExtensionCredits['parserhook'][] = array(
        'name' => 'C Style Wiki Includes',
        'url' => 'http://www.mediawiki.org/wiki/Extension:C_Style_Wiki_Includes',
        'author' => '[http://central.wiki-tools.com/wiki/User:Dantman Daniel Friesen]',
        'description' => 'C Style WikiText and HTML includes.',
);
 
$egCWikiInclude_limit = 3;
$egCWikiWikiText_html = "/^#include\s*\"(https?:\/\/[^<>\"']*?)\"(;?)$/sim";
$egCWikiWikiText_text = "/^#include\s*{(https?:\/\/[^<>\"']*?)}(;?)$/sim";
$egCWikiWikiText_wiki = "/^#include\s*<(https?:\/\/[^<>\"']*?)>(;?)$/sim";
$egCWikiInclude_html = "/<tt>#include\s*&quot;(https?:\/\/[^<>\"']*?)&quot;(;?)<\/tt><br \/>/sim";
$egCWikiInclude_text = "/<tt>#include\s*{(https?:\/\/[^<>\"']*?)}(;?)<\/tt>/sim";
$egCWikiInclude_wiki = "/<tt><nowiki>#include\s*<(https?:\/\/[^<>\"']*?)>(;?)<\/nowiki><\/tt><br \/>/sim";
function efCWikiIncludeSetup() {
        global $wgMessageCache;
        $wgMessageCache->addMessages(
                array(
                        'cwikiinclude_add_html' => 
                                'You tried to add a C Style HTML Include',
                        'cwikiinclude_modify_html' => 
                                'You tried to modify a C Style HTML Include',
                        'cwikiinclude_forbidden' =>
                                'Forbidden',
                )
        );
}
 
 
function efCWikiBeforeParse( &$parser, &$text, &$stripState ) {
        global $egCWikiWikiText_html, $egCWikiWikiText_text, $egCWikiWikiText_wiki, $egCWikiInclude_wiki, $egCWikiInclude_limit;
 
        /* Escape The Includes */
        $text = preg_replace( array(
                $egCWikiWikiText_html,
                $egCWikiWikiText_text,
                $egCWikiWikiText_wiki
        ), array(
                "<tt><nowiki>#include \"\\1\"\\2</nowiki></tt><br />",
                "<tt><nowiki>#include {\\1}\\2</nowiki></tt><br />",
                "<tt><nowiki>#include <\\1>\\2</nowiki></tt><br />"
        ), $text );
 
        /* Do the WikiText include */
        $text = preg_replace( $egCWikiInclude_wiki.'e', 'efCWikiIncludeCallback( "\\0", false, "\\1" )', $text, $egCWikiInclude_limit );
 
        return true;
}
function efCWikiAfterParse( &$parser, &$text ) { 
        global $egCWikiInclude_limit, $egCWikiInclude_html, $egCWikiInclude_text;
 
        /* Do the HTML include */
        $text = preg_replace( array(
                $egCWikiInclude_html.'e',
                $egCWikiInclude_text.'e'
        ), array(
                'efCWikiIncludeCallback( "\\0", false, html_entity_decode( "\\1" , ENT_QUOTES ) )',
                'efCWikiIncludeCallback( "\\0", true, html_entity_decode( "\\1" , ENT_QUOTES ) )'
        ), $text, $egCWikiInclude_limit );
 
        return true;
}
 
function efCWikiIncludeCallback( $original, $escapeHTML, $url ) {
        global $wgMemc, $wgUser, $wgOut, $wgTitle;
 
        $key = wfMemcKey( 'include', $url );
        $content = $wgMemc->get( $key );
        if( $content == "" ) {
                $content = Http::get( $url );
                if( $content ) {
                        $wgMemc->set( $key, $content, time() + 86400 );
                }
        }
        if( $escapeHTML ) {
                $text = htmlspecialchars( $text );
        }
        if( $content === false ) {
                $content = $original;
        }
        return $content;
}
 
function efCWikiDeleteCallback( $url ) {
        global $wgMemc;
        $key = wfMemcKey( 'include', $url );
        $wgMemc->delete( $key );
        return "";
}
 
/**
 * @todo Document
 * @param $editpage
 * @param $textbox1
 * @param $section
 */
function efCheckCWikiInclude( $editpage, $textbox1, $section )  {
        global $egCWikiInclude_limit, $egCWikiWikiText_html, $egCWikiWikiText_text, $egCWikiWikiText_wiki;
        # check for partial protection 
        global $wgUser,$wgParser;
 
        # Purge memcached for a URL when attempting a save
        preg_replace( array(
                $egCWikiWikiText_html.'e',
                $egCWikiWikiText_text.'e',
                $egCWikiWikiText_wiki.'e'
        ), array_fill ( 0, 3,
                'efCWikiDeleteCallback( html_entity_decode( "\\1" , ENT_QUOTES ) )'
        ), $text, $egCWikiInclude_limit );
 
        if ( !$wgUser->isAllowed( 'cwikiinclude_html' ) ) {
                $modifyProtect = false; 
                $text1 = $editpage->mArticle->getContent(true);
 
                if( $section != '' ) {
                        if( $section == 'new' ) {
                                $text1 = "";
                        } else {
                                $text1 = $wgParser->getSection( $text1, $section );
                        }
                }
 
                $text2 = $textbox1;
 
                preg_match_all( $egCWikiWikiText_html, $text1, $list1, PREG_SET_ORDER );
                preg_match_all( $egCWikiWikiText_html, $text2, $list2, PREG_SET_ORDER );
 
                if( count($list1) < count($list2)) { 
                        $msg = wfMsg( 'cwikiinclude_add_html'); 
                        $modifyProtect = true; 
                }
                else for ( $i=0 ; $i < count( $list1 ); $i++ ) {
                        if( $list1[$i][0] != $list2[$i][0]) { 
                                $msg = wfMsg( 'cwikiinclude_modify_html' );
                                $modifyProtect = true; 
                                break;
                        }
                }
 
                if( $modifyProtect ) {
                        global $wgOut;
                        $wgOut->setPageTitle( wfMsg( 'cwikiinclude_forbidden' ) );
                        $wgOut->addWikiText($msg);
                        return false;
                }
        }
        return true;
}
Personal tools