--- EditPage.php.orig 2007-01-26 10:35:36.000000000 -0800 +++ EditPage.php 2007-01-27 14:22:34.000000000 -0800 @@ -171,18 +171,62 @@ /** * This is the function that extracts metadata from the article body on the first view. * To turn the feature on, set $wgUseMetadataEdit = true ; in LocalSettings - * and set $wgMetadataWhitelist to the *full* title of the template whitelist + * and set $wgMetadataWhitelist to the *full* title of the template whitelist. + * $wgMetadataEdit and $wgMetadataWhitelist may also be associative arrays, with one entry + * per namespace */ function extractMetaDataFromArticle () { - global $wgUseMetadataEdit , $wgMetadataWhitelist , $wgLang ; $this->mMetaData = '' ; - if ( !$wgUseMetadataEdit ) return ; - if ( $wgMetadataWhitelist == '' ) return ; + if (! $this->useMetadataEdit()) return ; + if (! count($this->getMetadataWhitelist())) return ; $s = '' ; - $t = $this->getContent(); - # MISSING : filtering + if ($this->section) { + $t = $this->mArticle->getContent(); + } else { + $t = $this->getContent(); + } + + list($t, $s) = $this->extractMetadataFromText($t); + + $this->mArticle->mContent = $t ; + $this->mMetaData = $s ; + } + + /** + * Extract metadata from an arbitrary chunk of text. The title is needed to determine + * the namespace, to figure out which whitelist to use, if this function is not called + * in object context. + */ + function extractMetadataFromText ($t, $title = null) { + global $wgMetadataWhitelist, $wgLang, $wgMetadataSeparator; + + if (! $title && is_object($this)) { + $whitelist = $this->getMetadataWhitelist($title); + } else { + $whitelist = EditPage::getMetadataWhitelist($title); + } + if (count($whitelist) == 0) { + return; + } + + if (! $title && is_object($this)) { + $title = $this->mArticle->getTitle(); + } + + $r = null; + wfRunHooks( 'AlternateMetaDataExtract', array( $t, $title, &$r ) ); + + if ($r) { + return $r; + } + + + $s = '' ; + + # MISSING : filtering + # Categories and language links $t = explode ( "\n" , $t ) ; $catlow = strtolower ( $wgLang->getNsText ( NS_CATEGORY ) ) ; @@ -205,34 +249,15 @@ $x = implode ( ']]' , $y ) ; $t[$key] = $x ; $y = trim ( strtolower ( $x ) ) ; + } else { + $y = implode("]]", $y); } } } - if ( count ( $cat ) ) $s .= implode ( ' ' , $cat ) . "\n" ; - if ( count ( $ll ) ) $s .= implode ( ' ' , $ll ) . "\n" ; + if ( count ( $cat ) ) $s .= implode ( $wgMetadataSeparator , $cat ) . "\n" ; + if ( count ( $ll ) ) $s .= implode ( $wgMetadataSeparator , $ll ) . "\n" ; $t = implode ( "\n" , $t ) ; - # Load whitelist - $sat = array () ; # stand-alone-templates; must be lowercase - $wl_title = Title::newFromText ( $wgMetadataWhitelist ) ; - $wl_article = new Article ( $wl_title ) ; - $wl = explode ( "\n" , $wl_article->getContent() ) ; - foreach ( $wl AS $x ) - { - $isentry = false ; - $x = trim ( $x ) ; - while ( substr ( $x , 0 , 1 ) == '*' ) - { - $isentry = true ; - $x = trim ( substr ( $x , 1 ) ) ; - } - if ( $isentry ) - { - $sat[] = strtolower ( $x ) ; - } - - } - # Templates, but only some $t = explode ( '{{' , $t ) ; $tl = array () ; @@ -244,7 +269,7 @@ $z = $y[0] ; $z = explode ( '|' , $z ) ; $tn = array_shift ( $z ) ; - if ( in_array ( strtolower ( $tn ) , $sat ) ) + if (array_key_exists(strtolower($tn), $whitelist)) { $tl[] = '{{' . $y[0] . '}}' ; $t[$key] = $y[1] ; @@ -255,12 +280,119 @@ else if ( $key != 0 ) $t[$key] = '{{' . $x ; else $t[$key] = $x ; } - if ( count ( $tl ) ) $s .= implode ( ' ' , $tl ) ; + if ( count ( $tl ) ) $s .= implode ( $wgMetadataSeparator, $tl ) ; $t = implode ( '' , $t ) ; + $t = rtrim($t); - $t = str_replace ( "\n\n\n" , "\n" , $t ) ; - $this->mArticle->mContent = $t ; - $this->mMetaData = $s ; + return array($t,$s); + } + + /* + * get the metadata whitelist for this article. The title must be + * specified if this function is called in non-object context + */ + + function getMetadataWhitelist($title = null) { + global $wgMetadataWhitelist; + + if (! $wgMetadataWhitelist) { + return array(); + } + + if (! $title && ! is_object($this)) { + $title = $this->mArticle->getTitle(); + } + + if (is_array($wgMetadataWhitelist)) { + if ($title) { + $ns = $title->getNamespace(); + } else { + $ns = NS_MAIN; + } + if (! array_key_exists($ns, $wgMetadataWhitelist)) { + return array(); + } + $wl_name = $wgMetadataWhitelist[$ns]; + + } else { + $wl_name = $wgMetadataWhitelist; + } + + $wl_title = Title::newFromText ( $wl_name ) ; + $rev = Revision::newFromTitle($wl_title); + if (! $rev) { + return array(); + } + + $whitelist = array(); + + $wl = explode ( "\n" , $rev->getRawText() ); + + foreach ( $wl AS $x ) + { + $isentry = false ; + $isdata = false; + $x = trim ( $x ) ; + while ( (substr ( $x , 0 , 1 ) == '*') || (substr ( $x , 0 , 1 ) == '#') ) + { + if (substr ( $x , 0 , 1 ) == '*') { + $isentry = true ; + } elseif (substr ( $x , 0 , 1 ) == '#') { + $isdata = true; + } + + $x = trim ( substr ( $x , 1 ) ) ; + } + if ( $isentry ) { + $whitelist[$x] = array(); + $last = $x; + } elseif ($isdata) { + $d = preg_split("/\s*=\s*/", $x, 2); + + if (count($d) == 2) { + $key = $d[0]; + $val = $d[1]; + } else { + print "aieeeee!"; + print_r($x); exit; + $key = 'desc'; + $val = $d[0]; + } + + $whitelist[$last][$key] = $val; + } + } + + return $whitelist; + } + + /* + * determine if the metadata functions shoul be used on this article. + */ + + function useMetadataEdit($title = null) { + global $wgUseMetadataEdit; + + if (! $wgUseMetadataEdit) { + return; + } + + if (! is_array($wgUseMetadataEdit)) { + return true; + } + + if (! $title && is_object($this)) { + $title = $this->mArticle->getTitle(); + if ($title) { + $ns = $title->getNamespace(); + } else { + $ns = NS_MAIN; + } + if (array_key_exists($ns, $wgUseMetadataEdit) && $wgUseMetadataEdit[$ns]) { + return true; + } + } + return false; } function submit() { @@ -609,8 +741,19 @@ } # Reintegrate metadata - if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ; - $this->mMetaData = '' ; + + if ($this->useMetadataEdit()) { + if (! $this->section) { + if ( $this->mMetaData != '' ) { + $this->textbox1 .= "\n" . $this->mMetaData ; + } + # extract the new metadata, and drop any non-metadata + # text that was entered in the metadata textbox + $t = $this->extractMetadataFromText($this->textbox1); + $this->textBox1 = join("\n", $t); + $this->mMetaData = '' ; + } + } # Check for spam $matches = array(); @@ -841,6 +984,12 @@ return true; } + # append the metadata if this was a section edit + if ($this->mMetaData != '') { + list($t, $s) = $this->extractMetadataFromText($text); + $text = $t . "\n" . $this->mMetaData; + } + # update the article here if( $this->mArticle->updateArticle( $text, $this->summary, $this->minoredit, $this->watchthis, '', $sectionanchor ) ) { @@ -1106,12 +1255,13 @@ $templates = ($this->preview || $this->section) ? $this->mPreviewTemplates : $this->mArticle->getUsedTemplates(); $formattedtemplates = $sk->formatTemplates( $templates, $this->preview, $this->section != ''); - global $wgUseMetadataEdit ; - if ( $wgUseMetadataEdit ) { + if ($this->useMetadataEdit()) { $metadata = $this->mMetaData ; $metadata = htmlspecialchars( $wgContLang->recodeForEdit( $metadata ) ) ; - $top = wfMsgWikiHtml( 'metadata_help' ); - $metadata = $top . "" ; + if (! wfRunHooks( 'AlternateMetadataEdit', array( &$metadata ) ) ) { + $top = wfMsgWikiHtml( 'metadata_help' ); + $metadata = $top . "" ; + } } else $metadata = "" ; @@ -1787,6 +1937,12 @@ $oldtext = $this->mArticle->fetchContent(); $newtext = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary, $this->edittime ); + + # include metadata if it exists + if (! $section && $this->mMetaData != '') { + $newtext .= "\n" . $this->mMetaData; + } + $newtext = $this->mArticle->preSaveTransform( $newtext ); $oldtitle = wfMsgExt( 'currentrev', array('parseinline') ); $newtitle = wfMsgExt( 'yourtext', array('parseinline') );