Index: trunk/extensions/EducationProgram/sql/EducationProgram.sql |
— | — | @@ -22,48 +22,48 @@ |
23 | 23 | CREATE INDEX /*i*/ep_org_students ON /*_*/ep_orgs (org_students); |
24 | 24 | CREATE INDEX /*i*/ep_org_active ON /*_*/ep_orgs (org_active); |
25 | 25 | |
26 | | -CREATE TABLE IF NOT EXISTS /*_*/ep_courses ( |
27 | | - course_id INT unsigned NOT NULL auto_increment PRIMARY KEY, |
| 26 | +-- Master courses. These describe a specific course, time-independent. |
| 27 | +CREATE TABLE IF NOT EXISTS /*_*/ep_mcs ( |
| 28 | + mc_id INT unsigned NOT NULL auto_increment PRIMARY KEY, |
28 | 29 | |
29 | | - course_org_id INT unsigned NOT NULL, -- Foreign key on ep_orgs.org_id |
30 | | - course_name VARCHAR(255) NOT NULL, -- Name of the course |
31 | | - course_description TEXT NOT NULL, -- Description of the course |
32 | | - course_lang VARCHAR(10) NOT NULL, -- Language (code) |
33 | | - course_instructors BLOB NOT NULL, -- List of associated instructors |
| 30 | + mc_org_id INT unsigned NOT NULL, -- Foreign key on ep_orgs.org_id |
| 31 | + mc_name VARCHAR(255) NOT NULL, -- Name of the course |
| 32 | + mc_description TEXT NOT NULL, -- Description of the course |
| 33 | + mc_lang VARCHAR(10) NOT NULL, -- Language (code) |
| 34 | + mc_instructors BLOB NOT NULL, -- List of associated instructors |
34 | 35 | |
35 | | - course_active TINYINT unsigned NOT NULL, -- If the course has any active terms |
36 | | - course_students SMALLINT unsigned NOT NULL -- Amount of students |
| 36 | + mc_active TINYINT unsigned NOT NULL, -- If the course has any active terms |
| 37 | + mc_students SMALLINT unsigned NOT NULL -- Amount of students |
37 | 38 | ) /*$wgDBTableOptions*/; |
38 | 39 | |
39 | | -CREATE INDEX /*i*/ep_course_org_id ON /*_*/ep_courses (course_org_id); |
40 | | -CREATE UNIQUE INDEX /*i*/ep_course_name ON /*_*/ep_courses (course_name); |
41 | | -CREATE INDEX /*i*/ep_course_lang ON /*_*/ep_courses (course_lang); |
42 | | -CREATE INDEX /*i*/ep_course_students ON /*_*/ep_courses (course_students); |
43 | | -CREATE INDEX /*i*/ep_course_active ON /*_*/ep_courses (course_active); |
| 40 | +CREATE INDEX /*i*/ep_mc_org_id ON /*_*/ep_mcs (mc_org_id); |
| 41 | +CREATE UNIQUE INDEX /*i*/ep_mc_name ON /*_*/ep_mcs (mc_name); |
| 42 | +CREATE INDEX /*i*/ep_mc_lang ON /*_*/ep_mcs (mc_lang); |
| 43 | +CREATE INDEX /*i*/ep_mc_students ON /*_*/ep_mcs (mc_students); |
| 44 | +CREATE INDEX /*i*/ep_mc_active ON /*_*/ep_mcs (mc_active); |
44 | 45 | |
45 | | -CREATE TABLE IF NOT EXISTS /*_*/ep_terms ( |
46 | | - term_id INT unsigned NOT NULL auto_increment PRIMARY KEY, |
| 46 | +-- Courses. These are "instances" of a master course in a certain period. |
| 47 | +CREATE TABLE IF NOT EXISTS /*_*/ep_courses ( |
| 48 | + course_id INT unsigned NOT NULL auto_increment PRIMARY KEY, |
47 | 49 | |
48 | | - term_course_id INT unsigned NOT NULL, -- Foreign key on ep_courses.course_id |
49 | | - term_org_id INT unsigned NOT NULL, -- Foreign key on ep_orgs.org_id. Helper field, not strictly needed. |
50 | | - term_year SMALLINT unsigned NOT NULL, -- Yeah in which the term takes place |
51 | | - term_start varbinary(14) NOT NULL, -- Start time of the term |
52 | | - term_end varbinary(14) NOT NULL, -- End time of the term |
53 | | - term_description TEXT NOT NULL, -- Description of the term |
54 | | - term_online_ambs BLOB NOT NULL, -- List of associated online abmassadors |
55 | | - term_campus_ambs BLOB NOT NULL, -- List of associated campus abmassadors |
56 | | - term_token VARCHAR(255) NOT NULL, -- Token needed to enroll |
| 50 | + course_mc_id INT unsigned NOT NULL, -- Foreign key on ep_mcs.mc_id |
| 51 | + course_org_id INT unsigned NOT NULL, -- Foreign key on ep_orgs.org_id. Helper field, not strictly needed. |
| 52 | + course_year SMALLINT unsigned NOT NULL, -- Year in which the course takes place |
| 53 | + course_start varbinary(14) NOT NULL, -- Start time of the course |
| 54 | + course_end varbinary(14) NOT NULL, -- End time of the course |
| 55 | + course_description TEXT NOT NULL, -- Description of the course |
| 56 | + course_online_ambs BLOB NOT NULL, -- List of associated online ambassadors |
| 57 | + course_campus_ambs BLOB NOT NULL, -- List of associated campus ambassadors |
| 58 | + course_token VARCHAR(255) NOT NULL, -- Token needed to enroll |
57 | 59 | |
58 | | - term_students SMALLINT unsigned NOT NULL -- Amount of students |
| 60 | + course_students SMALLINT unsigned NOT NULL -- Amount of students |
59 | 61 | ) /*$wgDBTableOptions*/; |
60 | 62 | |
61 | | -CREATE INDEX /*i*/ep_term_year ON /*_*/ep_terms (term_year); |
62 | | -CREATE INDEX /*i*/ep_term_start ON /*_*/ep_terms (term_start); |
63 | | -CREATE INDEX /*i*/ep_term_end ON /*_*/ep_terms (term_end); |
64 | | -CREATE UNIQUE INDEX /*i*/ep_trem_period ON /*_*/ep_terms (term_org_id, term_start, term_end); |
65 | | -CREATE INDEX /*i*/ep_term_students ON /*_*/ep_terms (term_students); |
| 63 | +CREATE INDEX /*i*/ep_course_year ON /*_*/ep_courses (course_year); |
| 64 | +CREATE INDEX /*i*/ep_course_start ON /*_*/ep_courses (course_start); |
| 65 | +CREATE INDEX /*i*/ep_course_end ON /*_*/ep_courses (course_end); |
| 66 | +CREATE UNIQUE INDEX /*i*/ep_trem_period ON /*_*/ep_courses (course_org_id, course_start, course_end); |
| 67 | +CREATE INDEX /*i*/ep_course_students ON /*_*/ep_courses (course_students); |
66 | 68 | |
67 | 69 | -- Students. In essence this is an extension to the user table. |
68 | 70 | CREATE TABLE IF NOT EXISTS /*_*/ep_students ( |
— | — | @@ -89,14 +89,22 @@ |
90 | 90 | |
91 | 91 | CREATE UNIQUE INDEX /*i*/ep_mentors_user_id ON /*_*/ep_mentors (mentor_user_id); |
92 | 92 | |
93 | | -CREATE TABLE IF NOT EXISTS /*_*/ep_students_per_term ( |
94 | | - spt_student_id INT unsigned NOT NULL, -- Foreign key on ep_students.student_id |
95 | | - spt_term_id INT unsigned NOT NULL -- Foreign key on ep_terms.term_id |
| 93 | +-- Links the courses with all their students. |
| 94 | +CREATE TABLE IF NOT EXISTS /*_*/ep_students_per_course ( |
| 95 | + spc_student_id INT unsigned NOT NULL, -- Foreign key on ep_students.student_id |
| 96 | + spc_course_id INT unsigned NOT NULL -- Foreign key on ep_courses.course_id |
96 | 97 | ) /*$wgDBTableOptions*/; |
97 | 98 | |
98 | | -CREATE UNIQUE INDEX /*i*/ep_students_per_term ON /*_*/ep_students_per_term (spt_student_id, spt_term_id); |
| 99 | +CREATE UNIQUE INDEX /*i*/ep_students_per_course ON /*_*/ep_students_per_course (spc_student_id, spc_course_id); |
99 | 100 | |
| 101 | +-- Links the campus ambassadors with all their orgs. |
| 102 | +CREATE TABLE IF NOT EXISTS /*_*/ep_cas_per_org ( |
| 103 | + cpo_ca_id INT unsigned NOT NULL, -- Foreign key on ep_cas.ca_id |
| 104 | + cpo_org_id INT unsigned NOT NULL -- Foreign key on ep_orgs.org_id |
| 105 | +) /*$wgDBTableOptions*/; |
| 106 | + |
| 107 | +CREATE UNIQUE INDEX /*i*/ep_cas_per_org ON /*_*/ep_cas_per_org (cpo_ca_id, cpo_org_id); |
| 108 | + |
100 | 109 | -- Revision table, holding blobs of various types of objects, such as orgs or students. |
101 | 110 | -- This is somewhat based on the (core) revision table and is meant to serve |
102 | 111 | -- as a prototype for a more general system to store this kind of data in a versioned fashion. |
Index: trunk/extensions/EducationProgram/EducationProgram.php |
— | — | @@ -140,15 +140,16 @@ |
141 | 141 | $egEPDBObjects[] = array( 'table' => 'ep_students_per_term', 'prefix' => 'spt_' ); |
142 | 142 | |
143 | 143 | // API |
144 | | -$wgAPIModules['deleteeducation'] = 'ApiDeleteEducation'; |
145 | | -$wgAPIModules['instructor'] = 'ApiInstructor'; |
146 | | -$wgAPIModules['refresheducation'] = 'ApiRefreshEducation'; |
| 144 | +$wgAPIModules['deleteeducation'] = 'ApiDeleteEducation'; |
| 145 | +$wgAPIModules['instructor'] = 'ApiInstructor'; |
| 146 | +$wgAPIModules['refresheducation'] = 'ApiRefreshEducation'; |
147 | 147 | |
148 | 148 | // Hooks |
149 | | -$wgHooks['LoadExtensionSchemaUpdates'][] = 'EPHooks::onSchemaUpdate'; |
150 | | -$wgHooks['UnitTestsList'][] = 'EPHooks::registerUnitTests'; |
151 | | -$wgHooks['PersonalUrls'][] = 'EPHooks::onPersonalUrls'; |
152 | | -$wgHooks['GetPreferences'][] = 'EPHooks::onGetPreferences'; |
| 149 | +$wgHooks['LoadExtensionSchemaUpdates'][] = 'EPHooks::onSchemaUpdate'; |
| 150 | +$wgHooks['UnitTestsList'][] = 'EPHooks::registerUnitTests'; |
| 151 | +$wgHooks['PersonalUrls'][] = 'EPHooks::onPersonalUrls'; |
| 152 | +$wgHooks['GetPreferences'][] = 'EPHooks::onGetPreferences'; |
| 153 | +$wgHooks['SkinTemplateNavigation::SpecialPage'][] = 'EPHooks::onSpecialPageTabs'; |
153 | 154 | |
154 | 155 | // Logging |
155 | 156 | $wgLogTypes[] = 'institution'; |
Index: trunk/extensions/EducationProgram/EducationProgram.hooks.php |
— | — | @@ -170,4 +170,35 @@ |
171 | 171 | return $message->inLanguage( $forUI === null ? $wgContLang : $wgLang )->text(); |
172 | 172 | } |
173 | 173 | |
| 174 | + /** |
| 175 | + * Called on special pages after the special tab is added but before variants have been added. |
| 176 | + * @see https://www.mediawiki.org/wiki/Manual:Hooks/SkinTemplateNavigation::SpecialPage |
| 177 | + * |
| 178 | + * @since 0.1 |
| 179 | + * |
| 180 | + * @param SkinTemplate $sktemplate |
| 181 | + * @param array $links |
| 182 | + * |
| 183 | + * @return true |
| 184 | + */ |
| 185 | + public static function onSpecialPageTabs( SkinTemplate &$sktemplate, array &$links ) { |
| 186 | + $viewLinks = $links['views']; |
| 187 | + |
| 188 | + $title = $sktemplate->getTitle(); |
| 189 | + |
| 190 | + switch ( $title->getBaseText() ) { |
| 191 | + case 'Institution': case 'EditInstitution': |
| 192 | + $editTitle = SpecialPage::getTitleFor( 'EditInstitution', $title->getSubpageText() ); |
| 193 | + $viewLinks['edit'] = array( |
| 194 | + 'class' => $title->getBaseText() == 'EditInstitution' ? 'selected' : false, |
| 195 | + 'text' => wfMsg( 'edit' ), |
| 196 | + 'href' => $editTitle->getLocalUrl() |
| 197 | + ); |
| 198 | + break; |
| 199 | + // TODO: test & add other links |
| 200 | + } |
| 201 | + |
| 202 | + $links['views'] = $viewLinks; |
| 203 | + } |
| 204 | + |
174 | 205 | } |