r110498 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r110497‎ | r110498 | r110499 >
Date:16:51, 1 February 2012
Author:jeroendedauw
Status:ok
Tags:
Comment:
work on admbassador manegement
Modified paths:
  • /trunk/extensions/EducationProgram/EducationProgram.i18n.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.php (modified) (history)
  • /trunk/extensions/EducationProgram/actions/ViewCourseAction.php (modified) (history)
  • /trunk/extensions/EducationProgram/api/ApiEnlist.php (added) (history)
  • /trunk/extensions/EducationProgram/api/ApiInstructor.php (deleted) (history)
  • /trunk/extensions/EducationProgram/includes/EPCA.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPCourse.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPIRole.php (added) (history)
  • /trunk/extensions/EducationProgram/includes/EPInstructor.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPOA.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPUtils.php (modified) (history)
  • /trunk/extensions/EducationProgram/resources/ep.api.js (modified) (history)
  • /trunk/extensions/EducationProgram/resources/ep.enlist.js (added) (history)
  • /trunk/extensions/EducationProgram/resources/ep.instructor.js (deleted) (history)

Diff [purge]

Index: trunk/extensions/EducationProgram/EducationProgram.php
@@ -70,7 +70,7 @@
7171 $wgAutoloadClasses['ViewOrgAction'] = dirname( __FILE__ ) . '/actions/ViewOrgAction.php';
7272
7373 $wgAutoloadClasses['ApiDeleteEducation'] = dirname( __FILE__ ) . '/api/ApiDeleteEducation.php';
74 -$wgAutoloadClasses['ApiInstructor'] = dirname( __FILE__ ) . '/api/ApiInstructor.php';
 74+$wgAutoloadClasses['ApiEnlist'] = dirname( __FILE__ ) . '/api/ApiEnlist.php';
7575 $wgAutoloadClasses['ApiRefreshEducation'] = dirname( __FILE__ ) . '/api/ApiRefreshEducation.php';
7676
7777 $wgAutoloadClasses['EPCourse'] = dirname( __FILE__ ) . '/includes/EPCourse.php';
@@ -94,6 +94,7 @@
9595 $wgAutoloadClasses['EPRevisionPager'] = dirname( __FILE__ ) . '/includes/EPRevisionPager.php';
9696 $wgAutoloadClasses['EPPageObject'] = dirname( __FILE__ ) . '/includes/EPPageObject.php';
9797 $wgAutoloadClasses['EPFailForm'] = dirname( __FILE__ ) . '/includes/EPFailForm.php';
 98+$wgAutoloadClasses['EPIRole'] = dirname( __FILE__ ) . '/includes/EPIRole.php';
9899
99100 $wgAutoloadClasses['CoursePage'] = dirname( __FILE__ ) . '/pages/CoursePage.php';
100101 $wgAutoloadClasses['EPPage'] = dirname( __FILE__ ) . '/pages/EPPage.php';
@@ -153,7 +154,7 @@
154155
155156 // API
156157 $wgAPIModules['deleteeducation'] = 'ApiDeleteEducation';
157 -$wgAPIModules['instructor'] = 'ApiInstructor';
 158+$wgAPIModules['enlist'] = 'ApiEnlist';
158159 $wgAPIModules['refresheducation'] = 'ApiRefreshEducation';
159160
160161 // Hooks
@@ -171,14 +172,16 @@
172173 $wgLogTypes[] = 'institution';
173174 $wgLogTypes[] = 'course';
174175 $wgLogTypes[] = 'student';
175 -$wgLogTypes[] = 'ambassador';
 176+$wgLogTypes[] = 'online';
 177+$wgLogTypes[] = 'campus';
176178 $wgLogTypes[] = 'instructor';
177179
178180 if ( array_key_exists( 'LogFormatter', $wgAutoloadLocalClasses ) ) {
179181 $wgLogActionsHandlers['institution/*'] = 'EPLogFormatter';
180182 $wgLogActionsHandlers['course/*'] = 'EPLogFormatter';
181183 $wgLogActionsHandlers['student/*'] = 'EPLogFormatter';
182 - $wgLogActionsHandlers['ambassador/*'] = 'EPLogFormatter';
 184+ $wgLogActionsHandlers['online/*'] = 'EPLogFormatter';
 185+ $wgLogActionsHandlers['campus/*'] = 'EPLogFormatter';
183186 $wgLogActionsHandlers['instructor/*'] = 'EPLogFormatter';
184187 }
185188 else {
@@ -384,9 +387,9 @@
385388 $wgResourceModules['ep.formpage']['dependencies'][] = 'ext.wikiEditor.toolbar';
386389 }
387390
388 -$wgResourceModules['ep.instructor'] = $moduleTemplate + array(
 391+$wgResourceModules['ep.enlist'] = $moduleTemplate + array(
389392 'scripts' => array(
390 - 'ep.instructor.js',
 393+ 'ep.enlist.js',
391394 ),
392395 'dependencies' => array(
393396 'mediawiki.user',
@@ -398,30 +401,80 @@
399402 ),
400403 'messages' => array(
401404 'ep-instructor-remove-title',
 405+ 'ep-online-remove-title',
 406+ 'ep-campus-remove-title',
402407 'ep-instructor-remove-button',
 408+ 'ep-online-remove-button',
 409+ 'ep-campus-remove-button',
403410 'ep-instructor-removing',
 411+ 'ep-online-removing',
 412+ 'ep-campus-removing',
404413 'ep-instructor-removal-success',
 414+ 'ep-online-removal-success',
 415+ 'ep-campus-removal-success',
405416 'ep-instructor-close-button',
 417+ 'ep-online-close-button',
 418+ 'ep-campus-close-button',
406419 'ep-instructor-remove-retry',
 420+ 'ep-online-remove-retry',
 421+ 'ep-campus-remove-retry',
407422 'ep-instructor-remove-failed',
 423+ 'ep-online-remove-failed',
 424+ 'ep-campus-remove-failed',
408425 'ep-instructor-cancel-button',
 426+ 'ep-online-cancel-button',
 427+ 'ep-campus-cancel-button',
409428 'ep-instructor-remove-text',
 429+ 'ep-online-remove-text',
 430+ 'ep-campus-remove-text',
410431 'ep-instructor-adding',
 432+ 'ep-online-adding',
 433+ 'ep-campus-adding',
411434 'ep-instructor-addittion-success',
 435+ 'ep-online-addittion-success',
 436+ 'ep-campus-addittion-success',
412437 'ep-instructor-addittion-self-success',
 438+ 'ep-online-addittion-self-success',
 439+ 'ep-campus-addittion-self-success',
413440 'ep-instructor-add-close-button',
 441+ 'ep-online-add-close-button',
 442+ 'ep-campus-add-close-button',
414443 'ep-instructor-add-retry',
 444+ 'ep-online-add-retry',
 445+ 'ep-campus-add-retry',
415446 'ep-instructor-addittion-failed',
 447+ 'ep-online-addittion-failed',
 448+ 'ep-campus-addittion-failed',
416449 'ep-instructor-add-title',
 450+ 'ep-online-add-title',
 451+ 'ep-campus-add-title',
417452 'ep-instructor-add-button',
 453+ 'ep-online-add-button',
 454+ 'ep-campus-add-button',
418455 'ep-instructor-add-self-button',
 456+ 'ep-online-add-self-button',
 457+ 'ep-campus-add-self-button',
419458 'ep-instructor-add-text',
 459+ 'ep-online-add-text',
 460+ 'ep-campus-add-text',
420461 'ep-instructor-add-self-text',
 462+ 'ep-online-add-self-text',
 463+ 'ep-campus-add-self-text',
421464 'ep-instructor-add-self-title',
 465+ 'ep-online-add-self-title',
 466+ 'ep-campus-add-self-title',
422467 'ep-instructor-add-cancel-button',
 468+ 'ep-online-add-cancel-button',
 469+ 'ep-campus-add-cancel-button',
423470 'ep-instructor-summary-input',
 471+ 'ep-online-summary-input',
 472+ 'ep-campus-summary-input',
424473 'ep-instructor-name-input',
425 - 'ep-course-no-instructors',
 474+ 'ep-online-name-input',
 475+ 'ep-campus-name-input',
 476+ 'ep-course-no-instructor',
 477+ 'ep-course-no-online',
 478+ 'ep-course-no-campus',
426479 ),
427480 );
428481
Index: trunk/extensions/EducationProgram/actions/ViewCourseAction.php
@@ -79,29 +79,32 @@
8080 );
8181 }
8282
83 - $stats['instructors'] = $this->getInstructorsList( $course ) . $this->getInstructorControls( $course );
 83+ $stats['instructors'] = $this->getRoleList( $course, 'instructor' ) . $this->getRoleControls( $course, 'instructor' );
 84+ $stats['online'] = $this->getRoleList( $course, 'online' ) . $this->getRoleControls( $course, 'online' );
 85+ $stats['campus'] = $this->getRoleList( $course, 'campus' ) . $this->getRoleControls( $course, 'campus' );
8486
8587 return $stats;
8688 }
8789
8890 /**
89 - * Returns a list with the instructors for the provided course
 91+ * Returns a list with the users that the specified role for the provided course
9092 * or a message indicating there are none.
9193 *
9294 * @since 0.1
9395 *
9496 * @param EPCourse $course
 97+ * @param string $roleName
9598 *
9699 * @return string
97100 */
98 - protected function getInstructorsList( EPCourse $course ) {
99 - $instructors = $course->getInstructors();
 101+ protected function getRoleList( EPCourse $course, $roleName ) {
 102+ $users = $course->getUserWithRole( $roleName );
100103
101 - if ( count( $instructors ) > 0 ) {
 104+ if ( count( $users ) > 0 ) {
102105 $instList = array();
103106
104 - foreach ( $instructors as /* EPInstructor */ $instructor ) {
105 - $instList[] = $instructor->getUserLink() . $instructor->getToolLinks( $this->getContext(), $course );
 107+ foreach ( $users as /* EPIRole */ $user ) {
 108+ $instList[] = $user->getUserLink() . $user->getToolLinks( $this->getContext(), $course );
106109 }
107110
108111 if ( false ) { // count( $instructors ) == 1
@@ -112,119 +115,71 @@
113116 }
114117 }
115118 else {
116 - $html = wfMsgHtml( 'ep-course-no-instructors' );
 119+ $html = wfMsgHtml( 'ep-course-no-' . $roleName );
117120 }
118121
119122 return Html::rawElement(
120123 'div',
121 - array( 'id' => 'ep-course-instructors' ),
 124+ array( 'id' => 'ep-course-' . $roleName ),
122125 $html
123126 );
124127 }
125128
126129 /**
127 - * Returns instructor addition controls for the course if the
 130+ * Returns role a controls for the course if the
128131 * current user has the right permissions.
129132 *
130133 * @since 0.1
131134 *
132135 * @param EPCourse $course
 136+ * @param string $roleName
133137 *
134138 * @return string
135139 */
136 - protected function getInstructorControls( EPCourse $course ) {
 140+ protected function getRoleControls( EPCourse $course, $roleName ) {
137141 $user = $this->getUser();
138142 $links = array();
139143
140 - if ( ( $user->isAllowed( 'ep-instructor' ) || $user->isAllowed( 'ep-beinstructor' ) )
141 - && !in_array( $user->getId(), $course->getField( 'instructors' ) )
 144+ $field = $roleName === 'instructor' ? 'instructors' : $roleName . '_ambs';
 145+
 146+ if ( ( $user->isAllowed( 'ep-' . $roleName ) || $user->isAllowed( 'ep-be' . $roleName ) )
 147+ && !in_array( $user->getId(), $course->getField( $field ) )
142148 ) {
143149 $links[] = Html::element(
144150 'a',
145151 array(
146152 'href' => '#',
147 - 'class' => 'ep-add-instructor',
 153+ 'class' => 'ep-add-role',
 154+ 'data-role' => $roleName,
148155 'data-courseid' => $course->getId(),
149156 'data-coursename' => $course->getField( 'name' ),
150157 'data-mode' => 'self',
151158 ),
152 - wfMsg( 'ep-course-become-instructor' )
 159+ wfMsg( 'ep-course-become-' . $roleName )
153160 );
154161 }
155162
156 - if ( $user->isAllowed( 'ep-instructor' ) ) {
 163+ if ( $user->isAllowed( 'ep-' . $roleName ) ) {
157164 $links[] = Html::element(
158165 'a',
159166 array(
160167 'href' => '#',
161 - 'class' => 'ep-add-instructor',
 168+ 'class' => 'ep-add-role',
 169+ 'data-role' => $roleName,
162170 'data-courseid' => $course->getId(),
163171 'data-coursename' => $course->getField( 'name' ),
164172 ),
165 - wfMsg( 'ep-course-add-instructor' )
 173+ wfMsg( 'ep-course-add-' . $roleName )
166174 );
167175 }
168176
169177 if ( count( $links ) > 0 ) {
170 - $this->getOutput()->addModules( 'ep.instructor' );
 178+ $this->getOutput()->addModules( 'ep.enlist' );
171179 return '<br />' . $this->getLanguage()->pipeList( $links );
172180 }
173181 else {
174182 return '';
175183 }
176184 }
177 -
178 - /**
179 - * Returns ambassador addiction controls for the course if the
180 - * current user has the right permissions.
181 - *
182 - * @since 0.1
183 - *
184 - * @param EPCourse $course
185 - * @param string $type
186 - *
187 - * @return string
188 - */
189 - protected function getAmbassadorControls( EPCourse $course, $type ) {
190 - $user = $this->getUser();
191 - $links = array();
192 -
193 - if ( ( $user->isAllowed( 'ep-' . $type ) || $user->isAllowed( 'ep-be' . $type ) )
194 - && !in_array( $user->getId(), $course->getField( 'instructors' ) )
195 - ) {
196 - $links[] = Html::element(
197 - 'a',
198 - array(
199 - 'href' => '#',
200 - 'class' => 'ep-add-instructor',
201 - 'data-courseid' => $course->getId(),
202 - 'data-coursename' => $course->getField( 'name' ),
203 - 'data-mode' => 'self',
204 - ),
205 - wfMsg( 'ep-course-become-instructor' )
206 - );
207 - }
208 -
209 - if ( $user->isAllowed( 'ep-instructor' ) ) {
210 - $links[] = Html::element(
211 - 'a',
212 - array(
213 - 'href' => '#',
214 - 'class' => 'ep-add-instructor',
215 - 'data-courseid' => $course->getId(),
216 - 'data-coursename' => $course->getField( 'name' ),
217 - ),
218 - wfMsg( 'ep-course-add-instructor' )
219 - );
220 - }
221 -
222 - if ( count( $links ) > 0 ) {
223 - $this->getOutput()->addModules( 'ep.instructor' );
224 - return '<br />' . $this->getLanguage()->pipeList( $links );
225 - }
226 - else {
227 - return '';
228 - }
229 - }
230185
231186 }
\ No newline at end of file
Index: trunk/extensions/EducationProgram/includes/EPIRole.php
@@ -0,0 +1,87 @@
 2+<?php
 3+
 4+/**
 5+ * Interface for classes representing a user in a certain role.
 6+ *
 7+ * @since 0.1
 8+ *
 9+ * @file EPIRole.php
 10+ * @ingroup EducationProgram
 11+ *
 12+ * @licence GNU GPL v3 or later
 13+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 14+ */
 15+interface EPIRole {
 16+
 17+ /**
 18+ * Create a new role object from a user id.
 19+ *
 20+ * @since 0.1
 21+ *
 22+ * @param integer $userId
 23+ *
 24+ * @return EPIRole
 25+ */
 26+ public static function newFromUserId( $userId );
 27+
 28+ /**
 29+ * Create a new role object from a user object.
 30+ *
 31+ * @since 0.1
 32+ *
 33+ * @param User $user
 34+ *
 35+ * @return EPIRole
 36+ */
 37+ public static function newFromUser( User $user );
 38+
 39+
 40+ /**
 41+ * Returns the user.
 42+ *
 43+ * @since 0.1
 44+ *
 45+ * @return User
 46+ */
 47+ public function getUser();
 48+
 49+ /**
 50+ * Returns name of the user.
 51+ *
 52+ * @since 0.1
 53+ *
 54+ * @return string
 55+ */
 56+ public function getName();
 57+
 58+ /**
 59+ * Retruns the user link.
 60+ *
 61+ * @since 0.1
 62+ *
 63+ * @return string
 64+ */
 65+ public function getUserLink();
 66+
 67+ /**
 68+ * Returns the tool links for this user.
 69+ *
 70+ * @since 0.1
 71+ *
 72+ * @param IContextSource $context
 73+ * @param EPCourse|null $course
 74+ *
 75+ * @return string
 76+ */
 77+ public function getToolLinks( IContextSource $context, EPCourse $course = null );
 78+
 79+ /**
 80+ * Returns a short name for the role.
 81+ *
 82+ * @since 0.1
 83+ *
 84+ * @return string
 85+ */
 86+ public function getRoleName();
 87+
 88+}
Property changes on: trunk/extensions/EducationProgram/includes/EPIRole.php
___________________________________________________________________
Added: svn:eol-style
189 + native
Index: trunk/extensions/EducationProgram/includes/EPInstructor.php
@@ -11,7 +11,7 @@
1212 * @licence GNU GPL v3 or later
1313 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1414 */
15 -class EPInstructor {
 15+class EPInstructor implements EPIRole {
1616
1717 /**
1818 * Field for caching the linked user.
@@ -38,7 +38,7 @@
3939 *
4040 * @return EPInstructor
4141 */
42 - public static function newFromId( $userId ) {
 42+ public static function newFromUserId( $userId ) {
4343 return new self( $userId );
4444 }
4545
@@ -126,32 +126,15 @@
127127 * @return string
128128 */
129129 public function getToolLinks( IContextSource $context, EPCourse $course = null ) {
130 - $links = array();
131 -
132 - $links[] = Linker::userTalkLink( $this->getUser()->getId(), $this->getUser()->getName() );
133 -
134 - $links[] = Linker::link( SpecialPage::getTitleFor( 'Contributions', $this->getUser()->getName() ), wfMsgHtml( 'contribslink' ) );
135 -
136 - if ( !is_null( $course ) &&
137 - ( $context->getUser()->isAllowed( 'ep-instructor' ) || $this->getUser()->getId() == $context->getUser()->getId() ) ) {
138 - $links[] = Html::element(
139 - 'a',
140 - array(
141 - 'href' => '#',
142 - 'class' => 'ep-instructor-remove',
143 - 'data-courseid' => $course->getId(),
144 - 'data-coursename' => $course->getField( 'name' ),
145 - 'data-userid' => $this->getUser()->getId(),
146 - 'data-username' => $this->getUser()->getName(),
147 - 'data-bestname' => $this->getName(),
148 - ),
149 - wfMsg( 'ep-instructor-remove' )
150 - );
151 -
152 - $context->getOutput()->addModules( 'ep.instructor' );
153 - }
154 -
155 - return ' <span class="mw-usertoollinks">(' . $context->getLanguage()->pipeList( $links ) . ')</span>';
 130+ return EPUtils::getRoleToolLinks( $this, $context, $course );
156131 }
157132
 133+ /**
 134+ * @since 0.1
 135+ * @see EPIRole::getRoleName
 136+ */
 137+ public function getRoleName() {
 138+ return 'instructor';
 139+ }
 140+
158141 }
Index: trunk/extensions/EducationProgram/includes/EPCA.php
@@ -11,9 +11,45 @@
1212 * @licence GNU GPL v3 or later
1313 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1414 */
15 -class EPCA extends EPDBObject {
 15+class EPCA extends EPDBObject implements EPIRole {
1616
1717 /**
 18+ * Field for caching the linked user.
 19+ *
 20+ * @since 0.1
 21+ * @var User|false
 22+ */
 23+ protected $user = false;
 24+
 25+ /**
 26+ * Create a new instructor object from a user id.
 27+ *
 28+ * @since 0.1
 29+ *
 30+ * @param integer $userId
 31+ *
 32+ * @return EPCA
 33+ */
 34+ public static function newFromUserId( $userId ) {
 35+ $data = array( 'user_id' => $userId );
 36+ $ca = static::selectRow( null, $data );
 37+ return $ca === false ? new static( $data, true ) : $ca;
 38+ }
 39+
 40+ /**
 41+ * Create a new instructor object from a User object.
 42+ *
 43+ * @since 0.1
 44+ *
 45+ * @param User $user
 46+ *
 47+ * @return EPCA|false
 48+ */
 49+ public static function newFromUser( User $user ) {
 50+ return self::newFromUserId( $user->getId() );
 51+ }
 52+
 53+ /**
1854 * @see parent::getFieldTypes
1955 *
2056 * @since 0.1
@@ -24,8 +60,48 @@
2561 return array(
2662 'id' => 'id',
2763 'user_id' => 'id',
 64+
 65+ 'bio' => 'str',
 66+ 'photo' => 'str',
2867 );
2968 }
 69+
 70+ /**
 71+ * (non-PHPdoc)
 72+ * @see EPDBObject::getDefaults()
 73+ */
 74+ public static function getDefaults() {
 75+ return array(
 76+ 'bio' => '',
 77+ 'photo' => '',
 78+ );
 79+ }
 80+
 81+ /**
 82+ * Returns the user that this instructor is.
 83+ *
 84+ * @since 0.1
 85+ *
 86+ * @return User
 87+ */
 88+ public function getUser() {
 89+ if ( $this->user === false ) {
 90+ $this->user = User::newFromId( $this->getField( 'user_id' ) );
 91+ }
 92+
 93+ return $this->user;
 94+ }
 95+
 96+ /**
 97+ * Returns the name of the instroctor, using their real name when available.
 98+ *
 99+ * @since 0.1
 100+ *
 101+ * @return string
 102+ */
 103+ public function getName() {
 104+ return $this->getUser()->getRealName() === '' ? $this->getUser()->getName() : $this->getUser()->getRealName();
 105+ }
30106
31107 /**
32108 * Display a pager with campus ambassadors.
@@ -52,5 +128,42 @@
53129 $context->getOutput()->addWikiMsg( 'ep-ca-noresults' );
54130 }
55131 }
 132+
 133+ /**
 134+ * Returns the tool links for this ambassador.
 135+ *
 136+ * @since 0.1
 137+ *
 138+ * @param IContextSource $context
 139+ * @param EPCourse|null $course
 140+ *
 141+ * @return string
 142+ */
 143+ public function getToolLinks( IContextSource $context, EPCourse $course = null ) {
 144+ return EPUtils::getRoleToolLinks( $this, $context, $course );
 145+ }
56146
 147+ /**
 148+ * @since 0.1
 149+ * @see EPIRole::getRoleName
 150+ */
 151+ public function getRoleName() {
 152+ return 'campus';
 153+ }
 154+
 155+ /**
 156+ * Retruns the user link for this ambassador, using their real name when available.
 157+ *
 158+ * @since 0.1
 159+ *
 160+ * @return string
 161+ */
 162+ public function getUserLink() {
 163+ return Linker::userLink(
 164+ $this->getUser()->getId(),
 165+ $this->getUser()->getName(),
 166+ $this->getName()
 167+ );
 168+ }
 169+
57170 }
Index: trunk/extensions/EducationProgram/includes/EPOA.php
@@ -11,9 +11,45 @@
1212 * @licence GNU GPL v3 or later
1313 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1414 */
15 -class EPOA extends EPDBObject {
 15+class EPOA extends EPDBObject implements EPIRole {
1616
1717 /**
 18+ * Field for caching the linked user.
 19+ *
 20+ * @since 0.1
 21+ * @var User|false
 22+ */
 23+ protected $user = false;
 24+
 25+ /**
 26+ * Create a new instructor object from a user id.
 27+ *
 28+ * @since 0.1
 29+ *
 30+ * @param integer $userId
 31+ *
 32+ * @return EPCA
 33+ */
 34+ public static function newFromUserId( $userId ) {
 35+ $data = array( 'user_id' => $userId );
 36+ $oa = static::selectRow( null, $data );
 37+ return $oa === false ? new static( $data, true ) : $oa;
 38+ }
 39+
 40+ /**
 41+ * Create a new instructor object from a User object.
 42+ *
 43+ * @since 0.1
 44+ *
 45+ * @param User $user
 46+ *
 47+ * @return EPCA|false
 48+ */
 49+ public static function newFromUser( User $user ) {
 50+ return self::newFromUserId( $user->getId() );
 51+ }
 52+
 53+ /**
1854 * @see parent::getFieldTypes
1955 *
2056 * @since 0.1
@@ -24,8 +60,48 @@
2561 return array(
2662 'id' => 'id',
2763 'user_id' => 'id',
 64+
 65+ 'bio' => 'str',
 66+ 'photo' => 'str',
2867 );
2968 }
 69+
 70+ /**
 71+ * (non-PHPdoc)
 72+ * @see EPDBObject::getDefaults()
 73+ */
 74+ public static function getDefaults() {
 75+ return array(
 76+ 'bio' => '',
 77+ 'photo' => '',
 78+ );
 79+ }
 80+
 81+ /**
 82+ * Returns the user that this instructor is.
 83+ *
 84+ * @since 0.1
 85+ *
 86+ * @return User
 87+ */
 88+ public function getUser() {
 89+ if ( $this->user === false ) {
 90+ $this->user = User::newFromId( $this->getField( 'user_id' ) );
 91+ }
 92+
 93+ return $this->user;
 94+ }
 95+
 96+ /**
 97+ * Returns the name of the instroctor, using their real name when available.
 98+ *
 99+ * @since 0.1
 100+ *
 101+ * @return string
 102+ */
 103+ public function getName() {
 104+ return $this->getUser()->getRealName() === '' ? $this->getUser()->getName() : $this->getUser()->getRealName();
 105+ }
30106
31107 /**
32108 * Display a pager with online ambassadors.
@@ -52,5 +128,42 @@
53129 $context->getOutput()->addWikiMsg( 'ep-oa-noresults' );
54130 }
55131 }
 132+
 133+ /**
 134+ * Returns the tool links for this ambassador.
 135+ *
 136+ * @since 0.1
 137+ *
 138+ * @param IContextSource $context
 139+ * @param EPCourse|null $course
 140+ *
 141+ * @return string
 142+ */
 143+ public function getToolLinks( IContextSource $context, EPCourse $course = null ) {
 144+ return EPUtils::getRoleToolLinks( $this, $context, $course );
 145+ }
 146+
 147+ /**
 148+ * @since 0.1
 149+ * @see EPIRole::getRoleName
 150+ */
 151+ public function getRoleName() {
 152+ return 'online';
 153+ }
 154+
 155+ /**
 156+ * Retruns the user link for this ambassador, using their real name when available.
 157+ *
 158+ * @since 0.1
 159+ *
 160+ * @return string
 161+ */
 162+ public function getUserLink() {
 163+ return Linker::userLink(
 164+ $this->getUser()->getId(),
 165+ $this->getUser()->getName(),
 166+ $this->getName()
 167+ );
 168+ }
56169
57170 }
Index: trunk/extensions/EducationProgram/includes/EPCourse.php
@@ -36,6 +36,22 @@
3737 * @var {array of EPInstructor}|false
3838 */
3939 protected $instructors = false;
 40+
 41+ /**
 42+ * Field for caching the online ambassaords.
 43+ *
 44+ * @since 0.1
 45+ * @var {array of EPOA}|false
 46+ */
 47+ protected $oas = false;
 48+
 49+ /**
 50+ * Field for caching the campus ambassaords.
 51+ *
 52+ * @since 0.1
 53+ * @var {array of EPCA}|false
 54+ */
 55+ protected $cas = false;
4056
4157 /**
4258 * Returns a list of statuses a term can have.
@@ -479,14 +495,78 @@
480496 $this->instructors = array();
481497
482498 foreach ( $this->getField( 'instructors' ) as $userId ) {
483 - $this->instructors[] = EPInstructor::newFromId( $userId );
 499+ $this->instructors[] = EPInstructor::newFromUserId( $userId );
484500 }
485501 }
486502
487503 return $this->instructors;
488504 }
 505+
 506+ /**
 507+ * Returns the campus ambassadors as a list of EPCA objects.
 508+ *
 509+ * @since 0.1
 510+ *
 511+ * @return array of EPCA
 512+ */
 513+ public function getCampusAmbassadors() {
 514+ if ( $this->cas === false ) {
 515+ $this->cas = array();
489516
 517+ foreach ( $this->getField( 'campus_ambs' ) as $userId ) {
 518+ $this->cas[] = EPCA::newFromUserId( $userId );
 519+ }
 520+ }
 521+
 522+ return $this->cas;
 523+ }
 524+
490525 /**
 526+ * Returns the online ambassadors as a list of EPOA objects.
 527+ *
 528+ * @since 0.1
 529+ *
 530+ * @return array of EPOA
 531+ */
 532+ public function getOnlineAmbassadors() {
 533+ if ( $this->oas === false ) {
 534+ $this->oas = array();
 535+
 536+ foreach ( $this->getField( 'online_ambs' ) as $userId ) {
 537+ $this->oas[] = EPOA::newFromUserId( $userId );
 538+ }
 539+ }
 540+
 541+ return $this->oas;
 542+ }
 543+
 544+ /**
 545+ * Returns the users that have a certain role as list of EPIRole objects.
 546+ *
 547+ * @since 0.1
 548+ *
 549+ * @param string $roleName
 550+ *
 551+ * @return array of EPIRole
 552+ * @throws MWException
 553+ */
 554+ public function getUserWithRole( $roleName ) {
 555+ switch ( $roleName ) {
 556+ case 'instructor':
 557+ return $this->getInstructors();
 558+ break;
 559+ case 'online':
 560+ return $this->getOnlineAmbassadors();
 561+ break;
 562+ case 'campus':
 563+ return $this->getCampusAmbassadors();
 564+ break;
 565+ }
 566+
 567+ throw new MWException( 'Invalid role name: ' . $roleName );
 568+ }
 569+
 570+ /**
491571 * (non-PHPdoc)
492572 * @see EPDBObject::setField()
493573 */
@@ -499,36 +579,38 @@
500580 }
501581
502582 /**
503 - * Adds a number of instructors to this course,
 583+ * Adds a role for a number of users to this course,
504584 * by default also saving the course and only
505 - * logging the adittion of the instructors.
 585+ * logging the adittion of the users/roles.
506586 *
507587 * @since 0.1
508588 *
509 - * @param array|integer $newInstructors
 589+ * @param array|integer $newUsers
 590+ * @param string $role
510591 * @param string $message
511592 * @param boolean $save
512593 * @param boolean $log
513594 *
514595 * @return boolean Success indicator
515596 */
516 - public function addInstructors( $newInstructors, $message = '', $save = true, $log = true ) {
517 - $instructors = $this->getField( 'instructors' );
518 - $addedInstructors = array();
 597+ public function enlistUsers( $newUsers, $role, $message = '', $save = true, $log = true ) {
 598+ $field = $role === 'instructor' ? 'instructors' : $role . '_ambs';
 599+ $users = $this->getField( $field );
 600+ $addedUsers = array();
519601
520 - foreach ( (array)$newInstructors as $userId ) {
 602+ foreach ( (array)$newUsers as $userId ) {
521603 if ( !is_integer( $userId ) ) {
522604 throw new MWException( 'Provided user id is not an integer' );
523605 }
524 -
525 - if ( !in_array( $userId, $instructors ) ) {
526 - $instructors[] = $userId;
527 - $addedInstructors[] = $userId;
 606+
 607+ if ( !in_array( $userId, $users ) ) {
 608+ $users[] = $userId;
 609+ $addedUsers[] = $userId;
528610 }
529611 }
530612
531 - if ( count( $addedInstructors ) > 0 ) {
532 - $this->setField( 'instructors', $instructors );
 613+ if ( count( $addedUsers ) > 0 ) {
 614+ $this->setField( $field, $users );
533615
534616 $success = true;
535617
@@ -539,7 +621,7 @@
540622 }
541623
542624 if ( $success && $log ) {
543 - $this->logInstructorChange( 'add', $addedInstructors, $message );
 625+ $this->logRoleChange( 'add', $role, $addedUsers, $message );
544626 }
545627
546628 return $success;
@@ -550,35 +632,38 @@
551633 }
552634
553635 /**
554 - * Remove a number of instructors to this course,
 636+ * Remove the role for a number of users for this course,
555637 * by default also saving the course and only
556 - * logging the removal of the instructors.
 638+ * logging the role changes.
557639 *
558640 * @since 0.1
559641 *
560 - * @param array|integer $sadInstructors
 642+ * @param array|integer $sadUsers
 643+ * @param string $role
561644 * @param string $message
562645 * @param boolean $save
563646 * @param boolean $log
564647 *
565648 * @return boolean Success indicator
566649 */
567 - public function removeInstructors( $sadInstructors, $message = '', $save = true, $log = true ) {
568 - $removedInstructors = array();
569 - $remaimingInstructors = array();
570 - $sadInstructors = (array)$sadInstructors;
 650+ public function unenlistUsers( $sadUsers, $role, $message = '', $save = true, $log = true ) {
 651+ $removedUser = array();
 652+ $remaimingUsers = array();
 653+ $sadUsers = (array)$sadUsers;
571654
572 - foreach ( $this->getField( 'instructors' ) as $userId ) {
573 - if ( in_array( $userId, $sadInstructors ) ) {
574 - $removedInstructors[] = $userId;
 655+ $field = $role === 'instructor' ? 'instructors' : $role . '_ambs';
 656+
 657+ foreach ( $this->getField( $field ) as $userId ) {
 658+ if ( in_array( $userId, $sadUsers ) ) {
 659+ $removedUser[] = $userId;
575660 }
576661 else {
577 - $remaimingInstructors[] = $userId;
 662+ $remaimingUsers[] = $userId;
578663 }
579664 }
580665
581 - if ( count( $removedInstructors ) > 0 ) {
582 - $this->setField( 'instructors', $remaimingInstructors );
 666+ if ( count( $removedUser ) > 0 ) {
 667+ $this->setField( $field, $remaimingUsers );
583668
584669 $success = true;
585670
@@ -589,7 +674,7 @@
590675 }
591676
592677 if ( $success && $log ) {
593 - $this->logInstructorChange( 'remove', $removedInstructors, $message );
 678+ $this->logRoleChange( 'remove', $role, $removedUser, $message );
594679 }
595680
596681 return $success;
@@ -605,18 +690,27 @@
606691 * @since 0.1
607692 *
608693 * @param string $action
609 - * @param array $instructors
 694+ * @param string $role
 695+ * @param array $users
610696 * @param string $message
611697 */
612 - protected function logInstructorChange( $action, array $instructors, $message ) {
 698+ protected function logRoleChange( $action, $role, array $users, $message ) {
613699 $names = array();
614700
615 - foreach ( $instructors as $userId ) {
616 - $names[] = EPInstructor::newFromId( $userId )->getName();
 701+ $classes = array(
 702+ 'instructor' => 'EPInstructor',
 703+ 'campus' => 'EPCA',
 704+ 'online' => 'EPOA',
 705+ );
 706+
 707+ $class = $classes[$role];
 708+
 709+ foreach ( $users as $userId ) {
 710+ $names[] = $class::newFromUserId( $userId )->getName();
617711 }
618712
619713 $info = array(
620 - 'type' => 'instructor',
 714+ 'type' => $role,
621715 'subtype' => $action,
622716 'title' => $this->getTitle(),
623717 'parameters' => array(
Index: trunk/extensions/EducationProgram/includes/EPUtils.php
@@ -109,5 +109,47 @@
110110 )
111111 );
112112 }
 113+
 114+ /**
 115+ * Returns the tool links for this ambassador.
 116+ *
 117+ * @since 0.1
 118+ *
 119+ * @param EPIRole $role
 120+ * @param IContextSource $context
 121+ * @param EPCourse|null $course
 122+ *
 123+ * @return string
 124+ */
 125+ public static function getRoleToolLinks( EPIRole $role, IContextSource $context, EPCourse $course = null ) {
 126+ $roleName = $role->getRoleName();
 127+ $links = array();
 128+
 129+ $links[] = Linker::userTalkLink( $role->getUser()->getId(), $role->getUser()->getName() );
 130+
 131+ $links[] = Linker::link( SpecialPage::getTitleFor( 'Contributions', $role->getUser()->getName() ), wfMsgHtml( 'contribslink' ) );
 132+
 133+ if ( !is_null( $course ) &&
 134+ ( $context->getUser()->isAllowed( 'ep-' . $roleName ) || $role->getUser()->getId() == $context->getUser()->getId() ) ) {
 135+ $links[] = Html::element(
 136+ 'a',
 137+ array(
 138+ 'href' => '#',
 139+ 'class' => 'ep-remove-role',
 140+ 'data-role' => $roleName,
 141+ 'data-courseid' => $course->getId(),
 142+ 'data-coursename' => $course->getField( 'name' ),
 143+ 'data-userid' => $role->getUser()->getId(),
 144+ 'data-username' => $role->getUser()->getName(),
 145+ 'data-bestname' => $role->getName(),
 146+ ),
 147+ wfMsg( 'ep-' . $roleName . '-remove' )
 148+ );
 149+
 150+ $context->getOutput()->addModules( 'ep.enlist' );
 151+ }
 152+
 153+ return ' <span class="mw-usertoollinks">(' . $context->getLanguage()->pipeList( $links ) . ')</span>';
 154+ }
113155
114156 }
Index: trunk/extensions/EducationProgram/EducationProgram.i18n.php
@@ -49,22 +49,25 @@
5050 'ep-nav-mentors' => 'Ambassador list',
5151
5252 // Logging
53 - 'log-name-institution' => 'Institution log',
54 - 'log-name-course' => 'Course log',
55 - 'log-name-student' => 'Student log',
56 - 'log-name-ambassador' => 'Ambassador log',
57 - 'log-name-instructor' => 'Instructor log',
 53+ 'log-name-institution' => 'Education Program institution log',
 54+ 'log-name-course' => 'Education Program course log',
 55+ 'log-name-student' => 'Education Program student log',
 56+ 'log-name-online' => 'Education Program Online Ambassador log',
 57+ 'log-name-campus' => 'Education Program Campus Ambassador log',
 58+ 'log-name-instructor' => 'Education Program instructor log',
5859
59 - 'log-header-institution' => 'These events track the changes that are made to institutions.',
60 - 'log-header-course' => 'These events track the changes that are made to courses.',
61 - 'log-header-instructor' => 'These events track the changes that are made to instructors.',
62 - 'log-header-ambassador' => 'These events track the changes that are made to ambassadors.',
63 - 'log-header-student' => 'These events track the changes that are made to students.',
 60+ 'log-header-institution' => 'These events track the changes that are made to Education Program institutions.',
 61+ 'log-header-course' => 'These events track the changes that are made to Education Program courses.',
 62+ 'log-header-instructor' => 'These events track the changes that are made to Education Program instructors.',
 63+ 'log-header-campus' => 'These events track the changes that are made to Education Program Campus Ambassadors.',
 64+ 'log-header-online' => 'These events track the changes that are made to Education Program Online Ambassadors.',
 65+ 'log-header-student' => 'These events track the changes that are made to Education Program students.',
6466
6567 'log-description-institution' => 'Log of all changes to [[Special:Institutions|institutions]].',
6668 'log-description-course' => 'Log of all changes to [[Special:Courses|courses]].',
6769 'log-description-instructor' => 'Log of all changes to instructors.',
68 - 'log-description-ambassador' => 'Log of all changes to [[Special:OnlineAmbassadors|online]] and [[Special:CampusAmbassadors|campus ambassadors]].',
 70+ 'log-description-online' => 'Log of all changes to Education Program [[Special:OnlineAmbassadors|Online Ambassadors]]',
 71+ 'log-description-campus' => 'Log of all changes to Education Program [[Special:CampusAmbassadors|Campus Ambassadors]]',
6972 'log-description-student' => 'Log of all changes to [[Special:Students|students]].',
7073
7174 'logentry-institution-add' => '$1 created institution $3',
@@ -77,14 +80,19 @@
7881
7982 'logentry-instructor-add' => '$1 {{GENDER:$2|added}} {{PLURAL:$4|instructor|instructors}} $5 to course $3',
8083 'logentry-instructor-remove' => '$1 {{GENDER:$2|removed}} {{PLURAL:$4|instructor|instructors}} $5 from course $3',
81 - 'logentry-instructor-selfadd' => '$1 {{GENDER:$2|added himself|added herself}} as instructor to course $3',
82 - 'logentry-instructor-selfremove' => '$1 {{GENDER:$2|removed himself|removed herself}} as instructor from course $3',
 84+ 'logentry-instructor-selfadd' => '$1 added {{GENDER:$2|added himself|herself}} as {{GENDER:$2|instructor}} to course $3',
 85+ 'logentry-instructor-selfremove' => '$1 removed {{GENDER:$2|removed himself|herself}} as {{GENDER:$2|instructor}} from course $3',
8386
84 - 'logentry-ambassador-add' => '$1 added {{PLURAL:$4|ambassador|ambassadors}} $5 to course $3',
85 - 'logentry-ambassador-remove' => '$1 removed {{PLURAL:$4|ambassador|ambassadors}} $5 from course $3',
86 - 'logentry-ambassador-selfadd' => '$1 added {{GENDER:$2|himself|herself}} as ambassador to course $3',
87 - 'logentry-ambassador-selfremove' => '$1 removed {{GENDER:$2|himself|herself}} as ambassador from course $3',
 87+ 'logentry-online-add' => '$1 added {{PLURAL:$4|Online Ambassador|Online Ambassadors}} $5 to course $3',
 88+ 'logentry-online-remove' => '$1 removed {{PLURAL:$4|Online Ambassador|Online Ambassadors}} $5 from course $3',
 89+ 'logentry-online-selfadd' => '$1 added {{GENDER:$2|himself|herself}} as {{GENDER:$2|Online Ambassador}} to course $3',
 90+ 'logentry-online-selfremove' => '$1 removed {{GENDER:$2|himself|herself}} as {{GENDER:$2|Online Ambassador}} from course $3',
8891
 92+ 'logentry-campus-add' => '$1 added {{PLURAL:$4|Campus Ambassador|Campus Ambassadors}} $5 to course $3',
 93+ 'logentry-campus-remove' => '$1 removed {{PLURAL:$4|Campus Ambassador|Campus Ambassadors}} $5 from course $3',
 94+ 'logentry-campus-selfadd' => '$1 added {{GENDER:$2|himself|herself}} as {{GENDER:$2|Campus Ambassador}} to course $3',
 95+ 'logentry-campus-selfremove' => '$1 removed {{GENDER:$2|himself|herself}} as {{GENDER:$2|Campus Ambassador}} from course $3',
 96+
8997 'logentry-student-enroll' => '$1 enrolled in course $3',
9098 'logentry-student-remove' => '$1 removed $4 as student from course $3',
9199 'logentry-student-selfremove' => '$1 removed {{GENDER:$2|his|her}} enrollment from course $3',
@@ -172,9 +180,6 @@
173181 'ep-courses-add' => 'Add course',
174182 'ep-courses-noorgs' => 'There are no institutions yet. You need to [[Special:Institutions|add an institution]] before you can create any courses.',
175183 'ep-courses-addorgfirst' => 'There are no institutions yet. You need to [[Special:Institutions|add an institution]] before you can create any courses.',
176 - 'ep-course-no-instructors' => 'There are no instructors for this course yet.',
177 - 'ep-course-become-instructor' => 'Become an instructor',
178 - 'ep-course-add-instructor' => 'Add an instructor',
179184
180185 // Special:Students
181186 'ep-students-noresults' => 'There are no students to list.',
@@ -296,6 +301,8 @@
297302 'ep-course-students' => 'Students',
298303 'ep-course-none' => 'There is no course with id "$1". See [[Special:Courses|here]] for a list of courses.',
299304 'ep-course-create' => 'There is no course with id "$1", but you can create a new one.',
 305+ 'ep-course-description' => 'description',
 306+ 'ep-course-no-online' => '',
300307 'viewcourseaction-summary-org' => 'Institution',
301308 'viewcourseaction-summary-term' => 'Term',
302309 'viewcourseaction-summary-start' => 'Start',
@@ -304,7 +311,17 @@
305312 'viewcourseaction-summary-status' => 'Status',
306313 'viewcourseaction-summary-token' => 'Enrollment token',
307314 'viewcourseaction-summary-instructors' => 'Instructors',
308 - 'ep-course-description' => 'description',
 315+ 'viewcourseaction-summary-online' => 'Online Ambassaords',
 316+ 'viewcourseaction-summary-campus' => 'Campus Ambassaords',
 317+ 'ep-course-no-instructor' => 'There are no instructors for this course yet.',
 318+ 'ep-course-become-instructor' => 'Become an instructor',
 319+ 'ep-course-add-instructor' => 'Add an instructor',
 320+ 'ep-course-no-online' => 'There are no Online Ambassadors for this course yet.',
 321+ 'ep-course-become-online' => 'Become an Online Ambassador',
 322+ 'ep-course-add-online' => 'Add an Online Ambassador',
 323+ 'ep-course-no-campus' => 'There are no Campus Ambassadors for this course yet.',
 324+ 'ep-course-become-campus' => 'Become an Campus Ambassador',
 325+ 'ep-course-add-campus' => 'Add an Campus Ambassador',
309326
310327 // Institution history
311328 'ep-org-history' => 'View logs for this institution',
@@ -363,7 +380,7 @@
364381 'specialmycourses-summary-org' => 'Institution name',
365382 'ep-mycourses-not-a-student' => 'You are not enrolled in any [[Special:Courses|courses]].',
366383
367 - // ep.instructor
 384+ // ep.enlist instructor
368385 'ep-instructor-remove-title' => 'Remove instructor from course',
369386 'ep-instructor-remove-button' => 'Remove instructor',
370387 'ep-instructor-removing' => 'Removing...',
@@ -389,13 +406,71 @@
390407 'ep-instructor-summary-input' => 'Summary',
391408 'ep-instructor-name-input' => 'User name',
392409
 410+ // ep.enlist online
 411+ 'ep-online-remove-title' => 'Remove Online Ambassador from course',
 412+ 'ep-online-remove-button' => 'Remove Online Ambassador',
 413+ 'ep-online-removing' => 'Removing...',
 414+ 'ep-online-removal-success' => 'This Online Ambassador has been successfully removed from this course.',
 415+ 'ep-online-close-button' => 'Close',
 416+ 'ep-online-remove-retry' => 'Retry',
 417+ 'ep-online-remove-failed' => 'Something went wrong - could not remove the Online Ambassador from the course.',
 418+ 'ep-online-cancel-button' => 'Cancel',
 419+ 'ep-online-remove-text' => 'You are about to remove $2 (Username: $1) as {{GENDER:$1|Online Ambassador}} from course $3. Please enter a brief summary with the reason for this removal.',
 420+ 'ep-online-adding' => 'Adding...',
 421+ 'ep-online-addittion-success' => '$1 has been successfully added as {{GENDER:$1|Online Ambassador}} for course $2!',
 422+ 'ep-online-addittion-self-success' => 'You have been successfully added as {{GENDER:$1|Online Ambassador}} for course $2!',
 423+ 'ep-online-add-close-button' => 'Close',
 424+ 'ep-online-add-retry' => 'Retry',
 425+ 'ep-online-addittion-failed' => 'Something went wrong - could not add the Online Ambassador to the course.',
 426+ 'ep-online-add-title' => 'Add an Online Ambassador to the course',
 427+ 'ep-online-add-self-title' => 'Become an {{GENDER:$1|Online Ambassador}} for this course',
 428+ 'ep-online-add-button' => 'Add Online Ambassador',
 429+ 'ep-online-add-self-button' => 'Become {{GENDER:$1|Online Ambassador}}',
 430+ 'ep-online-add-text' => 'You are adding an Online Ambassador for course $1. Enter the username of the Online Ambassador and a brief description why this person is being added.',
 431+ 'ep-online-add-self-text' => 'You are adding yourself as {{GENDER:$1|Online Ambassador}} for course $1. Please add a brief description why you are doing so.',
 432+ 'ep-online-add-cancel-button' => 'Cancel',
 433+ 'ep-online-summary-input' => 'Summary',
 434+ 'ep-online-name-input' => 'User name',
 435+
 436+ // ep.enlist campus
 437+ 'ep-campus-remove-title' => 'Remove Campus Ambassador from course',
 438+ 'ep-campus-remove-button' => 'Remove Campus Ambassador',
 439+ 'ep-campus-removing' => 'Removing...',
 440+ 'ep-campus-removal-success' => 'This Campus Ambassador has been successfully removed from this course.',
 441+ 'ep-campus-close-button' => 'Close',
 442+ 'ep-campus-remove-retry' => 'Retry',
 443+ 'ep-campus-remove-failed' => 'Something went wrong - could not remove the Campus Ambassador from the course.',
 444+ 'ep-campus-cancel-button' => 'Cancel',
 445+ 'ep-campus-remove-text' => 'You are about to remove $2 (Username: $1) as {{GENDER:$1|Campus Ambassador}} from course $3. Please enter a brief summary with the reason for this removal.',
 446+ 'ep-campus-adding' => 'Adding...',
 447+ 'ep-campus-addittion-success' => '$1 has been successfully added as {{GENDER:$1|Campus Ambassador}} for course $2!',
 448+ 'ep-campus-addittion-self-success' => 'You have been successfully added as {{GENDER:$1|Campus Ambassador}} for course $2!',
 449+ 'ep-campus-add-close-button' => 'Close',
 450+ 'ep-campus-add-retry' => 'Retry',
 451+ 'ep-campus-addittion-failed' => 'Something went wrong - could not add the Campus Ambassador to the course.',
 452+ 'ep-campus-add-title' => 'Add an Campus Ambassador to the course',
 453+ 'ep-campus-add-self-title' => 'Become an {{GENDER:$1|Campus Ambassador}} for this course',
 454+ 'ep-campus-add-button' => 'Add Campus Ambassador',
 455+ 'ep-campus-add-self-button' => 'Become {{GENDER:$1|Campus Ambassador}}',
 456+ 'ep-campus-add-text' => 'You are adding an Campus Ambassador for course $1. Enter the username of the Campus Ambassador and a brief description why this person is being added.',
 457+ 'ep-campus-add-self-text' => 'You are adding yourself as {{GENDER:$1|Campus Ambassador}} for course $1. Please add a brief description why you are doing so.',
 458+ 'ep-campus-add-cancel-button' => 'Cancel',
 459+ 'ep-campus-summary-input' => 'Summary',
 460+ 'ep-campus-name-input' => 'User name',
 461+
393462 // EPInstrucor
394463 'ep-instructor-remove' => 'remove as instructor',
395464
396 - // API addinstructor
397 - 'ep-addinstructor-invalid-user-args' => 'You need to either provide the username or the userid parameter',
398 - 'ep-addinstructor-invalid-user' => 'The provided user id or name is not valid and can therefore not be associated as instrucor with the specified course',
399 - 'ep-addinstructor-invalid-course' => 'There is no course with the provided ID',
 465+ // EPCA
 466+ 'ep-campus-remove' => 'remove as Campus Ambassador',
 467+
 468+ // EPOA
 469+ 'ep-online-remove' => 'remove as Online Ambassador',
 470+
 471+ // API enlist
 472+ 'ep-enlist-invalid-user-args' => 'You need to either provide the username or the userid parameter',
 473+ 'ep-enlist-invalid-user' => 'The provided user id or name is not valid and can therefore not be associated as instrucor or ambassador with the specified course',
 474+ 'ep-enlist-invalid-course' => 'There is no course with the provided ID',
400475 );
401476
402477 /** Message documentation (Message documentation)
Index: trunk/extensions/EducationProgram/api/ApiInstructor.php
@@ -1,171 +0,0 @@
2 -<?php
3 -
4 -/**
5 - * API module to associate/disassociate users as instructor with/from a course.
6 - *
7 - * @since 0.1
8 - *
9 - * @file ApiInstructor.php
10 - * @ingroup EducationProgram
11 - * @ingroup API
12 - *
13 - * @licence GNU GPL v3+
14 - * @author Jeroen De Dauw < jeroendedauw@gmail.com >
15 - */
16 -class ApiInstructor extends ApiBase {
17 -
18 - public function execute() {
19 - $params = $this->extractRequestParams();
20 -
21 - if ( !( isset( $params['username'] ) XOR isset( $params['userid'] ) ) ) {
22 - $this->dieUsage( wfMsg( 'ep-addinstructor-invalid-user-args' ), 'username-xor-userid' );
23 - }
24 -
25 - if ( isset( $params['username'] ) ) {
26 - $user = User::newFromName( $params['username'] );
27 - $userId = $user->getId();
28 - }
29 - else {
30 - $userId = $params['userid'];
31 - }
32 -
33 - if ( $userId < 1 ) {
34 - $this->dieUsage( wfMsg( 'ep-addinstructor-invalid-user' ), 'invalid-user' );
35 - }
36 -
37 - if ( !$this->userIsAllowed( $userId ) ) {
38 - $this->dieUsageMsg( array( 'badaccess-groups' ) );
39 - }
40 -
41 - $course = EPCourse::selectRow( array( 'id', 'name', 'instructors' ), array( 'id' => $params['courseid'] ) );
42 -
43 - if ( $course === false ) {
44 - $this->dieUsage( wfMsg( 'ep-addinstructor-invalid-course' ), 'invalid-course' );
45 - }
46 -
47 - $success = false;
48 -
49 - switch ( $params['subaction'] ) {
50 - case 'add':
51 - $success = $course->addInstructors( array( $userId ), $params['reason'] );
52 - break;
53 - case 'remove':
54 - $success = $course->removeInstructors( array( $userId ), $params['reason'] );
55 - break;
56 - }
57 -
58 - $this->getResult()->addValue(
59 - null,
60 - 'success',
61 - $success
62 - );
63 - }
64 -
65 - /**
66 - * Get the User being used for this instance.
67 - * ApiBase extends ContextSource as of 1.19.
68 - *
69 - * @since 0.1
70 - *
71 - * @return User
72 - */
73 - public function getUser() {
74 - return method_exists( 'ApiBase', 'getUser' ) ? parent::getUser() : $GLOBALS['wgUser'];
75 - }
76 -
77 - /**
78 - * Returns if the user is allowed to do the requested action.
79 - *
80 - * @since 0.1
81 - *
82 - * @param integer $userId User id of the mentor affected
83 - */
84 - protected function userIsAllowed( $userId ) {
85 - $user = $this->getUser();
86 -
87 - if ( $user->isAllowed( 'ep-instructor' ) ) {
88 - return true;
89 - }
90 -
91 - if ( $user->isAllowed( 'ep-beinstructor' ) && $user->getId() === $userId ) {
92 - return true;
93 - }
94 -
95 - return false;
96 - }
97 -
98 - public function needsToken() {
99 - return true;
100 - }
101 -
102 - public function mustBePosted() {
103 - return true;
104 - }
105 -
106 - public function getAllowedParams() {
107 - return array(
108 - 'subaction' => array(
109 - ApiBase::PARAM_TYPE => array( 'add', 'remove' ),
110 - ApiBase::PARAM_REQUIRED => true,
111 - ),
112 - 'username' => array(
113 - ApiBase::PARAM_TYPE => 'string',
114 - ApiBase::PARAM_REQUIRED => false,
115 - ),
116 - 'userid' => array(
117 - ApiBase::PARAM_TYPE => 'integer',
118 - ApiBase::PARAM_REQUIRED => false,
119 - ),
120 - 'courseid' => array(
121 - ApiBase::PARAM_TYPE => 'integer',
122 - ApiBase::PARAM_REQUIRED => true,
123 - ),
124 - 'reason' => array(
125 - ApiBase::PARAM_TYPE => 'string',
126 - ApiBase::PARAM_REQUIRED => false,
127 - ApiBase::PARAM_DFLT => '',
128 - ),
129 - 'token' => null,
130 - );
131 - }
132 -
133 - public function getParamDescription() {
134 - return array(
135 - 'subaction' => 'Specifies what you want to do with the instructor',
136 - 'courseid' => 'The ID of the course to/from which the instructor should be added/removed',
137 - 'username' => 'Name of the user to associate as instructor',
138 - 'userid' => 'Id of the user to associate as instructor',
139 - 'reason' => 'Message with the reason for this change for the log',
140 - 'token' => 'Edit token. You can get one of these through prop=info.',
141 - );
142 - }
143 -
144 - public function getDescription() {
145 - return array(
146 - 'API module for associating/disassociating a user as instructor with/from a course.'
147 - );
148 - }
149 -
150 - public function getPossibleErrors() {
151 - return array_merge( parent::getPossibleErrors(), array(
152 - array( 'code' => 'username-xor-userid', 'info' => 'You need to either provide the username or the userid parameter' ),
153 - array( 'code' => 'invalid-user', 'info' => 'An invalid user name or id was provided' ),
154 - array( 'code' => 'invalid-course', 'info' => 'There is no course with the provided ID' ),
155 - ) );
156 - }
157 -
158 - protected function getExamples() {
159 - return array(
160 - 'api.php?action=instructor&subaction=add&courseid=42&userid=9001',
161 - 'api.php?action=instructor&subaction=add&courseid=42&username=Jeroen%20De%20Dauw',
162 - 'api.php?action=instructor&subaction=remove&courseid=42&userid=9001',
163 - 'api.php?action=instructor&subaction=remove&courseid=42&username=Jeroen%20De%20Dauw',
164 - 'api.php?action=instructor&subaction=remove&courseid=42&username=Jeroen%20De%20Dauw&reason=Removed%20from%20program%20because%20of%20evil%20plans%20to%20take%20over%20the%20world',
165 - );
166 - }
167 -
168 - public function getVersion() {
169 - return __CLASS__ . ': $Id$';
170 - }
171 -
172 -}
Index: trunk/extensions/EducationProgram/api/ApiEnlist.php
@@ -0,0 +1,177 @@
 2+<?php
 3+
 4+/**
 5+ * API module to associate/disassociate users as instructor or ambassador with/from a course.
 6+ *
 7+ * @since 0.1
 8+ *
 9+ * @file ApiEnlist.php
 10+ * @ingroup EducationProgram
 11+ * @ingroup API
 12+ *
 13+ * @licence GNU GPL v3+
 14+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 15+ */
 16+class ApiEnlist extends ApiBase {
 17+
 18+ public function execute() {
 19+ $params = $this->extractRequestParams();
 20+
 21+ if ( !( isset( $params['username'] ) XOR isset( $params['userid'] ) ) ) {
 22+ $this->dieUsage( wfMsg( 'ep-enlist-invalid-user-args' ), 'username-xor-userid' );
 23+ }
 24+
 25+ if ( isset( $params['username'] ) ) {
 26+ $user = User::newFromName( $params['username'] );
 27+ $userId = $user->getId();
 28+ }
 29+ else {
 30+ $userId = $params['userid'];
 31+ }
 32+
 33+ if ( $userId < 1 ) {
 34+ $this->dieUsage( wfMsg( 'ep-enlist-invalid-user' ), 'invalid-user' );
 35+ }
 36+
 37+ if ( !$this->userIsAllowed( $userId ) ) {
 38+ $this->dieUsageMsg( array( 'badaccess-groups' ) );
 39+ }
 40+
 41+ $field = $params['role'] === 'instructor' ? 'instructors' : $params['role'] . '_ambs';
 42+ $course = EPCourse::selectRow( array( 'id', 'name', $field ), array( 'id' => $params['courseid'] ) );
 43+
 44+ if ( $course === false ) {
 45+ $this->dieUsage( wfMsg( 'ep-enlist-invalid-course' ), 'invalid-course' );
 46+ }
 47+
 48+ $success = false;
 49+
 50+ switch ( $params['subaction'] ) {
 51+ case 'add':
 52+ $success = $course->enlistUsers( array( $userId ), $params['role'], $params['reason'] );
 53+ break;
 54+ case 'remove':
 55+ $success = $course->unenlistUsers( array( $userId ), $params['role'], $params['reason'] );
 56+ break;
 57+ }
 58+
 59+ $this->getResult()->addValue(
 60+ null,
 61+ 'success',
 62+ $success
 63+ );
 64+ }
 65+
 66+ /**
 67+ * Get the User being used for this instance.
 68+ * ApiBase extends ContextSource as of 1.19.
 69+ *
 70+ * @since 0.1
 71+ *
 72+ * @return User
 73+ */
 74+ public function getUser() {
 75+ return method_exists( 'ApiBase', 'getUser' ) ? parent::getUser() : $GLOBALS['wgUser'];
 76+ }
 77+
 78+ /**
 79+ * Returns if the user is allowed to do the requested action.
 80+ *
 81+ * @since 0.1
 82+ *
 83+ * @param integer $userId User id of the mentor affected
 84+ */
 85+ protected function userIsAllowed( $userId ) {
 86+ $user = $this->getUser();
 87+
 88+ if ( $user->isAllowed( 'ep-instructor' ) ) {
 89+ return true;
 90+ }
 91+
 92+ if ( $user->isAllowed( 'ep-beinstructor' ) && $user->getId() === $userId ) {
 93+ return true;
 94+ }
 95+
 96+ return false;
 97+ }
 98+
 99+ public function needsToken() {
 100+ return true;
 101+ }
 102+
 103+ public function mustBePosted() {
 104+ return true;
 105+ }
 106+
 107+ public function getAllowedParams() {
 108+ return array(
 109+ 'subaction' => array(
 110+ ApiBase::PARAM_TYPE => array( 'add', 'remove' ),
 111+ ApiBase::PARAM_REQUIRED => true,
 112+ ),
 113+ 'role' => array(
 114+ ApiBase::PARAM_TYPE => array( 'instructor', 'online', 'campus' ),
 115+ ApiBase::PARAM_REQUIRED => true,
 116+ ),
 117+ 'username' => array(
 118+ ApiBase::PARAM_TYPE => 'string',
 119+ ApiBase::PARAM_REQUIRED => false,
 120+ ),
 121+ 'userid' => array(
 122+ ApiBase::PARAM_TYPE => 'integer',
 123+ ApiBase::PARAM_REQUIRED => false,
 124+ ),
 125+ 'courseid' => array(
 126+ ApiBase::PARAM_TYPE => 'integer',
 127+ ApiBase::PARAM_REQUIRED => true,
 128+ ),
 129+ 'reason' => array(
 130+ ApiBase::PARAM_TYPE => 'string',
 131+ ApiBase::PARAM_REQUIRED => false,
 132+ ApiBase::PARAM_DFLT => '',
 133+ ),
 134+ 'token' => null,
 135+ );
 136+ }
 137+
 138+ public function getParamDescription() {
 139+ return array(
 140+ 'subaction' => 'Specifies what you want to do with the instructor or ambassador',
 141+ 'role' => 'The role to affect. "instructor" for instructor, "online" for online ambassadors and "campus" for campus ambassadors',
 142+ 'courseid' => 'The ID of the course to/from which the instructor or ambassador should be added/removed',
 143+ 'username' => 'Name of the user to associate as instructor or ambassador',
 144+ 'userid' => 'Id of the user to associate as instructor or ambassador',
 145+ 'reason' => 'Message with the reason for this change for the log',
 146+ 'token' => 'Edit token. You can get one of these through prop=info.',
 147+ );
 148+ }
 149+
 150+ public function getDescription() {
 151+ return array(
 152+ 'API module for associating/disassociating a user as instructor or ambassador with/from a course.'
 153+ );
 154+ }
 155+
 156+ public function getPossibleErrors() {
 157+ return array_merge( parent::getPossibleErrors(), array(
 158+ array( 'code' => 'username-xor-userid', 'info' => 'You need to either provide the username or the userid parameter' ),
 159+ array( 'code' => 'invalid-user', 'info' => 'An invalid user name or id was provided' ),
 160+ array( 'code' => 'invalid-course', 'info' => 'There is no course with the provided ID' ),
 161+ ) );
 162+ }
 163+
 164+ protected function getExamples() {
 165+ return array(
 166+ 'api.php?action=instructor&subaction=add&courseid=42&userid=9001',
 167+ 'api.php?action=instructor&subaction=add&courseid=42&username=Jeroen%20De%20Dauw',
 168+ 'api.php?action=instructor&subaction=remove&courseid=42&userid=9001',
 169+ 'api.php?action=instructor&subaction=remove&courseid=42&username=Jeroen%20De%20Dauw',
 170+ 'api.php?action=instructor&subaction=remove&courseid=42&username=Jeroen%20De%20Dauw&reason=Removed%20from%20program%20because%20of%20evil%20plans%20to%20take%20over%20the%20world',
 171+ );
 172+ }
 173+
 174+ public function getVersion() {
 175+ return __CLASS__ . ': $Id$';
 176+ }
 177+
 178+}
Property changes on: trunk/extensions/EducationProgram/api/ApiEnlist.php
___________________________________________________________________
Added: svn:eol-style
1179 + native
Added: svn:keywords
2180 + Id
Index: trunk/extensions/EducationProgram/resources/ep.instructor.js
@@ -1,229 +0,0 @@
2 -/**
3 - * JavasSript for the Education Program MediaWiki extension.
4 - * @see https://www.mediawiki.org/wiki/Extension:Education_Program
5 - *
6 - * @licence GNU GPL v3 or later
7 - * @author Jeroen De Dauw <jeroendedauw at gmail dot com>
8 - */
9 -
10 -(function( $, mw ) {
11 -
12 - var ep = mw.educationProgram;
13 -
14 - $( document ).ready( function() {
15 -
16 - $( '.ep-instructor-remove' ).click( function( event ) {
17 - var $this = $( this ),
18 - courseId = $this.attr( 'data-courseid' ),
19 - courseName = $this.attr( 'data-coursename' ),
20 - userId = $this.attr( 'data-userid' ),
21 - userName = $this.attr( 'data-username' ),
22 - bestName = $this.attr( 'data-bestname' ),
23 - $dialog = null;
24 -
25 - var doRemove = function() {
26 - var $remove = $( '#ep-instructor-remove-button' );
27 - var $cancel = $( '#ep-instructor-cancel-button' );
28 -
29 - $remove.button( 'option', 'disabled', true );
30 - $remove.button( 'option', 'label', ep.msg( 'ep-instructor-removing' ) );
31 -
32 - ep.api.removeInstructor( {
33 - 'courseid': courseId,
34 - 'userid': userId,
35 - 'reason': summaryInput.val()
36 - } ).done( function() {
37 - $dialog.text( ep.msg( 'ep-instructor-removal-success' ) );
38 - $remove.remove();
39 - $cancel.button( 'option', 'label', ep.msg( 'ep-instructor-close-button' ) );
40 - $cancel.focus();
41 -
42 - $li = $this.closest( 'li' );
43 - $ul = $li.closest( 'ul' );
44 - $li.remove();
45 -
46 - if ( $ul.find( 'li' ).length < 1 ) {
47 - $ul.closest( 'div' ).text( mw.msg( 'ep-course-no-instructors' ) );
48 - }
49 - } ).fail( function() {
50 - $remove.button( 'option', 'disabled', false );
51 - $remove.button( 'option', 'label', ep.msg( 'ep-instructor-remove-retry' ) );
52 - alert( ep.msg( 'ep-instructor-remove-failed' ) );
53 - } );
54 - };
55 -
56 - var summaryInput = $( '<input>' ).attr( {
57 - 'type': 'text',
58 - 'size': 60,
59 - 'maxlength': 250
60 - } );
61 -
62 - $dialog = $( '<div>' ).html( '' ).dialog( {
63 - 'title': ep.msg( 'ep-instructor-remove-title' ),
64 - 'minWidth': 550,
65 - 'buttons': [
66 - {
67 - 'text': ep.msg( 'ep-instructor-remove-button' ),
68 - 'id': 'ep-instructor-remove-button',
69 - 'click': doRemove
70 - },
71 - {
72 - 'text': ep.msg( 'ep-instructor-cancel-button' ),
73 - 'id': 'ep-instructor-cancel-button',
74 - 'click': function() {
75 - $dialog.dialog( 'close' );
76 - }
77 - }
78 - ]
79 - } );
80 -
81 - $dialog.append( $( '<p>' ).msg(
82 - 'ep-instructor-remove-text',
83 - mw.html.escape( userName ),
84 - $( '<b>' ).text( bestName ),
85 - $( '<b>' ).text( courseName )
86 - ) );
87 -
88 - //$dialog.append( $( '<p>' ).msg( 'ep-instructor-remove-title' ) );
89 -
90 - $dialog.append( summaryInput );
91 -
92 - summaryInput.focus();
93 -
94 - summaryInput.keypress( function( event ) {
95 - if ( event.which == '13' ) {
96 - event.preventDefault();
97 - doRemove();
98 - }
99 - } );
100 - } );
101 -
102 - $( '.ep-add-instructor' ).click( function( event ) {
103 - var $this = $( this ), _this = this;
104 -
105 - this.courseId = $this.attr( 'data-courseid' );
106 - this.courseName = $this.attr( 'data-mcname' );
107 - this.selfMode = $this.attr( 'data-mode' ) === 'self';
108 - this.$dialog = null;
109 -
110 - this.nameInput = $( '<input>' ).attr( {
111 - 'type': 'text',
112 - 'size': 30,
113 - 'maxlength': 250,
114 - 'id': 'ep-instructor-nameinput',
115 - 'name': 'ep-instructor-nameinput'
116 - } );
117 -
118 - this.summaryInput = $( '<input>' ).attr( {
119 - 'type': 'text',
120 - 'size': 60,
121 - 'maxlength': 250,
122 - 'id': 'ep-instructor-summaryinput',
123 - 'name': 'ep-instructor-summaryinput'
124 - } );
125 -
126 - this.getName = function() {
127 - return this.selfMode ? mw.user.name : this.nameInput.val();
128 - };
129 -
130 - this.doAdd = function() {
131 - var $add = $( '#ep-instructor-add-button' );
132 - var $cancel = $( '#ep-instructor-add-cancel-button' );
133 -
134 - $add.button( 'option', 'disabled', true );
135 - $add.button( 'option', 'label', ep.msg( 'ep-instructor-adding' ) );
136 -
137 - ep.api.addInstructor( {
138 - 'courseid': _this.courseId,
139 - 'username': _this.getName(),
140 - 'reason': _this.summaryInput.val()
141 - } ).done( function() {
142 - _this.$dialog.text( ep.msg(
143 - _this.selfMode ? 'ep-instructor-addittion-self-success' : 'ep-instructor-addittion-success',
144 - _this.getName(),
145 - _this.courseName
146 - ) );
147 -
148 - $add.remove();
149 - $cancel.button( 'option', 'label', ep.msg( 'ep-instructor-add-close-button' ) );
150 - $cancel.focus();
151 -
152 - // TODO: link name to user page and show control links
153 - $ul = $( '#ep-course-instructors' ).find( 'ul' );
154 -
155 - if ( $ul.length < 1 ) {
156 - $ul = $( '<ul>' );
157 - $( '#ep-course-instructors' ).html( $ul );
158 - }
159 -
160 - $ul.append( $( '<li>' ).text( _this.getName() ) )
161 - } ).fail( function() {
162 - // TODO: implement nicer handling for fails caused by invalid user name
163 -
164 - $add.button( 'option', 'disabled', false );
165 - $add.button( 'option', 'label', ep.msg( 'ep-instructor-add-retry' ) );
166 - alert( ep.msg( 'ep-instructor-addittion-failed' ) );
167 - } );
168 - };
169 -
170 - this.$dialog = $( '<div>' ).html( '' ).dialog( {
171 - 'title': ep.msg( this.selfMode ? 'ep-instructor-add-self-title' : 'ep-instructor-add-title', this.getName() ),
172 - 'minWidth': 550,
173 - 'buttons': [
174 - {
175 - 'text': ep.msg( this.selfMode ? 'ep-instructor-add-self-button' : 'ep-instructor-add-button', this.getName() ),
176 - 'id': 'ep-instructor-add-button',
177 - 'click': this.doAdd
178 - },
179 - {
180 - 'text': ep.msg( 'ep-instructor-add-cancel-button' ),
181 - 'id': 'ep-instructor-add-cancel-button',
182 - 'click': function() {
183 - _this.$dialog.dialog( 'close' );
184 - }
185 - }
186 - ]
187 - } );
188 -
189 - this.$dialog.append( $( '<p>' ).text( gM(
190 - this.selfMode ? 'ep-instructor-add-self-text' : 'ep-instructor-add-text',
191 - this.courseName,
192 - this.getName()
193 - ) ) );
194 -
195 - if ( !this.selfMode ) {
196 - this.$dialog.append(
197 - $( '<label>' ).attr( {
198 - 'for': 'ep-instructor-nameinput'
199 - } ).text( ep.msg( 'ep-instructor-name-input' ) + ' ' ),
200 - this.nameInput,
201 - '<br />',
202 - $( '<label>' ).attr( {
203 - 'for': 'ep-instructor-summaryinput'
204 - } ).text( ep.msg( 'ep-instructor-summary-input' ) )
205 - );
206 - }
207 -
208 - this.$dialog.append( this.summaryInput );
209 -
210 - if ( this.selfMode ) {
211 - this.summaryInput.focus();
212 - }
213 - else {
214 - this.nameInput.focus();
215 - }
216 -
217 - var enterHandler = function( event ) {
218 - if ( event.which == '13' ) {
219 - event.preventDefault();
220 - _this.doAdd();
221 - }
222 - };
223 -
224 - this.nameInput.keypress( enterHandler );
225 - this.summaryInput.keypress( enterHandler );
226 - } );
227 -
228 - } );
229 -
230 -})( window.jQuery, window.mediaWiki );
\ No newline at end of file
Index: trunk/extensions/EducationProgram/resources/ep.api.js
@@ -10,9 +10,9 @@
1111
1212 mw.educationProgram.api = {
1313
14 - instructor: function( args ) {
 14+ enlist: function( args ) {
1515 var requestArgs = $.extend( {
16 - 'action': 'instructor',
 16+ 'action': 'enlist',
1717 'format': 'json',
1818 'token': window.mw.user.tokens.get( 'editToken' )
1919 }, args );
@@ -35,14 +35,14 @@
3636 return deferred.promise();
3737 },
3838
39 - addInstructor: function( args ) {
 39+ enlistUser: function( args ) {
4040 args.subaction = 'add';
41 - return this.instructor( args );
 41+ return this.enlist( args );
4242 },
4343
44 - removeInstructor: function( args ) {
 44+ unenlistUser: function( args ) {
4545 args.subaction = 'remove';
46 - return this.instructor( args );
 46+ return this.enlist( args );
4747 },
4848
4949 remove: function( data, callback ) {
Index: trunk/extensions/EducationProgram/resources/ep.enlist.js
@@ -0,0 +1,237 @@
 2+/**
 3+ * JavasSript for the Education Program MediaWiki extension.
 4+ * @see https://www.mediawiki.org/wiki/Extension:Education_Program
 5+ *
 6+ * @licence GNU GPL v3 or later
 7+ * @author Jeroen De Dauw <jeroendedauw at gmail dot com>
 8+ */
 9+
 10+(function( $, mw ) {
 11+
 12+ var ep = mw.educationProgram;
 13+
 14+ $( document ).ready( function() {
 15+
 16+ $( '.ep-remove-role' ).click( function( event ) {
 17+ var $this = $( this ),
 18+ courseId = $this.attr( 'data-courseid' ),
 19+ courseName = $this.attr( 'data-coursename' ),
 20+ userId = $this.attr( 'data-userid' ),
 21+ userName = $this.attr( 'data-username' ),
 22+ bestName = $this.attr( 'data-bestname' ),
 23+ role = $this.attr( 'data-role' ),
 24+ $dialog = null;
 25+
 26+ var doRemove = function() {
 27+ var $remove = $( '#ep-' + role + '-remove-button' );
 28+ var $cancel = $( '#ep-' + role + '-cancel-button' );
 29+
 30+ $remove.button( 'option', 'disabled', true );
 31+ $remove.button( 'option', 'label', ep.msg( 'ep-' + role + '-removing' ) );
 32+
 33+ ep.api.unenlistUser( {
 34+ 'courseid': courseId,
 35+ 'userid': userId,
 36+ 'reason': summaryInput.val(),
 37+ 'role': role
 38+ } ).done( function() {
 39+ $dialog.text( ep.msg( 'ep-' + role + '-removal-success' ) );
 40+ $remove.remove();
 41+ $cancel.button( 'option', 'label', ep.msg( 'ep-' + role + '-close-button' ) );
 42+ $cancel.focus();
 43+
 44+ $li = $this.closest( 'li' );
 45+ $ul = $li.closest( 'ul' );
 46+ $li.remove();
 47+
 48+ if ( $ul.find( 'li' ).length < 1 ) {
 49+ $ul.closest( 'div' ).text( mw.msg( 'ep-course-no-' + role ) );
 50+ }
 51+ } ).fail( function() {
 52+ $remove.button( 'option', 'disabled', false );
 53+ $remove.button( 'option', 'label', ep.msg( 'ep-' + role + '-remove-retry' ) );
 54+ alert( ep.msg( 'ep-' + role + '-remove-failed' ) );
 55+ } );
 56+ };
 57+
 58+ var summaryInput = $( '<input>' ).attr( {
 59+ 'type': 'text',
 60+ 'size': 60,
 61+ 'maxlength': 250
 62+ } );
 63+
 64+ $dialog = $( '<div>' ).html( '' ).dialog( {
 65+ 'title': ep.msg( 'ep-' + role + '-remove-title' ),
 66+ 'minWidth': 550,
 67+ 'buttons': [
 68+ {
 69+ 'text': ep.msg( 'ep-' + role + '-remove-button' ),
 70+ 'id': 'ep-' + role + '-remove-button',
 71+ 'click': doRemove
 72+ },
 73+ {
 74+ 'text': ep.msg( 'ep-' + role + '-cancel-button' ),
 75+ 'id': 'ep-' + role + '-cancel-button',
 76+ 'click': function() {
 77+ $dialog.dialog( 'close' );
 78+ }
 79+ }
 80+ ]
 81+ } );
 82+
 83+ $dialog.append( $( '<p>' ).msg(
 84+ 'ep-' + role + '-remove-text',
 85+ mw.html.escape( userName ),
 86+ $( '<b>' ).text( bestName ),
 87+ $( '<b>' ).text( courseName )
 88+ ) );
 89+
 90+ //$dialog.append( $( '<p>' ).msg( 'ep-instructor-remove-title' ) );
 91+
 92+ $dialog.append( summaryInput );
 93+
 94+ summaryInput.focus();
 95+
 96+ summaryInput.keypress( function( event ) {
 97+ if ( event.which == '13' ) {
 98+ event.preventDefault();
 99+ doRemove();
 100+ }
 101+ } );
 102+ } );
 103+
 104+ $( '.ep-add-role' ).click( function( event ) {
 105+ var $this = $( this ),
 106+ _this = this,
 107+ role = $this.attr( 'data-role' );
 108+
 109+ this.courseId = $this.attr( 'data-courseid' );
 110+ this.courseName = $this.attr( 'data-coursename' );
 111+ this.selfMode = $this.attr( 'data-mode' ) === 'self';
 112+ this.$dialog = null;
 113+
 114+ this.nameInput = $( '<input>' ).attr( {
 115+ 'type': 'text',
 116+ 'size': 30,
 117+ 'maxlength': 250,
 118+ 'id': 'ep-' + role + '-nameinput',
 119+ 'name': 'ep-' + role + '-nameinput'
 120+ } );
 121+
 122+ this.summaryInput = $( '<input>' ).attr( {
 123+ 'type': 'text',
 124+ 'size': 60,
 125+ 'maxlength': 250,
 126+ 'id': 'ep-' + role + '-summaryinput',
 127+ 'name': 'ep-' + role + '-summaryinput'
 128+ } );
 129+
 130+ this.getName = function() {
 131+ return this.selfMode ? mw.user.name : this.nameInput.val();
 132+ };
 133+
 134+ this.doAdd = function() {
 135+ var $add = $( '#ep-' + role + '-add-button' );
 136+ var $cancel = $( '#ep-' + role + '-add-cancel-button' );
 137+
 138+ $add.button( 'option', 'disabled', true );
 139+ $add.button( 'option', 'label', ep.msg( 'ep-' + role + '-adding' ) );
 140+
 141+ ep.api.enlistUser( {
 142+ 'courseid': _this.courseId,
 143+ 'username': _this.getName(),
 144+ 'reason': _this.summaryInput.val(),
 145+ 'role': role
 146+ } ).done( function() {
 147+ _this.$dialog.text( ep.msg(
 148+ _this.selfMode ? 'ep-' + role + '-addittion-self-success' : 'ep-' + role + '-addittion-success',
 149+ _this.getName(),
 150+ _this.courseName
 151+ ) );
 152+
 153+ $add.remove();
 154+ $cancel.button( 'option', 'label', ep.msg( 'ep-' + role + '-add-close-button' ) );
 155+ $cancel.focus();
 156+
 157+ // TODO: link name to user page and show control links
 158+ $ul = $( '#ep-course-' + role ).find( 'ul' );
 159+
 160+ if ( $ul.length < 1 ) {
 161+ $ul = $( '<ul>' );
 162+ $( '#ep-course-' + role ).html( $ul );
 163+ }
 164+
 165+ $ul.append( $( '<li>' ).text( _this.getName() ) )
 166+ } ).fail( function() {
 167+ // TODO: implement nicer handling for fails caused by invalid user name
 168+
 169+ $add.button( 'option', 'disabled', false );
 170+ $add.button( 'option', 'label', ep.msg( 'ep-' + role + '-add-retry' ) );
 171+ alert( ep.msg( 'ep-' + role + '-addittion-failed' ) );
 172+ } );
 173+ };
 174+
 175+ this.$dialog = $( '<div>' ).html( '' ).dialog( {
 176+ 'title': ep.msg( this.selfMode ? 'ep-' + role + '-add-self-title' : 'ep-' + role + '-add-title', this.getName() ),
 177+ 'minWidth': 550,
 178+ 'buttons': [
 179+ {
 180+ 'text': ep.msg(
 181+ this.selfMode ? 'ep-' + role + '-add-self-button' : 'ep-' + role + '-add-button',
 182+ this.getName()
 183+ ),
 184+ 'id': 'ep-' + role + '-add-button',
 185+ 'click': this.doAdd
 186+ },
 187+ {
 188+ 'text': ep.msg( 'ep-' + role + '-add-cancel-button' ),
 189+ 'id': 'ep-' + role + '-add-cancel-button',
 190+ 'click': function() {
 191+ _this.$dialog.dialog( 'close' );
 192+ }
 193+ }
 194+ ]
 195+ } );
 196+
 197+ this.$dialog.append( $( '<p>' ).text( gM(
 198+ this.selfMode ? 'ep-' + role + '-add-self-text' : 'ep-' + role + '-add-text',
 199+ this.courseName,
 200+ this.getName()
 201+ ) ) );
 202+
 203+ if ( !this.selfMode ) {
 204+ this.$dialog.append(
 205+ $( '<label>' ).attr( {
 206+ 'for': 'ep-' + role + '-nameinput'
 207+ } ).text( ep.msg( 'ep-' + role + '-name-input' ) + ' ' ),
 208+ this.nameInput,
 209+ '<br />',
 210+ $( '<label>' ).attr( {
 211+ 'for': 'ep-' + role + '-summaryinput'
 212+ } ).text( ep.msg( 'ep-' + role + '-summary-input' ) )
 213+ );
 214+ }
 215+
 216+ this.$dialog.append( this.summaryInput );
 217+
 218+ if ( this.selfMode ) {
 219+ this.summaryInput.focus();
 220+ }
 221+ else {
 222+ this.nameInput.focus();
 223+ }
 224+
 225+ var enterHandler = function( event ) {
 226+ if ( event.which == '13' ) {
 227+ event.preventDefault();
 228+ _this.doAdd();
 229+ }
 230+ };
 231+
 232+ this.nameInput.keypress( enterHandler );
 233+ this.summaryInput.keypress( enterHandler );
 234+ } );
 235+
 236+ } );
 237+
 238+})( window.jQuery, window.mediaWiki );
\ No newline at end of file
Property changes on: trunk/extensions/EducationProgram/resources/ep.enlist.js
___________________________________________________________________
Added: svn:eol-style
1239 + native

Status & tagging log