r110661 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r110660‎ | r110661 | r110662 >
Date:16:28, 3 February 2012
Author:jeroendedauw
Status:deferred
Tags:
Comment:
work on special:mycourses
Modified paths:
  • /trunk/extensions/EducationProgram/EducationProgram.hooks.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.i18n.php (modified) (history)
  • /trunk/extensions/EducationProgram/EducationProgram.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPCA.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPCourse.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPCoursePager.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPIRole.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPInstructor.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPOA.php (modified) (history)
  • /trunk/extensions/EducationProgram/includes/EPRoleObject.php (added) (history)
  • /trunk/extensions/EducationProgram/includes/EPStudent.php (modified) (history)
  • /trunk/extensions/EducationProgram/specials/SpecialMyCourses.php (modified) (history)
  • /trunk/extensions/EducationProgram/sql/EducationProgram.sql (modified) (history)
  • /trunk/extensions/EducationProgram/sql/RenameAmbUserField.sql (added) (history)

Diff [purge]

Index: trunk/extensions/EducationProgram/EducationProgram.php
@@ -96,6 +96,7 @@
9797 $wgAutoloadClasses['EPFailForm'] = dirname( __FILE__ ) . '/includes/EPFailForm.php';
9898 $wgAutoloadClasses['EPIRole'] = dirname( __FILE__ ) . '/includes/EPIRole.php';
9999 $wgAutoloadClasses['EPRevisionedObject'] = dirname( __FILE__ ) . '/includes/EPRevisionedObject.php';
 100+$wgAutoloadClasses['EPRoleObject'] = dirname( __FILE__ ) . '/includes/EPRoleObject.php';
100101
101102 $wgAutoloadClasses['CoursePage'] = dirname( __FILE__ ) . '/pages/CoursePage.php';
102103 $wgAutoloadClasses['EPPage'] = dirname( __FILE__ ) . '/pages/EPPage.php';
@@ -152,6 +153,8 @@
153154 $egEPDBObjects['EPOA'] = array( 'table' => 'ep_oas', 'prefix' => 'oa_' );
154155 $egEPDBObjects['EPCA'] = array( 'table' => 'ep_cas', 'prefix' => 'ca_' );
155156 $egEPDBObjects[] = array( 'table' => 'ep_students_per_course', 'prefix' => 'spc_' );
 157+$egEPDBObjects[] = array( 'table' => 'ep_oas_per_course', 'prefix' => 'opc_' );
 158+$egEPDBObjects[] = array( 'table' => 'ep_cas_per_course', 'prefix' => 'cpc_' );
156159
157160 // API
158161 $wgAPIModules['deleteeducation'] = 'ApiDeleteEducation';
Index: trunk/extensions/EducationProgram/sql/EducationProgram.sql
@@ -40,9 +40,9 @@
4141 course_start varbinary(14) NOT NULL, -- Start time of the course
4242 course_end varbinary(14) NOT NULL, -- End time of the course
4343 course_description TEXT NOT NULL, -- Description of the course
44 - course_online_ambs BLOB NOT NULL, -- List of associated online ambassadors (linking ep_oas.oa_id)
45 - course_campus_ambs BLOB NOT NULL, -- List of associated campus ambassadors (linking ep_cas.ca_id)
46 - course_instructors BLOB NOT NULL, -- List of associated instructors (linking ep_instructors.instructor_id)
 44+ course_online_ambs BLOB NOT NULL, -- List of associated online ambassadors (linking user.user_id)
 45+ course_campus_ambs BLOB NOT NULL, -- List of associated campus ambassadors (linking user.user_id)
 46+ course_instructors BLOB NOT NULL, -- List of associated instructors (linking user.user_id)
4747 course_token VARCHAR(255) NOT NULL, -- Token needed to enroll
4848 course_field VARCHAR(255) NOT NULL, -- Field of study
4949 course_level VARCHAR(255) NOT NULL, -- Study level
@@ -139,11 +139,11 @@
140140 -- Links the campus ambassadors with all their courses.
141141 -- The is secondary storage for queries. The canonical data is in ep_course.campus_ambs
142142 CREATE TABLE IF NOT EXISTS /*_*/ep_cas_per_course (
143 - cpc_ca_id INT unsigned NOT NULL, -- Foreign key on ep_cas.ca_id
 143+ cpc_user_id INT unsigned NOT NULL, -- Foreign key on user.user_id
144144 cpc_course_id INT unsigned NOT NULL -- Foreign key on ep_course.course_id
145145 ) /*$wgDBTableOptions*/;
146146
147 -CREATE UNIQUE INDEX /*i*/ep_cas_per_course ON /*_*/ep_cas_per_course (cpc_ca_id, cpc_course_id);
 147+CREATE UNIQUE INDEX /*i*/ep_cas_per_course ON /*_*/ep_cas_per_course (cpc_user_id, cpc_course_id);
148148
149149
150150
@@ -163,11 +163,11 @@
164164 -- Links the online ambassadors with all their courses.
165165 -- The is secondary storage for queries. The canonical data is in ep_course.online_ambs
166166 CREATE TABLE IF NOT EXISTS /*_*/ep_oas_per_course (
167 - opc_oa_id INT unsigned NOT NULL, -- Foreign key on ep_oas.oa_id
 167+ opc_user_id INT unsigned NOT NULL, -- Foreign key on user.user_id
168168 opc_course_id INT unsigned NOT NULL -- Foreign key on ep_course.course_id
169169 ) /*$wgDBTableOptions*/;
170170
171 -CREATE UNIQUE INDEX /*i*/ep_oas_per_course ON /*_*/ep_oas_per_course (opc_oa_id, opc_course_id);
 171+CREATE UNIQUE INDEX /*i*/ep_oas_per_course ON /*_*/ep_oas_per_course (opc_user_id, opc_course_id);
172172
173173
174174
Index: trunk/extensions/EducationProgram/sql/RenameAmbUserField.sql
@@ -0,0 +1,6 @@
 2+-- MySQL for the Education Program extension.
 3+-- Licence: GNU GPL v3+
 4+-- Author: Jeroen De Dauw < jeroendedauw@gmail.com >
 5+
 6+ALTER TABLE /*_*/ep_cas_per_course CHANGE `cpc_ca_id` `cpc_user_id` INT( 10 ) UNSIGNED NOT NULL;
 7+ALTER TABLE /*_*/ep_oas_per_course CHANGE `opc_oa_id` `opc_user_id` INT( 10 ) UNSIGNED NOT NULL;
\ No newline at end of file
Property changes on: trunk/extensions/EducationProgram/sql/RenameAmbUserField.sql
___________________________________________________________________
Added: svn:eol-style
18 + native
Index: trunk/extensions/EducationProgram/specials/SpecialMyCourses.php
@@ -35,23 +35,35 @@
3636 public function execute( $subPage ) {
3737 parent::execute( $subPage );
3838
39 - if ( $this->getUser()->isAllowed( 'ep-org' ) ) {
40 - $this->displayNavigation();
41 - }
42 -
43 - if ( $this->subPage === '' ) {
44 - $this->displayCourses();
45 - }
46 - else {
47 - $course = EPCourse::selectRow( null, array( 'name' => $this->subPage ) );
 39+ if ( $this->getUser()->isLoggedIn() ) {
 40+ if ( $this->getUser()->isAllowed( 'ep-org' ) ) {
 41+ $this->displayNavigation();
 42+ }
4843
49 - if ( $course === false ) {
50 -
 44+ if ( $this->subPage === '' ) {
 45+ $this->displayCourses();
5146 }
5247 else {
53 - $this->displayCourse( $course );
54 - }
 48+ $course = EPCourse::selectRow( null, array( 'name' => $this->subPage ) );
 49+
 50+ if ( $course === false ) {
 51+ // TODO
 52+ }
 53+ else {
 54+ $this->displayCourse( $course );
 55+ }
 56+ }
5557 }
 58+ else {
 59+ $this->getOutput()->addHTML( Linker::linkKnown(
 60+ SpecialPage::getTitleFor( 'Userlogin' ),
 61+ wfMsgHtml( 'ep-mycourses-login-first' ),
 62+ array(),
 63+ array(
 64+ 'returnto' => $this->getTitle( $this->subPage )->getFullText()
 65+ )
 66+ ) );
 67+ }
5668 }
5769
5870 /**
@@ -76,11 +88,11 @@
7789 }
7890
7991 if ( $this->getUser()->isAllowed( 'ep-online' ) ) {
80 - $this->displayOnlineMentorship();
 92+ $this->displayMentorship( 'EPOA' );
8193 }
8294
8395 if ( $this->getUser()->isAllowed( 'ep-campus' ) ) {
84 - $this->displayCampusMentorship();
 96+ $this->displayMentorship( 'EPCA' );
8597 }
8698 }
8799
@@ -91,47 +103,53 @@
92104
93105 $student = EPStudent::newFromUser( $this->getUser() );
94106
95 - if ( $student !== false ) {
96 - $courses = $student->getCourses( 'id' );
 107+ $courses = $student->getCourses( 'id' );
 108+
 109+ $courseIds = array_map(
 110+ function( EPCourse $course ) {
 111+ return $course->getId();
 112+ },
 113+ $courses
 114+ );
 115+
 116+ if ( $this->getRequest()->getCheck( 'enrolled' ) && in_array( $this->getRequest()->getInt( 'enrolled' ), $courseIds ) ) {
 117+ $course = EPCourse::selectRow( array( 'name', 'org_id' ), array( 'id' => $this->getRequest()->getInt( 'enrolled' ) ) );
97118
98 - $courseIds = array_map(
99 - function( EPCourse $course ) {
100 - return $course->getId();
101 - },
102 - $courses
103 - );
104 -
105 - if ( $this->getRequest()->getCheck( 'enrolled' ) && in_array( $this->getRequest()->getInt( 'enrolled' ), $courseIds ) ) {
106 - $course = EPCourse::selectRow( array( 'name', 'org_id' ), array( 'id' => $this->getRequest()->getInt( 'enrolled' ) ) );
107 -
108 - $this->showSuccess( wfMessage(
109 - 'ep-mycourses-enrolled',
110 - $course->getField( 'name' ),
111 - $course->getOrg()->getField( 'name' )
112 - ) );
113 - }
114 -
115 - if ( count( $courseIds ) === 0 ) {
116 - // TODO
117 - }
118 - elseif ( count( $courseIds ) === 1 ) {
119 - $course = $courses[0];
120 - $course->loadFields();
121 - $this->displayCourse( $course );
122 - }
123 - else {
124 - $this->getOutput()->addElement( 'h2', array(), wfMsg( 'ep-mycourses-enrollment' ) );
125 - EPCourse::displayPager( $this->getContext(), array( 'id' => $courseIds ) );
126 - }
 119+ $this->showSuccess( wfMessage(
 120+ 'ep-mycourses-enrolled',
 121+ $course->getField( 'name' ),
 122+ $course->getOrg()->getField( 'name' )
 123+ ) );
127124 }
128 - }
129 -
130 - protected function displayOnlineMentorship() {
131125
 126+ if ( count( $courseIds ) === 1 ) {
 127+ $course = $courses[0];
 128+ $course->loadFields();
 129+ $this->displayCourse( $course );
 130+ }
 131+ elseif ( count( $courseIds ) > 1 ) {
 132+ $this->getOutput()->addElement( 'h2', array(), wfMsg( 'ep-mycourses-enrollment' ) );
 133+ EPCourse::displayPager( $this->getContext(), array( 'id' => $courseIds ), true );
 134+ }
132135 }
133136
134 - protected function displayCampusMentorship() {
 137+ protected function displayMentorship( $class ) {
 138+ $ambassador = $class::newFromUser( $this->getUser() );
135139
 140+ $courseIds = array_map(
 141+ function( EPCourse $course ) {
 142+ return $course->getId();
 143+ },
 144+ $ambassador->getCourses( 'id' )
 145+ );
 146+
 147+ if ( count( $courseIds ) > 0 ) {
 148+ $this->getOutput()->addElement( 'h2', array(), wfMsg( 'ep-mycourses-ambcourses-' . strtolower( $class ) ) );
 149+ EPCourse::displayPager( $this->getContext(), array( 'id' => $courseIds ), true );
 150+ }
 151+ else {
 152+ $this->getOutput()->addWikiMsg( 'ep-mycourses-noambcourses-' . strtolower( $class ) );
 153+ }
136154 }
137155
138156 protected function displayInstructorship() {
Index: trunk/extensions/EducationProgram/includes/EPIRole.php
@@ -19,10 +19,11 @@
2020 * @since 0.1
2121 *
2222 * @param integer $userId
 23+ * @param null|array|string $fields
2324 *
2425 * @return EPIRole
2526 */
26 - public static function newFromUserId( $userId );
 27+ public static function newFromUserId( $userId, $fields = null );
2728
2829 /**
2930 * Create a new role object from a user object.
@@ -30,10 +31,11 @@
3132 * @since 0.1
3233 *
3334 * @param User $user
 35+ * @param null|array|string $fields
3436 *
3537 * @return EPIRole
3638 */
37 - public static function newFromUser( User $user );
 39+ public static function newFromUser( User $user, $fields = null );
3840
3941
4042 /**
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 implements EPIRole {
 15+class EPInstructor extends EPRoleObject implements EPIRole {
1616
1717 /**
1818 * Field for caching the linked user.
@@ -35,10 +35,11 @@
3636 * @since 0.1
3737 *
3838 * @param integer $userId
 39+ * @param null|array|string $fields
3940 *
4041 * @return EPInstructor
4142 */
42 - public static function newFromUserId( $userId ) {
 43+ public static function newFromUserId( $userId, $fields = null ) {
4344 return new self( $userId );
4445 }
4546
@@ -48,10 +49,11 @@
4950 * @since 0.1
5051 *
5152 * @param User $user
 53+ * @param null|array|string $fields
5254 *
5355 * @return EPInstructor
5456 */
55 - public static function newFromUser( User $user ) {
 57+ public static function newFromUser( User $user, $fields = null ) {
5658 return new self( $user );
5759 }
5860
@@ -136,5 +138,21 @@
137139 public function getRoleName() {
138140 return 'instructor';
139141 }
 142+
 143+ /**
 144+ * Not implemented as we do not need this, so no need for having it in the
 145+ * db in a way we can efficiently query this. If needed at some point,
 146+ * most stuff is in place already since the ambassador stuff is similar.
 147+ *
 148+ * @since 0.1
 149+ *
 150+ * @param string|array|null $fields
 151+ * @param array $conditions
 152+ *
 153+ * @return array of EPCourse
 154+ */
 155+ protected function doGetCourses( $fields, array $conditions ) {
 156+ throw new MWException( 'doGetCourses is not implemented by EPInstructor' );
 157+ }
140158
141159 }
Index: trunk/extensions/EducationProgram/includes/EPCoursePager.php
@@ -14,12 +14,22 @@
1515 class EPCoursePager extends EPPager {
1616
1717 /**
 18+ * When in read only mode, the pager should not show any course editing controls.
 19+ *
 20+ * @since 0.1
 21+ * @var boolean
 22+ */
 23+ protected $readOnlyMode;
 24+
 25+ /**
1826 * Constructor.
1927 *
2028 * @param IContextSource $context
2129 * @param array $conds
 30+ * @param boolean $readOnlyMode
2231 */
23 - public function __construct( IContextSource $context, array $conds = array() ) {
 32+ public function __construct( IContextSource $context, array $conds = array(), $readOnlyMode = false ) {
 33+ $this->readOnlyMode = $readOnlyMode;
2434 parent::__construct( $context, $conds, 'EPCourse' );
2535 }
2636
@@ -177,7 +187,7 @@
178188
179189 $links[] = $item->getLink( 'view', wfMsgHtml( 'view' ) );
180190
181 - if ( $this->getUser()->isAllowed( 'ep-course' ) ) {
 191+ if ( !$this->readOnlyMode && $this->getUser()->isAllowed( 'ep-course' ) ) {
182192 $links[] = $item->getLink(
183193 'edit',
184194 wfMsgHtml( 'edit' ),
@@ -201,7 +211,7 @@
202212 protected function getMultipleItemActions() {
203213 $actions = parent::getMultipleItemActions();
204214
205 - if ( $this->getUser()->isAllowed( 'ep-course' ) ) {
 215+ if ( !$this->readOnlyMode && $this->getUser()->isAllowed( 'ep-course' ) ) {
206216 $actions[wfMsg( 'ep-pager-delete-selected' )] = array(
207217 'class' => 'ep-pager-delete-selected',
208218 'data-type' => ApiDeleteEducation::getTypeForClassName( $this->className )
@@ -239,5 +249,13 @@
240250
241251 return $conds;
242252 }
 253+
 254+ /**
 255+ * (non-PHPdoc)
 256+ * @see EPPager::hasActionsColumn()
 257+ */
 258+ protected function hasActionsColumn() {
 259+ return !$this->readOnlyMode;
 260+ }
243261
244262 }
Index: trunk/extensions/EducationProgram/includes/EPCA.php
@@ -11,45 +11,9 @@
1212 * @licence GNU GPL v3 or later
1313 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1414 */
15 -class EPCA extends EPDBObject implements EPIRole {
 15+class EPCA extends EPRoleObject 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 - /**
5418 * @see parent::getFieldTypes
5519 *
5620 * @since 0.1
@@ -76,32 +40,6 @@
7741 'photo' => '',
7842 );
7943 }
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 - }
10644
10745 /**
10846 * Display a pager with campus ambassadors.
@@ -130,21 +68,7 @@
13169 }
13270
13371 /**
134 - * Returns the tool links for this ambassador.
135 - *
13672 * @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
14973 * @see EPIRole::getRoleName
15074 */
15175 public function getRoleName() {
@@ -152,17 +76,25 @@
15377 }
15478
15579 /**
156 - * Retruns the user link for this ambassador, using their real name when available.
157 - *
 80+ * Returns the courses this campus ambassdor is associated with.
 81+ *
15882 * @since 0.1
159 - *
160 - * @return string
 83+ *
 84+ * @param string|array|null $fields
 85+ * @param array $conditions
 86+ *
 87+ * @return array of EPCourse
16188 */
162 - public function getUserLink() {
163 - return Linker::userLink(
164 - $this->getUser()->getId(),
165 - $this->getUser()->getName(),
166 - $this->getName()
 89+ protected function doGetCourses( $fields, array $conditions ) {
 90+ $conditions[] = array( array( 'ep_cas_per_course', 'user_id' ), $this->getField( 'user_id' ) );
 91+
 92+ return EPCourse::select(
 93+ $fields,
 94+ $conditions,
 95+ array(),
 96+ array(
 97+ 'ep_cas_per_course' => array( 'INNER JOIN', array( array( array( 'ep_cas_per_course', 'course_id' ), array( 'ep_courses', 'id' ) ) ) ),
 98+ )
16799 );
168100 }
169101
Index: trunk/extensions/EducationProgram/includes/EPStudent.php
@@ -11,25 +11,9 @@
1212 * @licence GNU GPL v3 or later
1313 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1414 */
15 -class EPStudent extends EPDBObject {
 15+class EPStudent extends EPRoleObject {
1616
1717 /**
18 - * Cached array of the linked EPCourse objects.
19 - *
20 - * @since 0.1
21 - * @var array|false
22 - */
23 - protected $courses = false;
24 -
25 - /**
26 - * Cached user object of the user that is this student.
27 - *
28 - * @since 0.1
29 - * @var User|false
30 - */
31 - protected $user = false;
32 -
33 - /**
3418 * @see parent::getFieldTypes
3519 *
3620 * @since 0.1
@@ -49,114 +33,37 @@
5034 }
5135
5236 /**
53 - * Get the student object of a user, or false if there is none.
 37+ * Display a pager with students.
5438 *
5539 * @since 0.1
5640 *
57 - * @param User $user
58 - * @param string|array|null $fields
59 - *
60 - * @return EPStudent|false
61 - */
62 - public static function newFromUser( User $user, $fields = null ) {
63 - return self::selectRow( $fields, array( 'user_id' => $user->getId() ) );
64 - }
65 -
66 - /**
67 - * Associate the student with the provided courses.
68 - *
69 - * @since 0.1
70 - *
71 - * @param array $courses
72 - *
73 - * @return bool
74 - */
75 - public function associateWithCourses( array /* of EPCourse */ $courses ) {
76 - $dbw = wfGetDB( DB_MASTER );
77 -
78 - $success = true;
79 -
80 - $dbw->begin();
81 -
82 - foreach ( $courses as /* EPCourse */ $course ) {
83 - $success = $dbw->insert(
84 - 'ep_students_per_course',
85 - array(
86 - 'spc_student_id' => $this->getId(),
87 - 'spc_course_id' => $course->getId(),
88 - )
89 - ) && $success;
90 - }
91 -
92 - $dbw->commit();
93 -
94 - foreach ( $courses as /* EPCourse */ $course ) {
95 - EPOrg::updateSummaryFields( 'students', array( 'id' => $course->getField( 'org_id' ) ) );
96 - EPCourse::updateSummaryFields( 'students', array( 'id' => $course->getId() ) );
97 - }
98 -
99 - return $success;
100 - }
101 -
102 - /**
103 - * Returns the courses this student is enrolled in.
104 - * Caches the result when no conditions are provided and all fields are selected.
105 - *
106 - * @since 0.1
107 - *
108 - * @param string|array|null $fields
 41+ * @param IContextSource $context
10942 * @param array $conditions
110 - *
111 - * @return array of EPCourse
11243 */
113 - public function getCourses( $fields = null, array $conditions = array() ) {
114 - if ( count( $conditions ) !== 0 ) {
115 - return $this->doGetCourses( $fields, $conditions );
116 - }
 44+ public static function displayPager( IContextSource $context, array $conditions = array() ) {
 45+ $pager = new EPStudentPager( $context, $conditions );
11746
118 - if ( $this->courses === false ) {
119 - $courses = $this->doGetCourses( $fields, $conditions );
120 -
121 - if ( is_null( $fields ) ) {
122 - $this->courses = $courses;
123 - }
124 -
125 - return $courses;
 47+ if ( $pager->getNumRows() ) {
 48+ $context->getOutput()->addHTML(
 49+ $pager->getFilterControl() .
 50+ $pager->getNavigationBar() .
 51+ $pager->getBody() .
 52+ $pager->getNavigationBar() .
 53+ $pager->getMultipleItemControl()
 54+ );
12655 }
12756 else {
128 - return $this->courses;
 57+ $context->getOutput()->addHTML( $pager->getFilterControl( true ) );
 58+ $context->getOutput()->addWikiMsg( 'ep-students-noresults' );
12959 }
13060 }
13161
13262 /**
133 - * Get the courses with a certain state.
134 - * States can be 'current', 'passed' and 'planned'
135 - *
13663 * @since 0.1
137 - *
138 - * @param string $state
139 - * @param array|null $fields
140 - * @param array $conditions
141 - *
142 - * @return array of EPCourse
 64+ * @see EPIRole::getRoleName
14365 */
144 - public function getCoursesWithState( $state, $fields = null, array $conditions = array() ) {
145 - $now = wfGetDB( DB_SLAVE )->addQuotes( wfTimestampNow() );
146 -
147 - switch ( $state ) {
148 - case 'passed':
149 - $conditions[] = 'end < ' . $now;
150 - break;
151 - case 'planned':
152 - $conditions[] = 'start > ' . $now;
153 - break;
154 - case 'current':
155 - $conditions[] = 'end >= ' . $now;
156 - $conditions[] = 'start <= ' . $now;
157 - break;
158 - }
159 -
160 - return $this->getCourses( $fields, $conditions );
 66+ public function getRoleName() {
 67+ return 'student';
16168 }
16269
16370 /**
@@ -182,70 +89,5 @@
18390 )
18491 );
18592 }
186 -
187 - /**
188 - * Returns if the student has any course matching the provided conditions.
189 - *
190 - * @since 0.1
191 - *
192 - * @param array $conditions
193 - *
194 - * @return boolean
195 - */
196 - public function hasCourse( array $conditions = array() ) {
197 - return count( $this->getCourses( 'id', $conditions ) ) > 0;
198 - }
199 -
200 - /**
201 - * Display a pager with students.
202 - *
203 - * @since 0.1
204 - *
205 - * @param IContextSource $context
206 - * @param array $conditions
207 - */
208 - public static function displayPager( IContextSource $context, array $conditions = array() ) {
209 - $pager = new EPStudentPager( $context, $conditions );
210 -
211 - if ( $pager->getNumRows() ) {
212 - $context->getOutput()->addHTML(
213 - $pager->getFilterControl() .
214 - $pager->getNavigationBar() .
215 - $pager->getBody() .
216 - $pager->getNavigationBar() .
217 - $pager->getMultipleItemControl()
218 - );
219 - }
220 - else {
221 - $context->getOutput()->addHTML( $pager->getFilterControl( true ) );
222 - $context->getOutput()->addWikiMsg( 'ep-students-noresults' );
223 - }
224 - }
225 -
226 - /**
227 - * Returns the user that is this student.
228 - *
229 - * @since 0.1
230 - *
231 - * @return User
232 - */
233 - public function getUser() {
234 - if ( $this->user === false ) {
235 - $this->user = User::newFromId( $this->loadAndGetField( 'user_id' ) );
236 - }
237 -
238 - return $this->user;
239 - }
240 -
241 - /**
242 - * Returns the display name for the student.
243 - *
244 - * @since 0.1
245 - *
246 - * @return String
247 - */
248 - public function getName() {
249 - return $this->getUser()->getRealName() === '' ? $this->user->getName() : $this->user->getRealName();
250 - }
251 -
 93+
25294 }
Index: trunk/extensions/EducationProgram/includes/EPRoleObject.php
@@ -0,0 +1,239 @@
 2+<?php
 3+
 4+/**
 5+ * Object representing a user in a certain role linked to courses.
 6+ *
 7+ * @since 0.1
 8+ *
 9+ * @file EPRoleObject.php
 10+ * @ingroup EducationProgram
 11+ *
 12+ * @licence GNU GPL v3 or later
 13+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
 14+ */
 15+abstract class EPRoleObject extends EPDBObject implements EPIRole {
 16+
 17+ /**
 18+ * Field for caching the linked user.
 19+ *
 20+ * @since 0.1
 21+ * @var User|false
 22+ */
 23+ protected $user = false;
 24+
 25+ /**
 26+ * Cached array of the linked EPCourse objects.
 27+ *
 28+ * @since 0.1
 29+ * @var array|false
 30+ */
 31+ protected $courses = false;
 32+
 33+ /**
 34+ * Create a new instructor object from a user id.
 35+ *
 36+ * @since 0.1
 37+ *
 38+ * @param integer $userId
 39+ * @param null|array|string $fields
 40+ *
 41+ * @return EPRoleObject
 42+ */
 43+ public static function newFromUserId( $userId, $fields = null ) {
 44+ $data = array( 'user_id' => $userId );
 45+ $userRole = static::selectRow( null, $data );
 46+ return $userRole === false ? new static( $data, true ) : $userRole;
 47+ }
 48+
 49+ /**
 50+ * Create a new instructor object from a User object.
 51+ *
 52+ * @since 0.1
 53+ *
 54+ * @param User $user
 55+ * @param null|array|string $fields
 56+ *
 57+ * @return EPRoleObject
 58+ */
 59+ public static function newFromUser( User $user, $fields = null ) {
 60+ return static::newFromUserId( $user->getId(), $fields );
 61+ }
 62+
 63+ /**
 64+ * Returns the user that this instructor is.
 65+ *
 66+ * @since 0.1
 67+ *
 68+ * @return User
 69+ */
 70+ public function getUser() {
 71+ if ( $this->user === false ) {
 72+ $this->user = User::newFromId( $this->getField( 'user_id' ) );
 73+ }
 74+
 75+ return $this->user;
 76+ }
 77+
 78+ /**
 79+ * Returns the name of the instroctor, using their real name when available.
 80+ *
 81+ * @since 0.1
 82+ *
 83+ * @return string
 84+ */
 85+ public function getName() {
 86+ return $this->getUser()->getRealName() === '' ? $this->getUser()->getName() : $this->getUser()->getRealName();
 87+ }
 88+
 89+ /**
 90+ * Returns the tool links for this ambassador.
 91+ *
 92+ * @since 0.1
 93+ *
 94+ * @param IContextSource $context
 95+ * @param EPCourse|null $course
 96+ *
 97+ * @return string
 98+ */
 99+ public function getToolLinks( IContextSource $context, EPCourse $course = null ) {
 100+ return EPUtils::getRoleToolLinks( $this, $context, $course );
 101+ }
 102+
 103+ /**
 104+ * Retruns the user link for this ambassador, using their real name when available.
 105+ *
 106+ * @since 0.1
 107+ *
 108+ * @return string
 109+ */
 110+ public function getUserLink() {
 111+ return Linker::userLink(
 112+ $this->getUser()->getId(),
 113+ $this->getUser()->getName(),
 114+ $this->getName()
 115+ );
 116+ }
 117+
 118+ /**
 119+ * Associate the student with the provided courses.
 120+ *
 121+ * @since 0.1
 122+ *
 123+ * @param array $courses
 124+ *
 125+ * @return bool
 126+ */
 127+ public function associateWithCourses( array /* of EPCourse */ $courses ) {
 128+ $dbw = wfGetDB( DB_MASTER );
 129+
 130+ $success = true;
 131+
 132+ $dbw->begin();
 133+
 134+ foreach ( $courses as /* EPCourse */ $course ) {
 135+ $success = $dbw->insert(
 136+ 'ep_students_per_course',
 137+ array(
 138+ 'spc_student_id' => $this->getId(),
 139+ 'spc_course_id' => $course->getId(),
 140+ )
 141+ ) && $success;
 142+ }
 143+
 144+ $dbw->commit();
 145+
 146+ foreach ( $courses as /* EPCourse */ $course ) {
 147+ EPOrg::updateSummaryFields( 'students', array( 'id' => $course->getField( 'org_id' ) ) );
 148+ EPCourse::updateSummaryFields( 'students', array( 'id' => $course->getId() ) );
 149+ }
 150+
 151+ return $success;
 152+ }
 153+
 154+ /**
 155+ * Returns the courses this student is enrolled in.
 156+ * Caches the result when no conditions are provided and all fields are selected.
 157+ *
 158+ * @since 0.1
 159+ *
 160+ * @param string|array|null $fields
 161+ * @param array $conditions
 162+ *
 163+ * @return array of EPCourse
 164+ */
 165+ public function getCourses( $fields = null, array $conditions = array() ) {
 166+ if ( count( $conditions ) !== 0 ) {
 167+ return $this->doGetCourses( $fields, $conditions );
 168+ }
 169+
 170+ if ( $this->courses === false ) {
 171+ $courses = $this->doGetCourses( $fields, $conditions );
 172+
 173+ if ( is_null( $fields ) ) {
 174+ $this->courses = $courses;
 175+ }
 176+
 177+ return $courses;
 178+ }
 179+ else {
 180+ return $this->courses;
 181+ }
 182+ }
 183+
 184+ /**
 185+ * Get the courses with a certain state.
 186+ * States can be 'current', 'passed' and 'planned'
 187+ *
 188+ * @since 0.1
 189+ *
 190+ * @param string $state
 191+ * @param array|null $fields
 192+ * @param array $conditions
 193+ *
 194+ * @return array of EPCourse
 195+ */
 196+ public function getCoursesWithState( $state, $fields = null, array $conditions = array() ) {
 197+ $now = wfGetDB( DB_SLAVE )->addQuotes( wfTimestampNow() );
 198+
 199+ switch ( $state ) {
 200+ case 'passed':
 201+ $conditions[] = 'end < ' . $now;
 202+ break;
 203+ case 'planned':
 204+ $conditions[] = 'start > ' . $now;
 205+ break;
 206+ case 'current':
 207+ $conditions[] = 'end >= ' . $now;
 208+ $conditions[] = 'start <= ' . $now;
 209+ break;
 210+ }
 211+
 212+ return $this->getCourses( $fields, $conditions );
 213+ }
 214+
 215+ /**
 216+ * Returns if the student has any course matching the provided conditions.
 217+ *
 218+ * @since 0.1
 219+ *
 220+ * @param array $conditions
 221+ *
 222+ * @return boolean
 223+ */
 224+ public function hasCourse( array $conditions = array() ) {
 225+ return count( $this->getCourses( 'id', $conditions ) ) > 0;
 226+ }
 227+
 228+ /**
 229+ * Returns the courses this user is associated with.
 230+ *
 231+ * @since 0.1
 232+ *
 233+ * @param string|array|null $fields
 234+ * @param array $conditions
 235+ *
 236+ * @return array of EPCourse
 237+ */
 238+ protected abstract function doGetCourses( $fields, array $conditions );
 239+
 240+}
\ No newline at end of file
Property changes on: trunk/extensions/EducationProgram/includes/EPRoleObject.php
___________________________________________________________________
Added: svn:eol-style
1241 + native
Index: trunk/extensions/EducationProgram/includes/EPOA.php
@@ -11,45 +11,9 @@
1212 * @licence GNU GPL v3 or later
1313 * @author Jeroen De Dauw < jeroendedauw@gmail.com >
1414 */
15 -class EPOA extends EPDBObject implements EPIRole {
16 -
17 - /**
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 - }
 15+class EPOA extends EPRoleObject implements EPIRole {
3916
4017 /**
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 - /**
5418 * @see parent::getFieldTypes
5519 *
5620 * @since 0.1
@@ -78,32 +42,6 @@
7943 }
8044
8145 /**
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 - }
106 -
107 - /**
10846 * Display a pager with online ambassadors.
10947 *
11048 * @since 0.1
@@ -130,21 +68,7 @@
13169 }
13270
13371 /**
134 - * Returns the tool links for this ambassador.
135 - *
13672 * @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
14973 * @see EPIRole::getRoleName
15074 */
15175 public function getRoleName() {
@@ -152,18 +76,26 @@
15377 }
15478
15579 /**
156 - * Retruns the user link for this ambassador, using their real name when available.
157 - *
 80+ * Returns the courses this online ambassdor is associated with.
 81+ *
15882 * @since 0.1
159 - *
160 - * @return string
 83+ *
 84+ * @param string|array|null $fields
 85+ * @param array $conditions
 86+ *
 87+ * @return array of EPCourse
16188 */
162 - public function getUserLink() {
163 - return Linker::userLink(
164 - $this->getUser()->getId(),
165 - $this->getUser()->getName(),
166 - $this->getName()
 89+ protected function doGetCourses( $fields, array $conditions ) {
 90+ $conditions[] = array( array( 'ep_oas_per_course', 'user_id' ), $this->getField( 'user_id' ) );
 91+
 92+ return EPCourse::select(
 93+ $fields,
 94+ $conditions,
 95+ array(),
 96+ array(
 97+ 'ep_oas_per_course' => array( 'INNER JOIN', array( array( array( 'ep_oas_per_course', 'course_id' ), array( 'ep_courses', 'id' ) ) ) ),
 98+ )
16799 );
168100 }
169 -
 101+
170102 }
Index: trunk/extensions/EducationProgram/includes/EPCourse.php
@@ -301,7 +301,7 @@
302302
303303 if ( $this->updateSummaries && $success ) {
304304 if ( array_key_exists( 'org_id', $currentFields ) && $currentFields['org_id'] !== $this->getField( 'org_id' ) ) {
305 - $conds = array( 'id' => array( $oldOrgId, $this->getField( 'org_id' ) ) );
 305+ $conds = array( 'id' => array( $currentFields['org_id'], $this->getField( 'org_id' ) ) );
306306 EPOrg::updateSummaryFields( array( 'courses', 'students', 'active', 'instructors', 'oas', 'cas' ), $conds );
307307 }
308308
@@ -310,19 +310,27 @@
311311
312312 if ( array_key_exists( $field, $currentFields ) && $currentFields[$field] !== $this->getField( $field ) ) {
313313 $courseField = $ambs === 'oas' ? 'opc_course_id' : 'cpc_course_id';
314 - $userField = $ambs === 'oas' ? 'opc_oa_id' : 'cpc_ca_id';
 314+ $userField = $ambs === 'oas' ? 'opc_user_id' : 'cpc_user_id';
315315 $table = 'ep_' . $ambs . '_per_course';
316316
 317+ $addedIds = array_diff( $this->getField( $field ), $currentFields[$field] );
 318+ $removedIds = array_diff( $currentFields[$field], $this->getField( $field ) );
 319+
317320 $dbw = wfGetDB( DB_MASTER );
318321
319 - $dbw->delete( $table, array( $courseField => $id ) );
 322+ if ( count( $removedIds ) > 0 ) {
 323+ $dbw->delete( $table, array(
 324+ $courseField => $this->getId(),
 325+ $userField => $removedIds
 326+ ) );
 327+ }
320328
321329 $dbw->begin();
322330
323 - foreach ( $this->getField( $field ) as $userId ) {
 331+ foreach ( $addedIds as $ambassadorId ) {
324332 $dbw->insert( $table, array(
325333 $courseField => $this->getId(),
326 - $userField => $userId
 334+ $userField => $ambassadorId
327335 ) );
328336 }
329337
@@ -370,9 +378,10 @@
371379 *
372380 * @param IContextSource $context
373381 * @param array $conditions
 382+ * @param boolean $readOnlyMode
374383 */
375 - public static function displayPager( IContextSource $context, array $conditions = array() ) {
376 - $pager = new EPCoursePager( $context, $conditions );
 384+ public static function displayPager( IContextSource $context, array $conditions = array(), $readOnlyMode = false ) {
 385+ $pager = new EPCoursePager( $context, $conditions, $readOnlyMode );
377386
378387 if ( $pager->getNumRows() ) {
379388 $context->getOutput()->addHTML(
Index: trunk/extensions/EducationProgram/EducationProgram.i18n.php
@@ -388,6 +388,11 @@
389389 'ep-mycourses-not-a-student' => 'You are not enrolled in any [[Special:Courses|courses]].',
390390 'ep-mycourses-enrollment' => 'Courses I am enrolled in',
391391 'ep-mycourses-course-enrollment' => 'Course I am enrolled in',
 392+ 'ep-mycourses-login-first' => 'You need to login before you can view your courses.',
 393+ 'ep-mycourses-ambcourses-epoa' => 'Courses I am Online Ambassador for',
 394+ 'ep-mycourses-ambcourses-epca' => 'Courses I am Campus Ambassador for',
 395+ 'ep-mycourses-noambcourses-epca' => 'There are no courses you are Campus Ambassador for yet.',
 396+ 'ep-mycourses-noambcourses-epoa' => 'There are no courses you are Online Ambassador for yet.',
392397
393398 // ep.enlist instructor
394399 'ep-instructor-remove-title' => 'Remove instructor from course',
Index: trunk/extensions/EducationProgram/EducationProgram.hooks.php
@@ -35,6 +35,14 @@
3636 dirname( __FILE__ ) . '/sql/AddAmbassadorLinks.sql',
3737 true
3838 ) );
 39+
 40+ $updater->addExtensionUpdate( array(
 41+ 'addField',
 42+ 'ep_oas_per_course',
 43+ 'user_id',
 44+ dirname( __FILE__ ) . '/sql/RenameAmbUserField.sql',
 45+ true
 46+ ) );
3947
4048 return true;
4149 }

Status & tagging log