Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.sql |
— | — | @@ -0,0 +1,18 @@ |
| 2 | +-- MySQL version of the database schema for the Semantic Watchlist extension. |
| 3 | +-- Licence: GNU GPL v3+ |
| 4 | +-- Author: Jeroen De Dauw < jeroendedauw@gmail.com > |
| 5 | + |
| 6 | +-- Watch groups |
| 7 | +CREATE TABLE IF NOT EXISTS /*$wgDBprefix*/swl_groups ( |
| 8 | + group_id INT(10) unsigned NOT NULL auto_increment PRIMARY KEY, |
| 9 | + group_categories BLOB NOT NULL, -- No need to have this stuff relational, so keep it simple |
| 10 | + group_namespaces BLOB NOT NULL, -- No need to have this stuff relational, so keep it simple |
| 11 | + group_properties BLOB NOT NULL, -- No need to have this stuff relational, so keep it simple |
| 12 | +) /*$wgDBTableOptions*/; |
| 13 | + |
| 14 | +-- Watchlists |
| 15 | +CREATE TABLE IF NOT EXISTS /*$wgDBprefix*/swl_watchlists ( |
| 16 | + list _id INT(10) unsigned NOT NULL auto_increment PRIMARY KEY, |
| 17 | + list_user_id INT(10) unsigned NOT NULL UNIQUE, -- TODO |
| 18 | + -- TODO |
| 19 | +) /*$wgDBTableOptions*/; |
\ No newline at end of file |
Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.settings.php |
— | — | @@ -19,3 +19,4 @@ |
20 | 20 | die( 'Not an entry point.' ); |
21 | 21 | } |
22 | 22 | |
| 23 | +$egSWLEnableEmailNotify = true; |
Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.php |
— | — | @@ -67,6 +67,15 @@ |
68 | 68 | |
69 | 69 | require_once 'SemanticWatchlist.settings.php'; |
70 | 70 | |
| 71 | +// This overrides the default value for the setting in SMW, as the behaviour it enables is used by this extension. |
| 72 | +$smwgCheckChangesBeforeUpdate = true; |
| 73 | + |
71 | 74 | $wgAutoloadClasses['SWLHooks'] = dirname( __FILE__ ) . '/SemanticWatchlist.hooks.php'; |
72 | 75 | |
73 | | -$wgHooks['SMWStore::updateDataBefore'][] = 'SWLHooks::onBeforeDataUpdate'; |
| 76 | +$wgHooks['LoadExtensionSchemaUpdates'][] = 'SWLHooks::onSchemaUpdate'; |
| 77 | + |
| 78 | +$wgHooks['SMWStore::dataChanged'][] = 'SWLHooks::onBeforeDataUpdate'; |
| 79 | + |
| 80 | +if ( $egSWLEnableEmailNotify ) { |
| 81 | + $wgHooks['SWLGroupNotify'][] = 'SWLHooks::onGroupNotify'; |
| 82 | +} |
Index: trunk/extensions/SemanticWatchlist/SemanticWatchlist.hooks.php |
— | — | @@ -12,9 +12,147 @@ |
13 | 13 | * @author Jeroen De Dauw < jeroendedauw@gmail.com > |
14 | 14 | */ |
15 | 15 | final class SWLHooks { |
16 | | - |
17 | | - public static function onBeforeDataUpdate( SMWStore $store, SMWSemanticData $data ) { |
18 | | - |
| 16 | + |
| 17 | + /** |
| 18 | + * Handle the onDataChanged hook of SMW >1.6, which gets called |
| 19 | + * every time the value of a propery changes somewhere. |
| 20 | + * |
| 21 | + * @since 0.1 |
| 22 | + * |
| 23 | + * @param SMWStore $store |
| 24 | + * @param SMWSemanticData $data |
| 25 | + */ |
| 26 | + public static function onDataChanged( SMWStore $store, SMWSemanticData $data ) { |
| 27 | + $title = $data->getSubject()->getTitle(); |
| 28 | + $groups = self::getMatchingWatchGroups( $title ); |
| 29 | + |
| 30 | + foreach ( $groups as $group ) { |
| 31 | + $matches = self::getIfGroupMatches( $group, $title ); |
| 32 | + |
| 33 | + if ( $matches ) { |
| 34 | + self::notifyUsersForGroup( $group, $data ); |
| 35 | + wfRunHooks( 'SWLGroupNotify', array( $group, $data ) ); |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + |
19 | 40 | } |
| 41 | + |
| 42 | + /** |
| 43 | + * Returns all watchlist groups that watch the specified page. |
| 44 | + * |
| 45 | + * @since 0.1 |
| 46 | + * |
| 47 | + * @param Title $title |
| 48 | + * |
| 49 | + * @return array |
| 50 | + */ |
| 51 | + protected static function getMatchingWatchGroups( Title $title ) { |
| 52 | + $dbr = wfGetDB( DB_SLAVE ); |
| 53 | + |
| 54 | + $groups = $dbr->select( 'swl_groups', array( 'group_id', 'group_categories', 'group_namespaces', 'group_properties' ) ); |
| 55 | + |
| 56 | + $matchingGroups = array(); |
| 57 | + |
| 58 | + foreach ( $groups as $group ) { |
| 59 | + if ( self::getIfGroupMatches( $group, $title ) ) { |
| 60 | + $matchingGroups[] = $group; |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + return $matchingGroups; |
| 65 | + } |
| 66 | + |
| 67 | + /** |
| 68 | + * Determines and returns if the specified watchlist group covers |
| 69 | + *the provided page or not. |
| 70 | + * |
| 71 | + * @since 0.1 |
| 72 | + * |
| 73 | + * @param $group |
| 74 | + * |
| 75 | + * @return boolean |
| 76 | + */ |
| 77 | + protected static function getIfGroupMatches( $group, Title $title ) { |
| 78 | + |
| 79 | + } |
| 80 | + |
| 81 | + public static function onGroupNotify( $group, SMWSemanticData $data ) { |
| 82 | + self::notifyUsersForGroup( $group, $data ); |
| 83 | + } |
| 84 | + |
| 85 | + /** |
| 86 | + * Notifies all users that are watching a group and that should be notified |
| 87 | + * of the provided changes. |
| 88 | + * |
| 89 | + * @since 0.1 |
| 90 | + * |
| 91 | + * @param $group |
| 92 | + * @param SMWSemanticData $data |
| 93 | + */ |
| 94 | + protected static function notifyUsersForGroup( $group, SMWSemanticData $data ) { |
| 95 | + $users = self::getUsersForGroup( $group ); |
| 96 | + |
| 97 | + foreach ( $users as $userId ) { |
| 98 | + if ( self::userShouldBeNotified( $userId ) ) { |
| 99 | + self::notifyUserOfChangesToGroup( $userId, $group, $data ); |
| 100 | + } |
| 101 | + } |
| 102 | + } |
| 103 | + |
| 104 | + /** |
| 105 | + * Returns the list of users watching the specified watchlist group. |
| 106 | + * |
| 107 | + * @since 0.1 |
| 108 | + * |
| 109 | + * @param $group |
| 110 | + * |
| 111 | + * @return array |
| 112 | + */ |
| 113 | + protected static function getUsersForGroup( $group ) { |
| 114 | + |
| 115 | + } |
| 116 | + |
| 117 | + /** |
| 118 | + * Determines and returns if a certain user should be notified of changes |
| 119 | + * or not (in case this already happened, so this extension doesn't spam). |
| 120 | + * |
| 121 | + * @since 0.1 |
| 122 | + * |
| 123 | + * @param integer $userId |
| 124 | + * |
| 125 | + * @return boolean |
| 126 | + */ |
| 127 | + protected static function userShouldBeNotified( $userId ) { |
| 128 | + |
| 129 | + } |
| 130 | + |
| 131 | + protected static function notifyUserOfChangesToGroup( $userId, $group, SMWSemanticData $data ) { |
| 132 | + |
| 133 | + } |
| 134 | + |
| 135 | + /** |
| 136 | + * Schema update to set up the needed database tables. |
| 137 | + * |
| 138 | + * @since 0.1 |
| 139 | + * |
| 140 | + * @param DatabaseUpdater $updater |
| 141 | + * |
| 142 | + * @return true |
| 143 | + */ |
| 144 | + public static function onSchemaUpdate( /* DatabaseUpdater */ $updater = null ) { |
| 145 | + global $wgDBtype; |
| 146 | + |
| 147 | + if ( $wgDBtype == 'mysql' ) { |
| 148 | + $updater->addExtensionUpdate( array( |
| 149 | + 'addTable', |
| 150 | + 'swl_groups', |
| 151 | + dirname( __FILE__ ) . '/SemanticWatchlist.sql', |
| 152 | + true |
| 153 | + ) ); |
| 154 | + } |
| 155 | + |
| 156 | + return true; |
| 157 | + } |
20 | 158 | |
21 | 159 | } |
\ No newline at end of file |