r113967 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113966‎ | r113967 | r113968 >
Date:22:51, 15 March 2012
Author:jeroendedauw
Status:deferred
Tags:
Comment:
work on adding special:StudentActivity
Modified paths:
  • /trunk/extensions/EducationProgram/EducationProgram.hooks.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.i18n.alias.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.i18n.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.settings.php (modified) (history)
  • /trunk/extensions/EducationProgram/specials/SpecialStudentActivity.php (added) (history)
  • /trunk/extensions/EducationProgram/sql/AddActivityStuff.sql (added) (history)
  • /trunk/extensions/EducationProgram/sql/EducationProgram.sql (modified) (history)

Diff [purge]

Index: trunk/extensions/EducationProgram/EducationProgram.settings.php
@@ -34,7 +34,8 @@
3535 ),
3636 'ambassadorCommonsUrl' => 'https://commons.wikimedia.org/wiki/Special:UploadWizard',
3737 'citylessCountries' => array( 'BT', 'BV', 'IO', 'VG', 'TD', 'CX', 'CC', 'KM', 'DJ', 'GQ', 'FK', 'FX', 'TF', 'GW', 'HM', 'KI', 'YT', 'MS', 'NR', 'NU', 'NF', 'PN', 'SH', 'PM', 'WS', 'SC', 'GS', 'SJ', 'TK', 'TP', 'TV', 'UM', 'VU', 'EH' ),
38 - 'ambassadorImgWidth' => 140
 38+ 'ambassadorImgWidth' => 140,
 39+ 'recentActivityLimit' => 24 * 60 * 60,
3940 );
4041 }
4142
Index: trunk/extensions/EducationProgram/EducationProgram.php
@@ -142,6 +142,7 @@
143143 $wgAutoloadClasses['SpecialOAProfile'] = dirname( __FILE__ ) . '/specials/SpecialOAProfile.php';
144144 $wgAutoloadClasses['SpecialCAProfile'] = dirname( __FILE__ ) . '/specials/SpecialCAProfile.php';
145145 $wgAutoloadClasses['SpecialAmbassadorProfile'] = dirname( __FILE__ ) . '/specials/SpecialAmbassadorProfile.php';
 146+$wgAutoloadClasses['SpecialStudentActivity'] = dirname( __FILE__ ) . '/specials/SpecialStudentActivity.php';
146147
147148 // Special pages
148149 $wgSpecialPages['MyCourses'] = 'SpecialMyCourses';
@@ -156,6 +157,7 @@
157158 $wgSpecialPages['OnlineAmbassadors'] = 'SpecialOAs';
158159 $wgSpecialPages['CampusAmbassadorProfile'] = 'SpecialCAProfile';
159160 $wgSpecialPages['OnlineAmbassadorProfile'] = 'SpecialOAProfile';
 161+$wgSpecialPages['StudentActivity'] = 'SpecialStudentActivity';
160162
161163 $wgSpecialPageGroups['MyCourses'] = 'education';
162164 $wgSpecialPageGroups['Institutions'] = 'education';
@@ -169,6 +171,7 @@
170172 $wgSpecialPageGroups['OnlineAmbassadorProfile'] = 'education';
171173 $wgSpecialPageGroups['Enroll'] = 'education';
172174 $wgSpecialPageGroups['Disenroll'] = 'education';
 175+$wgSpecialPageGroups['StudentActivity'] = 'education';
173176
174177 define( 'EP_STUDENT', 0 );
175178 define( 'EP_INSTRUCTOR', 1 );
Index: trunk/extensions/EducationProgram/sql/EducationProgram.sql
@@ -100,28 +100,36 @@
101101 CREATE TABLE IF NOT EXISTS /*_*/ep_users_per_course (
102102 upc_user_id INT unsigned NOT NULL, -- Foreign key on ep_user.user_id
103103 upc_course_id INT unsigned NOT NULL, -- Foreign key on ep_courses.course_id
104 - upc_role TINYINT unsigned NOT NULL -- The role the user has for the course
 104+ upc_role TINYINT unsigned NOT NULL, -- The role the user has for the course
 105+ upc_time varbinary(14) NOT NULL -- Time at which the link was made
105106 ) /*$wgDBTableOptions*/;
106107
107108 CREATE UNIQUE INDEX /*i*/ep_users_per_course ON /*_*/ep_users_per_course (upc_user_id, upc_course_id, upc_role);
108109 CREATE INDEX /*i*/ep_upc_course_id ON /*_*/ep_users_per_course (upc_course_id);
109110 CREATE INDEX /*i*/ep_upc_role ON /*_*/ep_users_per_course (upc_role);
 111+CREATE INDEX /*i*/ep_upc_time ON /*_*/ep_users_per_course (upc_time);
110112
111113
112114
113115 -- Students. In essence this is an extension to the user table.
114116 CREATE TABLE IF NOT EXISTS /*_*/ep_students (
115117 student_id INT unsigned NOT NULL auto_increment PRIMARY KEY,
 118+ student_user_id INT unsigned NOT NULL, -- Foreign key on user.user_id
116119
117 - student_user_id INT unsigned NOT NULL, -- Foreign key on user.user_id
 120+ -- Summary fields - cahing data or computations on data stored elswhere
118121 student_first_enroll varbinary(14) NOT NULL, -- Time of first enrollment
119 -
120 - student_last_active varbinary(14) NOT NULL, -- Time of last activity
 122+ student_first_course INT unsigned NOT NULL, -- First course the user enrolled in
 123+ student_last_enroll varbinary(14) NOT NULL, -- Time of last enrollment
 124+ student_last_course INT unsigned NOT NULL, -- Last course the user enrolled in
 125+ student_last_active varbinary(14) NOT NULL, -- Time of last activity in article NS
121126 student_active_enroll TINYINT unsigned NOT NULL -- If the student is enrolled in any active courses
122127 ) /*$wgDBTableOptions*/;
123128
124129 CREATE UNIQUE INDEX /*i*/ep_students_user_id ON /*_*/ep_students (student_user_id);
125130 CREATE INDEX /*i*/ep_students_first_enroll ON /*_*/ep_students (student_first_enroll);
 131+CREATE INDEX /*i*/ep_students_first_course ON /*_*/ep_students (student_first_course);
 132+CREATE INDEX /*i*/ep_students_last_enroll ON /*_*/ep_students (student_last_enroll);
 133+CREATE INDEX /*i*/ep_students_last_course ON /*_*/ep_students (student_last_course);
126134 CREATE INDEX /*i*/ep_students_last_active ON /*_*/ep_students (student_last_active);
127135 CREATE INDEX /*i*/ep_students_active_enroll ON /*_*/ep_students (student_active_enroll);
128136
Index: trunk/extensions/EducationProgram/sql/AddActivityStuff.sql
@@ -0,0 +1,20 @@
 2+-- MySQL patch for the Education Program extension.
 3+-- Licence: GNU GPL v3+
 4+-- Author: Jeroen De Dauw < jeroendedauw@gmail.com >
 5+
 6+ALTER TABLE /*_*/ep_users_per_course ADD COLUMN upc_time varbinary(14) NOT NULL;
 7+
 8+CREATE INDEX /*i*/ep_upc_time ON /*_*/ep_users_per_course (upc_time);
 9+
 10+ALTER TABLE /*_*/ep_students ADD COLUMN student_last_enroll varbinary(14) NOT NULL;
 11+ALTER TABLE /*_*/ep_students ADD COLUMN student_last_course INT unsigned NOT NULL;
 12+ALTER TABLE /*_*/ep_students ADD COLUMN student_first_course INT unsigned NOT NULL;
 13+
 14+CREATE INDEX /*i*/ep_students_first_course ON /*_*/ep_students (student_first_course);
 15+CREATE INDEX /*i*/ep_students_last_enroll ON /*_*/ep_students (student_last_enroll);
 16+CREATE INDEX /*i*/ep_students_last_course ON /*_*/ep_students (student_last_course);
 17+
 18+UPDATE /*_*/ep_users_per_course SET upc_time = '20120315224638';
 19+UPDATE /*_*/ep_students SET student_last_enroll = '20120315224638';
 20+UPDATE /*_*/ep_students SET student_last_active = '20120315224638';
 21+
Index: trunk/extensions/EducationProgram/EducationProgram.i18n.alias.php
@@ -26,10 +26,9 @@
2727 'Disenroll' => array( 'Disenroll' ),
2828 'CampusAmbassadors' => array( 'CampusAmbassadors' ),
2929 'OnlineAmbassadors' => array( 'OnlineAmbassadors' ),
30 -// 'CampusAmbassador' => array( 'CampusAmbassador' ),
31 -// 'OnlineAmbassador' => array( 'OnlineAmbassador' ),
3230 'OnlineAmbassadorProfile' => array( 'OnlineAmbassadorProfile' ),
3331 'CampusAmbassadorProfile' => array( 'CampusAmbassadorProfile' ),
 32+ 'StudentActivity' => array( 'StudentActivity' ),
3433 );
3534
3635 /** Dutch (Nederlands) */
Index: trunk/extensions/EducationProgram/specials/SpecialStudentActivity.php
@@ -0,0 +1,237 @@
 2+<?php
 3+
 4+/**
 5+ * Page listing recent student activity.
 6+ *
 7+ * @since 0.1
 8+ *
 9+ * @file SpecialStudentActivity.php
 10+ * @ingroup EducationProgram
 11+ *
 12+ * @licence GNU GPL v3 or later
 13+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 14+ */
 15+class SpecialStudentActivity extends SpecialEPPage {
 16+
 17+ /**
 18+ * Constructor.
 19+ *
 20+ * @since 0.1
 21+ */
 22+ public function __construct() {
 23+ parent::__construct( 'StudentActivity' );
 24+ }
 25+
 26+ /**
 27+ * Main method.
 28+ *
 29+ * @since 0.1
 30+ *
 31+ * @param string $subPage
 32+ */
 33+ public function execute( $subPage ) {
 34+ parent::execute( $subPage );
 35+
 36+ $this->displayNavigation();
 37+
 38+ $out = $this->getOutput();
 39+
 40+ $pager = new EPStudentActivityPager( $this->getContext(), array() );
 41+
 42+ if ( $pager->getNumRows() ) {
 43+ $out->addHTML(
 44+ $pager->getFilterControl() .
 45+ $pager->getNavigationBar() .
 46+ $pager->getBody() .
 47+ $pager->getNavigationBar() .
 48+ $pager->getMultipleItemControl()
 49+ );
 50+ }
 51+ else {
 52+ $out->addHTML( $pager->getFilterControl( true ) );
 53+ $out->addWikiMsg( 'ep-studentactivity-noresults' );
 54+ }
 55+ }
 56+
 57+}
 58+
 59+
 60+/**
 61+ * Student pager, primarily for Special:Students.
 62+ *
 63+ * @since 0.1
 64+ *
 65+ * @file EPStudentPager.php
 66+ * @ingroup EductaionProgram
 67+ *
 68+ * @licence GNU GPL v3 or later
 69+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 70+ */
 71+class EPStudentActivityPager extends EPPager {
 72+
 73+ /**
 74+ * List of user ids mapped to user names and real names, set in doBatchLookups.
 75+ * The real names will just hold the user name when no real name is set.
 76+ * user id => array( user name, real name )
 77+ *
 78+ * @since 0.1
 79+ * @var array
 80+ */
 81+ protected $userNames = array();
 82+
 83+ /**
 84+ * List of user ids with the names of their associated courses.
 85+ * user id => array( course name 0, ... )
 86+ *
 87+ * @since 0.1
 88+ * @var array
 89+ */
 90+ protected $courseNames = array();
 91+
 92+ /**
 93+ * Constructor.
 94+ *
 95+ * @param IContextSource $context
 96+ * @param array $conds
 97+ */
 98+ public function __construct( IContextSource $context, array $conds = array() ) {
 99+ $this->mDefaultDirection = true;
 100+
 101+// $conds[] = 'last_active > ' . wfGetDB( DB_SLAVE )->addQuotes(
 102+// wfTimestamp( TS_MW, time() - ( EPSettings::get( 'recentActivityLimit' ) ) )
 103+// );
 104+
 105+ parent::__construct( $context, $conds, EPStudents::singleton() );
 106+ }
 107+
 108+ /**
 109+ * (non-PHPdoc)
 110+ * @see EPPager::getFields()
 111+ */
 112+ public function getFields() {
 113+ return array(
 114+ 'id',
 115+ 'user_id',
 116+ 'last_course',
 117+ 'last_active',
 118+ );
 119+ }
 120+
 121+ /**
 122+ * (non-PHPdoc)
 123+ * @see TablePager::getRowClass()
 124+ */
 125+ function getRowClass( $row ) {
 126+ return 'ep-studentactivity-row';
 127+ }
 128+
 129+ /**
 130+ * (non-PHPdoc)
 131+ * @see TablePager::getTableClass()
 132+ */
 133+ public function getTableClass() {
 134+ return 'TablePager ep-studentactivity';
 135+ }
 136+
 137+ /**
 138+ * (non-PHPdoc)
 139+ * @see EPPager::getFormattedValue()
 140+ */
 141+ protected function getFormattedValue( $name, $value ) {
 142+ switch ( $name ) {
 143+ case 'user_id':
 144+ if ( array_key_exists( $value, $this->userNames ) ) {
 145+ list( $userName, $realName ) = $this->userNames[$value];
 146+ $value = Linker::userLink( $value, $userName, $realName ) . Linker::userToolLinks( $value, $userName );
 147+ }
 148+ else {
 149+ wfWarn( 'User id not in $this->userNames in ' . __METHOD__ );
 150+ }
 151+ break;
 152+ case 'first_enroll': case 'last_active':
 153+ $value = htmlspecialchars( $this->getLanguage()->date( $value ) );
 154+ break;
 155+ }
 156+
 157+ return $value;
 158+ }
 159+
 160+ /**
 161+ * (non-PHPdoc)
 162+ * @see EPPager::getSortableFields()
 163+ */
 164+ protected function getSortableFields() {
 165+ return array(
 166+ );
 167+ }
 168+
 169+ /**
 170+ * (non-PHPdoc)
 171+ * @see EPPager::hasActionsColumn()
 172+ */
 173+ protected function hasActionsColumn() {
 174+ return false;
 175+ }
 176+
 177+ /**
 178+ * (non-PHPdoc)
 179+ * @see IndexPager::getDefaultSort()
 180+ */
 181+ function getDefaultSort() {
 182+ return 'last_active';
 183+ }
 184+
 185+ /**
 186+ * (non-PHPdoc)
 187+ * @see EPPager::getFieldNames()
 188+ */
 189+ public function getFieldNames() {
 190+ $fields = parent::getFieldNames();
 191+
 192+ unset( $fields['id'] );
 193+
 194+ $fields = wfArrayInsertAfter( $fields, array( 'org_id' => 'org-id' ), 'user_id' );
 195+
 196+ return $fields;
 197+ }
 198+
 199+ /**
 200+ * (non-PHPdoc)
 201+ * @see IndexPager::doBatchLookups()
 202+ */
 203+ protected function doBatchLookups() {
 204+ $userIds = array();
 205+ $field = $this->table->getPrefixedField( 'user_id' );
 206+
 207+ while( $student = $this->mResult->fetchObject() ) {
 208+ $userIds[] = (int)$student->$field;
 209+ }
 210+
 211+ if ( !empty( $userIds ) ) {
 212+ $result = wfGetDB( DB_SLAVE )->select(
 213+ 'user',
 214+ array( 'user_id', 'user_name', 'user_real_name' ),
 215+ array( 'user_id' => $userIds ),
 216+ __METHOD__
 217+ );
 218+
 219+ while( $user = $result->fetchObject() ) {
 220+ $real = $user->user_real_name === '' ? $user->user_name : $user->user_real_name;
 221+ $this->userNames[$user->user_id] = array( $user->user_name, $real );
 222+ }
 223+
 224+ $courseNameField = EPCourses::singleton()->getPrefixedField( 'name' );
 225+
 226+ // TODO: $this->courseNames[] =
 227+ }
 228+ }
 229+
 230+ /**
 231+ * (non-PHPdoc)
 232+ * @see EPPager::getMsg()
 233+ */
 234+ protected function getMsg( $messageKey ) {
 235+ return wfMsg( strtolower( get_called_class() ) . '-' . str_replace( '_', '-', $messageKey ) );
 236+ }
 237+
 238+}
\ No newline at end of file
Index: trunk/extensions/EducationProgram/EducationProgram.i18n.php
@@ -200,6 +200,7 @@
201201 'special-onlineambassador' => 'Online ambassador',
202202 'special-campusambassador' => 'Campus ambassador',
203203 'special-disenroll' => 'Disenroll',
 204+ 'special-studentactivity' => 'Student activity',
204205
205206 // Course statuses
206207 'ep-course-status-passed' => 'Passed',
@@ -362,6 +363,12 @@
363364 'epoapager-header-courses' => 'Current courses',
364365 'ep-oa-noresults' => 'There are no Online Ambassadors to list.',
365366
 367+ // Student activity pager
 368+ 'epstudentactivitypager-header-user-id' => 'Student',
 369+ 'epstudentactivitypager-header-org-id' => 'Institution',
 370+ 'epstudentactivitypager-header-last-course' => 'Course',
 371+ 'epstudentactivitypager-header-last-active' => 'Last activity',
 372+
366373 // Institution editing
367374 'editinstitution-text' => 'Enter the institution details below and click submit to save your changes.',
368375 'educationprogram-org-edit-name' => 'Institution name',
@@ -825,7 +832,6 @@
826833 'special-onlineambassador' => '{{doc-special|onlineambassador}}',
827834 'special-campusambassador' => '{{doc-special|campusambassador}}',
828835 'special-disenroll' => '{{doc-special|disenroll}}',
 836+ 'special-studentactivity' => '{{doc-special|studentactivity}}',
829837
830 -
831 -
832838 );
Index: trunk/extensions/EducationProgram/EducationProgram.hooks.php
@@ -53,6 +53,14 @@
5454 true
5555 ) );
5656
 57+ $updater->addExtensionUpdate( array(
 58+ 'addField',
 59+ 'ep_users_per_course',
 60+ 'upc_time',
 61+ dirname( __FILE__ ) . '/sql/AddActivityStuff.sql',
 62+ true
 63+ ) );
 64+
5765 return true;
5866 }
5967

Follow-up revisions

RevisionCommit summaryAuthorDate
r113975Follow up to r113967;jeroendedauw23:21, 15 March 2012

Status & tagging log