Extension:PDF Include

From MediaWiki.org
Jump to navigation Jump to search
MediaWiki extensions manual
OOjs UI icon advanced.svg
PDF Include
Release status: unmaintained
Implementation Tag
Description Allows to include PDF-files on a page from any URL
Author(s)
Latest version 1.4.3 (2017-11-17)
MediaWiki 1.22+
Database changes No
License No license specified
Download See the code section
pdf
Check usage and version matrix.

The PDF Include allows to include PDF-files on a page from any URL.

Installing[edit]

  • Add the following code at the bottom of your LocalSettings.php:
    require_once "$IP/extensions/PDFInclude/PDFInclude.php";
    
  • Yes Done – Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

Usage[edit]

<pdf width="width" height="height">Path</pdf>
<pdf width="800px" height="1000px">http://www.example.com/example.pdf</pdf>

Variables[edit]

Size[edit]

If height and width are not specified, then they default to 800px by 800px. You can change this by setting the settings in your LocalSettings.php:

$wgPDF['width'] = 400;
$wgPDF['height'] = 400;

Blocking domains[edit]

Domain blocking is done by adding a domain to array in $wgPDF[‘black']:

$wgPDF['black'][] = 'example.com';
$wgPDF['black'][] = 'example.net';

Permissions[edit]

To use the PDF tag, users have to be in a group with the “pdf” permission.

$wgGroupPermissions['*']['pdf'] = true;     // Allows anonymous users to add the pdf tag.
$wgGroupPermissions['user']['pdf'] = true;  // Allows any logged in users to add the tag.
$wgGroupPermissions['sysop']['pdf'] = true; // Default — users in the sysop group only.

Changelog[edit]

0.5
The user-right system was added.
1.0
Domain blocking added.
1.1
Rewrite
1.2
  • Updated for current MediaWiki.
  • Better display of errors.
  • Fix handling of case where anonymous users can edit
1.3
  • Implemented whitelist
1.4
  • Allows usage of Template parameters like <pdf>{{{pdflink|}}}</pdf>
1.4.1
  • Allows usage of #page additions like <pdf>somepdf.pdf#20</pdf> which will link to page 20 of this pdf
1.4.2
  • Improves code
1.4.3
  • Fixes recusive tag parsing isuse (macros could not be used for setting pdf), improves error handling for local files with file not found message

Code[edit]

PDFInclude.php
<?php
if (!defined ('MEDIAWIKI')) {
	echo 'This is a MediaWiki-Extension and not meant to be run standalone!';
	exit (1);
}
 
$wgExtensionCredits['parserhook'] [] = array (
	'name'             => 'PDF Include',
	'author'           => array( 'Chrisi200014', '[http://hexmode.com Mark A. Hershberger]','[http://www.bitplan.com Wolfgang Fahl/ProfiWiki]', '...'),
	'url'              => 'https://www.mediawiki.org/wiki/Extension:PDF_Include',
	'description'      => 'Allows to include PDF-files on a page from any URL',
	'version'          => '1.4.3',
	'path'             => __FILE__,
);
 
$wgGroupPermissions['sysop']['pdf'] = true; //To allow the Sysop group to use the pdf-tags
if( !isset($wgPDF['width']) ) {
	$wgPDF['width'] = 800;
}
if( !isset($wgPDF['height']) ) {
	$wgPDF['height'] = 800;
}
if( !isset($wgPDF['black']) ) {
	$wgPDF['black'] = array();
}
if( !isset($wgPDF['white']) ) {
	$wgPDF['white'] = array();
}
 
if(defined('MW_SUPPORTS_PARSERFIRSTCALLINIT')) {
	$wgHooks['ParserFirstCallInit'][] = 'pdfRegister';
} else {
	$wgExtensionFunctions[] = 'pdfRegister';
}
 
function pdfRegister() {
	global $wgParser;
	$wgParser->setHook( 'pdf', 'pdfInclude' );
	return true;
}

/**
 * return a pdfObject with the given data, width and height
 * @param data - the data to convert to an object
 * @param width - the width in pixels
 * @param height - the height in pixels
 */ 
function pdfObject( $data, $width, $height ){
  $html='<object width="'.$width.'" height="'.$height.'" data="'.htmlentities($data).'" type="application/pdf">'."\n";
  $html.='<a href="'.htmlentities($data).'">load PDF</a>'."\n";
  $html.='</object>'."\n";
	return $html;
}

/**
 * return an error with the given message
 * @param msg - the message to show as an error
 */ 
function pdfError( $msg ) {
	return "<span class='error'>PDF tag error: $msg</span>";
}

/**
  * this is the hook to render the <pdf></pdf> tag content
  * @param obj - the content of the tag to be rendered
  * @param argv - the array of arguments to the tag
  * @param parser - the parser
  * @param frame - the parser frame
  */ 
function pdfInclude( $obj, array $argv, Parser $parser, PPFrame $frame ){
	// disable the parser's cache
	$parser->disableCache();
        // grab the uri by parsing to html
	$html = $parser->recursiveTagParse( $obj, $frame );
	// we don't want the html but just the href of the link
	// so reverse some of the parsing again by examining the html 
        // whether it contains an anchor <a href= ...
        if (strpos($html,'<a') !== false) {
        	$a = new SimpleXMLElement($html);
		// is there a href element?
          	if (isset($a['href'])) {
			// that's what we want ...
        		$html=$a['href'];
		}
	}
	global $wgPDF;
	$parser->disableCache();
	$width = ( isset( $argv['width'] ) ) ? $argv['width'] : $wgPDF['width'];
	$height = ( isset( $argv['height'] ) ) ? $argv['height'] : $wgPDF['height'];
	$user = User::newFromName ($parser->getRevisionUser());
 
	if( $user === false ) {
		$allowed = array_flip( User::getGroupPermissions( array( "*" ) ) );
		if( !isset( $allowed['pdf'] ) ) {
			return pdfError( "Permission denied" );
		}
	} else {
		$user->load();
		if(!$user->isAllowed( 'pdf' )) {
			return pdfError( "Permission denied" );
		}
	}
	if( !$html ) {
		return pdfError( "No path given" );
	}
 
	if( !preg_match( '~^\d+~', $width ) ) {
		return pdfError( "Width not valid" );
	} elseif ( !preg_match( '~^\d+~',$height ) ) {
		return pdfError( "Height not valid" );
	}

  # if there are no slashes in the name we assume this
  # might be a pointer to a file 
	if( preg_match( '~^([^\/]+\.pdf)(#[0-9]+)?$~', $html,$re ) ){
    		#re contains the groups
		$filename=$re[1];
		if (count($re)==3) {
 			$page=$re[2];
 		} else {
 			$page="";
 		}
		$image = wfFindFile( $filename );
		if( $image != NULL ) {
			$url=$image->getURL();
			# optional #page suffix
			$url.=$page;
			return pdfObject( $url, $width, $height );
		} else {
			return pdfError( "file ".$filename." not found" );
		}
	}

	// parse the given url 
	$domain = parse_url( $html );
	// check that the parsing worked and retrieve a valid host
	// no relative urls are allowed ...
	if( $domain === false || ( !isset( $domain['host'] ) ) ) {
		$msg="Invalid URL ".$html;
		if ( !isset( $domain['host'] ) )  {
			$msg.=" relative domain not allowed!";
		}
		return pdfError( $msg );
	}

	foreach( $wgPDF['black'] as $x => $y ) {
		$wgPDF['black'][$x] = strtolower( $y );
	}
	foreach( $wgPDF['white'] as $x => $y ) {
		$wgPDF['white'][$x] = strtolower( $y );
	}

	$host= strtolower( $domain['host'] );

	$whitelisted = false;
	if( in_array( $host , $wgPDF['white'] ) ){
		$whitelisted = true;
	}
 
	if ( $wgPDF['white'] != array() && !$whitelisted ){
		return pdfError( "Domain is not allowed" );
	}
 
	if( !$whitelisted ){ 
		if( in_array( $host , $wgPDF['black'] ) ){
			return pdfError( "Domain is blocked" );
		}
	}

  # check that url is valid 
	if( filter_var( $html, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED ) ) {
    		$html=pdfObject( $html, $width, $height );
		return $html; 
	} else {
		return pdfError( "Path is not valid" );
	}
}

See also[edit]