Jump to content
MediaWiki

User:Zayoo/Extension:Advanced Meta Code

From mediawiki.org

***THIS PAGE IS NO LONGER VALID***

Changes has been updated to Extension:Advanced Meta and this page no longer updates.

Code

[edit ]
<?php
/* SQL to create required table:
CREATE TABLE IF NOT EXISTS `mw_ext_meta` ( -- replace "mw" with your prefix
 `pageid` int(8) NOT NULL,
 `rindex` tinyint(1) NOT NULL,
 `rfollow` tinyint(1) NOT NULL,
 `titlealias` varchar(255),
 `keywords` varchar(500),
 `description` varchar(2000),
 PRIMARY KEY (`pageid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 */
/**
 * MediaWiki Advanced Meta extension
 * Add meta data to individual pages or entire namespaces
 * @version 1.4.0
 * @author Stephan Muller <mail@litso.com> (Main author)
 * @author Bart van Heukelom <b@rtvh.nl> (Objectification)
 * @author Zayoo <zayoo@126.com> (Revise & TitleAlias, refer to Extension:Add HTML Meta and Title & Extension:TitleAlias)
 */
$wgExtensionCredits['parserhook'][] = array(
 'name' => 'Advanced Meta',
 'author' => 'Stephan Muller, Bart van Heukelom, Zayoo',
 'descriptionmsg' => 'ameta-desc',
 'url' => 'http://www.mediawiki.org/wiki/Extension:Advanced_Meta',
 'version' => '1.4.0'
 );
$wgExtensionMessagesFiles['Advanced Meta'] = dirname(__FILE__) . '/MWAdvancedMeta.i18n.php';
MWAdvancedMeta::setup();
class MWAdvancedMeta {
 private static $instance = null;
 /**
 * Initialise the advanced meta plugin.
 * @return MWAdvancedMeta the plugin object, which you can use to set settings.
 */
 public static function setup() {
 // check for wiki
 if (!defined('MEDIAWIKI')) {
 throw new Exception('This is an extension to the MediaWiki software and cannot be used standalone.');
 }
 // create plugin
 if (self::$instance === null) {
 self::$instance = new self();
 }
 return self::$instance;
 }
 private $indexedPages = array(NS_MAIN, NS_PROJECT);
 private $globalKeywords = array();
 private $allowedUsers = array();
 private $allowedUsergroups = array('sysop', 'bureaucrat');
 private $savedMeta = null;
 public function __construct() {
 /*********
 * Hooks *
 *********/
 global $wgHooks;
 //Inserts HTML for meta input fields into the edit page.
 $wgHooks['ParserBeforeTidy'][] = $this;
 //Before the updated text and properties of an article are saved to the database
 //the new meta info is saved too
 $wgHooks['ArticleSave'][] = $this; 
 //If a new article is created the meta is temporarily saved as article ID '0'
 //Move it to the newly created article now
 $wgHooks['ArticleInsertComplete'][] = $this;
 //Insert meta into article
 $wgHooks['OutputPageBeforeHTML'][] = $this;
 //Title Alias
 $wgHooks['BeforePageDisplay'][] = $this;
 }
 /**
 * All namespaces get a robots setting of "noindex, nofollow" by default.
 * Use this method to specify namespaces with interesting content, pages in which should be indexed.
 * Default is NS_MAIN and NS_PROJECT.
 * @param $indexedPages Array of namespace names.
 */
 public function setIndexedPages(array $indexedPages) {
 $this->indexedPages = $indexedPages;
 }
 /**
 * Specify keywords that should be added to every page.
 * @param $keywords The keywords in an array.
 */
 public function setGlobalKeywords($keywords) {
 $this->globalKeywords = $keywords;
 }
 /**
 * SEO can be a delicate issue. Define here who is allowed to edit the meta tags
 * allow users individually, by username. Warning: Case sensitive!
 */
 public function setAllowedUsers($users) {
 $this->allowedUsers = $users;
 }
 /**
 * allow users by mediawiki's own usergroups
 * or the special groups 'loggedin' and 'all' ('all' allowing even anonymous edits)
 */
 public function setAllowedUsergroups($usergroups) {
 $this->allowedUsergroups = $usergroups;
 }
 /*********
 * Hooks *
 *********/
 /**
 * Hook 1: in /includes/parser/Parser.php
 * Loops through the different sections of the page being parsed
 * and adds html for the meta input forms into the article edit pages
 *
 * @param object $parser The parser object
 * @param string $text
 *
 * @global indexedpages defined in the global config section above
 * @global alloweusers defined in the global config section above
 *
 * @return true
 *
 */
 public function onParserBeforeTidy(&$parser, &$text) {
 $fname = 'MWAdvancedMeta::onParserBeforeTidy';
 global $wgTitle, $wgUser, $wgRequest;
 // only run this hook for edit forms
 if(!$wgRequest->getVal('action') == ('edit' || 'submit')) return false;
 // can this user edit meta for this page?
 if(!$this->canEditMeta()) return false;
 // handle submit (preview)
 if ($wgRequest->wasPosted()) {
 // it's probably a preview, so show the newly submitted meta too, otherwise we'll lose 'em
 $meta = array(
 'rindex' => (isset($_POST['wpIndex'])) ? '1' : '0',
 'rfollow' => (isset($_POST['wpFollow'])) ? '1' : '0',
 'titlealias' => $_POST['wpTitleAlias'],
 'keywords' => $_POST['wpKeywords'],
 'description' => $_POST['wpDescription']
 );
 } else {
 // else just get the meta from the db
 $meta = $this->getMetaByArticleID($wgTitle->getArticleID());
 // no meta or creating a new article? make default values
 if(empty($meta) || $wgTitle->getArticleID() == '0') {
 $meta = array(
 'rindex' => '1',
 'rfollow' => '1',
 'titlealias' => '',
 'keywords' => '',
 'description' => ''
 );
 }
 }
 // prepare checkboxes
 $checkindex = ($meta['rindex'] == '1') ? 'checked="checked"' : '' ;
 $checkfollow = ($meta['rfollow'] == '1') ? 'checked="checked"' : '' ;
 // some mediawiki preference variables
 $cols = $wgUser->getIntOption('cols');
 $ew = $wgUser->getOption('editwidth');
 $hidden = ""; //don't know when this is exactly used. If I find out, I'll do something with it :)
 /*$addedkeywords =
 count($this->globalKeywords) == 0
  ? '(none)'
  : implode(', ', $this->globalKeywords);
 */
 $addedkeywords = wfMsg( 'globalkeywords' )=='&lt;globalkeywords&gt;' ? '(none)' : wfMsg( 'globalkeywords' );
 // define replacements
 $replaceFrom[] = '<div id="editpage-copywarn">';
 $replaceWith[] =
 "<h2>" . wfMsg( 'ameta-metasettings' ) . "</h2>
 <strong>Robots:</strong>
 <label><input tabindex='2' id='wpIndex' type='checkbox' name='wpIndex' value='1' {$checkindex} accesskey='/'>
 Index</label>
 <label><input tabindex='3' id='wpFollow' type='checkbox' name='wpFollow' value='1' {$checkfollow} >
 Follow</label>
 <br /><strong>" . wfMsg( 'ameta-titlealias' ) . "</strong><br />
 <input type='text' name='wpTitleAlias' id='wpTitleAlias' value='{$meta['titlealias']}' size='64'>
 <br /><strong>Keywords:</strong> <small>" . wfMsg( 'ameta-keywordsadd' ) . "<a href='javascript:;' title='" . wfMsg( 'ameta-keywordsmodify' ) . "'>" . htmlspecialchars(str_replace("1ドル",$wgTitle,$addedkeywords))."</a>
 </small><br />
 <textarea tabindex='4' name='wpKeywords' id='wpKeywords' rows='1'
 cols='{$cols}'{$ew}{$hidden}>{$meta['keywords']}</textarea>
 <br /><strong>Description:</strong><br />
 <textarea tabindex='4' name='wpDescription' id='wpDescription' rows='2'
 cols='{$cols}'{$ew}{$hidden}>{$meta['description']}</textarea>
 <div id=\"editpage-copywarn\">";
 // apply replacements
 $text = str_replace($replaceFrom, $replaceWith, $text);
 return true;
 }
 /**
 * Hook 2: Called during function doEdit() in /includes/Article.php
 * Adds the new meta information to the database when an article is saved
 *
 * @param object $article The entire article and it's properties
 * @param object $user The user updating the article
 * @return true
 *
 * @global indexedpages, array of namespaces that should be indexed
 *
 */
 public function onArticleSave(&$article, &$user) {
 $fname = 'MWAdvancedMeta::onArticleSave';
 $id = $article->mTitle->getArticleID();
 //can this user edit meta for this page?
 if (!$this->canEditMeta()) return true; //return false gives edit conflicts
 // get meta from the posted forms
 $metaData = array(
 'rindex' => isset($_POST['wpIndex']) ? '1' : '0',
 'rfollow' => isset($_POST['wpFollow']) ? '1' : '0',
 'titlealias' => htmlspecialchars($_POST['wpTitleAlias']),
 'keywords' => htmlspecialchars($_POST['wpKeywords']),
 'description' => htmlspecialchars($_POST['wpDescription'])
 );
 if ($id == 0) {
 // if this is an insert, we need to store the meta until we know the page id
 $this->savedMeta = $metaData;
 } else {
 // write new metadata to the database
 $this->writeMeta($id, $metaData);
 }
 // empty cache for the page
 $dbw = wfGetDB( DB_MASTER );
 $timestamp = $dbw->timestamp();
 $dbw->update( 'page',
 array( 'page_touched' => $timestamp ),
 array(
 'page_id' => $id ),
 $fname );
 return true;
 }
 /**
 * Hook 3: Called during function doEdit() in /includes/Article.php
 * Move the new meta information from a temporary id='0' to the new article's id
 *
 * @param object $article: the article (object) saved
 * @param object $user: the user (object) who saved the article
 * @param string $text: the new article content
 * @param string $summary: the article summary (comment)
 * @param bool $minoredit: minor edit flag
 * @param bool $watchthis: not used as of 1.8 (automatically set to "null")
 * @param bool $sectionanchor: not used as of 1.8 (automatically set to "null")
 * @param unknown $flags: bitfield, see source code for details; passed to Article::doedit()
 * @param object $revision: The newly inserted revision object (as of 1.11.0)
 * @return true
 *
 * @global indexedpages, array of namespaces that should be indexed
 *
 */
 function onArticleInsertComplete(&$article, &$user, $text, $summary, $minoredit,
 $watchthis, $sectionanchor, &$flags, $revision) {
 $fname = 'MWAdvancedMeta::onArticleInsertComplete';
 // if we have saved metadata, insert it
 if($this->savedMeta !== null) {
 // write new metadata to the database
 $this->writeMeta($article->getID(), $this->savedMeta);
 $this->savedMeta = null;
 }
 return true;
 }
 /**
 * Hook 4: Called during function view() in /includes/OutputPage.php
 * Adds the proper meta tags to the article when a page is viewed
 *
 * @param object $out The outputted page
 * @param string $text The file description
 * @return true
 */
 function onOutputPageBeforeHTML(&$out, &$text) {
 global $wgTitle;
 $fname = 'MWAdvancedMeta::onOutputPageBeforeHTML';
 $addedkeywords = wfMsg( 'globalkeywords' )=='&lt;globalkeywords&gt;' ? '' : wfMsg( 'globalkeywords' , $wgTitle);
 // pages that aren't in the array indexedpages won't be indexed, but links will be followed
 if (!in_array($wgTitle->getnamespace(), $this->indexedPages)) {
 $out->setRobotPolicy('noindex, follow');
 } else {
 $out->setRobotPolicy('index, follow');
 }
 // for indexed namespaces, get the info from the db
 $meta = $this->getMetaByArticleID($wgTitle->getArticleID());
 // nothing in db? use global keywords other than exit now
 if (empty($meta)) {
 $out->mKeywords = array_merge(explode(',',$addedkeywords), $out->mKeywords); //Global keywords should be shown even no meta data
 return false;
 }
 // set the keywords
 // only overwrite keywords if any were provided (else the ones generated by mediawiki are used)
 if (!empty($meta['keywords'])) {
 $out->mKeywords = array_merge(explode(',',$addedkeywords), explode(',', $meta['keywords']));
 } else {
 $out->mKeywords = array_merge(explode(',',$addedkeywords), $out->mKeywords);
 }
 // set the description
 if(!empty($meta['description']))
 $out->addMeta("description", $meta['description']);
 // set robots information
 $index = ($meta['rindex'] == '1') ? 'index' : 'noindex';
 $follow = ($meta['rfollow'] == '1') ? 'follow' : 'nofollow';
 $out->setRobotPolicy($index.', '.$follow);
 return true;
 }
 /**
 * Hook 5: Called during function output() in /includes/OutputPage.php
 * Allows last minute changes to the output page, e.g. adding of CSS or Javascript by extensions
 *
 * @param object $out The OutputPage object
 * @param string $sk Skin object that will be used to generate the page
 * @return true
 */
 function onBeforePageDisplay(&$out, &$text) {
 
 global $wgTitle;
 $fname = 'MWAdvancedMeta::onBeforePageDisplay';
 $meta = $this->getMetaByArticleID($wgTitle->getArticleID());
 if (empty($meta)) return true;
 if (!empty($meta['titlealias']))
 $out->mHTMLtitle=wfMsg( 'pagetitle', $meta['titlealias'] );
 return true;
 }
 /*************
 * Functions *
 *************/
 private function getMetaByArticleID($id) {
 $fname = 'MWAdvancedMeta::getMetaByArticleID';
 // get metadata from database
 $dbr = wfGetDB( DB_MASTER );
 $data = $dbr->select( 'ext_meta',
 array( 'rindex', 'rfollow', 'titlealias', 'keywords', 'description' ),
 array( 'pageid' => $id ),
 $fname
 );
 $meta = $dbr->fetchRow( $data );
 $dbr->freeResult($data);
 return $meta;
 }
 private function writeMeta($id, $metaData) {
 $fname = 'MWAdvancedMeta::writeMeta';
 $dbw = wfGetDB( DB_MASTER );
 if($metaData['rindex']=='1'&&$metaData['rfollow']=='1'&&empty($metaData['titlealias'])&&empty($metaData['keywords'])&&empty($metaData['description']))
 {
 $dbw->delete( 'ext_meta', array( 'pageid' => $id ), __METHOD__ ); //delete meta with normal robot policies and without titlealias, keywords & description to save space
 } else {
 $dbw->replace(
 'ext_meta',
 array( 'pageid' => $id),
 array_merge($metaData, array('pageid' => $id)),
 $fname
 );
 }
 }
 private function canEditMeta() {
 global $wgUser, $wgTitle;
 $fname = 'MWAdvancedMeta::canEditMeta';
 $ns = $wgTitle->getNamespace();
 // redirect pages don't need metadata
 // TODO: make work in MediaWiki < 1.13
 // if ($wgTitle->isRedirect()) {
 // return false;
 // }
 // does the user have permission?
 return (in_array($wgUser->getName(), $this->allowedUsers)
 || in_array('all', $this->allowedUsergroups)
 || (in_array('loggedin', $this->allowedUsergroups) && $wgUser->isLoggedIn())
 || count(array_intersect($wgUser->getGroups(), $this->allowedUsergroups)) !== 0
 );
 }
}

AltStyle によって変換されたページ (->オリジナル) /