';
166 | } else {
167 | $properties .= ' (';
168 | }
169 |
170 | $url = new moodle_url('/sites/showvotes.php', array('id'=>$site->id));
171 |
172 | $properties .= $OUTPUT->action_link($url, 'votes', new popup_action('click', $url, 'votes'));
173 |
174 | //$properties .= link_to_popup_window('/sites/showvotes.php?id='.$site->id, 'votes', $countvotes[$site->id].'»'.$site->cool,400,500,'votes','',true);
175 | $properties .= ')';
176 | }
177 | }
178 | }
179 |
180 | if ($isadmin && $USER->siteediting) {
181 | $properties .= ' ';
182 | $properties .= $OUTPUT->action_icon(new moodle_url('/sites/edit.php', array('edit'=>$site->id, 'sesskey'=>sesskey())), new pix_icon('t/edit', 'edit', null, array('style'=>'height:11px;width:11px;border:0;')));
183 | $properties .= ' ';
184 | $properties .= $OUTPUT->action_icon(new moodle_url('/sites/edit.php', array('delete'=>$site->id, 'sesskey'=>sesskey())), new pix_icon('t/delete', 'delete', 'moodle', array('style'=>'height:11px;width:11px;border:0;')));
185 |
186 | //$properties .= '
';
187 | //$properties .= '
';
188 | }
189 |
190 | if ($site->privacy=='linked') {
191 | $list->data[] = "$name$properties";
192 | } else if ($USER->siteediting===true) {
193 | $list->data[] = "$name$properties";
194 | } else {
195 | $list->data[] = $name.$properties;
196 | }
197 | }
198 | }
199 |
200 |
201 | $PAGE->navbar->add('Registered sites', new moodle_url('/sites/'));
202 | $PAGE->set_title(get_string('registeredmoodlesites_moodlenet', 'local_hub'));
203 | $PAGE->set_heading(get_string('registeredmoodlesites', 'local_hub'));
204 | $PAGE->set_button(edit_button($isadmin, $country));
205 |
206 | echo $OUTPUT->header();
207 | if (isset($message) && $message!==false) {
208 | echo $message;
209 | }
210 | echo html_writer::start_tag('div', array('class'=>'boxwidthwide boxaligncenter', 'style'=>'padding:20px;'));
211 | echo $OUTPUT->heading($PAGE->heading);
212 |
213 | echo html_writer::start_tag('p', array('class'=>'mdl-align'));
214 | echo get_string('moodlesiteslistintro', 'local_hub');
215 | echo html_writer::end_tag('p');
216 |
217 | echo html_writer::start_tag('p', array('class'=>'mdl-align'));
218 | echo html_writer::empty_tag('img', array('src'=>$CFG->wwwroot.'/sites/moodle-registered-sites-20091103-small.jpg', 'class'=>'activesitesimg'));
219 | echo html_writer::end_tag('p');
220 |
221 | echo html_writer::start_tag('p', array('class'=>'mdl-align'));
222 | echo get_string('moodlesiteslistnumbers', 'local_hub', $totalcountryinfo);
223 | echo html_writer::end_tag('p');
224 |
225 | echo prepare_country_tag_cloud($countryarray, ($isadmin && $USER->siteediting), 500);
226 | echo html_writer::end_tag('div');
227 |
228 | if (isset($list)) {
229 | echo html_writer::start_tag('div', array('class'=>'boxwidthwide boxaligncenter', 'style'=>'padding:20px;'));
230 | if ($sitevoting) {
231 | echo '';
232 | if (!isloggedin() || isguestuser()) {
233 | echo 'Sites can be marked "Cool" if three or more people vote for them. Cool sites are promoted around moodle.org and other places. To vote on sites you need to be
logged in.';
234 | echo "
";
235 | } else {
236 | $options = array();
237 | $options['country'] = $country;
238 | if ($isadmin && $USER->siteediting) {
239 | $options['edit']='on';
240 | }
241 | if (empty($USER->sitevoting)) {
242 | echo 'Sites can be marked "Cool" if three or more people vote for them. Cool sites are promoted around moodle.org and other places. To see the voting controls, use this button:';
243 | $options['voting'] = 1;
244 | $button = new single_button(new moodle_url('/sites/index.php', $options), 'Show voting buttons for these sites');
245 | } else {
246 | $options['voting'] = -1;
247 | $button = new single_button(new moodle_url('/sites/index.php', $options), 'Hide voting buttons for these sites');
248 | }
249 | $OUTPUT->render($button);
250 | }
251 | echo "
";
252 | }
253 |
254 | print_list($list);
255 | echo "
";
256 | echo html_writer::end_tag('div');
257 | }
258 |
259 | echo $OUTPUT->footer();
260 |
--------------------------------------------------------------------------------
/admin/managecourses.php:
--------------------------------------------------------------------------------
1 | .
17 |
18 | /**
19 | * Administrator can manage registered course on this page
20 | * Delete, Hide,...
21 | * @package localhub
22 | * @copyright 2010 Moodle Pty Ltd (http://moodle.com)
23 | * @author Jerome Mouneyrac
24 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 | */
26 | require('../../../config.php');
27 |
28 | require_once($CFG->libdir . '/adminlib.php');
29 | require_once($CFG->dirroot . '/local/hub/lib.php');
30 | require_once($CFG->dirroot . "/local/hub/forms.php");
31 |
32 | admin_externalpage_setup('managecourses');
33 |
34 | //check that the PHP xmlrpc extension is enabled
35 | if (!extension_loaded('xmlrpc')) {
36 | echo $OUTPUT->header();
37 | $xmlrpcnotification = $OUTPUT->doc_link('admin/environment/php_extension/xmlrpc', '');
38 | $xmlrpcnotification .= get_string('xmlrpcdisabled', 'local_hub');
39 | echo $OUTPUT->notification($xmlrpcnotification);
40 | echo $OUTPUT->footer();
41 | die();
42 | }
43 |
44 | $hub = new local_hub();
45 | $renderer = $PAGE->get_renderer('local_hub');
46 |
47 | /// BULK OPERATIONS
48 | $bulkoperation = optional_param('bulkselect', false, PARAM_ALPHANUM);
49 | $confirm = optional_param('confirm', false, PARAM_INTEGER);
50 | if (!empty($bulkoperation) and confirm_sesskey()) {
51 | //retrieve all ids
52 | for ($i = 1; $i <= HUB_COURSE_PER_PAGE; $i = $i + 1) {
53 | $selectedcourseid = optional_param('bulk-' . $i, false, PARAM_INTEGER);
54 | if (!empty($selectedcourseid)) {
55 | $bulkcourses[] = $hub->get_course($selectedcourseid);
56 | }
57 | }
58 | if (!$confirm) {
59 | echo $OUTPUT->header();
60 | echo $OUTPUT->heading(get_string('managecourses', 'local_hub'), 3, 'main');
61 | echo $renderer->course_bulk_operation_confirmation($bulkcourses, $bulkoperation);
62 | echo $OUTPUT->footer();
63 | die();
64 | } else if ($bulkoperation == 'bulkdelete') {
65 | foreach ($bulkcourses as $bulkcourse) {
66 | $hub->delete_course($bulkcourse->id);
67 | }
68 | } else {
69 | foreach ($bulkcourses as $bulkcourse) {
70 | if ($bulkoperation == 'bulkvisible') {
71 | $bulkcourse->privacy = COURSEVISIBILITY_VISIBLE;
72 | } else if ($bulkoperation == 'bulknotvisible') {
73 | $bulkcourse->privacy = COURSEVISIBILITY_NOTVISIBLE;
74 | }
75 | $hub->update_course($bulkcourse);
76 | }
77 | }
78 | }
79 |
80 |
81 | /// VISIBLE OPERATION
82 | $courseid = optional_param('courseid', null, PARAM_INT);
83 | $visible = optional_param('visible', -1, PARAM_INTEGER);
84 | if ($visible != -1 and confirm_sesskey()) {
85 | $course = $hub->get_course($courseid);
86 | if (!empty($course)) {
87 | $course->privacy = $visible;
88 | $hub->update_course($course);
89 | if (!empty($course->privacy)) {
90 | $notificationstring = get_string('coursevisible', 'local_hub', $course->fullname);
91 | } else {
92 | $notificationstring = get_string('coursenotvisible', 'local_hub', $course->fullname);
93 | }
94 | $notification = $OUTPUT->notification($notificationstring, 'notifysuccess');
95 | }
96 | }
97 |
98 | $search = optional_param('search', '', PARAM_TEXT);
99 | $options = array();
100 | $courses = null;
101 |
102 | /// FORM DATA
103 | $fromformdata['coverage'] = optional_param('coverage', 'all', PARAM_TEXT);
104 | $fromformdata['licence'] = optional_param('licence', 'all', PARAM_ALPHANUMEXT);
105 | $fromformdata['subject'] = optional_param('subject', 'all', PARAM_ALPHANUMEXT);
106 | $fromformdata['siteid'] = optional_param('siteid', 'all', PARAM_ALPHANUMEXT);
107 | $fromformdata['lastmodified'] = optional_param('lastmodified', HUB_LASTMODIFIED_WEEK, PARAM_ALPHANUMEXT);
108 | $fromformdata['audience'] = optional_param('audience', 'all', PARAM_ALPHANUMEXT);
109 | $fromformdata['language'] = optional_param('language', 'all', PARAM_ALPHANUMEXT);
110 | $fromformdata['educationallevel'] = optional_param('educationallevel', 'all', PARAM_ALPHANUMEXT);
111 | $fromformdata['visibility'] = optional_param('visibility', COURSEVISIBILITY_NOTVISIBLE, PARAM_ALPHANUMEXT);
112 | $fromformdata['downloadable'] = optional_param('downloadable', 'all', PARAM_ALPHANUM);
113 | $fromformdata['orderby'] = optional_param('orderby', 'newest', PARAM_ALPHA);
114 | $fromformdata['adminform'] = 1;
115 | $fromformdata['search'] = $search;
116 |
117 | $coursesearchform = new course_search_form('', $fromformdata);
118 | $fromform = $coursesearchform->get_data();
119 |
120 | $coursesearchform->set_data($fromformdata);
121 | $fromform = (object) $fromformdata;
122 |
123 |
124 | /// COURSE DATA
125 | if (!empty($courseid)) {
126 | $options['ids'] = array($courseid);
127 | $options['downloadable'] = true;
128 | $options['enrollable'] = true;
129 | $courses = $hub->get_courses($options);
130 | unset($options['ids']);
131 | unset($options['downloadable']);
132 | unset($options['enrollable']);
133 | $coursetotal = 1;
134 | } else {
135 | if (!empty($fromform->coverage)) {
136 | $options['coverage'] = $fromform->coverage;
137 | }
138 | if ($fromform->licence != 'all') {
139 | $options['licenceshortname'] = $fromform->licence;
140 | }
141 | if ($fromform->subject != 'all') {
142 | $options['subject'] = $fromform->subject;
143 | }
144 | if ($fromform->audience != 'all') {
145 | $options['audience'] = $fromform->audience;
146 | }
147 | if ($fromform->educationallevel != 'all') {
148 | $options['educationallevel'] = $fromform->educationallevel;
149 | }
150 | if ($fromform->language != 'all') {
151 | $options['language'] = $fromform->language;
152 | }
153 | if ($fromform->siteid != 'all') {
154 | $options['siteid'] = $fromform->siteid;
155 | }
156 | if ($fromform->lastmodified != 'all') {
157 | switch ($fromform->lastmodified) {
158 | case HUB_LASTMODIFIED_WEEK:
159 | $lastmodified = strtotime("-7 day");
160 | break;
161 | case HUB_LASTMODIFIED_FORTEENNIGHT:
162 | $lastmodified = strtotime("-14 day");
163 | break;
164 | case HUB_LASTMODIFIED_MONTH:
165 | $lastmodified = strtotime("-30 day");
166 | break;
167 | }
168 |
169 | $options['lastmodified'] = $lastmodified;
170 | }
171 |
172 | $options['visibility'] = $fromform->visibility;
173 |
174 | //sort method
175 | switch ($fromform->orderby) {
176 | case 'newest':
177 | $options['orderby'] = 'timemodified DESC';
178 | break;
179 | case 'eldest':
180 | $options['orderby'] = 'timemodified ASC';
181 | break;
182 | case 'publisher':
183 | $options['orderby'] = 'publishername ASC';
184 | break;
185 | case 'fullname':
186 | $options['orderby'] = 'fullname ASC';
187 | break;
188 | default:
189 | break;
190 | }
191 |
192 | //get courses
193 | $options['search'] = $search;
194 | $options['onlyvisible'] = false;
195 | if ($fromform->downloadable != 'all') {
196 | $options['downloadable'] = $fromform->downloadable;
197 | $options['enrollable'] = !$fromform->downloadable;
198 | } else {
199 | $options['downloadable'] = 1;
200 | $options['enrollable'] = 1;
201 | }
202 |
203 | $page = optional_param('page', 0, PARAM_INT);
204 |
205 | $courses = $hub->get_courses($options,
206 | $page * HUB_COURSE_PER_PAGE, HUB_COURSE_PER_PAGE);
207 |
208 | $coursetotal = $hub->get_courses($options, 0, 0, true);
209 |
210 | //$options will be reused to call the same url with same GET param,
211 | //need to reinitialize
212 | $options['downloadable'] = $fromform->downloadable;
213 | $options['lastmodified'] = $fromform->lastmodified;
214 | $options['orderby'] = $fromform->orderby;
215 | }
216 |
217 |
218 | //complete course data with site name and course content
219 | $courseids = array();
220 | $courseimagenumbers = array(); //number of screenshots of all courses (must be exact same order than $courseids)
221 |
222 | if (!empty($courses)) {
223 | foreach ($courses as $tmpcourse) {
224 | $courseids[] = $tmpcourse->id;
225 | }
226 | $courseidslist = implode(',', $courseids);
227 | $sites = $DB->get_records_sql('SELECT site.* FROM {hub_course_directory} course, {hub_site_directory} site WHERE '
228 | . 'course.id IN (' . $courseidslist . ') AND site.id = course.siteid GROUP BY site.id');
229 |
230 | foreach ($courses as &$course) {
231 | //get site name for each courses
232 | $course->site = $sites[$course->siteid];
233 |
234 | //get course content for each course
235 | $contents = $hub->get_course_contents($course->id);
236 | if (!empty($contents)) {
237 | foreach ($contents as $content) {
238 | $course->contents[] = $content;
239 | }
240 | }
241 |
242 | //some information for the YUI imagegallery javascript
243 | $courseimagenumbers[] = $course->screenshots;
244 | }
245 |
246 | //add rating information to the course
247 | require_once($CFG->dirroot . '/rating/lib.php');
248 | $ratingoptions = new stdclass();
249 | $ratingoptions->context = context_course::instance(SITEID); //front page course
250 | $ratingoptions->items = $courses;
251 | $ratingoptions->aggregate = RATING_AGGREGATE_COUNT; //the aggregation method
252 | $ratingoptions->scaleid = 0 - get_config('local_hub', 'courseratingscaleid'); //rating API is expecting "minus scaleid"
253 | $ratingoptions->userid = $USER->id;
254 | $ratingoptions->returnurl = $CFG->wwwroot . "/local/hub/admin/managecourses.php";
255 | $ratingoptions->component = 'local_hub';
256 | $ratingoptions->ratingarea = 'featured';
257 | $rm = new rating_manager();
258 | $courses = $rm->get_ratings($ratingoptions); //this function return $ratingoptions->items with information about the ratings
259 |
260 | //load javascript for YUI imagegallery javascript screenshot
261 | $PAGE->requires->yui_module('moodle-block_community-imagegallery',
262 | 'M.blocks_community.init_imagegallery',
263 | array(array('imageids' => $courseids,
264 | 'imagenumbers' => $courseimagenumbers,
265 | 'huburl' => $CFG->wwwroot)));
266 | }
267 |
268 | //display header
269 | echo $OUTPUT->header();
270 |
271 | //display a message if we come back from site settings page
272 | $updatecourse = optional_param('coursesettings', '', PARAM_TEXT);
273 | if (!empty($updatecourse) and confirm_sesskey()) {
274 | echo $OUTPUT->notification(get_string('coursesettingsupdated', 'local_hub', $updatecourse),
275 | 'notifysuccess');
276 | }
277 |
278 | //display some notification
279 | if (!empty($notification)) {
280 | echo $notification;
281 | }
282 |
283 | //display heading title
284 | echo $OUTPUT->heading(get_string('managecourses', 'local_hub'), 3, 'main');
285 |
286 | //display course search form
287 | $coursesearchform->display();
288 |
289 | if (isset($courses) and empty($courseid)) {
290 | if (empty($coursetotal)) {
291 | $coursetotalhtml = get_string('nocourse', 'local_hub');
292 | } else {
293 | $coursetotalhtml = get_string('coursetotal', 'local_hub', $coursetotal);
294 | }
295 | echo html_writer::tag('div', $coursetotalhtml, array('class' => 'hubcoursetotal'));
296 | }
297 |
298 | //display the top paging bar
299 | if ($coursetotal > HUB_COURSE_PER_PAGE) {
300 | $baseurl = new moodle_url('', $options);
301 | $pagingbarhtml = $OUTPUT->paging_bar($coursetotal, $page, HUB_COURSE_PER_PAGE, $baseurl);
302 | $pagingbarhtml = html_writer::tag('div', $pagingbarhtml, array('class' => 'pagingbar'));
303 | echo $pagingbarhtml;
304 | }
305 |
306 | //display course result list
307 | echo $renderer->course_list($courses, true, $options);
308 |
309 | //display the bottom paging bar
310 | if (!empty($pagingbarhtml)) {
311 | echo $pagingbarhtml;
312 | }
313 |
314 | $PAGE->requires->string_for_js('nocourseselected', 'local_hub');
315 | $PAGE->requires->yui_module('moodle-local_hub-courses', 'M.local_hub.init_hubcourses',
316 | array(array('scriptname' => 'local/hub/admin/managecourses.php')));
317 |
318 | //display footer
319 | echo $OUTPUT->footer();
--------------------------------------------------------------------------------
/top/sites/index_norecordset.php:
--------------------------------------------------------------------------------
1 | dirroot.'/local/hub/top/sites/siteslib.php');
5 |
6 | $country = optional_param('country', '', PARAM_ALPHA);
7 | $cool = optional_param('cool', 0, PARAM_INT);
8 | $uncool = optional_param('uncool', 0, PARAM_INT);
9 | $sitevoting = optional_param('voting', 0, PARAM_INT);
10 | $edit = optional_param('edit', '', PARAM_ALPHA);
11 |
12 | $isadmin = ismoodlesiteadmin();
13 |
14 | $USER->siteediting = ($isadmin && $edit == "on");
15 |
16 | /// Try to get the country, from USER, IP or request
17 | $usercountry = "";
18 | if (!empty($USER->country)) {
19 | $usercountry = $USER->country;
20 | } else {
21 | $ip = $_SERVER['REMOTE_ADDR'];
22 | if ($countryinfo = $DB->get_record_sql("SELECT * FROM {countries} WHERE ipfrom <= inet_aton('$ip') AND inet_aton('$ip') <= ipto ")) {
23 | $usercountry = $countryinfo->code2;
24 | }
25 | }
26 |
27 | if (empty($country) and $usercountry) {
28 | $country = $usercountry;
29 | }
30 |
31 | $hide_all_links = false;
32 | $mostrecent = 0;
33 | $strresources = get_string("modulenameplural", "resource");
34 |
35 | $PAGE->set_context(context_system::instance());
36 | $PAGE->set_url(new moodle_url('/sites/index_norecordset.php'));
37 | $PAGE->set_title('Moodle: Moodle sites');
38 | $PAGE->set_heading('Moodle sites');
39 | $PAGE->set_button(edit_button($isadmin, $country));
40 | $PAGE->navbar->add($strresources.' '.$PAGE->heading, new moodle_url('/mod/resource/index.php', array('id'=>SITEID)));
41 |
42 | echo $OUTPUT->header();
43 |
44 | /// Process cool / uncool
45 | if ($cool or $uncool) {
46 | if (isloggedin() and confirm_sesskey()) {
47 | if ($site = $DB->get_record('registry', array('id'=>$cool+$uncool))) { // site exists
48 | $country = $site->country;
49 | if ($DB->record_exists('hub_site_directory_votes', array('userid'=>$USER->id, 'siteid'=>$site->id))) {
50 | echo $OUTPUT->notification(get_string('erroralreadyvoted', 'local_hub', s($site->sitename)));
51 | } else {
52 | if ($cool) {
53 | $site->cool = $site->cool + 1;
54 | } else if ($uncool) {
55 | $site->cool = $site->cool - 1;
56 | }
57 | $coolsite = new stdClass;
58 | $coolsite->id = $site->id;
59 | $coolsite->cool = $site->cool;
60 | $coolsite->cooldate = time();
61 | $DB->update_record('registry', $coolsite);
62 |
63 | $vote = new stdClass;
64 | $vote->userid = $USER->id;
65 | $vote->siteid = $site->id;
66 | $vote->vote = $cool ? 1 : -1;
67 | $vote->timevoted = time();
68 | $DB->insert_record('registry_votes', $vote);
69 |
70 | if ($cool) {
71 | echo $OUTPUT->notification('Your positive feeling for "'.s($site->sitename).'" has been recorded', 'notifysuccess');
72 | } else {
73 | echo $OUTPUT->notification('Your negative feeling against "'.s($site->sitename).'" has been recorded', 'notifysuccess');
74 | }
75 | }
76 | }
77 | }
78 | }
79 |
80 | echo "";
81 | echo html_writer::start_tag('div', array('class'=>'boxaligncenter boxwidthwide', 'style'=>'padding:20px;'));
82 |
83 | echo "Moodle Sites
\n";
84 |
85 | echo "Some of the growing community of Moodle users are listed below.
";
86 | echo "To add or update your site, just use the \"Registration\" button on your Moodle admin page.
";
87 | echo "(Note: sites that are unreachable or obviously just for testing are not accepted)
";
88 |
89 | echo "
";
90 |
91 |
92 | /// Sort the sites
93 |
94 | $countries = get_string_manager()->get_list_of_countries();
95 | foreach ($countries as $code => $fullname) {
96 | $list[$code]->name = $fullname;
97 | $list[$code]->count = 0;
98 | }
99 |
100 | $counthidden = 0;
101 |
102 | $usedcountry = array();
103 |
104 | $sites = $DB->get_records_select('hub_site_directory', '', null, 'sitename', 'id, country, sitename, public, url, timecreated, timeupdated, lang, cool');
105 | foreach ($sites as $key => $site) {
106 | if (empty($list[$site->country]->name)) { /// Unknown country
107 | $list[$site->country]->name = $site->country;
108 | }
109 | if (!isset($list[$site->country]->count)) {
110 | $list[$site->country]->count = 0;
111 | }
112 | $list[$site->country]->count++;
113 | $usedcountry[$site->country] = true;
114 | if ($site->public > 0 or !empty($USER->siteediting)) {
115 | $list[$site->country]->sites[$site->url] = $site;
116 | }
117 | if ($site->timeupdated > $mostrecent) {
118 | $mostrecent = $site->timeupdated;
119 | }
120 | if (!$site->public) {
121 | $counthidden++;
122 | }
123 | }
124 |
125 | echo "Currently there are ".$DB->count_records("hub_site_directory")." sites from ".count($usedcountry)." countries who have registered.
";
126 |
127 | echo "$counthidden of these have requested privacy and are not shown in the lists below.
";
128 |
129 | if ($hide_all_links) {
130 | echo "(Links have been temporarily switched off)
";
131 | }
132 |
133 | echo "";
134 | $startlist = true;
135 | foreach ($list as $code => $acountry) {
136 | if ($acountry->count) {
137 | if ($startlist) {
138 | $startlist = false;
139 | } else {
140 | echo " | ";
141 | }
142 | if ($code == $usercountry) {
143 | echo "$acountry->name ";
144 | } else {
145 | echo "$acountry->name ";
146 | }
147 | }
148 | }
149 | echo "| SHOW ALL";
150 | echo "
";
151 |
152 | echo html_writer::end_tag('div');
153 | echo "
";
154 |
155 |
156 |
157 | if ($sitevoting) {
158 | if ($sitevoting == 1) {
159 | $USER->sitevoting = true;
160 | } else {
161 | $USER->sitevoting = false;
162 | }
163 | }
164 |
165 | echo '';
166 | if (!isloggedin() || isguestuser()) {
167 | echo 'Sites can be marked "Cool" if three or more people vote for them. Cool sites are promoted around moodle.org and other places. To vote on sites you need to be
logged in.
';
168 | echo "
";
169 | if (isguestuser()) {
170 | unset($USER->sitevoting);
171 | }
172 | } else {
173 | if (empty($USER->sitevoting)) {
174 | echo 'Sites can be marked "Cool" if three or more people vote for them. Cool sites are promoted around moodle.org and other places. To see the voting controls, use this button:
';
175 | $options = array('voting'=>1);
176 | $button = new single_button(new moodle_url('/sites/index.php', $options), 'Show voting buttons for these sites');
177 | } else {
178 | $options = array('voting'=>-1);
179 | $button = new single_button(new moodle_url('/sites/index.php', $options), 'Hide voting buttons for these sites');
180 | }
181 | echo $OUTPUT->single_button($button);
182 | echo '
';
183 | }
184 | echo '';
185 |
186 | $timenow = time();
187 |
188 | if (!empty($country)) {
189 |
190 | if (($country != 'all' and isset($list[$country]))) {
191 | $newlist[$country] = $list[$country];
192 | $list = $newlist;
193 |
194 | // Get old voting records
195 | if (!empty($USER->sitevoting)) {
196 | $oldvotes = $DB->get_records_menu('registry_votes', array('userid'=>$USER->id), '', 'siteid, vote');
197 | $countvotes = $DB->get_records_select_menu('registry_votes', 'siteid > 0 GROUP BY siteid', null, '', 'siteid, COUNT(*) number');
198 | }
199 | }
200 |
201 | foreach ($list as $code => $country) {
202 | if ($country->count) {
203 | if ($country->count == 1) {
204 | $strsite = "$country->count site";
205 | } else {
206 | $strsite = "$country->count sites";
207 | }
208 |
209 | if (!empty($country->sites)) {
210 | $countsites = count($country->sites);
211 | } else {
212 | $countsites = 0;
213 | }
214 | if ($countsites < $country->count) {
215 | $countsites = $country->count - $countsites;
216 | $strsite .= " ($countsites not shown here)";
217 | }
218 |
219 | echo "
\n";
301 | }
302 | }
303 | }
304 |
305 | echo "
";
306 |
307 | echo "Page last updated: ";
308 | echo userdate($mostrecent);
309 | echo "
";
310 |
311 | echo $OUTPUT->footer();
312 |
--------------------------------------------------------------------------------
/top/sites/index_norestrictbycountry.php:
--------------------------------------------------------------------------------
1 | siteediting = ($isadmin && $edit == "on");
16 |
17 | /// Try to get the country, from USER, IP or request
18 | $usercountry = "";
19 | if (!empty($USER->country)) {
20 | $usercountry = $USER->country;
21 | } else {
22 | $ip = $_SERVER['REMOTE_ADDR'];
23 | if ($countryinfo = $DB->get_record_sql("SELECT * FROM {countries} WHERE ipfrom <= inet_aton('$ip') AND inet_aton('$ip') <= ipto ")) {
24 | $usercountry = $countryinfo->code2;
25 | }
26 | }
27 |
28 | if (empty($country) and $usercountry) {
29 | $country = $usercountry;
30 | }
31 |
32 | $hide_all_links = false;
33 | $mostrecent = 0;
34 | $strresources = get_string("modulenameplural", "resource");
35 |
36 | $PAGE->set_context(context_system::instance());
37 | $PAGE->set_url(new moodle_url('/sites/index_norecordset.php'));
38 | $PAGE->set_title('Moodle: Moodle sites');
39 | $PAGE->set_heading('Moodle sites');
40 | $PAGE->set_button(edit_button($isadmin, $country));
41 | $PAGE->navbar->add($strresources.' '.$PAGE->heading, new moodle_url('/mod/resource/index.php', array('id'=>SITEID)));
42 |
43 | echo $OUTPUT->header();
44 |
45 | /// Process cool / uncool
46 | if ($cool or $uncool) {
47 | if (isloggedin() and confirm_sesskey()) {
48 | if ($site = $DB->get_record('hub_site_directory', array('id'=>$cool+$uncool))) { // site exists
49 | $country = $site->country;
50 | if ($DB->record_exists('registry_votes', array('userid'=>$USER->id, 'siteid'=>$site->id))) {
51 | echo $OUTPUT->notification(get_string('erroralreadyvoted', 'local_hub', s($site->sitename)));
52 | } else {
53 | if ($cool) {
54 | $site->cool = $site->cool + 1;
55 | } else if ($uncool) {
56 | $site->cool = $site->cool - 1;
57 | }
58 | $coolsite = new stdClass;
59 | $coolsite->id = $site->id;
60 | $coolsite->cool = $site->cool;
61 | $coolsite->cooldate = time();
62 | $DB->update_record('hub_site_directory', $coolsite);
63 |
64 | $vote = new stdClass;
65 | $vote->userid = $USER->id;
66 | $vote->siteid = $site->id;
67 | $vote->vote = $cool ? 1 : -1;
68 | $vote->timevoted = time();
69 | $DB->insert_record('registry_votes', $vote);
70 |
71 | if ($cool) {
72 | echo $OUTPUT->notification('Your positive feeling for "'.s($site->sitename).'" has been recorded', 'notifysuccess');
73 | } else {
74 | echo $OUTPUT->notification('Your negative feeling against "'.s($site->sitename).'" has been recorded', 'notifysuccess');
75 | }
76 | }
77 | }
78 | }
79 | }
80 |
81 | echo "";
82 | echo html_writer::start_tag('div', array('class'=>'boxaligncenter boxwidthwide', 'style'=>'padding:20px;'));
83 |
84 | echo "Moodle Sites
\n";
85 |
86 | echo "Some of the growing community of Moodle users are listed below.
";
87 | echo "To add or update your site, just use the \"Registration\" button on your Moodle admin page.
";
88 | echo "(Note: sites that are unreachable or obviously just for testing are not accepted)
";
89 |
90 | echo "
";
91 |
92 |
93 | /// Sort the sites
94 |
95 | $countries = get_string_manager()->get_list_of_countries();
96 | foreach ($countries as $code => $fullname) {
97 | $list[$code]->name = $fullname;
98 | $list[$code]->count = 0;
99 | }
100 |
101 | $counthidden = 0;
102 | $usedcountry = array();
103 |
104 |
105 | $sitesrs = $DB->get_recordset_select('hub_site_directory', '', null, 'sitename', "id, country, sitename, public, url, timecreated, timeupdated, lang, cool");
106 | foreach ($sitesrs as $site) {
107 | if (empty($list[$site->country]->name)) { /// Unknown country
108 | $list[$site->country]->name = $site->country;
109 | }
110 | if (!isset($list[$site->country]->count)) {
111 | $list[$site->country]->count = 0;
112 | }
113 | $list[$site->country]->count++;
114 | $usedcountry[$site->country] = true;
115 | if ($site->public > 0 or !empty($USER->siteediting)) {
116 | $list[$site->country]->sites[$site->url] = $site;
117 | }
118 | if ($site->timeupdated > $mostrecent) {
119 | $mostrecent = $site->timeupdated;
120 | }
121 | if (!$site->public) {
122 | $counthidden++;
123 | }
124 | }
125 | $sitesrs->close();
126 |
127 | echo "Currently there are ".$DB->count_records("hub_site_directory")." sites from ".count($usedcountry)." countries who have registered.
";
128 |
129 | echo "$counthidden of these have requested privacy and are not shown in the lists below.
";
130 |
131 | if ($hide_all_links) {
132 | echo "(Links have been temporarily switched off)
";
133 | }
134 |
135 | echo "";
136 | $startlist = true;
137 | foreach ($list as $code => $acountry) {
138 | if ($acountry->count) {
139 | if ($startlist) {
140 | $startlist = false;
141 | } else {
142 | echo " | ";
143 | }
144 | if ($code == $usercountry) {
145 | echo "$acountry->name ";
146 | } else {
147 | echo "$acountry->name ";
148 | }
149 | }
150 | }
151 | echo "| SHOW ALL";
152 | echo "
";
153 |
154 | echo htnl_writer::end_tag('div');
155 | echo "
";
156 |
157 |
158 |
159 | if ($sitevoting) {
160 | if ($sitevoting == 1) {
161 | $USER->sitevoting = true;
162 | } else {
163 | $USER->sitevoting = false;
164 | }
165 | }
166 |
167 | echo '';
168 | if (!isloggedin() || isguestuser()) {
169 | echo 'Sites can be marked "Cool" if three or more people vote for them. Cool sites are promoted around moodle.org and other places. To vote on sites you need to be
logged in.
';
170 | echo "
";
171 | if (isguestuser()) {
172 | unset($USER->sitevoting);
173 | }
174 | } else {
175 | if (empty($USER->sitevoting)) {
176 | echo 'Sites can be marked "Cool" if three or more people vote for them. Cool sites are promoted around moodle.org and other places. To see the voting controls, use this button:
';
177 | $options = array('voting'=>1);
178 | $button = new single_button(new moodle_url('/sites/index.php', $options), 'Show voting buttons for these sites');
179 | } else {
180 | $options = array('voting'=>-1);
181 | $button = new single_button(new moodle_url('/sites/index.php', $options), 'Hide voting buttons for these sites');
182 | }
183 | echo $OUTPUT->single_button($button);
184 | echo '
';
185 | }
186 | echo '';
187 |
188 | $timenow = time();
189 |
190 | if (!empty($country)) {
191 |
192 | if (($country != 'all' and isset($list[$country]))) {
193 | $newlist[$country] = $list[$country];
194 | $list = $newlist;
195 |
196 | // Get old voting records
197 | if (!empty($USER->sitevoting)) {
198 | $oldvotes = $DB->get_records_menu('registry_votes', array('userid'=>$USER->id), '', 'siteid, vote');
199 | $countvotes = $DB->get_records_select_menu('registry_votes', 'siteid > 0 GROUP BY siteid', null, '', 'siteid, COUNT(*) number');
200 | }
201 | }
202 |
203 | foreach ($list as $code => $country) {
204 | if ($country->count) {
205 | if ($country->count == 1) {
206 | $strsite = "$country->count site";
207 | } else {
208 | $strsite = "$country->count sites";
209 | }
210 |
211 | if (!empty($country->sites)) {
212 | $countsites = count($country->sites);
213 | } else {
214 | $countsites = 0;
215 | }
216 | if ($countsites < $country->count) {
217 | $countsites = $country->count - $countsites;
218 | $strsite .= " ($countsites not shown here)";
219 | }
220 |
221 | echo "
\n";
303 | }
304 | }
305 | }
306 |
307 | echo "
";
308 |
309 | echo "Page last updated: ";
310 | echo userdate($mostrecent);
311 | echo "
";
312 |
313 |
314 | echo "
";
315 |
316 | echo $OUTPUT->footer();
317 |
--------------------------------------------------------------------------------
/tests/lib_test.php:
--------------------------------------------------------------------------------
1 | .
16 |
17 | /**
18 | * Unit tests for hub
19 | *
20 | * @package local_hub
21 | * @copyright 2014 Dan Poltawski
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 | */
24 |
25 | defined('MOODLE_INTERNAL') || die();
26 |
27 | require_once(__DIR__ . '/../lib.php');
28 |
29 | class local_hub_lib_testcase extends advanced_testcase
30 | {
31 |
32 | public function test_is_remote_site_valid() {
33 | $hub = new local_hub();
34 |
35 | // TODO: move to: https://github.com/moodlehq/moodle-exttests
36 | $invalidsites = array(
37 | 'http://localhost',
38 | 'http://127.0.0.1',
39 | 'https://download.moodle.org/does-not-exist',
40 | );
41 |
42 | foreach ($invalidsites as $site) {
43 | $this->assertFalse($hub->is_remote_site_valid($site), "$site reported valid");
44 | }
45 |
46 | $validsites = array(
47 | 'http://download.moodle.org', // NOTE the http redirect.
48 | 'http://learn.moodle.net', // More tests.
49 | 'https://learn.gold.ac.uk', // Normal site dan worked with.
50 | 'http://devmooc.net/', // Problem site MDLSITE-3433.
51 | 'http://englishwat.com/qvilearn/', // Problem site which doesn't like header requests MDLSITE-3920.
52 | );
53 |
54 | foreach ($validsites as $site) {
55 | $this->assertTrue($hub->is_remote_site_valid($site), "$site reported invalid");
56 | }
57 |
58 | }
59 |
60 | public function test_check_secret_validity() {
61 | global $DB;
62 |
63 | $this->resetAfterTest(true);
64 | $hub = new local_hub();
65 |
66 | $token = 'this is my token';
67 | $md5 = md5($token);
68 | $this->assertTrue($hub->check_secret_validity($md5));
69 |
70 | // Mark it stolen.
71 | $stolensecret = new stdClass();
72 | $stolensecret->secret = $md5;
73 | $stolensecret->siteurl = 'http://example.com';
74 | $stolensecret->blockeddate = time();
75 | $DB->insert_record('hub_stolen_site_secrets', $stolensecret);
76 |
77 | $this->assertFalse($hub->check_secret_validity($md5));
78 | }
79 |
80 | public function test_create_hub_token() {
81 | $this->resetAfterTest(true);
82 |
83 | $hub = new local_hub();
84 | $url = 'http://example.com';
85 |
86 | // These capabilities and the arguments to create_hub_token() are modeled
87 | // on the call in register_site() in lib.php.
88 |
89 | $capabilities = array('local/hub:updateinfo', 'local/hub:registercourse',
90 | 'local/hub:view', 'local/hub:unregistercourse', 'local/hub:viewsmallinfo');
91 |
92 | $tokenusedbysite = $hub->create_hub_token('Registered Hub User',
93 | 'Registered site',
94 | $url . '_registered_site_user',
95 | $capabilities);
96 |
97 | // If it already exists, the existing token should be found.
98 | $foundtoken = $hub->create_hub_token('Registered Hub User',
99 | 'Registered site',
100 | $url . '_registered_site_user',
101 | $capabilities);
102 | $this->assertEquals($foundtoken->id, $tokenusedbysite->id);
103 | }
104 |
105 | public function test_register_site() {
106 | global $DB;
107 | $this->resetAfterTest(true);
108 |
109 | $hub = new local_hub();
110 | $originalurl = 'http://example.com';
111 | $changedurl = 'http://example2.com';
112 |
113 | $sitevalues = $this->get_sitevalues($originalurl);
114 |
115 | // Missing language code.
116 | $sitevalues['language'] = '';
117 | try {
118 | $token = $hub->register_site($sitevalues);
119 | $this->fail('Exception expected due to invalid language code.');
120 | } catch (moodle_exception $e) {
121 | $this->assertEquals('errorlangnotrecognized', $e->errorcode);
122 | }
123 |
124 | // Should succeed.
125 | $sitevalues['language'] = 'en';
126 | $token = $hub->register_site($sitevalues);
127 | $siterecord = $DB->get_record('hub_site_directory', array('name' => $sitevalues['name']), '*', MUST_EXIST);
128 | $this->assertEquals($siterecord->url, $originalurl);
129 |
130 | $this->check_tokens($hub, $sitevalues['url']);
131 |
132 | // Trying to register the same site a second time should fail.
133 | try {
134 | $hub->register_site($sitevalues);
135 | $this->fail('Exception expected due to duplicate secret/token.');
136 | } catch (moodle_exception $e) {
137 | $this->assertEquals('sitesecretalreadyexist', $e->errorcode);
138 | }
139 |
140 | // Re-registering with a different URL.
141 | $sitevalues['url'] = $changedurl;
142 | $tokenupdated = $hub->register_site($sitevalues, $originalurl);
143 | $this->assertEquals($token, $tokenupdated); // Token should remain unchanged.
144 | $siterecord = $DB->get_record('hub_site_directory', array('name' => $sitevalues['name']), '*', MUST_EXIST);
145 | $this->assertEquals($siterecord->url, $changedurl);
146 | }
147 |
148 | public function test_unregister_site() {
149 | global $DB;
150 | $this->resetAfterTest(true);
151 |
152 | $hub = new local_hub();
153 | $url = "http://example.com";
154 | $sitevalues = $this->get_sitevalues($url);
155 |
156 | // Not sure why this behaviour is important but unregister_site() specificaly supports it.
157 | $hub->unregister_site(null);
158 |
159 | $token = $hub->register_site($sitevalues);
160 |
161 | $this->check_tokens($hub, $sitevalues['url']);
162 |
163 | $site = $hub->get_site_by_url($url);
164 | $hub->unregister_site($site);
165 | $this->assertEquals($site->deleted, 1);
166 | // Note that lib.php unregister_site() does not do anything but mark the site as deleted.
167 | // Deleting tokens is done by externallib.php local_hub_external::unregister_site() and lib.php delete_site().
168 | // Should externallib.php unregister_site() be calling lib.php delete_site() instead of lib.php unregister_site()?
169 | }
170 |
171 | public function test_get_site_by_url() {
172 | global $DB;
173 | $this->resetAfterTest(true);
174 |
175 | $hub = new local_hub();
176 | $url = "http://example.com";
177 | $sitevalues = $this->get_sitevalues($url);
178 |
179 | $token = $hub->register_site($sitevalues);
180 |
181 | $this->check_tokens($hub, $sitevalues['url']);
182 |
183 | // Try (and fail) to find a deleted site.
184 | $site = $hub->get_site_by_url($url, 1);
185 | $this->assertTrue($site == null);
186 |
187 | // Find a not deleted site.
188 | $site = $hub->get_site_by_url($url, 0);
189 | $this->assertTrue($site != null);
190 | // Should work the same with the default second parameter.
191 | $site = $hub->get_site_by_url($url);
192 | $this->assertTrue($site != null);
193 | // Find the not deleted site regardless of deletion status.
194 | $site = $hub->get_site_by_url($url, null);
195 | $this->assertTrue($site != null);
196 |
197 | // Delete the site.
198 | $hub->unregister_site($site);
199 |
200 | // Finding the deleted site should not happen without providing 1 as the second param.
201 | $site = $hub->get_site_by_url($url, 0);
202 | $this->assertTrue($site == null);
203 | $site = $hub->get_site_by_url($url);
204 | $this->assertTrue($site == null);
205 |
206 | // Explicitly request a deleted site.
207 | $site = $hub->get_site_by_url($url, 1);
208 | $this->assertTrue($site != null);
209 |
210 | // Find the deleted site regardless of deletion status.
211 | $site = $hub->get_site_by_url($url, null);
212 | $this->assertTrue($site != null);
213 | }
214 |
215 | public function test_get_sites() {
216 | global $DB;
217 | $this->resetAfterTest(true);
218 | set_config('noemailever', 1);
219 |
220 | $hub = new local_hub();
221 | $url = "http://example.com";
222 | $sitevalues = $this->get_sitevalues($url);
223 |
224 | $token = $hub->register_site($sitevalues);
225 | $this->check_tokens($hub, $sitevalues['url']);
226 |
227 | $sites = $hub->get_sites(array('urls' => array($url, 'http://doesntexist.com')));
228 | $this->assertTrue(count($sites) == 1);
229 |
230 | $sites = $hub->get_sites(array('contactemail' => $sitevalues['contactemail']));
231 | $this->assertTrue(count($sites) == 1);
232 |
233 | $sites = $hub->get_sites(array('contactemail' => 'doesntexist' . $sitevalues['contactemail']));
234 | $this->assertTrue(count($sites) == 0);
235 | }
236 |
237 | public function test_add_site() {
238 | global $DB;
239 | $this->resetAfterTest(true);
240 |
241 | $hub = new local_hub();
242 | $url = "http://example.com";
243 | $sitevalues = $this->get_sitevalues($url);
244 |
245 | $token = $hub->register_site($sitevalues);
246 |
247 | $this->check_tokens($hub, $sitevalues['url']);
248 |
249 | // Delete the site then re-add and check the deleted site is found.
250 | $site = $hub->get_site_by_url($url);
251 | $hub->delete_site($site->id);
252 |
253 | $oldid = $site->id;
254 | $site = $hub->add_site($site);
255 | $this->assertEquals($site->id, $oldid);
256 |
257 | // Attempt to re-add a not deleted site and check that the old one is found.
258 | $site = $hub->add_site($site);
259 | $this->assertEquals($site->id, $oldid);
260 | }
261 |
262 | public function test_delete_site() {
263 | global $DB;
264 | $this->resetAfterTest(true);
265 |
266 | $hub = new local_hub();
267 | $url = "http://example.com";
268 | $sitevalues = $this->get_sitevalues($url);
269 |
270 | $token = $hub->register_site($sitevalues);
271 |
272 | $this->check_tokens($hub, $sitevalues['url']);
273 |
274 | $site = $hub->get_site_by_url($url);
275 | $hub->delete_site($site->id);
276 |
277 | $site = $hub->get_site($site->id); // Should we be able to retrieve deleted sites like this?
278 | $this->assertEquals($site->deleted, 1);
279 |
280 | // Verify the tokens are either deleted or marked as deleted.
281 | $username = $url . '_registered_site_user';
282 | $user = $DB->get_record('user', array('username' => $username, 'idnumber' => $username));
283 | $service = $DB->get_record('external_services', array('name' => 'Registered site'));
284 |
285 | $this->assertEquals($this->get_external_token($user, $service), null);
286 | $this->assertEquals($hub->get_communication(WSSERVER, REGISTEREDSITE, $sitevalues['url']), null);
287 | }
288 |
289 | public function test_add_communication() {
290 | global $DB;
291 | $this->resetAfterTest(true);
292 |
293 | $hub = new local_hub();
294 |
295 | $sitetohubcommunication = new stdClass();
296 | $sitetohubcommunication->token = '123456';
297 | $sitetohubcommunication->type = WSSERVER;
298 | $sitetohubcommunication->remoteentity = REGISTEREDSITE;
299 | $sitetohubcommunication->remotename = 'test site';
300 | $sitetohubcommunication->remoteurl = 'http://example.com';
301 | $sitetohubcommunication->confirmed = 1;
302 | $sitetohubcommunication->id = $hub->add_communication($sitetohubcommunication);
303 | $this->assertTrue($sitetohubcommunication->id > 0);
304 |
305 | // Deleting a communication just toggles a deleted flage.
306 | // Adding another communication with the same details
307 | // should result in the ID of the new and old communication matching.
308 | $originalID = $sitetohubcommunication->id;
309 | $hub->delete_communication($sitetohubcommunication);
310 | $newID = $hub->add_communication($sitetohubcommunication);
311 | $this->assertTrue($originalID == $newID);
312 | }
313 |
314 | private function get_sitevalues($url) {
315 | $sitevalues = array(
316 | 'name' => 'test site',
317 | 'url' => $url,
318 | 'token' => '',
319 | 'secret' => '',
320 | 'description' => 'this is a test site',
321 | 'contactname' => 'Fictional Fred',
322 | 'contactemail' => 'fred@example.com',
323 | 'contactphone' => '',
324 | 'imageurl' => '',
325 | 'privacy' => '',
326 | 'language' => 'en',
327 | 'users' => '',
328 | 'courses' => '',
329 | 'street' => '',
330 | 'regioncode' => '',
331 | 'countrycode' => '',
332 | 'geolocation' => '',
333 | 'contactable' => '',
334 | 'emailalert' => '',
335 | 'enrolments' => '',
336 | 'posts' => '',
337 | 'questions' => '',
338 | 'resources' => '',
339 | 'participantnumberaverage' => '',
340 | 'modulenumberaverage' => '',
341 | 'moodleversion' => '',
342 | 'moodlerelease' => '',
343 | 'password' => '',
344 | 'badges' => '',
345 | 'issuedbadges' => '');
346 |
347 | return $sitevalues;
348 | }
349 |
350 | private function check_tokens($hub, $url) {
351 | global $DB;
352 |
353 | // Check a token was created and inserted into external_tokens and hub_communications.
354 | $username = $url . '_registered_site_user';
355 | $user = $DB->get_record('user', array('username' => $username, 'idnumber' => $username));
356 | $service = $DB->get_record('external_services', array('name' => 'Registered site'));
357 |
358 | $externaltoken = $this->get_external_token($user, $service);
359 | $communication = $hub->get_communication(WSSERVER, REGISTEREDSITE, $url);
360 | $this->assertTrue($externaltoken->token == $communication->token);
361 | }
362 |
363 | private function get_external_token($user, $service) {
364 | global $DB;
365 |
366 | $resulttoken = new stdClass();
367 | $resulttoken->userid = $user->id;
368 | $resulttoken->tokentype = EXTERNAL_TOKEN_PERMANENT;
369 | $resulttoken->externalserviceid = $service->id;
370 | $resulttoken->contextid = context_system::instance()->id;
371 | $resulttoken->creatorid = $user->id;
372 | return $DB->get_record('external_tokens', (array) $resulttoken);
373 | }
374 | }
375 |
--------------------------------------------------------------------------------