PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/extensions/SemanticMediaWiki/includes/datavalues/SMW_DV_WikiPage.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 381 lines | 206 code | 35 blank | 140 comment | 69 complexity | 8a13da0e6c0e108dbc73d2c902944926 MD5 | raw file
  1. <?php
  2. /**
  3. * @file
  4. * @ingroup SMWDataValues
  5. */
  6. /**
  7. * This datavalue implements special processing suitable for defining
  8. * wikipages as values of properties.
  9. *
  10. * The class can support general wiki pages, or pages of a fixed
  11. * namespace, Whether a namespace is fixed is decided based on the
  12. * type ID when the object is constructed.
  13. *
  14. * @author Nikolas Iwan
  15. * @author Markus Krötzsch
  16. * @ingroup SMWDataValues
  17. */
  18. class SMWWikiPageValue extends SMWDataValue {
  19. /**
  20. * The isolated title as text. Always set when this object is valid.
  21. * @var string
  22. */
  23. protected $m_textform;
  24. /**
  25. * Fragment text for user-specified title. Not stored, but kept for
  26. * printout on page.
  27. * @var string
  28. */
  29. protected $m_fragment = '';
  30. /**
  31. * Full titletext with prefixes, including interwiki prefix.
  32. * Set to empty string if not computed yet.
  33. * @var string
  34. */
  35. protected $m_prefixedtext = '';
  36. /**
  37. * Cache for the related MW page ID.
  38. * Set to -1 if not computed yet.
  39. * @var integer
  40. */
  41. protected $m_id = -1;
  42. /**
  43. * Cache for the related MW title object.
  44. * Set to null if not computed yet.
  45. * @var Title
  46. */
  47. protected $m_title = null;
  48. /**
  49. * If this has a value other than NS_MAIN, the datavalue will only
  50. * accept pages in this namespace. This field is initialized when
  51. * creating the object (based on the type id or base on the preference
  52. * of some subclass); it is not usually changed afterwards.
  53. * @var integer
  54. */
  55. protected $m_fixNamespace = NS_MAIN;
  56. public function __construct( $typeid ) {
  57. parent::__construct( $typeid );
  58. switch ( $typeid ) {
  59. case '__typ':
  60. $this->m_fixNamespace = SMW_NS_TYPE;
  61. break;
  62. case '_wpp' : case '__sup':
  63. $this->m_fixNamespace = SMW_NS_PROPERTY;
  64. break;
  65. case '_wpc' : case '__suc': case '__sin':
  66. $this->m_fixNamespace = NS_CATEGORY;
  67. break;
  68. case '_wpf' : case '__spf':
  69. $this->m_fixNamespace = SF_NS_FORM;
  70. break;
  71. default: // case '_wpg':
  72. $this->m_fixNamespace = NS_MAIN;
  73. }
  74. }
  75. protected function parseUserValue( $value ) {
  76. global $wgContLang;
  77. $value = ltrim( rtrim( $value, ' ]' ), ' [' ); // support inputs like " [[Test]] "
  78. if ( $this->m_caption === false ) {
  79. $this->m_caption = $value;
  80. }
  81. if ( $value != '' ) {
  82. $this->m_title = Title::newFromText( $value, $this->m_fixNamespace );
  83. ///TODO: Escape the text so users can see punctuation problems (bug 11666).
  84. if ( $this->m_title === null ) {
  85. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  86. $this->addError( wfMsgForContent( 'smw_notitle', $value ) );
  87. } elseif ( ( $this->m_fixNamespace != NS_MAIN ) &&
  88. ( $this->m_fixNamespace != $this->m_title->getNamespace() ) ) {
  89. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  90. $this->addError( wfMsgForContent( 'smw_wrong_namespace', $wgContLang->getNsText( $this->m_fixNamespace ) ) );
  91. } else {
  92. $this->m_textform = $this->m_title->getText();
  93. $this->m_fragment = $this->m_title->getFragment();
  94. $this->m_prefixedtext = '';
  95. $this->m_id = -1; // unset id
  96. $this->m_dataitem = SMWDIWikiPage::newFromTitle( $this->m_title, $this->m_typeid );
  97. }
  98. } else {
  99. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  100. $this->addError( wfMsgForContent( 'smw_notitle', $value ) );
  101. }
  102. }
  103. /**
  104. * @see SMWDataValue::loadDataItem()
  105. * @param $dataitem SMWDataItem
  106. * @return boolean
  107. */
  108. protected function loadDataItem( SMWDataItem $dataItem ) {
  109. if ( $dataItem->getDIType() == SMWDataItem::TYPE_WIKIPAGE ) {
  110. $this->m_dataitem = $dataItem;
  111. $this->m_textform = str_replace( '_', ' ', $dataItem->getDBkey() );
  112. $this->m_id = -1;
  113. $this->m_title = null;
  114. $this->m_fragment = $this->m_prefixedtext = '';
  115. $this->m_caption = false;
  116. if ( ( $this->m_fixNamespace != NS_MAIN ) && ( $this->m_fixNamespace != $dataItem->getNamespace() ) ) {
  117. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  118. $this->addError( wfMsgForContent( 'smw_notitle', $this->getPrefixedText() ) );
  119. }
  120. return true;
  121. } else {
  122. return false;
  123. }
  124. }
  125. public function getShortWikiText( $linked = null ) {
  126. if ( ( $linked === null ) || ( $linked === false ) || ( $this->m_outformat == '-' ) || ( !$this->isValid() ) || ( $this->m_caption === '' ) ) {
  127. return $this->getCaption();
  128. } else {
  129. return '[[:' . str_replace( "'", '&#x0027;', $this->getPrefixedText() ) .
  130. ( $this->m_fragment ? "#{$this->m_fragment}" : '' ) . '|' . $this->getCaption() . ']]';
  131. }
  132. }
  133. public function getShortHTMLText( $linker = null ) {
  134. if ( ( $linker !== null ) && ( $this->m_caption !== '' ) && ( $this->m_outformat != '-' ) ) $this->getTitle(); // init the Title object, may reveal hitherto unnoticed errors
  135. if ( ( $linker === null ) || ( !$this->isValid() ) || ( $this->m_outformat == '-' ) || ( $this->m_caption === '' ) ) {
  136. return htmlspecialchars( $this->getCaption() );
  137. } elseif ( $this->getNamespace() == NS_MEDIA ) { // this extra case *is* needed
  138. return $linker->makeMediaLinkObj( $this->getTitle(), $this->getCaption() );
  139. } else {
  140. return $linker->makeLinkObj( $this->getTitle(), htmlspecialchars( $this->getCaption() ) );
  141. }
  142. }
  143. /**
  144. * @note The getLong... functions of this class always hide the fragment. Fragments are currently
  145. * not stored, and hence should not be shown in the Factbox (where the getLongWikiText method is used).
  146. * In all other uses, values come from the store and do not have fragments anyway.
  147. */
  148. public function getLongWikiText( $linked = null ) {
  149. if ( !$this->isValid() ) {
  150. return $this->getErrorText();
  151. }
  152. if ( ( $linked === null ) || ( $linked === false ) || ( $this->m_outformat == '-' ) ) {
  153. return $this->m_fixNamespace == NS_MAIN ? $this->getPrefixedText():$this->getText();
  154. } elseif ( $this->m_dataitem->getNamespace() == NS_FILE ) {
  155. // For images and other files, embed them and display
  156. // their name, instead of just displaying their name
  157. $fileName = str_replace( "'", '&#x0027;', $this->getPrefixedText() );
  158. return '[[' . $fileName . '|' . $this->m_textform . '|frameless|border|text-top]]' . "<br />\n" . '[[:' . $fileName . '|' . $this->m_textform . ']]';
  159. } else {
  160. return '[[:' . str_replace( "'", '&#x0027;', $this->getPrefixedText() ) . '|' . $this->m_textform . ']]';
  161. }
  162. }
  163. public function getLongHTMLText( $linker = null ) {
  164. if ( ( $linker !== null ) && ( $this->m_outformat != '-' ) ) { $this->getTitle(); } // init the Title object, may reveal hitherto unnoticed errors
  165. if ( !$this->isValid() ) {
  166. return $this->getErrorText();
  167. }
  168. if ( ( $linker === null ) || ( $this->m_outformat == '-' ) ) {
  169. return htmlspecialchars( $this->m_fixNamespace == NS_MAIN ? $this->getPrefixedText():$this->getText() );
  170. } elseif ( $this->getNamespace() == NS_MEDIA ) { // this extra case is really needed
  171. return $linker->makeMediaLinkObj( $this->getTitle(), $this->m_textform );
  172. } else { // all others use default linking, no embedding of images here
  173. return $linker->makeLinkObj( $this->getTitle(), htmlspecialchars( $this->m_textform ) );
  174. }
  175. }
  176. public function getWikiValue() {
  177. if ( $this->m_fixNamespace != NS_MAIN ) { // no explicit namespace needed!
  178. return $this->getText();
  179. } elseif ( $this->m_dataitem->getNamespace() == NS_CATEGORY ) {
  180. // escape to enable use in links; todo: not generally required/suitable :-/
  181. return ':' . $this->getPrefixedText();
  182. } else {
  183. return $this->getPrefixedText();
  184. }
  185. }
  186. public function getHash() {
  187. return $this->isValid() ? $this->getPrefixedText() : implode( "\t", $this->getErrors() );
  188. }
  189. /**
  190. * Create links to mapping services based on a wiki-editable message.
  191. * The parameters available to the message are:
  192. * $1: urlencoded article name (no namespace)
  193. *
  194. * @return array
  195. */
  196. protected function getServiceLinkParams() {
  197. if ( $this->isValid() ) {
  198. return array( rawurlencode( str_replace( '_', ' ', $this->m_dataitem->getDBkey() ) ) );
  199. } else {
  200. return array();
  201. }
  202. }
  203. ///// special interface for wiki page values
  204. /**
  205. * Return according Title object or null if no valid value was set.
  206. * null can be returned even if this object returns true for isValid(),
  207. * since the latter function does not check whether MediaWiki can really
  208. * make a Title out of the given data.
  209. * However, isValid() will return false *after* this function failed in
  210. * trying to create a title.
  211. *
  212. * @return Title
  213. */
  214. public function getTitle() {
  215. if ( ( $this->isValid() ) && ( $this->m_title === null ) ) {
  216. $this->m_title = $this->m_dataitem->getTitle();
  217. if ( $this->m_title === null ) { // should not normally happen, but anyway ...
  218. global $wgContLang;
  219. smwfLoadExtensionMessages( 'SemanticMediaWiki' );
  220. $this->addError( wfMsgForContent( 'smw_notitle', $wgContLang->getNsText( $this->m_dataitem->getNamespace() ) . ':' . $this->m_dataitem->getDBkey() ) );
  221. }
  222. }
  223. return $this->m_title;
  224. }
  225. /**
  226. * Get MediaWiki's ID for this value, if any.
  227. */
  228. public function getArticleID() {
  229. if ( $this->m_id === false ) {
  230. $this->m_id = ( $this->getTitle() !== null ) ? $this->m_title->getArticleID() : 0;
  231. }
  232. return $this->m_id;
  233. }
  234. /**
  235. * Get namespace constant for this value.
  236. */
  237. public function getNamespace() {
  238. return $this->m_dataitem->getNamespace();
  239. }
  240. /**
  241. * Get DBKey for this value. Subclasses that allow for values that do not
  242. * correspond to wiki pages may choose a DB key that is not a legal title
  243. * DB key but rather another suitable internal ID. Thus it is not suitable
  244. * to use this method in places where only MediaWiki Title keys are allowed.
  245. */
  246. public function getDBkey() {
  247. return $this->m_dataitem->getDBkey();
  248. }
  249. /// Get text label for this value.
  250. public function getText() {
  251. return str_replace( '_', ' ', $this->m_dataitem->getDBkey() );
  252. }
  253. /**
  254. * Get the prefixed text for this value, including a localised namespace
  255. * prefix.
  256. *
  257. * @return string
  258. */
  259. public function getPrefixedText() {
  260. global $wgContLang;
  261. if ( $this->m_prefixedtext == '' ) {
  262. if ( $this->isValid() ) {
  263. $nstext = $wgContLang->getNSText( $this->m_dataitem->getNamespace() );
  264. $this->m_prefixedtext = ( $this->m_dataitem->getInterwiki() != '' ? $this->m_dataitem->getInterwiki() . ':' : '' ) .
  265. ( $nstext != '' ? "$nstext:" : '' ) . $this->m_textform;
  266. } else {
  267. $this->m_prefixedtext = 'NO_VALID_VALUE';
  268. }
  269. }
  270. return $this->m_prefixedtext;
  271. }
  272. /**
  273. * Get interwiki prefix or empty string.
  274. */
  275. public function getInterwiki() {
  276. return $this->m_dataitem->getInterwiki();
  277. }
  278. /**
  279. * Get the (default) caption for this value.
  280. * If a fixed namespace is set, we do not return the namespace prefix explicitly.
  281. */
  282. protected function getCaption() {
  283. return $this->m_caption !== false ? $this->m_caption :
  284. ( $this->m_fixNamespace == NS_MAIN ? $this->getPrefixedText() : $this->getText() );
  285. }
  286. /**
  287. * Find the sortkey for this object.
  288. *
  289. * @deprecated Use SMWStore::getWikiPageSortKey().
  290. *
  291. * @return string sortkey
  292. */
  293. public function getSortKey() {
  294. return smwfGetStore()->getWikiPageSortKey( $this->m_dataitem );
  295. }
  296. /**
  297. * Init this data value object based on a given Title object.
  298. * @deprecated Use setDataItem(); it's easy to create an SMWDIWikiPage from a Title, will vanish before SMW 1.7
  299. */
  300. public function setTitle( $title ) {
  301. $diWikiPage = SMWDIWikiPage::newFromTitle( $title );
  302. $this->setDataItem( $diWikiPage );
  303. $this->m_title = $title; // optional, just for efficiency
  304. }
  305. /**
  306. * @deprecated Use setDataItem()
  307. */
  308. public function setValues( $dbkey, $namespace, $id = false, $interwiki = '' ) {
  309. $dataItem = new SMWDIWikiPage( $dbkey, $namespace, $interwiki );
  310. $this->setDataItem( $dataItem);
  311. }
  312. /**
  313. * Static function for creating a new wikipage object from
  314. * data as it is typically stored internally. In particular,
  315. * the title string is supposed to be in DB key form.
  316. *
  317. * @note The resulting wikipage object might be invalid if
  318. * the provided title is not allowed. An object is returned
  319. * in any case.
  320. *
  321. * @deprecated This method will vanish before SMW 1.7. If you really need this, simply copy its code.
  322. *
  323. * @return SMWWikiPageValue
  324. */
  325. static public function makePage( $dbkey, $namespace, $ignoredParameter = '', $interwiki = '' ) {
  326. $diWikiPage = new SMWDIWikiPage( $dbkey, $namespace, $interwiki );
  327. $dvWikiPage = new SMWWikiPageValue( '_wpg' );
  328. $dvWikiPage->setDataItem( $diWikiPage );
  329. return $dvWikiPage;
  330. }
  331. /**
  332. * Static function for creating a new wikipage object from a
  333. * MediaWiki Title object.
  334. *
  335. * @deprecated This method will vanish before SMW 1.7. If you really need this, simply copy its code.
  336. *
  337. * @return SMWWikiPageValue
  338. */
  339. static public function makePageFromTitle( Title $title ) {
  340. $dvWikiPage = new SMWWikiPageValue( '_wpg' );
  341. $diWikiPage = SMWDIWikiPage::newFromTitle( $title );
  342. $dvWikiPage->setDataItem( $diWikiPage );
  343. $dvWikiPage->m_title = $title; // optional, just for efficiency
  344. return $dvWikiPage;
  345. }
  346. }