$user: user who performed the undeletion
$reason: reason
+'FormatAutocomments': When an autocomment is formatted by the Linker
+ &$comment: Reference to the accumulated comment. Initially null, when set the default code will be skipped.
+ $pre: Initial part of the parsed comment before the call to the hook.
+ $auto: The extracted part of the parsed comment before the call to the hook.
+ $post: The final part of the parsed comment before the call to the hook.
+ $title: An optional title object used to links to sections. Can be null.
+ $local: Boolean indicating whether section links should refer to local page.
+
'GetAutoPromoteGroups': When determining which autopromote groups a user
is entitled to be in.
&$user: user to promote.
}
}
- return $this->confirmDelete( $reason );
+ $this->confirmDelete( $reason );
}
/**
'MySQLMasterPos' => 'includes/db/DatabaseMysql.php',
'ORAField' => 'includes/db/DatabaseOracle.php',
'ORAResult' => 'includes/db/DatabaseOracle.php',
+ 'ORMIterator' => 'includes/db/ORMIterator',
'ORMResult' => 'includes/db/ORMResult.php',
'ORMRow' => 'includes/db/ORMRow.php',
'ORMTable' => 'includes/db/ORMTable.php',
'</div>';
return true;
}
- return false;
}
/**
* @param $msg String message key
*/
public function setSubmitTextMsg( $msg ) {
- return $this->setSubmitText( $this->msg( $msg )->text() );
+ $this->setSubmitText( $this->msg( $msg )->text() );
}
/**
* @param $msg String message key
*/
public function setWrapperLegendMsg( $msg ) {
- return $this->setWrapperLegend( $this->msg( $msg )->escaped() );
+ $this->setWrapperLegend( $this->msg( $msg )->escaped() );
}
/**
$pre = $match[1];
$auto = $match[2];
$post = $match[3];
- $link = '';
- if ( $title ) {
- $section = $auto;
-
- # Remove links that a user may have manually put in the autosummary
- # This could be improved by copying as much of Parser::stripSectionName as desired.
- $section = str_replace( '[[:', '', $section );
- $section = str_replace( '[[', '', $section );
- $section = str_replace( ']]', '', $section );
-
- $section = Sanitizer::normalizeSectionNameWhitespace( $section ); # bug 22784
- if ( $local ) {
- $sectionTitle = Title::newFromText( '#' . $section );
- } else {
- $sectionTitle = Title::makeTitleSafe( $title->getNamespace(),
- $title->getDBkey(), $section );
+ $comment = null;
+ wfRunHooks( 'FormatAutocomments', array( &$comment, $pre, $auto, $post, $title, $local ) );
+ if ( $comment === null ) {
+ $link = '';
+ if ( $title ) {
+ $section = $auto;
+
+ # Remove links that a user may have manually put in the autosummary
+ # This could be improved by copying as much of Parser::stripSectionName as desired.
+ $section = str_replace( '[[:', '', $section );
+ $section = str_replace( '[[', '', $section );
+ $section = str_replace( ']]', '', $section );
+
+ $section = Sanitizer::normalizeSectionNameWhitespace( $section ); # bug 22784
+ if ( $local ) {
+ $sectionTitle = Title::newFromText( '#' . $section );
+ } else {
+ $sectionTitle = Title::makeTitleSafe( $title->getNamespace(),
+ $title->getDBkey(), $section );
+ }
+ if ( $sectionTitle ) {
+ $link = self::link( $sectionTitle,
+ $wgLang->getArrow(), array(), array(),
+ 'noclasses' );
+ } else {
+ $link = '';
+ }
}
- if ( $sectionTitle ) {
- $link = self::link( $sectionTitle,
- $wgLang->getArrow(), array(), array(),
- 'noclasses' );
- } else {
- $link = '';
+ if ( $pre ) {
+ # written summary $presep autocomment (summary /* section */)
+ $pre .= wfMsgExt( 'autocomment-prefix', array( 'escapenoentities', 'content' ) );
}
+ if ( $post ) {
+ # autocomment $postsep written summary (/* section */ summary)
+ $auto .= wfMsgExt( 'colon-separator', array( 'escapenoentities', 'content' ) );
+ }
+ $auto = '<span class="autocomment">' . $auto . '</span>';
+ $comment = $pre . $link . $wgLang->getDirMark() . '<span dir="auto">' . $auto . $post . '</span>';
}
- if ( $pre ) {
- # written summary $presep autocomment (summary /* section */)
- $pre .= wfMsgExt( 'autocomment-prefix', array( 'escapenoentities', 'content' ) );
- }
- if ( $post ) {
- # autocomment $postsep written summary (/* section */ summary)
- $auto .= wfMsgExt( 'colon-separator', array( 'escapenoentities', 'content' ) );
- }
- $auto = '<span class="autocomment">' . $auto . '</span>';
- $comment = $pre . $link . $wgLang->getDirMark() . '<span dir="auto">' . $auto . $post . '</span>';
return $comment;
}
/**
* @param $type string
* @param $sign string ('+' or '-')
- * @return void
+ * @return string
*/
private function getTypeCacheKey( $type, $sign ) {
return wfMemcKey( 'sitestatsupdate', 'pendingdelta', $type, $sign );
/**
* Reduce pending delta counters after updates have been applied
- * @param Array Result of getPendingDeltas(), used for DB update
+ * @param Array $pd Result of getPendingDeltas(), used for DB update
* @return void
*/
protected function removePendingDeltas( array $pd ) {
*/
public function isConversionTable() {
return $this->getNamespace() == NS_MEDIAWIKI &&
- strpos( $this->getText(), 'Conversiontable' ) !== false;
+ strpos( $this->getText(), 'Conversiontable/' ) === 0;
}
/**
public function quickEdit( $text, $comment = '', $minor = 0 ) {
wfDeprecated( __METHOD__, '1.18' );
global $wgUser;
- return $this->doQuickEdit( $text, $wgUser, $comment, $minor );
+ $this->doQuickEdit( $text, $wgUser, $comment, $minor );
}
/**
* @return ResultWrapper
*/
function fetchRevisions( $limit, $offset, $direction ) {
+ // Fail if article doesn't exist.
+ if( !$this->getTitle()->exists() ) {
+ return new FakeResultWrapper( array() );
+ }
+
$dbr = wfGetDB( DB_SLAVE );
if ( $direction == HistoryPage::DIR_PREV ) {
'lang' => 'string',
'url' => array(
ApiBase::PROP_TYPE => 'string',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
),
'*' => 'string'
)
),
'cached' => array(
ApiBase::PROP_TYPE => 'boolean',
- Apibase::PROP_NULLABLE => false
+ ApiBase::PROP_NULLABLE => false
),
'cachedtimestamp' => array(
ApiBase::PROP_TYPE => 'timestamp',
'title' => 'string',
'new_ns' => array(
ApiBase::PROP_TYPE => 'namespace',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
),
'new_title' => array(
ApiBase::PROP_TYPE => 'string',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
)
),
'ids' => array(
'comment' => array(
'comment' => array(
ApiBase::PROP_TYPE => 'string',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
)
),
'parsedcomment' => array(
'parsedcomment' => array(
ApiBase::PROP_TYPE => 'string',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
)
),
'redirect' => array(
'loginfo' => array(
'logid' => array(
ApiBase::PROP_TYPE => 'integer',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
),
'logtype' => array(
ApiBase::PROP_TYPE => $wgLogTypes,
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
),
'logaction' => array(
ApiBase::PROP_TYPE => 'string',
- Apibase::PROP_NULLABLE => true
+ ApiBase::PROP_NULLABLE => true
)
)
);
* * array
* * blob
*
+ * TODO: get rid of the id field. Every row instance needs to have
+ * one so this is just causing hassle at various locations by requiring an extra check for field name.
+ *
* @since 1.20
*
* @return array
* @return ORMResult
*/
public function select( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
+ array $options = array(), $functionName = null );
/**
* Selects the the specified fields of the records matching the provided
* @return array of self
*/
public function selectObjects( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
+ array $options = array(), $functionName = null );
/**
* Do the actual select.
* @return ResultWrapper
*/
public function rawSelect( $fields = null, array $conditions = array(),
- array $options = array(), $functionName = null );
+ array $options = array(), $functionName = null );
/**
* Selects the the specified fields of the records matching the provided
* @return array of array
*/
public function selectFields( $fields = null, array $conditions = array(),
- array $options = array(), $collapse = true, $functionName = null );
+ array $options = array(), $collapse = true, $functionName = null );
/**
* Selects the the specified fields of the first matching record.
*/
public function canHaveField( $name );
-}
\ No newline at end of file
+}
--- /dev/null
+<?php
+
+/**
+ * Interface for Iterators containing IORMRows.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.20
+ *
+ * @file
+ * @ingroup ORM
+ *
+ * @licence GNU GPL v2 or later
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+interface ORMIterator extends Iterator {
+
+ /**
+ * @see Iterator::current()
+ * @return IORMRow
+ */
+ public function current();
+
+}
\ No newline at end of file
<?php
/**
- * Result of a ORMTable::select, which returns IORMRow objects.
+ * ORMIterator that takes a ResultWrapper object returned from
+ * a select operation returning IORMRow objects (ie IORMTable::select).
*
* 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
* @author Jeroen De Dauw < jeroendedauw@gmail.com >
*/
-class ORMResult implements Iterator {
+class ORMResult implements ORMIterator {
/**
* @var ResultWrapper
/**
* @var integer
*/
- protected $key;
+ protected $key;
/**
* @var IORMRow
$month = '', $filter = null, $tagFilter='' ) {
global $wgScript, $wgMiserMode;
- $action = $wgScript;
$title = SpecialPage::getTitleFor( 'Log' );
- $special = $title->getPrefixedDBkey();
// For B/C, we take strings, but make sure they are converted...
$types = ($types === '') ? array() : (array)$types;
$tagSelector = ChangeTags::buildTagFilterSelector( $tagFilter );
- $html = Html::hidden( 'title', $special );
+ $html = Html::hidden( 'title', $title->getPrefixedDBkey() );
// Basic selectors
$html .= $this->getTypeMenu( $types ) . "\n";
$html = Xml::fieldset( wfMsg( 'log' ), $html );
// Form wrapping
- $html = Xml::tags( 'form', array( 'action' => $action, 'method' => 'get' ), $html );
+ $html = Xml::tags( 'form', array( 'action' => $wgScript, 'method' => 'get' ), $html );
$this->out->addHTML( $html );
}
$hideVal = 1 - intval($val);
$query[$queryKey] = $hideVal;
- $link = Linker::link(
+ $link = Linker::linkKnown(
$this->getDisplayTitle(),
$messages[$hideVal],
array(),
- $query,
- array( 'known', 'noclasses' )
+ $query
);
$links[$type] = wfMsgHtml( "log-show-hide-{$type}", $link );
if( self::typeAction( $row, 'move', 'move', 'move' ) && !empty( $paramArray[0] ) ) {
$destTitle = Title::newFromText( $paramArray[0] );
if( $destTitle ) {
- $revert = Linker::link(
+ $revert = Linker::linkKnown(
SpecialPage::getTitleFor( 'Movepage' ),
$this->message['revertmove'],
array(),
'wpNewTitle' => $title->getPrefixedDBkey(),
'wpReason' => wfMsgForContent( 'revertmove' ),
'wpMovetalk' => 0
- ),
- array( 'known', 'noclasses' )
+ )
);
$revert = wfMessage( 'parentheses' )->rawParams( $revert )->escaped();
}
} else {
$viewdeleted = $this->message['undeletelink'];
}
- $revert = Linker::link(
+ $revert = Linker::linkKnown(
SpecialPage::getTitleFor( 'Undelete' ),
$viewdeleted,
array(),
- array( 'target' => $title->getPrefixedDBkey() ),
- array( 'known', 'noclasses' )
+ array( 'target' => $title->getPrefixedDBkey() )
);
$revert = wfMessage( 'parentheses' )->rawParams( $revert )->escaped();
// Show unblock/change block link
} elseif( self::typeAction( $row, array( 'block', 'suppress' ), array( 'block', 'reblock' ), 'block' ) ) {
- $revert = Linker::link(
+ $revert = Linker::linkKnown(
SpecialPage::getTitleFor( 'Unblock', $row->log_title ),
- $this->message['unblocklink'],
- array(),
- array(),
- 'known'
+ $this->message['unblocklink']
) .
$this->message['pipe-separator'] .
- Linker::link(
+ Linker::linkKnown(
SpecialPage::getTitleFor( 'Block', $row->log_title ),
- $this->message['change-blocklink'],
- array(),
- array(),
- 'known'
+ $this->message['change-blocklink']
);
$revert = wfMessage( 'parentheses' )->rawParams( $revert )->escaped();
// Show change protection link
$revert = ' ' . wfMessage( 'parentheses' )->rawParams( $revert )->escaped();
// Show unmerge link
} elseif( self::typeAction( $row, 'merge', 'merge', 'mergehistory' ) ) {
- $revert = Linker::link(
+ $revert = Linker::linkKnown(
SpecialPage::getTitleFor( 'MergeHistory' ),
$this->message['revertmerge'],
array(),
'target' => $paramArray[0],
'dest' => $title->getPrefixedDBkey(),
'mergepoint' => $paramArray[1]
- ),
- array( 'known', 'noclasses' )
+ )
);
$revert = wfMessage( 'parentheses' )->rawParams( $revert )->escaped();
// If an edit was hidden from a page give a review link to the history
// $paramArray[1] is a CSV of the IDs
$query = $paramArray[0];
// Link to each hidden object ID, $paramArray[1] is the url param
- $revert = Linker::link(
+ $revert = Linker::linkKnown(
$revdel,
$this->message['revdel-restore'],
array(),
'target' => $title->getPrefixedText(),
'type' => 'logging',
'ids' => $query
- ),
- array( 'known', 'noclasses' )
+ )
);
$revert = wfMessage( 'parentheses' )->rawParams( $revert )->escaped();
}
$link = ($s->page_is_redirect ? '<div class="allpagesredirect">' : '' ) .
Linker::linkKnown(
$t,
- htmlspecialchars( $t->getText() )
+ htmlspecialchars( $t->getText() ),
+ $s->page_is_redirect ? array( 'class' => 'mw-redirect' ) : array()
) .
($s->page_is_redirect ? '</div>' : '' );
} else {
) .
Xml::element( 'legend', null, $this->msg('powersearch-legend' )->text() ) .
Xml::tags( 'h4', null, $this->msg( 'powersearch-ns' )->parse() ) .
- Xml::tags(
- 'div',
- array( 'id' => 'mw-search-togglebox' ),
- Xml::label( $this->msg( 'powersearch-togglelabel' )->text(), 'mw-search-togglelabel' ) .
- Xml::element(
- 'input',
- array(
- 'type'=>'button',
- 'id' => 'mw-search-toggleall',
- 'value' => $this->msg( 'powersearch-toggleall' )->text()
- )
- ) .
- Xml::element(
- 'input',
- array(
- 'type'=>'button',
- 'id' => 'mw-search-togglenone',
- 'value' => $this->msg( 'powersearch-togglenone' )->text()
- )
- )
- ) .
+ Html::element( 'div', array( 'id' => 'mw-search-togglebox' ) ) .
Xml::element( 'div', array( 'class' => 'divider' ), '', false ) .
implode( Xml::element( 'div', array( 'class' => 'divider' ), '', false ), $showSections ) .
$hidden .
*
* @param $code string
*
+ * @throws MWException
* @since 1.18
* @return bool
*/
* @param $title Title object to link
* @param $offset Integer offset parameter
* @param $limit Integer limit parameter
- * @param $query String optional URL query parameter string
+ * @param $query array|String optional URL query parameter string
* @param $atend Bool optional param for specified if this is the last page
* @return String
*/
'mediawiki.special.search' => array(
'scripts' => 'resources/mediawiki.special/mediawiki.special.search.js',
'styles' => 'resources/mediawiki.special/mediawiki.special.search.css',
+ 'messages' => array(
+ 'powersearch-togglelabel',
+ 'powersearch-toggleall',
+ 'powersearch-togglenone',
+ ),
),
'mediawiki.special.undelete' => array(
'scripts' => 'resources/mediawiki.special/mediawiki.special.undelete.js',
/*
* JavaScript for Special:Search
*/
-jQuery( function( $ ) {
+( function( $, mw ) { $( function() {
// Emulate HTML5 autofocus behavior in non HTML5 compliant browsers
if ( !( 'autofocus' in document.createElement( 'input' ) ) ) {
$( 'input[autofocus]:first' ).focus();
}
-// Bind check all/none button
+// Create check all/none button
var $checkboxes = $('#powersearch input[id^=mw-search-ns]');
-$('#mw-search-toggleall').click( function() {
- $checkboxes.prop("checked", true);
-} );
-$('#mw-search-togglenone').click( function() {
- $checkboxes.prop("checked", false);
-} );
+$('#mw-search-togglebox').append(
+ $('<label />')
+ .text(mw.msg('powersearch-togglelabel'))
+).append(
+ $('<input type="button" />')
+ .attr('id', 'mw-search-toggleall')
+ .attr('value', mw.msg('powersearch-toggleall'))
+ .click( function() {
+ $checkboxes.prop('checked', true);
+ } )
+).append(
+ $('<input type="button" />')
+ .attr('id', 'mw-search-togglenone')
+ .attr('value', mw.msg('powersearch-togglenone'))
+ .click( function() {
+ $checkboxes.prop('checked', false);
+ } )
+);
// Change the header search links to what user entered
var headerLinks = $('.search-types a');
});
}).trigger('change');
-} );
+} ); } )( jQuery, mediaWiki );
return new $class( $this->getTableInstance(), $data, $loadDefaults );
}
+ /**
+ * @since 1.20
+ * @return array
+ */
+ protected function getMockValues() {
+ return array(
+ 'id' => 1,
+ 'str' => 'foobar4645645',
+ 'int' => 42,
+ 'float' => 4.2,
+ 'bool' => true,
+ 'array' => array( 42, 'foobar' ),
+ 'blob' => new stdClass()
+ );
+ }
+
+ /**
+ * @since 1.20
+ * @return array
+ */
+ protected function getMockFields() {
+ $mockValues = $this->getMockValues();
+ $mockFields = array();
+
+ foreach ( $this->getTableInstance()->getFields() as $name => $type ) {
+ if ( $name !== 'id' ) {
+ $mockFields[$name] = $mockValues[$type];
+ }
+ }
+
+ return $mockFields;
+ }
+
+ /**
+ * @since 1.20
+ * @return array of IORMRow
+ */
+ public function instanceProvider() {
+ $instances = array();
+
+ foreach ( $this->constructorTestProvider() as $arguments ) {
+ $instances[] = array( call_user_func_array( array( $this, 'getRowInstance' ), $arguments ) );
+ }
+
+ return $instances;
+ }
+
/**
* @dataProvider constructorTestProvider
*/
$this->verifyFields( $item, $data );
}
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testSetField( IORMRow $item ) {
+ foreach ( $this->getMockFields() as $name => $value ) {
+ $item->setField( $name, $value );
+ $this->assertEquals( $value, $item->getField( $name ) );
+ }
+ }
+
+ /**
+ * @since 1.20
+ * @param array $expected
+ * @param IORMRow $item
+ */
+ protected function assertFieldValues( array $expected, IORMRow $item ) {
+ foreach ( $expected as $name => $type ) {
+ if ( $name !== 'id' ) {
+ $this->assertEquals( $expected[$name], $item->getField( $name ) );
+ }
+ }
+ }
+
+ /**
+ * @dataProvider instanceProvider
+ */
+ public function testSetFields( IORMRow $item ) {
+ $originalValues = $item->getFields();
+
+ $item->setFields( array(), false );
+
+ foreach ( $item->getTable()->getFields() as $name => $type ) {
+ $originalHas = array_key_exists( $name, $originalValues );
+ $newHas = $item->hasField( $name );
+
+ $this->assertEquals( $originalHas, $newHas );
+
+ if ( $originalHas && $newHas ) {
+ $this->assertEquals( $originalValues[$name], $item->getField( $name ) );
+ }
+ }
+
+ $mockFields = $this->getMockFields();
+
+ $item->setFields( $mockFields, false );
+
+ $this->assertFieldValues( $originalValues, $item );
+
+ $item->setFields( $mockFields, true );
+
+ $this->assertFieldValues( $mockFields, $item );
+ }
+
// TODO: test all of the methods!
}
\ No newline at end of file