Licenses.php 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. /**
  3. * License selector for use on Special:Upload.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. * http://www.gnu.org/copyleft/gpl.html
  19. *
  20. * @file
  21. * @ingroup SpecialPage
  22. * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com>
  23. * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason
  24. */
  25. use MediaWiki\MediaWikiServices;
  26. /**
  27. * A License class for use on Special:Upload
  28. */
  29. class Licenses extends HTMLFormField {
  30. /** @var string */
  31. protected $msg;
  32. /** @var array */
  33. protected $lines = [];
  34. /** @var string */
  35. protected $html;
  36. /** @var string|null */
  37. protected $selected;
  38. /** #@- */
  39. /**
  40. * @param array $params
  41. */
  42. public function __construct( $params ) {
  43. parent::__construct( $params );
  44. $this->msg = static::getMessageFromParams( $params );
  45. $this->selected = null;
  46. $this->makeLines();
  47. }
  48. /**
  49. * @param array $params
  50. * @return string
  51. */
  52. protected static function getMessageFromParams( $params ) {
  53. if ( !empty( $params['licenses'] ) ) {
  54. return $params['licenses'];
  55. }
  56. // If the licenses page is in $wgForceUIMsgAsContentMsg (which is the case
  57. // on Commons), translations will be in the database, in subpages of this
  58. // message (e.g. MediaWiki:Licenses/<lang>)
  59. // If there is no such translation, the result will be '-' (the empty default
  60. // in the i18n files), so we'll need to force it to look up the actual licenses
  61. // in the default site language (= get the translation from MediaWiki:Licenses)
  62. // Also see https://phabricator.wikimedia.org/T3495
  63. $defaultMsg = wfMessage( 'licenses' )->inContentLanguage();
  64. if ( !$defaultMsg->exists() || $defaultMsg->plain() === '-' ) {
  65. $defaultMsg = wfMessage( 'licenses' )->inLanguage(
  66. MediaWikiServices::getInstance()->getContentLanguage() );
  67. }
  68. return $defaultMsg->plain();
  69. }
  70. /**
  71. * @param string $line
  72. * @return License
  73. */
  74. protected function buildLine( $line ) {
  75. return new License( $line );
  76. }
  77. /**
  78. * @private
  79. */
  80. protected function makeLines() {
  81. $levels = [];
  82. $lines = explode( "\n", $this->msg );
  83. foreach ( $lines as $line ) {
  84. if ( strpos( $line, '*' ) !== 0 ) {
  85. continue;
  86. } else {
  87. list( $level, $line ) = $this->trimStars( $line );
  88. if ( strpos( $line, '|' ) !== false ) {
  89. $obj = $this->buildLine( $line );
  90. $this->stackItem( $this->lines, $levels, $obj );
  91. } else {
  92. if ( $level < count( $levels ) ) {
  93. $levels = array_slice( $levels, 0, $level );
  94. }
  95. if ( $level == count( $levels ) ) {
  96. $levels[$level - 1] = $line;
  97. } elseif ( $level > count( $levels ) ) {
  98. $levels[] = $line;
  99. }
  100. }
  101. }
  102. }
  103. }
  104. /**
  105. * @param string $str
  106. * @return array
  107. */
  108. protected function trimStars( $str ) {
  109. $numStars = strspn( $str, '*' );
  110. return [ $numStars, ltrim( substr( $str, $numStars ), ' ' ) ];
  111. }
  112. /**
  113. * @param array &$list
  114. * @param array $path
  115. * @param mixed $item
  116. */
  117. protected function stackItem( &$list, $path, $item ) {
  118. $position =& $list;
  119. if ( $path ) {
  120. foreach ( $path as $key ) {
  121. $position =& $position[$key];
  122. }
  123. }
  124. $position[] = $item;
  125. }
  126. /**
  127. * @param array $tagset
  128. * @param int $depth
  129. * @return string
  130. */
  131. protected function makeHtml( $tagset, $depth = 0 ) {
  132. $html = '';
  133. foreach ( $tagset as $key => $val ) {
  134. if ( is_array( $val ) ) {
  135. $html .= $this->outputOption(
  136. $key, '',
  137. [
  138. 'disabled' => 'disabled',
  139. 'style' => 'color: GrayText', // for MSIE
  140. ],
  141. $depth
  142. );
  143. $html .= $this->makeHtml( $val, $depth + 1 );
  144. } else {
  145. $html .= $this->outputOption(
  146. $val->text, $val->template,
  147. [ 'title' => '{{' . $val->template . '}}' ],
  148. $depth
  149. );
  150. }
  151. }
  152. return $html;
  153. }
  154. /**
  155. * @param string $message
  156. * @param string $value
  157. * @param null|array $attribs
  158. * @param int $depth
  159. * @return string
  160. */
  161. protected function outputOption( $message, $value, $attribs = null, $depth = 0 ) {
  162. $msgObj = $this->msg( $message );
  163. $text = $msgObj->exists() ? $msgObj->text() : $message;
  164. $attribs['value'] = $value;
  165. if ( $value === $this->selected ) {
  166. $attribs['selected'] = 'selected';
  167. }
  168. $val = str_repeat( /* &nbsp */ "\u{00A0}", $depth * 2 ) . $text;
  169. return str_repeat( "\t", $depth ) . Xml::element( 'option', $attribs, $val ) . "\n";
  170. }
  171. /** #@- */
  172. /**
  173. * Accessor for $this->lines
  174. *
  175. * @return array
  176. */
  177. public function getLines() {
  178. return $this->lines;
  179. }
  180. /**
  181. * Accessor for $this->lines
  182. *
  183. * @return array
  184. *
  185. * @deprecated since 1.31 Use getLines() instead
  186. */
  187. public function getLicenses() {
  188. return $this->getLines();
  189. }
  190. /**
  191. * @inheritDoc
  192. */
  193. public function getInputHTML( $value ) {
  194. $this->selected = $value;
  195. // add a default "no license selected" option
  196. $default = $this->buildLine( '|nolicense' );
  197. array_unshift( $this->lines, $default );
  198. $html = $this->makeHtml( $this->getLines() );
  199. $attribs = [
  200. 'name' => $this->mName,
  201. 'id' => $this->mID
  202. ];
  203. if ( !empty( $this->mParams['disabled'] ) ) {
  204. $attribs['disabled'] = 'disabled';
  205. }
  206. $html = Html::rawElement( 'select', $attribs, $html );
  207. // remove default "no license selected" from lines again
  208. array_shift( $this->lines );
  209. return $html;
  210. }
  211. }