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 * Class preview
19 *
20 * @package     tool_uploaduser
21 * @copyright   2020 Marina Glancy
22 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace tool_uploaduser;
26
27defined('MOODLE_INTERNAL') || die();
28
29use tool_uploaduser\local\field_value_validators;
30
31require_once($CFG->libdir.'/csvlib.class.php');
32require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/uploaduser/locallib.php');
33
34/**
35 * Display the preview of a CSV file
36 *
37 * @package     tool_uploaduser
38 * @copyright   2020 Marina Glancy
39 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 */
41class preview extends \html_table {
42
43    /** @var \csv_import_reader  */
44    protected $cir;
45    /** @var array */
46    protected $filecolumns;
47    /** @var int */
48    protected $previewrows;
49    /** @var bool */
50    protected $noerror = true; // Keep status of any error.
51
52    /**
53     * preview constructor.
54     *
55     * @param \csv_import_reader $cir
56     * @param array $filecolumns
57     * @param int $previewrows
58     * @throws \coding_exception
59     */
60    public function __construct(\csv_import_reader $cir, array $filecolumns, int $previewrows) {
61        parent::__construct();
62        $this->cir = $cir;
63        $this->filecolumns = $filecolumns;
64        $this->previewrows = $previewrows;
65
66        $this->id = "uupreview";
67        $this->attributes['class'] = 'generaltable';
68        $this->tablealign = 'center';
69        $this->summary = get_string('uploaduserspreview', 'tool_uploaduser');
70        $this->head = array();
71        $this->data = $this->read_data();
72
73        $this->head[] = get_string('uucsvline', 'tool_uploaduser');
74        foreach ($filecolumns as $column) {
75            $this->head[] = $column;
76        }
77        $this->head[] = get_string('status');
78
79    }
80
81    /**
82     * Read data
83     *
84     * @return array
85     * @throws \coding_exception
86     * @throws \dml_exception
87     * @throws \moodle_exception
88     */
89    protected function read_data() {
90        global $DB, $CFG;
91
92        $data = array();
93        $this->cir->init();
94        $linenum = 1; // Column header is first line.
95        while ($linenum <= $this->previewrows and $fields = $this->cir->next()) {
96            $linenum++;
97            $rowcols = array();
98            $rowcols['line'] = $linenum;
99            foreach ($fields as $key => $field) {
100                $rowcols[$this->filecolumns[$key]] = s(trim($field));
101            }
102            $rowcols['status'] = array();
103
104            if (isset($rowcols['username'])) {
105                $stdusername = \core_user::clean_field($rowcols['username'], 'username');
106                if ($rowcols['username'] !== $stdusername) {
107                    $rowcols['status'][] = get_string('invalidusernameupload');
108                }
109                if ($userid = $DB->get_field('user', 'id',
110                        ['username' => $stdusername, 'mnethostid' => $CFG->mnet_localhost_id])) {
111                    $rowcols['username'] = \html_writer::link(
112                        new \moodle_url('/user/profile.php', ['id' => $userid]), $rowcols['username']);
113                }
114            } else {
115                $rowcols['status'][] = get_string('missingusername');
116            }
117
118            if (isset($rowcols['email'])) {
119                if (!validate_email($rowcols['email'])) {
120                    $rowcols['status'][] = get_string('invalidemail');
121                }
122
123                $select = $DB->sql_like('email', ':email', false, true, false, '|');
124                $params = array('email' => $DB->sql_like_escape($rowcols['email'], '|'));
125                if ($DB->record_exists_select('user', $select , $params)) {
126                    $rowcols['status'][] = get_string('useremailduplicate', 'error');
127                }
128            }
129
130            if (isset($rowcols['theme'])) {
131                list($status, $message) = field_value_validators::validate_theme($rowcols['theme']);
132                if ($status !== 'normal' && !empty($message)) {
133                    $rowcols['status'][] = $message;
134                }
135            }
136
137            // Check if rowcols have custom profile field with correct data and update error state.
138            $this->noerror = uu_check_custom_profile_data($rowcols) && $this->noerror;
139            $rowcols['status'] = implode('<br />', $rowcols['status']);
140            $data[] = $rowcols;
141        }
142        if ($fields = $this->cir->next()) {
143            $data[] = array_fill(0, count($fields) + 2, '...');
144        }
145        $this->cir->close();
146
147        return $data;
148    }
149
150    /**
151     * Getter for noerror
152     *
153     * @return bool
154     */
155    public function get_no_error() {
156        return $this->noerror;
157    }
158}