From OrganicDesign Wiki
<?php
# Extension:UploadCSV
# - See http://www.mediawiki.org/wiki/Extension:UploadCSV for installation and usage details
# - Author: Gunter Schmidt (http://www.mediawiki.org/wiki/User:GunterS)
if ( !defined( 'MEDIAWIKI' ) ) {
?>
<p>This is an MediaWiki-extension. To enable it, put </p>
<pre>require_once("$IP/extensions/UploadCSV/UploadCSV.php");</pre>
<p>near the bottom of your LocalSettings.php</p>
<?php
exit(1);
}
$Ext_Version = '0.2.3'; // Mar. 27, 2007
$wgExtensionFunctions[] = "wfUploadCSVStart";
$wgExtensionCredits['specialpage'][] = array(
'name' => 'Special:UploadCSV',
'description' => 'Mass creation of articles from a csv-file.',
'url' => 'http://www.mediawiki.org/wiki/Extension:UploadCSV',
'author' => 'Gunter Schmidt',
'version' => $Ext_Version
);
/* ToDo
- smart edit of existing articles, only replace template
- multiple templates on a page (maybe template given on the dataline, will need a template key)
- translation
- documentation
*/
require_once "$IP/includes/SpecialPage.php";
# Internationalisation file
require_once( dirname( __FILE__ ) . '/UploadCSV.i18n.php' );
function wfUploadCSVStart() {
global $wgMessageCache, $ExtensionTitles;
// Load messages, so we have a title in Special:SpecialPages
UploadCSVPage::loadTitles();
SpecialPage::addPage(new UploadCSVPage());
}
class UploadCSVPage extends SpecialPage {
public $Specialpage_Name='UploadCSV', $MsgPrefix; //keep this within the class or it will mess with other extensions!
public $curRow;
function UploadCSVPage() {
SpecialPage::SpecialPage($this->Specialpage_Name);
$this->MsgPrefix = strtolower($this->Specialpage_Name) . '_';
}
function execute( $par ) {
global $wgRequest, $wgOut, $wgUser, $csvInfo, $wgUploadDirectory;
$MsgPrefix = $this->MsgPrefix;
//Debug info
$hidden = "text"; // hidden or text
self::loadMessages();
$this->setHeaders();
#$wgOut->setPagetitle("Gunters Extension"); // only necessary if you do want a different title than in the Special:Specialpages list
$wgOut->addHTML( wfMsg( $MsgPrefix . 'intro' ) );
// Set form variables
$template = $wgRequest->getText('wpTemplate');
if (empty($template)) $template = "SAP-Jobstep"; #else $template = "ok";
# Put all templates into a select list
$templates = '';
$db =& wfGetDB(DB_SLAVE);
$pagetable = $db->tableName('page');
$ns = NS_TEMPLATE;
$result = $db->query("SELECT page_id FROM $pagetable WHERE page_namespace=$ns ORDER BY page_title");
while ($row = mysql_fetch_array($result)) {
$t = Title::newFromID($row[0])->getPrefixedText();
$selected = $t == $template ? ' selected' : '';
$templates .= "<option value='$t'$selected>$t</option>\n";
}
$UploadFile = $wgRequest->getText('wpUploadFile');
$curInfo = $wgRequest->getText('wpcurInfo');
$curAction = $wgRequest->getText('wpcurAction');
if (empty($curAction)) $curAction = 'start';
$this->curRow = $wgRequest->getText('wpcurRow');
if (empty($this->curRow)) $this->curRow = 1;
$endRow = $wgRequest->getText('wpendRow');
if (empty($endRow) || !is_numeric($endRow)) $endRow = 0;
# Allow separator character to be specified in form and allow escaping in content, eg \;
$separator = $wgRequest->getText('wpSeparator');
if (empty($separator)) $separator = ';';
$esc = $separator == '|' ? '\\' : '';
$sepPattern = "/(?<!\\\\)$esc$separator/";
# If file has only just been uploaded, move it to a permenant location
# - the files are currently not deleted
if ($curAction != 'start') $curUploadFile = $wgRequest->getText('wpcurUploadFile');
elseif ($tmp = $wgRequest->getFileTempname('wpUploadFile')) {
if (is_uploaded_file($tmp)) {
$curUploadFile = "$wgUploadDirectory/".basename($tmp);
if (move_uploaded_file($tmp,$curUploadFile) === false) $errormsg = 'Failed to move tmp file!';
}
else $errormsg = 'Invalid upload file!';
}
else $curUploadFile = '';
$UploadFile = $curUploadFile;
// build form
$wgOut->addHTML("<form name=\"userForm\" action=\"$this->action\" method=\"post\" enctype=\"multipart/form-data\"><br />" .
"<table style=\"text-align: left;\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">
<tbody>
<tr>
<td align='right'><b>" . wfMsg( 'nstab-template' ) . ":</b></td>
<td><select name='wpTemplate'>$templates</select>
<b>" . wfMsg( $MsgPrefix . 'separator' ) . ":</b> " .
wfElement( 'input', array(
'type' => 'text',
'name' => 'wpSeparator',
'size' => '1',
'value' => $separator
)) .
"</td>
</tr>
<tr>
<td align='right'><b>" . wfMsg( 'sourcefilename' ) . ":</b></td>
<td>" .
wfElement( 'input', array(
'type' => 'file',
'name' => 'wpUploadFile',
'size' => '70',
'maxlength' => '150',
'value' => $UploadFile,
'onchange' => "this.form.wpcurUploadFile.value = this.form.wpUploadFile.value"
)) .
"</td>
</tr>
<tr>
<td align='right'><b>" . wfMsg( $MsgPrefix . 'startline' ) . ":</b></td>
<td>" .
wfElement( 'input', array(
'type' => 'text',
'name' => 'wpcurRow',
'size' => '5',
'value' => $this->curRow
)) .
"</td>
</tr>
<tr>
<td align='right'><b>" . wfMsg( $MsgPrefix . 'endline' ) . ":</b></td>
<td>" .
wfElement( 'input', array(
'type' => 'text',
'name' => 'wpendRow',
'size' => '5',
'value' => $endRow
)) .
"</td>
</tr>
<tr>
<td align='right'><b>" . wfMsg( $MsgPrefix . 'status' ) . ":</b></td>
<td>" .
wfElement( 'input', array(
'type' => 'text',
'name' => 'wpcurAction',
'size' => '20',
'readonly' => 'readonly',
'value' => $curAction
)) .
"</td>
</tr>
<tr>
<td/>
<td>" .
wfElement( 'input', array(
'type' => 'submit',
'name' => 'create',
'value' => wfMsgHtml( 'uploadbtn' )
)) .
// hidden elements
wfElement( 'input', array(
'type' => "$hidden",
'name' => 'wpcurUploadFile',
'size' => '20',
'maxlength' => '150',
'value' => $curUploadFile
)) .
wfElement( 'input', array(
'type' => "$hidden",
'name' => 'wpcurInfo',
'size' => '20',
'value' => $curInfo
)) .
"</td>
</tr>
</tbody>
</table>
</form>\n"
);
// do the works
// if ($this->curRow > 1)
// $wgOut->addHTML("<b>Finished uploading data for article no. " . ($this->curRow + 1) . ".</b>");
// $wgOut->AddHTML ('<script type="text/javascript">
// var jscount = document.userForm.wpcurRow.value;
// document.write("<b>Uploading data for article no2. " +
// jscount +
// ".Ende</b>");
// </script>');
unset($errormsg);
$editAllowed = $wgUser->isAllowed('edit');
if ($editAllowed) {
if ($handle = fopen($UploadFile, "r")) {
// search for pagetitle
$headerline = fgets($handle);
$headers = preg_split($sepPattern,trim($headerline));
unset ($colPageTitle);
foreach ($headers as $key => $header) {
$headers[$key] = trim($header);
if ( stripos($header, "pagetitle") === 0 ) $colPageTitle = $key;
}
// Loop through the each line of the file if we have a pagetitle column
if (isset($colPageTitle)) {
$cRow = 0;
$sRow = $this->curRow;
if (!is_numeric($this->curRow)) $this->curRow = 0;
while ($dataline = fgets($handle)) {
$cRow += 1;
// Process the line if it's not before the start-line
if ($cRow >= $this->curRow) {
$this->curRow = $cRow;
$data = preg_split($sepPattern,trim($dataline));
$curInfo += 1;
if (is_array($data)) {
$pageTitle = trim($data[$colPageTitle]);
if (!empty($pageTitle)) {
$ret = $this->MakeArticle($pageTitle, $template, $headers, $data);
if ($ret !== true)
$wgOut->AddWikiText("Error creating article: $ret");
}
}
}
// check, if we are through
if (feof($handle) || ($this->curRow >= $endRow && $endRow > 0)) {
$wgOut->addHTML('<script type="text/javascript">
if (document.userForm.wpcurAction.value == "start") {
document.userForm.wpcurInfo.value = 1; }
else { document.userForm.wpcurInfo.value = ' . $curInfo . '}
document.userForm.wpcurAction.value = "running";
document.userForm.wpcurUploadFile.value = "' . addslashes($UploadFile) . '";
document.userForm.wpcurRow.value = "' . ($this->curRow+1) . '";
document.userForm.wpendRow.value = "' . (2*$this->curRow-$sRow+1) . '";
</script>');
unset($UploadFile);
$bolFinished = true;
$this->curRow = 0;
break;
}
}
}
else $errormsg = "One column needs to be defined as \"pagetitle\".";
fclose ($handle);
}
elseif ($UploadFile) $errormsg = "Couldn't open file.";
}
else $errormsg = "Not allowed to edit. Please log in first.";
if (isset($errormsg)) $wgOut->AddWikiText("'''Error: $errormsg'''");
// Output
$output = "<br />" . wfMsg( $MsgPrefix . 'lastmessage' );
#$wgOut->addHTML( $output );
//automatically repeat function until upload is finished
if (0 && $this->curRow > 1 && !empty($UploadFile)) {
#echo "<br>c: $this->curRow";
#sleep (2);
$wgOut->addHTML('<script type="text/javascript">
document.userForm.submit();
</script>');
}
elseif ($bolFinished)
$txt = wfMsg( $MsgPrefix . 'finished' );
$txt = ereg_replace('\$1', utf8_encode($curInfo), $txt);
$wgOut->addHTML("<br /><b>$txt</b>");
}
function MakeArticle($pageTitle, $templateName, $tvars, $data, $summary='') {
global $wgOut;
// $pageTitle: Article name
// $templateName: Full name of template, including Template:
// $tvars: array of template variables
// $tvarCol: array of column numbers corresponding to $tvars
// $data: array of data
// $summary: article change summary information
$MsgPrefix = $this->MsgPrefix;
$summary .= " (auto upload csv)";
$summary = trim($summary);
// get template title without "template:"
if (preg_match("/:(.*)/", $templateName, $ret ) ) {
$templateTitle = $ret[1];
#print "<br>$templateTitle";
}
else $templateTitle = $templateName;
//create content
$content = '{{' . "$templateTitle\r\n";
//nice output format
$maxlen = 0;
foreach ( $tvars as $tvar ) {
if ( mb_strlen ($tvar) > $maxlen ) $maxlen = mb_strlen ($tvar);
}
//populate vars
foreach ( $tvars as $key => $tvar ) {
$space = str_repeat(" ", $maxlen - mb_strlen($tvar));
$content .= "|$tvar$space = " . utf8_encode($data[$key]) . "\r\n";
}
$content .= '}}' . "\r\n";# . time() . "\r\n";
#print "$content";
//create article
$titleNew = title::newFromText(htmlentities($pageTitle));
$articleNew = new Article( $titleNew );
if( $titleNew->getArticleID() == 0 ) {
$mode = EDIT_NEW;
$ctext = 'created';
}
else {
$mode = EDIT_UPDATE;
$ctext = 'changed';
// smart edit, only replace template
$t = explode('{{', $articleNew->getContent()); //all template starts
echo "<br>";
#print_r ($t); echo "<br>";
if (count($t) > 1) {
//find our template, for now expect only one
$start = true;
$tc = '';
foreach ( $t AS $key => $x )
{
$xl = ltrim($x);
if (stripos($xl, $templateTitle)=== 0 ) {
// $foundkey = $key;
// now we need the end, but there might be templates within the template or following templates
$start = false;
$te = explode('}}', $x);
#print_r($te); echo "<br>";
if ( count($te) == 2 ) { //no included templates, if there are, count = 1
$tc .= substr($content,2) . $te[1];
}
else $tc .= implode('', $te);
// foreach ( $te as $key2 => $y ) {
// }
}
else $tc .= $x . '{{'; // rebuild content
}
$content = $tc;
// $y = explode ( '}}' , $x , 2 ) ;
// echo "<br>";
// print_r ($y);
// if ( count ( $y ) == 2 )
// {
// $z = $y[0] ;
// $z = explode ( '|' , $z ) ;
// $tn = array_shift ( $z ) ;
// $t[$key] = '{{' . $x ;
// }
// else if ( $key != 0 ) $t[$key] = '{{' . $x ;
// else $t[$key] = $x ;
}
else $content = implode('', $t) . $content; //no template found, so we add to the end
#if (count($t) == 2) { //simple, only one template
// $content_old = $articleNew->getContent();
// $reg = '/([[:Template:' . $templateTitle . '.*?]])/';
// $reg = '/.*?(' . $templateTitle . '.*?)B/';
// $reg = '/Sofort([^}]*})/';
// echo "<br>";
// if (preg_match($reg, $content_old, $regs))
// print_r ($regs);
// else print "Fehler<br>$content_old<br>$reg";
}
// create/update article
$createSuccess = $articleNew->doEdit( $content, $summary, $mode ); #| EDIT_FORCE_BOT
//sleep (2); // wait between mass creation
if ($createSuccess) {
$cr = $this->curRow;
$txt = wfMsg( $MsgPrefix . $ctext );
$txt = ereg_replace('\$1', utf8_encode($cr), $txt);
$txt = ereg_replace('\$2', utf8_encode($pageTitle), $txt);
$wgOut->addHTML("<p>$txt</p>");
return true;
}
}
function LoadTemplate($templateName='') {
global $namespaceNames, $wgOut;
//accept only templates, with or without "template:"
// echo "<br>Temp: " . Namespace::getCanonicalName(NS_TEMPLATE) . ", " . NS_TEMPLATE ;
// $tName = str_replace($namespaceNames[NS_TEMPLATE] . ':', '', $templateName);
// $tName = $namespaceNames[NS_TEMPLATE] . ':' . $tName;
// if ($tName <> $templateName)
// $wgOut->addHTML('<script type="text/javascript">
// document.userForm.wpTemplate.value = "' . $tName . '";
// </script>');
#print "Template: $templateName";
$title = title::newFromText($templateName);
$pageID = $title->getArticleID();
//Maybe the string template: was not given
if ($pageID == 0) {
$title = title::newFromText($templateName, NS_TEMPLATE);
$pageID = $title->getArticleID();
}
if ($pageID) {
#print "page: $pageID";
$article = new Article( $title );
$text = $article->getContent();
$reg = '/{{{(.+?)}}}/';
$varExist = preg_match_all($reg, $text, $tvars, PREG_PATTERN_ORDER);
#print_r ($tvars);
if ($varExist) {
// Variables may be used multiple times in an template, we need to delete all double entries.
$ret = array_unique($tvars[1]);
return $ret; //return array of template vars; does not check on <nowiki>
}
else return "novars";
}
else return "notemplate";
}
function loadMessages() {
self::loadMessagesS( 'messages' );
}
function loadTitles() {
self::loadMessagesS( 'titles' );
}
function loadMessagesS( $MsgType ) {
// using a function to save some memory instead of a global for the messages
global $wgMessageCache;
$Specialpage_Name='UploadCSV'; //needs to be defined here, because it is not always called in an object context
$extensionName = strtolower($Specialpage_Name);
//Need to change the function name accordingly
$Messages = SpecialUploadCSV_Messages( $MsgType, $Specialpage_Name );
if ( count ($Messages) == 0 ) return;
foreach ( $Messages as $lang => $langMessages ) {
foreach ( $langMessages as $key => $langMessage )
$wgMessageCache->addMessage( $key, utf8_encode( $langMessage ), $lang);
}
return;
}
}
?>