Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 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
namespace core_table;
18
 
19
use flexible_table;
20
use moodle_recordset;
21
use stdClass;
22
 
23
defined('MOODLE_INTERNAL') || die();
24
 
25
global $CFG;
26
 
27
require_once("{$CFG->libdir}/tablelib.php");
28
 
29
/**
30
 * A table whose data is provided by SQL queries.
31
 *
32
 * @package   core_table
33
 * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
34
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
35
 */
36
class sql_table extends flexible_table {
37
    /** @var string The SQL query to count records */
38
    public $countsql = null;
39
 
40
    /** @var array The parameters for the Count SQL */
41
    public $countparams = null;
42
 
43
    /** @var object sql for querying db. Has fields 'fields', 'from', 'where', 'params' */
44
    public $sql = null;
45
 
46
    /** @var array|\Traversable Data fetched from the db */
47
    public $rawdata = null;
48
 
49
    /** @var bool Overriding default for this */
50
 
51
    public $is_sortable = true; // phpcs:ignore moodle.NamingConventions.ValidVariableName.MemberNameUnderscore
52
 
53
    /** @var bool Overriding default for this */
54
    public $is_collapsible = true; // phpcs:ignore moodle.NamingConventions.ValidVariableName.MemberNameUnderscore
55
 
56
    /**
57
     * Create a new instance of the sql_table.
58
     *
59
     * @param string $uniqueid a string identifying this table.Used as a key in
60
     *                          session  vars.
61
     */
62
    public function __construct($uniqueid) {
63
        parent::__construct($uniqueid);
64
        // Set some sensible defaults.
65
        $this->set_attribute('class', 'generaltable generalbox');
66
    }
67
 
68
    /**
69
     * Build the table from the fetched data.
70
     *
71
     * Take the data returned from the db_query and go through all the rows
72
     * processing each col using either col_{columnname} method or other_cols
73
     * method or if other_cols returns NULL then put the data straight into the
74
     * table.
75
     *
76
     * After calling this function, don't forget to call close_recordset.
77
     */
78
    public function build_table() {
79
        if (!$this->rawdata) {
80
            return;
81
        }
82
 
83
        foreach ($this->rawdata as $row) {
84
            $formattedrow = $this->format_row($row);
85
            $this->add_data_keyed($formattedrow, $this->get_row_class($row));
86
        }
87
    }
88
 
89
    /**
90
     * Closes recordset (for use after building the table).
91
     */
92
    public function close_recordset() {
93
        if (
94
            $this->rawdata && ($this->rawdata instanceof \core\dml\recordset_walk ||
95
                $this->rawdata instanceof moodle_recordset)
96
        ) {
97
            $this->rawdata->close();
98
            $this->rawdata = null;
99
        }
100
    }
101
 
102
    /**
103
     * Get any extra classes names to add to this row in the HTML.
104
     *
105
     * @param array $row the data for this row.
106
     * @return string added to the class="" attribute of the tr.
107
     */
108
    public function get_row_class($row) {
109
        return '';
110
    }
111
 
112
    /**
113
     * Set the SQL used to count records.
114
     *
115
     * This is only needed if you want to use different sql to count rows.
116
     * Used for example when perhaps all db JOINS are not needed when counting
117
     * records. You don't need to call this function the count_sql
118
     * will be generated automatically.
119
     *
120
     * We need to count rows returned by the db seperately to the query itself
121
     * as we need to know how many pages of data we have to display.
122
     *
123
     * @param string $sql
124
     * @param null|array $params
125
     */
126
    public function set_count_sql($sql, ?array $params = null) {
127
        $this->countsql = $sql;
128
        $this->countparams = $params;
129
    }
130
 
131
    /**
132
     * Set the sql to query the db. Query will be :
133
     *      SELECT $fields FROM $from WHERE $where
134
     * Of course you can use sub-queries, JOINS etc. by putting them in the
135
     * appropriate clause of the query.
136
     *
137
     * @param string $fields
138
     * @param string $from
139
     * @param string $where
140
     * @param array $params
141
     */
142
    public function set_sql($fields, $from, $where, array $params = []) {
143
        $this->sql = new stdClass();
144
        $this->sql->fields = $fields;
145
        $this->sql->from = $from;
146
        $this->sql->where = $where;
147
        $this->sql->params = $params;
148
    }
149
 
150
    /**
151
     * Query the db. Store results in the table object for use by build_table.
152
     *
153
     * @param int $pagesize size of page for paginated displayed table.
154
     * @param bool $useinitialsbar do you want to use the initials bar. Bar
155
     * will only be used if there is a fullname column defined for the table.
156
     */
157
    public function query_db($pagesize, $useinitialsbar = true) {
158
        global $DB;
159
        if (!$this->is_downloading()) {
160
            if ($this->countsql === null) {
161
                $this->countsql = 'SELECT COUNT(1) FROM ' . $this->sql->from . ' WHERE ' . $this->sql->where;
162
                $this->countparams = $this->sql->params;
163
            }
164
            $grandtotal = $DB->count_records_sql($this->countsql, $this->countparams);
165
            if ($useinitialsbar && !$this->is_downloading()) {
166
                $this->initialbars(true);
167
            }
168
 
169
            [$wsql, $wparams] = $this->get_sql_where();
170
            if ($wsql) {
171
                $this->countsql .= ' AND ' . $wsql;
172
                $this->countparams = array_merge($this->countparams, $wparams);
173
 
174
                $this->sql->where .= ' AND ' . $wsql;
175
                $this->sql->params = array_merge($this->sql->params, $wparams);
176
 
177
                $total  = $DB->count_records_sql($this->countsql, $this->countparams);
178
            } else {
179
                $total = $grandtotal;
180
            }
181
 
182
            $this->pagesize($pagesize, $total);
183
        }
184
 
185
        // Fetch the attempts.
186
        $sort = $this->get_sql_sort();
187
        if ($sort) {
188
            $sort = "ORDER BY $sort";
189
        }
190
        $sql = "SELECT
191
                {$this->sql->fields}
192
                FROM {$this->sql->from}
193
                WHERE {$this->sql->where}
194
                {$sort}";
195
 
196
        if (!$this->is_downloading()) {
197
            $this->rawdata = $DB->get_records_sql($sql, $this->sql->params, $this->get_page_start(), $this->get_page_size());
198
        } else {
199
            $this->rawdata = $DB->get_records_sql($sql, $this->sql->params);
200
        }
201
    }
202
 
203
    /**
204
     * Convenience method to call a number of methods for you to display the
205
     * table.
206
     *
207
     * @param int $pagesize
208
     * @param bool $useinitialsbar
209
     * @param string $downloadhelpbutton
210
     */
211
    public function out($pagesize, $useinitialsbar, $downloadhelpbutton = '') {
212
        global $DB;
213
        if (!$this->columns) {
214
            $onerow = $DB->get_record_sql(
215
                "SELECT {$this->sql->fields} FROM {$this->sql->from} WHERE {$this->sql->where}",
216
                $this->sql->params,
217
                IGNORE_MULTIPLE
218
            );
219
            // If columns is not set then define columns as the keys of the rows returned
220
            // from the db.
221
            $this->define_columns(array_keys((array)$onerow));
222
            $this->define_headers(array_keys((array)$onerow));
223
        }
224
        $this->pagesize = $pagesize;
225
        $this->setup();
226
        $this->query_db($pagesize, $useinitialsbar);
227
        $this->build_table();
228
        $this->close_recordset();
229
        $this->finish_output();
230
    }
231
}
232
 
233
// Alias this class to the old name.
234
// This file will be autoloaded by the legacyclasses autoload system.
235
// In future all uses of this class will be corrected and the legacy references will be removed.
236
class_alias(sql_table::class, \table_sql::class);