MediaWiki  1.29.2
MssqlInstaller.php
Go to the documentation of this file.
1 <?php
27 
35 
36  protected $globalNames = [
37  'wgDBserver',
38  'wgDBname',
39  'wgDBuser',
40  'wgDBpassword',
41  'wgDBmwschema',
42  'wgDBprefix',
43  'wgDBWindowsAuthentication',
44  ];
45 
46  protected $internalDefaults = [
47  '_InstallUser' => 'sa',
48  '_InstallWindowsAuthentication' => 'sqlauth',
49  '_WebWindowsAuthentication' => 'sqlauth',
50  ];
51 
52  // SQL Server 2005 RTM
53  // @todo Are SQL Express version numbers different?)
54  public $minimumVersion = '9.00.1399';
55 
56  // These are schema-level privs
57  // Note: the web user will be created will full permissions if possible, this permission
58  // list is only used if we are unable to grant full permissions.
59  public $webUserPrivs = [
60  'DELETE',
61  'INSERT',
62  'SELECT',
63  'UPDATE',
64  'EXECUTE',
65  ];
66 
70  public function getName() {
71  return 'mssql';
72  }
73 
77  public function isCompiled() {
78  return self::checkExtension( 'sqlsrv' );
79  }
80 
84  public function getConnectForm() {
85  if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
86  $displayStyle = 'display: none;';
87  } else {
88  $displayStyle = 'display: block;';
89  }
90 
91  return $this->getTextBox(
92  'wgDBserver',
93  'config-db-host',
94  [],
95  $this->parent->getHelpBox( 'config-db-host-help' )
96  ) .
97  Html::openElement( 'fieldset' ) .
98  Html::element( 'legend', [], wfMessage( 'config-db-wiki-settings' )->text() ) .
99  $this->getTextBox( 'wgDBname', 'config-db-name', [ 'dir' => 'ltr' ],
100  $this->parent->getHelpBox( 'config-db-name-help' ) ) .
101  $this->getTextBox( 'wgDBmwschema', 'config-db-schema', [ 'dir' => 'ltr' ],
102  $this->parent->getHelpBox( 'config-db-schema-help' ) ) .
103  $this->getTextBox( 'wgDBprefix', 'config-db-prefix', [ 'dir' => 'ltr' ],
104  $this->parent->getHelpBox( 'config-db-prefix-help' ) ) .
105  Html::closeElement( 'fieldset' ) .
106  Html::openElement( 'fieldset' ) .
107  Html::element( 'legend', [], wfMessage( 'config-db-install-account' )->text() ) .
108  $this->getRadioSet( [
109  'var' => '_InstallWindowsAuthentication',
110  'label' => 'config-mssql-auth',
111  'itemLabelPrefix' => 'config-mssql-',
112  'values' => [ 'sqlauth', 'windowsauth' ],
113  'itemAttribs' => [
114  'sqlauth' => [
115  'class' => 'showHideRadio',
116  'rel' => 'dbCredentialBox',
117  ],
118  'windowsauth' => [
119  'class' => 'hideShowRadio',
120  'rel' => 'dbCredentialBox',
121  ]
122  ],
123  'help' => $this->parent->getHelpBox( 'config-mssql-install-auth' )
124  ] ) .
125  Html::openElement( 'div', [ 'id' => 'dbCredentialBox', 'style' => $displayStyle ] ) .
126  $this->getTextBox(
127  '_InstallUser',
128  'config-db-username',
129  [ 'dir' => 'ltr' ],
130  $this->parent->getHelpBox( 'config-db-install-username' )
131  ) .
132  $this->getPasswordBox(
133  '_InstallPassword',
134  'config-db-password',
135  [ 'dir' => 'ltr' ],
136  $this->parent->getHelpBox( 'config-db-install-password' )
137  ) .
138  Html::closeElement( 'div' ) .
139  Html::closeElement( 'fieldset' );
140  }
141 
142  public function submitConnectForm() {
143  // Get variables from the request.
144  $newValues = $this->setVarsFromRequest( [
145  'wgDBserver',
146  'wgDBname',
147  'wgDBmwschema',
148  'wgDBprefix'
149  ] );
150 
151  // Validate them.
153  if ( !strlen( $newValues['wgDBserver'] ) ) {
154  $status->fatal( 'config-missing-db-host' );
155  }
156  if ( !strlen( $newValues['wgDBname'] ) ) {
157  $status->fatal( 'config-missing-db-name' );
158  } elseif ( !preg_match( '/^[a-z0-9_]+$/i', $newValues['wgDBname'] ) ) {
159  $status->fatal( 'config-invalid-db-name', $newValues['wgDBname'] );
160  }
161  if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBmwschema'] ) ) {
162  $status->fatal( 'config-invalid-schema', $newValues['wgDBmwschema'] );
163  }
164  if ( !preg_match( '/^[a-z0-9_]*$/i', $newValues['wgDBprefix'] ) ) {
165  $status->fatal( 'config-invalid-db-prefix', $newValues['wgDBprefix'] );
166  }
167  if ( !$status->isOK() ) {
168  return $status;
169  }
170 
171  // Check for blank schema and remap to dbo
172  if ( $newValues['wgDBmwschema'] === '' ) {
173  $this->setVar( 'wgDBmwschema', 'dbo' );
174  }
175 
176  // User box
177  $this->setVarsFromRequest( [
178  '_InstallUser',
179  '_InstallPassword',
180  '_InstallWindowsAuthentication'
181  ] );
182 
183  // Try to connect
184  $status = $this->getConnection();
185  if ( !$status->isOK() ) {
186  return $status;
187  }
191  $conn = $status->value;
192 
193  // Check version
194  $version = $conn->getServerVersion();
195  if ( version_compare( $version, $this->minimumVersion ) < 0 ) {
196  return Status::newFatal( 'config-mssql-old', $this->minimumVersion, $version );
197  }
198 
199  return $status;
200  }
201 
205  public function openConnection() {
208  $user = $this->getVar( '_InstallUser' );
209  $password = $this->getVar( '_InstallPassword' );
210 
211  if ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth' ) {
212  // Use Windows authentication for this connection
213  $wgDBWindowsAuthentication = true;
214  } else {
216  }
217 
218  try {
219  $db = Database::factory( 'mssql', [
220  'host' => $this->getVar( 'wgDBserver' ),
221  'port' => $this->getVar( 'wgDBport' ),
222  'user' => $user,
223  'password' => $password,
224  'dbname' => false,
225  'flags' => 0,
226  'schema' => $this->getVar( 'wgDBmwschema' ),
227  'tablePrefix' => $this->getVar( 'wgDBprefix' ) ] );
228  $db->prepareStatements( false );
229  $db->scrollableCursor( false );
230  $status->value = $db;
231  } catch ( DBConnectionError $e ) {
232  $status->fatal( 'config-connection-error', $e->getMessage() );
233  }
234 
235  return $status;
236  }
237 
238  public function preUpgrade() {
240 
241  $status = $this->getConnection();
242  if ( !$status->isOK() ) {
243  $this->parent->showStatusError( $status );
244 
245  return;
246  }
250  $conn = $status->value;
251  $conn->selectDB( $this->getVar( 'wgDBname' ) );
252 
253  # Normal user and password are selected after this step, so for now
254  # just copy these two
255  $wgDBuser = $this->getVar( '_InstallUser' );
256  $wgDBpassword = $this->getVar( '_InstallPassword' );
257  }
258 
264  public function canCreateAccounts() {
265  $status = $this->getConnection();
266  if ( !$status->isOK() ) {
267  return false;
268  }
270  $conn = $status->value;
271 
272  // We need the server-level ALTER ANY LOGIN permission to create new accounts
273  $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'SERVER' )" );
274  $serverPrivs = [
275  'ALTER ANY LOGIN' => false,
276  'CONTROL SERVER' => false,
277  ];
278 
279  foreach ( $res as $row ) {
280  $serverPrivs[$row->permission_name] = true;
281  }
282 
283  if ( !$serverPrivs['ALTER ANY LOGIN'] ) {
284  return false;
285  }
286 
287  // Check to ensure we can grant everything needed as well
288  // We can't actually tell if we have WITH GRANT OPTION for a given permission, so we assume we do
289  // and just check for the permission
290  // https://technet.microsoft.com/en-us/library/ms178569.aspx
291  // The following array sets up which permissions imply whatever permissions we specify
292  $implied = [
293  // schema database server
294  'DELETE' => [ 'DELETE', 'CONTROL SERVER' ],
295  'EXECUTE' => [ 'EXECUTE', 'CONTROL SERVER' ],
296  'INSERT' => [ 'INSERT', 'CONTROL SERVER' ],
297  'SELECT' => [ 'SELECT', 'CONTROL SERVER' ],
298  'UPDATE' => [ 'UPDATE', 'CONTROL SERVER' ],
299  ];
300 
301  $grantOptions = array_flip( $this->webUserPrivs );
302 
303  // Check for schema and db-level permissions, but only if the schema/db exists
304  $schemaPrivs = $dbPrivs = [
305  'DELETE' => false,
306  'EXECUTE' => false,
307  'INSERT' => false,
308  'SELECT' => false,
309  'UPDATE' => false,
310  ];
311 
312  $dbPrivs['ALTER ANY USER'] = false;
313 
314  if ( $this->databaseExists( $this->getVar( 'wgDBname' ) ) ) {
315  $conn->selectDB( $this->getVar( 'wgDBname' ) );
316  $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( NULL, 'DATABASE' )" );
317 
318  foreach ( $res as $row ) {
319  $dbPrivs[$row->permission_name] = true;
320  }
321 
322  // If the db exists, we need ALTER ANY USER privs on it to make a new user
323  if ( !$dbPrivs['ALTER ANY USER'] ) {
324  return false;
325  }
326 
327  if ( $this->schemaExists( $this->getVar( 'wgDBmwschema' ) ) ) {
328  // wgDBmwschema is validated to only contain alphanumeric + underscore, so this is safe
329  $res = $conn->query( "SELECT permission_name FROM sys.fn_my_permissions( "
330  . "'{$this->getVar( 'wgDBmwschema' )}', 'SCHEMA' )" );
331 
332  foreach ( $res as $row ) {
333  $schemaPrivs[$row->permission_name] = true;
334  }
335  }
336  }
337 
338  // Now check all the grants we'll need to be doing to see if we can
339  foreach ( $this->webUserPrivs as $permission ) {
340  if ( ( isset( $schemaPrivs[$permission] ) && $schemaPrivs[$permission] )
341  || ( isset( $dbPrivs[$implied[$permission][0]] )
342  && $dbPrivs[$implied[$permission][0]] )
343  || ( isset( $serverPrivs[$implied[$permission][1]] )
344  && $serverPrivs[$implied[$permission][1]] )
345  ) {
346  unset( $grantOptions[$permission] );
347  }
348  }
349 
350  if ( count( $grantOptions ) ) {
351  // Can't grant everything
352  return false;
353  }
354 
355  return true;
356  }
357 
361  public function getSettingsForm() {
362  if ( $this->canCreateAccounts() ) {
363  $noCreateMsg = false;
364  } else {
365  $noCreateMsg = 'config-db-web-no-create-privs';
366  }
367 
368  $wrapperStyle = $this->getVar( '_SameAccount' ) ? 'display: none' : '';
369  $displayStyle = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth'
370  ? 'display: none'
371  : '';
372  $s = Html::openElement( 'fieldset' ) .
373  Html::element( 'legend', [], wfMessage( 'config-db-web-account' )->text() ) .
374  $this->getCheckBox(
375  '_SameAccount', 'config-db-web-account-same',
376  [ 'class' => 'hideShowRadio', 'rel' => 'dbOtherAccount' ]
377  ) .
378  Html::openElement( 'div', [ 'id' => 'dbOtherAccount', 'style' => $wrapperStyle ] ) .
379  $this->getRadioSet( [
380  'var' => '_WebWindowsAuthentication',
381  'label' => 'config-mssql-auth',
382  'itemLabelPrefix' => 'config-mssql-',
383  'values' => [ 'sqlauth', 'windowsauth' ],
384  'itemAttribs' => [
385  'sqlauth' => [
386  'class' => 'showHideRadio',
387  'rel' => 'dbCredentialBox',
388  ],
389  'windowsauth' => [
390  'class' => 'hideShowRadio',
391  'rel' => 'dbCredentialBox',
392  ]
393  ],
394  'help' => $this->parent->getHelpBox( 'config-mssql-web-auth' )
395  ] ) .
396  Html::openElement( 'div', [ 'id' => 'dbCredentialBox', 'style' => $displayStyle ] ) .
397  $this->getTextBox( 'wgDBuser', 'config-db-username' ) .
398  $this->getPasswordBox( 'wgDBpassword', 'config-db-password' ) .
399  Html::closeElement( 'div' );
400 
401  if ( $noCreateMsg ) {
402  $s .= $this->parent->getWarningBox( wfMessage( $noCreateMsg )->plain() );
403  } else {
404  $s .= $this->getCheckBox( '_CreateDBAccount', 'config-db-web-create' );
405  }
406 
407  $s .= Html::closeElement( 'div' ) . Html::closeElement( 'fieldset' );
408 
409  return $s;
410  }
411 
415  public function submitSettingsForm() {
416  $this->setVarsFromRequest( [
417  'wgDBuser',
418  'wgDBpassword',
419  '_SameAccount',
420  '_CreateDBAccount',
421  '_WebWindowsAuthentication'
422  ] );
423 
424  if ( $this->getVar( '_SameAccount' ) ) {
425  $this->setVar( '_WebWindowsAuthentication', $this->getVar( '_InstallWindowsAuthentication' ) );
426  $this->setVar( 'wgDBuser', $this->getVar( '_InstallUser' ) );
427  $this->setVar( 'wgDBpassword', $this->getVar( '_InstallPassword' ) );
428  }
429 
430  if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
431  $this->setVar( 'wgDBuser', '' );
432  $this->setVar( 'wgDBpassword', '' );
433  $this->setVar( 'wgDBWindowsAuthentication', true );
434  } else {
435  $this->setVar( 'wgDBWindowsAuthentication', false );
436  }
437 
438  if ( $this->getVar( '_CreateDBAccount' )
439  && $this->getVar( '_WebWindowsAuthentication' ) == 'sqlauth'
440  && strval( $this->getVar( 'wgDBpassword' ) ) == ''
441  ) {
442  return Status::newFatal( 'config-db-password-empty', $this->getVar( 'wgDBuser' ) );
443  }
444 
445  // Validate the create checkbox
446  $canCreate = $this->canCreateAccounts();
447  if ( !$canCreate ) {
448  $this->setVar( '_CreateDBAccount', false );
449  $create = false;
450  } else {
451  $create = $this->getVar( '_CreateDBAccount' );
452  }
453 
454  if ( !$create ) {
455  // Test the web account
456  $user = $this->getVar( 'wgDBuser' );
457  $password = $this->getVar( 'wgDBpassword' );
458 
459  if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
460  $user = 'windowsauth';
461  $password = 'windowsauth';
462  }
463 
464  try {
465  Database::factory( 'mssql', [
466  'host' => $this->getVar( 'wgDBserver' ),
467  'user' => $user,
468  'password' => $password,
469  'dbname' => false,
470  'flags' => 0,
471  'tablePrefix' => $this->getVar( 'wgDBprefix' ),
472  'schema' => $this->getVar( 'wgDBmwschema' ),
473  ] );
474  } catch ( DBConnectionError $e ) {
475  return Status::newFatal( 'config-connection-error', $e->getMessage() );
476  }
477  }
478 
479  return Status::newGood();
480  }
481 
482  public function preInstall() {
483  # Add our user callback to installSteps, right before the tables are created.
484  $callback = [
485  'name' => 'user',
486  'callback' => [ $this, 'setupUser' ],
487  ];
488  $this->parent->addInstallStep( $callback, 'tables' );
489  }
490 
494  public function setupDatabase() {
495  $status = $this->getConnection();
496  if ( !$status->isOK() ) {
497  return $status;
498  }
500  $conn = $status->value;
501  $dbName = $this->getVar( 'wgDBname' );
502  $schemaName = $this->getVar( 'wgDBmwschema' );
503  if ( !$this->databaseExists( $dbName ) ) {
504  $conn->query(
505  "CREATE DATABASE " . $conn->addIdentifierQuotes( $dbName ),
506  __METHOD__
507  );
508  }
509  $conn->selectDB( $dbName );
510  if ( !$this->schemaExists( $schemaName ) ) {
511  $conn->query(
512  "CREATE SCHEMA " . $conn->addIdentifierQuotes( $schemaName ),
513  __METHOD__
514  );
515  }
516  if ( !$this->catalogExists( $schemaName ) ) {
517  $conn->query(
518  "CREATE FULLTEXT CATALOG " . $conn->addIdentifierQuotes( $schemaName ),
519  __METHOD__
520  );
521  }
522  $this->setupSchemaVars();
523 
524  return $status;
525  }
526 
530  public function setupUser() {
531  $dbUser = $this->getVar( 'wgDBuser' );
532  if ( $dbUser == $this->getVar( '_InstallUser' )
533  || ( $this->getVar( '_InstallWindowsAuthentication' ) == 'windowsauth'
534  && $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) ) {
535  return Status::newGood();
536  }
537  $status = $this->getConnection();
538  if ( !$status->isOK() ) {
539  return $status;
540  }
541 
542  $this->setupSchemaVars();
543  $dbName = $this->getVar( 'wgDBname' );
544  $this->db->selectDB( $dbName );
545  $password = $this->getVar( 'wgDBpassword' );
546  $schemaName = $this->getVar( 'wgDBmwschema' );
547 
548  if ( $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth' ) {
549  $dbUser = 'windowsauth';
550  $password = 'windowsauth';
551  }
552 
553  if ( $this->getVar( '_CreateDBAccount' ) ) {
554  $tryToCreate = true;
555  } else {
556  $tryToCreate = false;
557  }
558 
559  $escUser = $this->db->addIdentifierQuotes( $dbUser );
560  $escDb = $this->db->addIdentifierQuotes( $dbName );
561  $escSchema = $this->db->addIdentifierQuotes( $schemaName );
562  $grantableNames = [];
563  if ( $tryToCreate ) {
564  $escPass = $this->db->addQuotes( $password );
565 
566  if ( !$this->loginExists( $dbUser ) ) {
567  try {
568  $this->db->begin();
569  $this->db->selectDB( 'master' );
570  $logintype = $this->getVar( '_WebWindowsAuthentication' ) == 'windowsauth'
571  ? 'FROM WINDOWS'
572  : "WITH PASSWORD = $escPass";
573  $this->db->query( "CREATE LOGIN $escUser $logintype" );
574  $this->db->selectDB( $dbName );
575  $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
576  $this->db->commit();
577  $grantableNames[] = $dbUser;
578  } catch ( DBQueryError $dqe ) {
579  $this->db->rollback();
580  $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getMessage() );
581  }
582  } elseif ( !$this->userExists( $dbUser ) ) {
583  try {
584  $this->db->begin();
585  $this->db->selectDB( $dbName );
586  $this->db->query( "CREATE USER $escUser FOR LOGIN $escUser WITH DEFAULT_SCHEMA = $escSchema" );
587  $this->db->commit();
588  $grantableNames[] = $dbUser;
589  } catch ( DBQueryError $dqe ) {
590  $this->db->rollback();
591  $status->warning( 'config-install-user-create-failed', $dbUser, $dqe->getMessage() );
592  }
593  } else {
594  $status->warning( 'config-install-user-alreadyexists', $dbUser );
595  $grantableNames[] = $dbUser;
596  }
597  }
598 
599  // Try to grant to all the users we know exist or we were able to create
600  $this->db->selectDB( $dbName );
601  foreach ( $grantableNames as $name ) {
602  try {
603  // First try to grant full permissions
604  $fullPrivArr = [
605  'BACKUP DATABASE', 'BACKUP LOG', 'CREATE FUNCTION', 'CREATE PROCEDURE',
606  'CREATE TABLE', 'CREATE VIEW', 'CREATE FULLTEXT CATALOG', 'SHOWPLAN'
607  ];
608  $fullPrivList = implode( ', ', $fullPrivArr );
609  $this->db->begin();
610  $this->db->query( "GRANT $fullPrivList ON DATABASE :: $escDb TO $escUser", __METHOD__ );
611  $this->db->query( "GRANT CONTROL ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
612  $this->db->commit();
613  } catch ( DBQueryError $dqe ) {
614  // If that fails, try to grant the limited subset specified in $this->webUserPrivs
615  try {
616  $privList = implode( ', ', $this->webUserPrivs );
617  $this->db->rollback();
618  $this->db->begin();
619  $this->db->query( "GRANT $privList ON SCHEMA :: $escSchema TO $escUser", __METHOD__ );
620  $this->db->commit();
621  } catch ( DBQueryError $dqe ) {
622  $this->db->rollback();
623  $status->fatal( 'config-install-user-grant-failed', $dbUser, $dqe->getMessage() );
624  }
625  // Also try to grant SHOWPLAN on the db, but don't fail if we can't
626  // (just makes a couple things in mediawiki run slower since
627  // we have to run SELECT COUNT(*) instead of getting the query plan)
628  try {
629  $this->db->query( "GRANT SHOWPLAN ON DATABASE :: $escDb TO $escUser", __METHOD__ );
630  } catch ( DBQueryError $dqe ) {
631  }
632  }
633  }
634 
635  return $status;
636  }
637 
638  public function createTables() {
639  $status = parent::createTables();
640 
641  // Do last-minute stuff like fulltext indexes (since they can't be inside a transaction)
642  if ( $status->isOK() ) {
643  $searchindex = $this->db->tableName( 'searchindex' );
644  $schema = $this->db->addIdentifierQuotes( $this->getVar( 'wgDBmwschema' ) );
645  try {
646  $this->db->query( "CREATE FULLTEXT INDEX ON $searchindex (si_title, si_text) "
647  . "KEY INDEX si_page ON $schema" );
648  } catch ( DBQueryError $dqe ) {
649  $status->fatal( 'config-install-tables-failed', $dqe->getMessage() );
650  }
651  }
652 
653  return $status;
654  }
655 
656  public function getGlobalDefaults() {
657  // The default $wgDBmwschema is null, which breaks Postgres and other DBMSes that require
658  // the use of a schema, so we need to set it here
659  return array_merge( parent::getGlobalDefaults(), [
660  'wgDBmwschema' => 'mediawiki',
661  ] );
662  }
663 
669  private function loginExists( $user ) {
670  $res = $this->db->selectField( 'sys.sql_logins', 1, [ 'name' => $user ] );
671  return (bool)$res;
672  }
673 
680  private function userExists( $user ) {
681  $res = $this->db->selectField( 'sys.sysusers', 1, [ 'name' => $user ] );
682  return (bool)$res;
683  }
684 
690  private function databaseExists( $dbName ) {
691  $res = $this->db->selectField( 'sys.databases', 1, [ 'name' => $dbName ] );
692  return (bool)$res;
693  }
694 
701  private function schemaExists( $schemaName ) {
702  $res = $this->db->selectField( 'sys.schemas', 1, [ 'name' => $schemaName ] );
703  return (bool)$res;
704  }
705 
712  private function catalogExists( $catalogName ) {
713  $res = $this->db->selectField( 'sys.fulltext_catalogs', 1, [ 'name' => $catalogName ] );
714  return (bool)$res;
715  }
716 
722  public function getSchemaVars() {
723  return [
724  'wgDBname' => $this->getVar( 'wgDBname' ),
725  'wgDBmwschema' => $this->getVar( 'wgDBmwschema' ),
726  'wgDBuser' => $this->getVar( 'wgDBuser' ),
727  'wgDBpassword' => $this->getVar( 'wgDBpassword' ),
728  ];
729  }
730 
731  public function getLocalSettings() {
732  $schema = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBmwschema' ) );
733  $prefix = LocalSettingsGenerator::escapePhpString( $this->getVar( 'wgDBprefix' ) );
734  $windowsauth = $this->getVar( 'wgDBWindowsAuthentication' ) ? 'true' : 'false';
735 
736  return "# MSSQL specific settings
737 \$wgDBWindowsAuthentication = {$windowsauth};
738 \$wgDBmwschema = \"{$schema}\";
739 \$wgDBprefix = \"{$prefix}\";";
740  }
741 }
Wikimedia\Rdbms\Database
Relational database abstraction object.
Definition: Database.php:45
MssqlInstaller\submitSettingsForm
submitSettingsForm()
Definition: MssqlInstaller.php:415
MssqlInstaller\submitConnectForm
submitConnectForm()
Set variables based on the request array, assuming it was submitted via the form returned by getConne...
Definition: MssqlInstaller.php:142
MssqlInstaller\loginExists
loginExists( $user)
Try to see if the login exists.
Definition: MssqlInstaller.php:669
DatabaseInstaller\checkExtension
static checkExtension( $name)
Convenience function.
Definition: DatabaseInstaller.php:411
captcha-old.count
count
Definition: captcha-old.py:225
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
DatabaseInstaller\getConnection
getConnection()
Connect to the database using the administrative user/password currently defined in the session.
Definition: DatabaseInstaller.php:152
$status
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
Definition: hooks.txt:1049
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:246
StatusValue\newFatal
static newFatal( $message)
Factory function for fatal errors.
Definition: StatusValue.php:63
MssqlInstaller\$webUserPrivs
$webUserPrivs
Definition: MssqlInstaller.php:59
DatabaseInstaller\getTextBox
getTextBox( $var, $label, $attribs=[], $helpData="")
Get a labelled text box to configure a local variable.
Definition: DatabaseInstaller.php:483
$s
$s
Definition: mergeMessageFileList.php:188
$res
$res
Definition: database.txt:21
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304
MssqlInstaller\setupUser
setupUser()
Definition: MssqlInstaller.php:530
MssqlInstaller\createTables
createTables()
Create database tables from scratch.
Definition: MssqlInstaller.php:638
$wgDBpassword
$wgDBpassword
Database user's password.
Definition: DefaultSettings.php:1770
MssqlInstaller\getLocalSettings
getLocalSettings()
Get the DBMS-specific options for LocalSettings.php generation.
Definition: MssqlInstaller.php:731
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
Html\closeElement
static closeElement( $element)
Returns "</$element>".
Definition: Html.php:309
MssqlInstaller\isCompiled
isCompiled()
Definition: MssqlInstaller.php:77
$wgDBWindowsAuthentication
$wgDBWindowsAuthentication
Use Windows Authentication instead of $wgDBuser / $wgDBpassword for MS SQL Server.
Definition: DefaultSettings.php:2064
DatabaseInstaller\getPasswordBox
getPasswordBox( $var, $label, $attribs=[], $helpData="")
Get a labelled password box to configure a local variable.
Definition: DatabaseInstaller.php:510
MssqlInstaller\getConnectForm
getConnectForm()
Definition: MssqlInstaller.php:84
MssqlInstaller\getSchemaVars
getSchemaVars()
Get variables to substitute into tables.sql and the SQL patch files.
Definition: MssqlInstaller.php:722
DatabaseInstaller\setupSchemaVars
setupSchemaVars()
Set appropriate schema variables in the current database connection.
Definition: DatabaseInstaller.php:312
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
Wikimedia\Rdbms\DBQueryError
Definition: DBQueryError.php:27
DatabaseInstaller\getRadioSet
getRadioSet( $params)
Get a set of labelled radio buttons.
Definition: DatabaseInstaller.php:562
MssqlInstaller\catalogExists
catalogExists( $catalogName)
Try to see if a given fulltext catalog exists We assume we already have the appropriate database sele...
Definition: MssqlInstaller.php:712
MssqlInstaller\setupDatabase
setupDatabase()
Definition: MssqlInstaller.php:494
$e
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LogException' returning false will NOT prevent logging $e
Definition: hooks.txt:2122
MssqlInstaller\$globalNames
$globalNames
Definition: MssqlInstaller.php:36
MssqlInstaller\userExists
userExists( $user)
Try to see if the user account exists We assume we already have the appropriate database selected.
Definition: MssqlInstaller.php:680
DatabaseInstaller\getVar
getVar( $var, $default=null)
Get a variable, taking local defaults into account.
Definition: DatabaseInstaller.php:453
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:76
MssqlInstaller\preInstall
preInstall()
Allow DB installers a chance to make last-minute changes before installation occurs.
Definition: MssqlInstaller.php:482
MssqlInstaller\schemaExists
schemaExists( $schemaName)
Try to see if a given schema exists We assume we already have the appropriate database selected.
Definition: MssqlInstaller.php:701
DatabaseInstaller
Base class for DBMS-specific installation helper classes.
Definition: DatabaseInstaller.php:33
plain
either a plain
Definition: hooks.txt:2007
MssqlInstaller\preUpgrade
preUpgrade()
Allow DB installers a chance to make checks before upgrade.
Definition: MssqlInstaller.php:238
MssqlInstaller\databaseExists
databaseExists( $dbName)
Try to see if a given database exists.
Definition: MssqlInstaller.php:690
MssqlInstaller
Class for setting up the MediaWiki database using Microsoft SQL Server.
Definition: MssqlInstaller.php:34
MssqlInstaller\getName
getName()
Definition: MssqlInstaller.php:70
MssqlInstaller\openConnection
openConnection()
Definition: MssqlInstaller.php:205
MssqlInstaller\canCreateAccounts
canCreateAccounts()
Return true if the install user can create accounts.
Definition: MssqlInstaller.php:264
MssqlInstaller\$minimumVersion
$minimumVersion
Definition: MssqlInstaller.php:54
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Html\openElement
static openElement( $element, $attribs=[])
Identical to rawElement(), but has no third parameter and omits the end tag (and the self-closing '/'...
Definition: Html.php:251
DatabaseInstaller\setVar
setVar( $name, $value)
Convenience alias for $this->parent->setVar()
Definition: DatabaseInstaller.php:470
DatabaseInstaller\setVarsFromRequest
setVarsFromRequest( $varNames)
Convenience function to set variables based on form data.
Definition: DatabaseInstaller.php:576
Wikimedia\Rdbms\DBConnectionError
Definition: DBConnectionError.php:26
LocalSettingsGenerator\escapePhpString
static escapePhpString( $string)
Returns the escaped version of a string of php code.
Definition: LocalSettingsGenerator.php:114
MssqlInstaller\getGlobalDefaults
getGlobalDefaults()
Get a name=>value map of MW configuration globals for the default values.
Definition: MssqlInstaller.php:656
wfMessage
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
$wgDBuser
$wgDBuser
Database username.
Definition: DefaultSettings.php:1765
DatabaseInstaller\$db
Database $db
The database connection.
Definition: DatabaseInstaller.php:49
MssqlInstaller\getSettingsForm
getSettingsForm()
Definition: MssqlInstaller.php:361
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
MssqlInstaller\$internalDefaults
$internalDefaults
Definition: MssqlInstaller.php:46
DatabaseInstaller\getCheckBox
getCheckBox( $var, $label, $attribs=[], $helpData="")
Get a labelled checkbox to configure a local boolean variable.
Definition: DatabaseInstaller.php:536