*/
class CommentStore {
- /** Maximum length of a comment. Longer comments will be truncated. */
+ /**
+ * Maximum length of a comment in UTF-8 characters. Longer comments will be truncated.
+ * @note This must be at least 255 and not greater than floor( MAX_COMMENT_LENGTH / 4 ).
+ */
+ const COMMENT_CHARACTER_LIMIT = 1000;
+
+ /**
+ * Maximum length of a comment in bytes. Longer comments will be truncated.
+ * @note This value is determined by the size of the underlying database field,
+ * currently BLOB in MySQL/MariaDB.
+ */
const MAX_COMMENT_LENGTH = 65535;
- /** Maximum length of serialized data. Longer data will result in an exception. */
+ /**
+ * Maximum length of serialized data in bytes. Longer data will result in an exception.
+ * @note This value is determined by the size of the underlying database field,
+ * currently BLOB in MySQL/MariaDB.
+ */
const MAX_DATA_LENGTH = 65535;
/**
# Truncate comment in a Unicode-sensitive manner
$comment->text = $this->lang->truncate( $comment->text, self::MAX_COMMENT_LENGTH );
+ if ( mb_strlen( $comment->text, 'UTF-8' ) > self::COMMENT_CHARACTER_LIMIT ) {
+ $ellipsis = wfMessage( 'ellipsis' )->inLanguage( $this->lang )->escaped();
+ if ( mb_strlen( $ellipsis ) >= self::COMMENT_CHARACTER_LIMIT ) {
+ // WTF?
+ $ellipsis = '...';
+ }
+ $maxLength = self::COMMENT_CHARACTER_LIMIT - mb_strlen( $ellipsis, 'UTF-8' );
+ $comment->text = mb_substr( $comment->text, 0, $maxLength, 'UTF-8' ) . $ellipsis;
+ }
if ( $this->stage > MIGRATION_OLD && !$comment->id ) {
$dbData = $comment->data;
* @deprecated since 1.30 use MediaWiki\Shell::isDisabled()
*/
function wfShellExecDisabled() {
+ wfDeprecated( __FUNCTION__, '1.30' );
return Shell::isDisabled() ? 'disabled' : false;
}
[ 'addPgIndex', 'user_groups', 'user_groups_expiry', '( ug_expiry )' ],
// 1.30
- [ 'modifyField', 'image', 'img_media_type', 'patch-add-3d.sql' ],
+ [ 'addPgEnumValue', 'media_type', '3D' ],
[ 'setDefault', 'revision', 'rev_comment', '' ],
[ 'changeNullableField', 'revision', 'rev_comment', 'NOT NULL', true ],
[ 'setDefault', 'archive', 'ar_comment', '' ],
}
}
+ /**
+ * Add a value to an existing PostgreSQL enum type
+ * @since 1.31
+ * @param string $type Type name. Must be in the core schema.
+ * @param string $value Value to add.
+ */
+ public function addPgEnumValue( $type, $value ) {
+ $row = $this->db->selectRow(
+ [
+ 't' => 'pg_catalog.pg_type',
+ 'n' => 'pg_catalog.pg_namespace',
+ 'e' => 'pg_catalog.pg_enum',
+ ],
+ [ 't.typname', 't.typtype', 'e.enumlabel' ],
+ [
+ 't.typname' => $type,
+ 'n.nspname' => $this->db->getCoreSchema(),
+ ],
+ __METHOD__,
+ [],
+ [
+ 'n' => [ 'JOIN', 't.typnamespace = n.oid' ],
+ 'e' => [ 'LEFT JOIN', [ 'e.enumtypid = t.oid', 'e.enumlabel' => $value ] ],
+ ]
+ );
+
+ if ( !$row ) {
+ $this->output( "...Type $type does not exist, skipping modify enum.\n" );
+ } elseif ( $row->typtype !== 'e' ) {
+ $this->output( "...Type $type does not seem to be an enum, skipping modify enum.\n" );
+ } elseif ( $row->enumlabel === $value ) {
+ $this->output( "...Enum type $type already contains value '$value'.\n" );
+ } else {
+ $this->output( "...Adding value '$value' to enum type $type.\n" );
+ $etype = $this->db->addIdentifierQuotes( $type );
+ $evalue = $this->db->addQuotes( $value );
+ $this->db->query( "ALTER TYPE $etype ADD VALUE $evalue" );
+ }
+ }
+
protected function dropFkey( $table, $field ) {
$fi = $this->db->fieldInfo( $table, $field );
if ( is_null( $fi ) ) {
+++ /dev/null
-ALTER TYPE media_type ADD VALUE '3D';
</rule>
<rule ref="MediaWiki.NamingConventions.PrefixedGlobalFunctions">
<properties>
- <property name="ignoreList" type="array" value="bfNormalizeTitleStrReplace,bfNormalizeTitleStrTr,cdbShowHelp,codepointToUtf8,compare_point,cssfilter,escapeSingleString,findAuxFile,findFiles,getEscapedProfileUrl,getFileCommentFromSourceWiki,getFileUserFromSourceWiki,hexSequenceToUtf8,mccGetHelp,mccShowUsage,mimeTypeMatch,moveToExternal,NothingFunction,NothingFunctionData,resolveStub,resolveStubs,showUsage,splitFilename,utf8ToCodepoint,utf8ToHexSequence" />
+ <!--
+ includes/compat/normal/UtfNormalUtil.php
+ * codepointToUtf8
+ * escapeSingleString
+ * hexSequenceToUtf8
+ * utf8ToCodepoint
+ * utf8ToHexSequence
+ includes/GlobalFunctions.php
+ * mimeTypeMatch
+ maintenance/benchmarks/bench_strtr_str_replace.php
+ * bfNormalizeTitleStrReplace
+ * bfNormalizeTitleStrTr
+ maintenance/cdb.php
+ * cdbShowHelp
+ maintenance/language/transstat.php
+ * showUsage
+ maintenance/mcc.php
+ * mccGetHelp
+ * mccShowUsage
+ maintenance/storage/moveToExternal.php
+ * moveToExternal
+ maintenance/storage/resolveStubs.php
+ * resolveStub
+ * resolveStubs
+ profileinfo.php
+ * compare_point
+ * getEscapedProfileUrl
+ tests/phpunit/includes/HooksTest.php
+ * NothingFunction
+ * NothingFunctionData
+ tests/qunit/data/styleTest.css.php
+ * cssfilter
+ -->
+ <property name="ignoreList" type="array" value="bfNormalizeTitleStrReplace,bfNormalizeTitleStrTr,cdbShowHelp,codepointToUtf8,compare_point,cssfilter,escapeSingleString,getEscapedProfileUrl,hexSequenceToUtf8,mccGetHelp,mccShowUsage,mimeTypeMatch,moveToExternal,NothingFunction,NothingFunctionData,resolveStub,resolveStubs,showUsage,utf8ToCodepoint,utf8ToHexSequence" />
</properties>
</rule>
<rule ref="MediaWiki.NamingConventions.ValidGlobalName">
public function testInsertTruncation() {
$comment = str_repeat( '💣', 16400 );
$truncated1 = str_repeat( '💣', 63 ) . '...';
- $truncated2 = str_repeat( '💣', 16383 ) . '...';
+ $truncated2 = str_repeat( '💣', CommentStore::COMMENT_CHARACTER_LIMIT - 3 ) . '...';
$store = $this->makeStore( MIGRATION_WRITE_BOTH, 'ipb_reason' );
$fields = $store->insert( $this->db, $comment );