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 * License manager.
19 *
20 * @package    tool_licensemanager
21 * @copyright  2019 Tom Dickman <tomdickman@catalyst-au.net>
22 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace tool_licensemanager;
26
27use tool_licensemanager\form\edit_license;
28use license_manager;
29use stdClass;
30
31defined('MOODLE_INTERNAL') || die();
32
33/**
34 * License manager, main controller for tool_licensemanager.
35 *
36 * @package    tool_licensemanager
37 * @copyright  2019 Tom Dickman <tomdickman@catalyst-au.net>
38 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 */
40class manager {
41
42    /**
43     * Action for creating a new custom license.
44     */
45    const ACTION_CREATE = 'create';
46
47    /**
48     * Action for updating a custom license's details.
49     */
50    const ACTION_UPDATE = 'update';
51
52    /**
53     * Action for deleting a custom license.
54     */
55    const ACTION_DELETE = 'delete';
56
57    /**
58     * Action for disabling a custom license.
59     */
60    const ACTION_DISABLE = 'disable';
61
62    /**
63     * Action for enabling a custom license.
64     */
65    const ACTION_ENABLE = 'enable';
66
67    /**
68     * Action for displaying the license list view.
69     */
70    const ACTION_VIEW_LICENSE_MANAGER = 'viewlicensemanager';
71
72    /**
73     * Action for moving a license up order.
74     */
75    const ACTION_MOVE_UP = 'moveup';
76
77    /**
78     * Action for moving a license down order.
79     */
80    const ACTION_MOVE_DOWN = 'movedown';
81
82    /**
83     * Entry point for internal license manager.
84     *
85     * @param string $action the api action to carry out.
86     * @param string|object $license the license object or shortname of license to carry action out on.
87     */
88    public function execute(string $action, $license) : void {
89
90        admin_externalpage_setup('licensemanager');
91
92        // Convert license to a string if it's a full license object.
93        if (is_object($license)) {
94            $license = $license->shortname;
95        }
96
97        $viewmanager = true;
98
99        switch ($action) {
100            case self::ACTION_DISABLE:
101                license_manager::disable($license);
102                break;
103
104            case self::ACTION_ENABLE:
105                license_manager::enable($license);
106                break;
107
108            case self::ACTION_DELETE:
109                license_manager::delete($license);
110                break;
111
112            case self::ACTION_CREATE:
113            case self::ACTION_UPDATE:
114                $viewmanager = $this->edit($action, $license);
115                break;
116
117            case self::ACTION_MOVE_UP:
118            case self::ACTION_MOVE_DOWN:
119                $this->change_license_order($action, $license);
120                break;
121
122            case self::ACTION_VIEW_LICENSE_MANAGER:
123            default:
124                break;
125        }
126        if ($viewmanager) {
127            $this->view_license_manager();
128        }
129    }
130
131    /**
132     * Edit an existing license or create a new license.
133     *
134     * @param string $action the form action to carry out.
135     * @param string $licenseshortname the shortname of the license to edit.
136     *
137     * @return bool true if license editing complete, false otherwise.
138     */
139    private function edit(string $action, string $licenseshortname) : bool {
140
141        if ($action != self::ACTION_CREATE && $action != self::ACTION_UPDATE) {
142            throw new \coding_exception('license edit actions are limited to create and update');
143        }
144
145        $form = new form\edit_license($action, $licenseshortname);
146
147        if ($form->is_cancelled()) {
148            return true;
149        } else if ($data = $form->get_data()) {
150
151            $license = new stdClass();
152            if ($action == self::ACTION_CREATE) {
153                // Check that license shortname isn't already in use.
154                if (!empty(license_manager::get_license_by_shortname($data->shortname))) {
155                    print_error('duplicatelicenseshortname', 'tool_licensemanager',
156                        helper::get_licensemanager_url(),
157                        $data->shortname);
158                }
159                $license->shortname = $data->shortname;
160            } else {
161                if (empty(license_manager::get_license_by_shortname($licenseshortname))) {
162                    print_error('licensenotfoundshortname', 'license',
163                        helper::get_licensemanager_url(),
164                        $licenseshortname);
165                }
166                $license->shortname = $licenseshortname;
167            }
168            $license->fullname = $data->fullname;
169            $license->source = $data->source;
170            // Legacy date format maintained to prevent breaking on upgrade.
171            $license->version = date('Ymd', $data->version) . '00';
172
173            license_manager::save($license);
174
175            return true;
176        } else {
177            $this->view_license_editor($action, $licenseshortname, $form);
178
179            return false;
180        }
181    }
182
183    /**
184     * Change license order by moving up or down license order.
185     *
186     * @param string $direction which direction to move, up or down.
187     * @param string $licenseshortname the shortname of the license to move up or down order.
188     */
189    private function change_license_order(string $direction, string $licenseshortname) : void {
190
191        if (!empty($licenseshortname)) {
192            if ($direction == self::ACTION_MOVE_UP) {
193                license_manager::change_license_sortorder(license_manager::LICENSE_MOVE_UP, $licenseshortname);
194            } else if ($direction == self::ACTION_MOVE_DOWN) {
195                license_manager::change_license_sortorder(license_manager::LICENSE_MOVE_DOWN, $licenseshortname);
196            }
197        }
198    }
199
200    /**
201     * View the license editor to create or edit a license.
202     *
203     * @param string $action
204     * @param string $licenseshortname the shortname of the license to create/edit.
205     * @param \tool_licensemanager\form\edit_license $form the form for submitting edit data.
206     */
207    private function view_license_editor(string $action, string $licenseshortname, edit_license $form) : void {
208        global $PAGE;
209
210        $renderer = $PAGE->get_renderer('tool_licensemanager');
211
212        if ($action == self::ACTION_UPDATE && $license = license_manager::get_license_by_shortname($licenseshortname)) {
213            $return = $renderer->render_edit_licence_headers($licenseshortname);
214
215            $form->set_data(['shortname' => $license->shortname]);
216            $form->set_data(['fullname' => $license->fullname]);
217            $form->set_data(['source' => $license->source]);
218            $form->set_data(['version' => helper::convert_version_to_epoch($license->version)]);
219
220        } else {
221            $return = $renderer->render_create_licence_headers();
222        }
223        $return .= $form->render();
224        $return .= $renderer->footer();
225
226        echo $return;
227    }
228
229    /**
230     * View the license manager.
231     */
232    private function view_license_manager() : void {
233        global $PAGE;
234
235        $PAGE->requires->js_call_amd('tool_licensemanager/delete_license');
236
237        $renderer = $PAGE->get_renderer('tool_licensemanager');
238        $html = $renderer->header();
239        $html .= $renderer->heading(get_string('licensemanager', 'tool_licensemanager'));
240
241        $table = new \tool_licensemanager\output\table();
242        $html .= $renderer->render($table);
243        $html .= $renderer->footer();
244
245        echo $html;
246    }
247}
248