/extensions/SemanticWatchlist/includes/SWL_Group.php

https://github.com/ChuguluGames/mediawiki-svn · PHP · 457 lines · 184 code · 58 blank · 215 comment · 27 complexity · f052614b8cb6d9bddd02db3eb9b625f3 MD5 · raw file

  1. <?php
  2. /**
  3. * Static class with functions interact with watchlist groups.
  4. *
  5. * @since 0.1
  6. *
  7. * @file SWL_Groups.php
  8. * @ingroup SemanticWatchlist
  9. *
  10. * @licence GNU GPL v3 or later
  11. * @author Jeroen De Dauw < jeroendedauw@gmail.com >
  12. */
  13. class SWLGroup {
  14. /**
  15. * The ID of the group; the group_id field in swl_groups.
  16. * When creating a new group, this will be null, and
  17. * automatically set after writing the group to the DB.
  18. *
  19. * @since 0.1
  20. *
  21. * @var integer or null
  22. */
  23. protected $id;
  24. /**
  25. * Name of the group.
  26. *
  27. * @since 0.1
  28. *
  29. * @var string
  30. */
  31. protected $name;
  32. /**
  33. * List of categories this group covers.
  34. *
  35. * @since 0.1
  36. *
  37. * @var array of string
  38. */
  39. protected $categories;
  40. /**
  41. * List of namespaces IDs of namespaces this group covers.
  42. *
  43. * @since 0.1
  44. *
  45. * @var array of integer
  46. */
  47. protected $namespaces = array();
  48. /**
  49. * List of SMW properties this group covers.
  50. *
  51. * @since 0.1
  52. *
  53. * @var array of string
  54. */
  55. protected $properties;
  56. /**
  57. * List of SMW concepts this group covers.
  58. *
  59. * @since 0.1
  60. *
  61. * @var array of string
  62. */
  63. protected $concepts;
  64. /**
  65. * Cached list of IDs of users that are watching this group,
  66. * or false if this data has not been obtained yet.
  67. *
  68. * @since 0.1
  69. *
  70. * @var array of integer or false
  71. */
  72. protected $watchingUsers = false;
  73. /**
  74. * Creates a new instance of SWLGroup from a DB result.
  75. *
  76. * @since 0.1
  77. *
  78. * @param $group
  79. *
  80. * @return SWLGroup
  81. */
  82. public static function newFromDBResult( $group ) {
  83. return new SWLGroup(
  84. $group->group_id,
  85. $group->group_name,
  86. $group->group_categories == '' ? array() : explode( '|', $group->group_categories ),
  87. $group->group_namespaces == '' ? array() : explode( '|', $group->group_namespaces ),
  88. $group->group_properties == '' ? array() : explode( '|', $group->group_properties ),
  89. $group->group_concepts == '' ? array() : explode( '|', $group->group_group_concepts )
  90. );
  91. }
  92. /**
  93. * Constructor.
  94. *
  95. * @since 0.1
  96. *
  97. * @param integer $id Set to null when creating a new group.
  98. * @param string $name
  99. * @param array $categories List of category names
  100. * @param array $namespaces List of namespace names or IDs
  101. * @param array $properties List of property names
  102. * @param array $concepts List of concept names
  103. */
  104. public function __construct( $id, $name, array $categories, array $namespaces, array $properties, array $concepts ) {
  105. $this->id = $id;
  106. $this->name = $name;
  107. $this->categories = $categories;
  108. $this->properties = $properties;
  109. $this->concepts = $concepts;
  110. foreach ( $namespaces as $ns ) {
  111. if ( preg_match( "/^-?([0-9])+$/", $ns ) ) {
  112. $this->namespaces[] = $ns;
  113. }
  114. elseif ( $ns == '' || strtolower( $ns ) == 'main' ) {
  115. $this->namespaces[] = 0;
  116. }
  117. else {
  118. $ns = MWNamespace::getCanonicalIndex( strtolower( $ns ) );
  119. if ( !is_null( $ns ) ) {
  120. $this->namespaces[] = $ns;
  121. }
  122. }
  123. }
  124. }
  125. /**
  126. * Writes the group to the database, either updating it
  127. * when it already exists, or inserting it when it doesn't.
  128. *
  129. * @since 0.1
  130. *
  131. * @return boolean Success indicator
  132. */
  133. public function writeToDB() {
  134. if ( is_null( $this->id ) ) {
  135. return $this->insertIntoDB();
  136. }
  137. else {
  138. return $this->updateInDB();
  139. }
  140. }
  141. /**
  142. * Updates the group in the database.
  143. *
  144. * @since 0.1
  145. *
  146. * @return boolean Success indicator
  147. */
  148. protected function updateInDB() {
  149. $dbr = wfGetDB( DB_MASTER );
  150. return $dbr->update(
  151. 'swl_groups',
  152. array(
  153. 'group_name' => $this->name,
  154. 'group_properties' => implode( '|', $this->properties ),
  155. 'group_categories' => implode( '|', $this->categories ),
  156. 'group_namespaces' => implode( '|', $this->namespaces ),
  157. 'group_concepts' => implode( '|', $this->concepts ),
  158. ),
  159. array( 'group_id' => $this->id )
  160. );
  161. }
  162. /**
  163. * Inserts the group into the database.
  164. *
  165. * @since 0.1
  166. *
  167. * @return boolean Success indicator
  168. */
  169. protected function insertIntoDB() {
  170. $dbr = wfGetDB( DB_MASTER );
  171. $result = $dbr->insert(
  172. 'swl_groups',
  173. array(
  174. 'group_name' => $this->name,
  175. 'group_properties' => $this->properties,
  176. 'group_categories' => $this->categories,
  177. 'group_namespaces' => $this->namespaces,
  178. 'group_concepts' => $this->concepts,
  179. )
  180. );
  181. $this->id = $dbr->insertId();
  182. return $result;
  183. }
  184. /**
  185. * Returns the categories specified by the group.
  186. *
  187. * @since 0.1
  188. *
  189. * @return array[string]
  190. */
  191. public function getCategories() {
  192. return $this->categories;
  193. }
  194. /**
  195. * Returns the namespaces specified by the group.
  196. *
  197. * @since 0.1
  198. *
  199. * @return array[integer]
  200. */
  201. public function getNamespaces() {
  202. return $this->namespaces;
  203. }
  204. /**
  205. * Returns the properties specified by the group as strings (serializations of SMWDIProperty).
  206. *
  207. * @since 0.1
  208. *
  209. * @return array[string]
  210. */
  211. public function getProperties() {
  212. return $this->properties;
  213. }
  214. /**
  215. * Returns the properties specified by the group as SMWDIProperty objects.
  216. *
  217. * @since 0.1
  218. *
  219. * @return array[SMWDIProperty]
  220. */
  221. public function getPropertyObjects() {
  222. $properties = array();
  223. foreach ( $this->properties as $property ) {
  224. $properties[] = SMWDIProperty::newFromSerialization( $property );
  225. }
  226. return $properties;
  227. }
  228. /**
  229. * Returns the concepts specified by the group.
  230. *
  231. * @since 0.1
  232. *
  233. * @return array[string]
  234. */
  235. public function getConcepts() {
  236. return $this->concepts;
  237. }
  238. /**
  239. * Returns the group database id.
  240. *
  241. * @since 0.1
  242. *
  243. * @return integer
  244. */
  245. public function getId() {
  246. return $this->id;
  247. }
  248. /**
  249. * Returns the group name.
  250. *
  251. * @since 0.1
  252. *
  253. * @return string
  254. */
  255. public function getName() {
  256. return $this->name;
  257. }
  258. /**
  259. * Returns whether the group contains the specified page.
  260. *
  261. * @since 0.1
  262. *
  263. * @param Title $title
  264. *
  265. * @return boolean
  266. */
  267. public function coversPage( Title $title ) {
  268. return $this->categoriesCoverPage( $title )
  269. && $this->namespacesCoversPage( $title )
  270. && $this->conceptsCoverPage( $title );
  271. }
  272. /**
  273. * Returns whether the namespaces of the group cover the specified page.
  274. *
  275. * @since 0.1
  276. *
  277. * @param Title $title
  278. *
  279. * @return boolean
  280. */
  281. public function namespacesCoversPage( Title $title ) {
  282. if ( count( $this->namespaces ) > 0 ) {
  283. if ( !in_array( $title->getNamespace(), $this->namespaces ) ) {
  284. return false;
  285. }
  286. }
  287. return true;
  288. }
  289. /**
  290. * Returns whether the catgeories of the group cover the specified page.
  291. *
  292. * @since 0.1
  293. *
  294. * @param Title $title
  295. *
  296. * @return boolean
  297. */
  298. public function categoriesCoverPage( Title $title ) {
  299. if ( count( $this->categories ) == 0 ) {
  300. return true;
  301. }
  302. $foundMatch = false;
  303. $cats = array_keys( $title->getParentCategories() );
  304. if ( count( $cats ) == 0 ) {
  305. return false;
  306. }
  307. global $wgContLang;
  308. $catPrefix = $wgContLang->getNSText( NS_CATEGORY ) . ':';
  309. foreach ( $this->categories as $groupCategory ) {
  310. $foundMatch = in_array( $catPrefix . $groupCategory, $cats );
  311. if ( $foundMatch ) {
  312. break;
  313. }
  314. }
  315. return $foundMatch;
  316. }
  317. /**
  318. * Returns whether the concepts of the group cover the specified page.
  319. *
  320. * @since 0.1
  321. *
  322. * @param Title $title
  323. *
  324. * @return boolean
  325. */
  326. public function conceptsCoverPage( Title $title ) {
  327. if ( count( $this->concepts ) == 0 ) {
  328. return true;
  329. }
  330. $foundMatch = false;
  331. foreach ( $this->concepts as $groupConcept ) {
  332. $queryDescription = new SMWConjunction();
  333. $conceptTitle = Title::newFromText( $groupConcept, SMW_NS_CONCEPT );
  334. $queryDescription->addDescription( new SMWConceptDescription( SMWDIWikiPage::newFromTitle( $conceptTitle ) ) );
  335. $queryDescription->addDescription( new SMWValueDescription( SMWDIWikiPage::newFromTitle( $title ) ) );
  336. $query = new SMWQuery( $queryDescription );
  337. $query->querymode = SMWQuery::MODE_COUNT;
  338. /* SMWQueryResult */ $result = smwfGetStore()->getQueryResult( $query );
  339. $foundMatch = $result->getCount() > 0;
  340. if ( $foundMatch ) {
  341. break;
  342. }
  343. }
  344. return $foundMatch;
  345. }
  346. /**
  347. * Returns the IDs of the users watching the group.
  348. *
  349. * @since 0.1
  350. *
  351. * @return array of integer
  352. */
  353. public function getWatchingUsers() {
  354. if ( $this->watchingUsers == false ) {
  355. $dbr = wfGetDB( DB_SLAVE );
  356. $users = $dbr->select(
  357. 'swl_users_per_group',
  358. array(
  359. 'upg_user_id'
  360. ),
  361. array(
  362. 'upg_group_id' => $this->getId()
  363. )
  364. );
  365. $userIds = array();
  366. foreach ( $users as $user ) {
  367. $userIds[] = $user->upg_user_id;
  368. }
  369. $this->watchingUsers = $userIds;
  370. }
  371. return $this->watchingUsers;
  372. }
  373. /**
  374. * Returns if the group is watched by the specified user or not.
  375. *
  376. * @since 0.1
  377. *
  378. * @param User $user
  379. *
  380. * @return boolean
  381. */
  382. public function isWatchedByUser( User $user ) {
  383. return in_array( $user->getId(), $this->getWatchingUsers() );
  384. }
  385. /**
  386. * Gets all the watching users and passes them, together with the specified
  387. * changes and the group object itself, to the SWLGroupNotify hook.
  388. *
  389. * @since 0.1
  390. *
  391. * @param SMWChangeSet $changes
  392. */
  393. public function notifyWatchingUsers( SWLChangeSet $changes ) {
  394. $users = $this->getWatchingUsers();
  395. if ( $changes->hasChanges( true ) ) {
  396. wfRunHooks( 'SWLGroupNotify', array( $this, $users, $changes ) );
  397. }
  398. }
  399. }