Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Paypal enrolment plugin.
19
 *
20
 * This plugin allows you to set up paid courses.
21
 *
22
 * @package    enrol_paypal
23
 * @copyright  2010 Eugene Venter
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
/**
30
 * Paypal enrolment plugin implementation.
31
 * @author  Eugene Venter - based on code by Martin Dougiamas and others
32
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 */
34
class enrol_paypal_plugin extends enrol_plugin {
35
 
36
    public function get_currencies() {
37
        // See https://www.paypal.com/cgi-bin/webscr?cmd=p/sell/mc/mc_intro-outside,
38
        // 3-character ISO-4217: https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_currency_codes
39
        $codes = array(
40
            'AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'INR', 'JPY',
41
            'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'RUB', 'SEK', 'SGD', 'THB', 'TRY', 'TWD', 'USD');
42
        $currencies = array();
43
        foreach ($codes as $c) {
44
            $currencies[$c] = new lang_string($c, 'core_currencies');
45
        }
46
 
47
        return $currencies;
48
    }
49
 
50
    /**
51
     * Returns optional enrolment information icons.
52
     *
53
     * This is used in course list for quick overview of enrolment options.
54
     *
55
     * We are not using single instance parameter because sometimes
56
     * we might want to prevent icon repetition when multiple instances
57
     * of one type exist. One instance may also produce several icons.
58
     *
59
     * @param array $instances all enrol instances of this type in one course
60
     * @return array of pix_icon
61
     */
62
    public function get_info_icons(array $instances) {
63
        $found = false;
64
        foreach ($instances as $instance) {
65
            if ($instance->enrolstartdate != 0 && $instance->enrolstartdate > time()) {
66
                continue;
67
            }
68
            if ($instance->enrolenddate != 0 && $instance->enrolenddate < time()) {
69
                continue;
70
            }
71
            $found = true;
72
            break;
73
        }
74
        if ($found) {
75
            return array(new pix_icon('icon', get_string('pluginname', 'enrol_paypal'), 'enrol_paypal'));
76
        }
77
        return array();
78
    }
79
 
80
    public function roles_protected() {
81
        // users with role assign cap may tweak the roles later
82
        return false;
83
    }
84
 
85
    public function allow_unenrol(stdClass $instance) {
86
        // users with unenrol cap may unenrol other users manually - requires enrol/paypal:unenrol
87
        return true;
88
    }
89
 
90
    public function allow_manage(stdClass $instance) {
91
        // users with manage cap may tweak period and status - requires enrol/paypal:manage
92
        return true;
93
    }
94
 
95
    public function show_enrolme_link(stdClass $instance) {
96
        return ($instance->status == ENROL_INSTANCE_ENABLED);
97
    }
98
 
99
    /**
100
     * Returns true if the user can add a new instance in this course.
101
     * @param int $courseid
102
     * @return boolean
103
     */
104
    public function can_add_instance($courseid) {
105
        $context = context_course::instance($courseid, MUST_EXIST);
106
 
107
        if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/paypal:config', $context)) {
108
            return false;
109
        }
110
 
111
        // multiple instances supported - different cost for different roles
112
        return true;
113
    }
114
 
115
    /**
116
     * We are a good plugin and don't invent our own UI/validation code path.
117
     *
118
     * @return boolean
119
     */
120
    public function use_standard_editing_ui() {
121
        return true;
122
    }
123
 
124
    /**
125
     * Add new instance of enrol plugin.
126
     * @param object $course
127
     * @param array $fields instance fields
128
     * @return int id of new instance, null if can not be created
129
     */
130
    public function add_instance($course, array $fields = null) {
131
        if ($fields && !empty($fields['cost'])) {
132
            $fields['cost'] = unformat_float($fields['cost']);
133
        }
134
        return parent::add_instance($course, $fields);
135
    }
136
 
137
    /**
138
     * Update instance of enrol plugin.
139
     * @param stdClass $instance
140
     * @param stdClass $data modified instance fields
141
     * @return boolean
142
     */
143
    public function update_instance($instance, $data) {
144
        if ($data) {
145
            $data->cost = unformat_float($data->cost);
146
        }
147
        return parent::update_instance($instance, $data);
148
    }
149
 
150
    /**
151
     * Creates course enrol form, checks if form submitted
152
     * and enrols user if necessary. It can also redirect.
153
     *
154
     * @param stdClass $instance
155
     * @return string html text, usually a form in a text box
156
     */
157
    function enrol_page_hook(stdClass $instance) {
158
        global $CFG, $USER, $OUTPUT, $PAGE, $DB;
159
 
160
        ob_start();
161
 
162
        if ($DB->record_exists('user_enrolments', array('userid'=>$USER->id, 'enrolid'=>$instance->id))) {
163
            return ob_get_clean();
164
        }
165
 
166
        if ($instance->enrolstartdate != 0 && $instance->enrolstartdate > time()) {
167
            return ob_get_clean();
168
        }
169
 
170
        if ($instance->enrolenddate != 0 && $instance->enrolenddate < time()) {
171
            return ob_get_clean();
172
        }
173
 
174
        $course = $DB->get_record('course', array('id'=>$instance->courseid));
175
        $context = context_course::instance($course->id);
176
 
177
        $shortname = format_string($course->shortname, true, array('context' => $context));
178
        $strloginto = get_string("loginto", "", $shortname);
179
        $strcourses = get_string("courses");
180
 
181
        // Pass $view=true to filter hidden caps if the user cannot see them
182
        if ($users = get_users_by_capability($context, 'moodle/course:update', 'u.*', 'u.id ASC',
183
                                             '', '', '', '', false, true)) {
184
            $users = sort_by_roleassignment_authority($users, $context);
185
            $teacher = array_shift($users);
186
        } else {
187
            $teacher = false;
188
        }
189
 
190
        if ( (float) $instance->cost <= 0 ) {
191
            $cost = (float) $this->get_config('cost');
192
        } else {
193
            $cost = (float) $instance->cost;
194
        }
195
 
196
        if (abs($cost) < 0.01) { // no cost, other enrolment methods (instances) should be used
197
            echo '<p>'.get_string('nocost', 'enrol_paypal').'</p>';
198
        } else {
199
 
200
            // Calculate localised and "." cost, make sure we send PayPal the same value,
201
            // please note PayPal expects amount with 2 decimal places and "." separator.
202
            $localisedcost = format_float($cost, 2, true);
203
            $cost = format_float($cost, 2, false);
204
 
205
            if (isguestuser()) { // force login only for guest user, not real users with guest role
206
                $wwwroot = $CFG->wwwroot;
207
                echo '<div class="mdl-align"><p>'.get_string('paymentrequired').'</p>';
208
                echo '<p><b>'.get_string('cost').": $instance->currency $localisedcost".'</b></p>';
209
                echo '<p><a href="'.$wwwroot.'/login/">'.get_string('loginsite').'</a></p>';
210
                echo '</div>';
211
            } else {
212
                //Sanitise some fields before building the PayPal form
213
                $coursefullname  = format_string($course->fullname, true, array('context'=>$context));
214
                $courseshortname = $shortname;
215
                $userfullname    = fullname($USER);
216
                $userfirstname   = $USER->firstname;
217
                $userlastname    = $USER->lastname;
218
                $useraddress     = $USER->address;
219
                $usercity        = $USER->city;
220
                $instancename    = $this->get_instance_name($instance);
221
 
222
                include($CFG->dirroot.'/enrol/paypal/enrol.html');
223
            }
224
 
225
        }
226
 
227
        return $OUTPUT->box(ob_get_clean());
228
    }
229
 
230
    /**
231
     * Restore instance and map settings.
232
     *
233
     * @param restore_enrolments_structure_step $step
234
     * @param stdClass $data
235
     * @param stdClass $course
236
     * @param int $oldid
237
     */
238
    public function restore_instance(restore_enrolments_structure_step $step, stdClass $data, $course, $oldid) {
239
        global $DB;
240
        if ($step->get_task()->get_target() == backup::TARGET_NEW_COURSE) {
241
            $merge = false;
242
        } else {
243
            $merge = array(
244
                'courseid'   => $data->courseid,
245
                'enrol'      => $this->get_name(),
246
                'roleid'     => $data->roleid,
247
                'cost'       => $data->cost,
248
                'currency'   => $data->currency,
249
            );
250
        }
251
        if ($merge and $instances = $DB->get_records('enrol', $merge, 'id')) {
252
            $instance = reset($instances);
253
            $instanceid = $instance->id;
254
        } else {
255
            $instanceid = $this->add_instance($course, (array)$data);
256
        }
257
        $step->set_mapping('enrol', $oldid, $instanceid);
258
    }
259
 
260
    /**
261
     * Restore user enrolment.
262
     *
263
     * @param restore_enrolments_structure_step $step
264
     * @param stdClass $data
265
     * @param stdClass $instance
266
     * @param int $oldinstancestatus
267
     * @param int $userid
268
     */
269
    public function restore_user_enrolment(restore_enrolments_structure_step $step, $data, $instance, $userid, $oldinstancestatus) {
270
        $this->enrol_user($instance, $userid, null, $data->timestart, $data->timeend, $data->status);
271
    }
272
 
273
    /**
274
     * Return an array of valid options for the status.
275
     *
276
     * @return array
277
     */
278
    protected function get_status_options() {
279
        $options = array(ENROL_INSTANCE_ENABLED  => get_string('yes'),
280
                         ENROL_INSTANCE_DISABLED => get_string('no'));
281
        return $options;
282
    }
283
 
284
    /**
285
     * Return an array of valid options for the roleid.
286
     *
287
     * @param stdClass $instance
288
     * @param context $context
289
     * @return array
290
     */
291
    protected function get_roleid_options($instance, $context) {
292
        if ($instance->id) {
293
            $roles = get_default_enrol_roles($context, $instance->roleid);
294
        } else {
295
            $roles = get_default_enrol_roles($context, $this->get_config('roleid'));
296
        }
297
        return $roles;
298
    }
299
 
300
 
301
    /**
302
     * Add elements to the edit instance form.
303
     *
304
     * @param stdClass $instance
305
     * @param MoodleQuickForm $mform
306
     * @param context $context
307
     * @return bool
308
     */
309
    public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
310
 
311
        $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
312
        $mform->setType('name', PARAM_TEXT);
313
 
314
        $options = $this->get_status_options();
315
        $mform->addElement('select', 'status', get_string('status', 'enrol_paypal'), $options);
316
        $mform->setDefault('status', $this->get_config('status'));
317
 
318
        $mform->addElement('text', 'cost', get_string('cost', 'enrol_paypal'), array('size' => 4));
319
        $mform->setType('cost', PARAM_RAW);
320
        $mform->setDefault('cost', format_float($this->get_config('cost'), 2, true));
321
 
322
        $paypalcurrencies = $this->get_currencies();
323
        $mform->addElement('select', 'currency', get_string('currency', 'enrol_paypal'), $paypalcurrencies);
324
        $mform->setDefault('currency', $this->get_config('currency'));
325
 
326
        $roles = $this->get_roleid_options($instance, $context);
327
        $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_paypal'), $roles);
328
        $mform->setDefault('roleid', $this->get_config('roleid'));
329
 
330
        $options = array('optional' => true, 'defaultunit' => 86400);
331
        $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_paypal'), $options);
332
        $mform->setDefault('enrolperiod', $this->get_config('enrolperiod'));
333
        $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_paypal');
334
 
335
        $options = array('optional' => true);
336
        $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_paypal'), $options);
337
        $mform->setDefault('enrolstartdate', 0);
338
        $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_paypal');
339
 
340
        $options = array('optional' => true);
341
        $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_paypal'), $options);
342
        $mform->setDefault('enrolenddate', 0);
343
        $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_paypal');
344
 
345
        if (enrol_accessing_via_instance($instance)) {
346
            $warningtext = get_string('instanceeditselfwarningtext', 'core_enrol');
347
            $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warningtext);
348
        }
349
    }
350
 
351
    /**
352
     * Perform custom validation of the data used to edit the instance.
353
     *
354
     * @param array $data array of ("fieldname"=>value) of submitted data
355
     * @param array $files array of uploaded files "element_name"=>tmp_file_path
356
     * @param object $instance The instance loaded from the DB
357
     * @param context $context The context of the instance we are editing
358
     * @return array of "element_name"=>"error_description" if there are errors,
359
     *         or an empty array if everything is OK.
360
     * @return void
361
     */
362
    public function edit_instance_validation($data, $files, $instance, $context) {
363
        $errors = array();
364
 
365
        if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) {
366
            $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_paypal');
367
        }
368
 
369
        $cost = str_replace(get_string('decsep', 'langconfig'), '.', $data['cost']);
370
        if (!is_numeric($cost)) {
371
            $errors['cost'] = get_string('costerror', 'enrol_paypal');
372
        }
373
 
374
        $validstatus = array_keys($this->get_status_options());
375
        $validcurrency = array_keys($this->get_currencies());
376
        $validroles = array_keys($this->get_roleid_options($instance, $context));
377
        $tovalidate = array(
378
            'name' => PARAM_TEXT,
379
            'status' => $validstatus,
380
            'currency' => $validcurrency,
381
            'roleid' => $validroles,
382
            'enrolperiod' => PARAM_INT,
383
            'enrolstartdate' => PARAM_INT,
384
            'enrolenddate' => PARAM_INT
385
        );
386
 
387
        $typeerrors = $this->validate_param_types($data, $tovalidate);
388
        $errors = array_merge($errors, $typeerrors);
389
 
390
        return $errors;
391
    }
392
 
393
    /**
394
     * Execute synchronisation.
395
     * @param progress_trace $trace
396
     * @return int exit code, 0 means ok
397
     */
398
    public function sync(progress_trace $trace) {
399
        $this->process_expirations($trace);
400
        return 0;
401
    }
402
 
403
    /**
404
     * Is it possible to delete enrol instance via standard UI?
405
     *
406
     * @param stdClass $instance
407
     * @return bool
408
     */
409
    public function can_delete_instance($instance) {
410
        $context = context_course::instance($instance->courseid);
411
        return has_capability('enrol/paypal:config', $context);
412
    }
413
 
414
    /**
415
     * Is it possible to hide/show enrol instance via standard UI?
416
     *
417
     * @param stdClass $instance
418
     * @return bool
419
     */
420
    public function can_hide_show_instance($instance) {
421
        $context = context_course::instance($instance->courseid);
422
        return has_capability('enrol/paypal:config', $context);
423
    }
424
}