Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | 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
declare(strict_types=1);
18
 
19
namespace core_reportbuilder\local\aggregation;
20
 
1441 ariadna 21
use core\lang_string;
1 efrain 22
use core_reportbuilder\local\report\column;
23
 
24
/**
25
 * Base class for column aggregation types
26
 *
27
 * @package     core_reportbuilder
28
 * @copyright   2021 Paul Holden <paulh@moodle.com>
29
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30
 */
31
abstract class base {
32
 
33
    /**
1441 ariadna 34
     * Constructor
35
     *
36
     * @param array $options Aggregation type specific options
37
     */
38
    public function __construct(
39
        /** @var array Aggregation type specific options */
40
        protected readonly array $options = [],
41
    ) {
42
 
43
    }
44
 
45
    /**
1 efrain 46
     * Return the class name of the aggregation type
47
     *
48
     * @return string
49
     */
50
    final public static function get_class_name(): string {
51
        $namespacedclass = explode('\\', get_called_class());
52
 
53
        return end($namespacedclass);
54
    }
55
 
56
    /**
57
     * Return the display name of the aggregation
58
     *
59
     * @return lang_string
60
     */
61
    abstract public static function get_name(): lang_string;
62
 
63
    /**
64
     * Whether the aggregation is compatible with the given column type
65
     *
66
     * @param int $columntype The type as defined by the {@see column::set_type} method
67
     * @return bool
68
     */
69
    abstract public static function compatible(int $columntype): bool;
70
 
71
    /**
72
     * Whether the aggregation is sortable, by default return the sortable status of the column itself
73
     *
74
     * @param bool $columnsortable
75
     * @return bool
76
     */
77
    public static function sortable(bool $columnsortable): bool {
78
        return $columnsortable;
79
    }
80
 
81
    /**
82
     * Return SQL suitable for using within {@see get_field_sql} for column fields, by default just the first one
83
     *
84
     * @param string[] $sqlfields
85
     * @return string
86
     */
87
    public static function get_column_field_sql(array $sqlfields): string {
88
        return reset($sqlfields);
89
    }
90
 
91
    /**
92
     * Helper method for concatenating given fields for a column, so they are suitable for aggregation
93
     *
94
     * @param string[] $sqlfields
95
     * @param string $delimeter
96
     * @param string $coalescechar
97
     * @return string
98
     */
99
    final protected static function get_column_fields_concat(
100
        array $sqlfields,
101
        string $delimeter = ',',
102
        string $coalescechar = ' '
103
    ): string {
104
        global $DB;
105
 
1441 ariadna 106
        // We need to ensure all values are char in supported DBs.
107
        $sqlfieldrequirescast = in_array($DB->get_dbfamily(), ['mssql', 'postgres']);
1 efrain 108
 
109
        $concatfields = [];
110
        foreach ($sqlfields as $sqlfield) {
111
            if ($sqlfieldrequirescast) {
112
                $sqlfield = $DB->sql_cast_to_char($sqlfield);
113
            }
114
 
115
            // Coalesce all the SQL fields. Ensure cross-DB compatibility, and that we always get string data back.
116
            $concatfields[] = "COALESCE({$sqlfield}, '{$coalescechar}')";
117
            $concatfields[] = "'{$delimeter}'";
118
        }
119
 
120
        // Slice off the last delimeter.
121
        return $DB->sql_concat(...array_slice($concatfields, 0, -1));
122
    }
123
 
124
    /**
125
     * Return the aggregated field SQL
126
     *
127
     * @param string $field
128
     * @param int $columntype
129
     * @return string
130
     */
131
    abstract public static function get_field_sql(string $field, int $columntype): string;
132
 
133
    /**
1441 ariadna 134
     * Whether the aggregation method is applied to a column, this method determines whether the report table should
135
     * group by the column fields or not
136
     *
137
     * @return bool
138
     */
139
    public static function column_groupby(): bool {
140
        return false;
141
    }
142
 
143
    /**
144
     * Return aggregated column type, that being one of the column TYPE_* constants like {@see column::get_type}
145
     *
146
     * Classes should override this method to define the type of data that the aggregated column value returns (e.g 'count'
147
     * returns a numeric value, regardless of the original column type to which it is applied)
148
     *
149
     * @param int $columntype The type of the column to which the aggregation is applied
150
     * @return int
151
     */
152
    public static function get_column_type(int $columntype): int {
153
        return column::TYPE_TEXT;
154
    }
155
 
156
    /**
1 efrain 157
     * Return formatted value for column when applying aggregation, by default executing all callbacks on the value
158
     *
159
     * Should be overridden in child classes that need to format the column value differently (e.g. 'sum' would just show
160
     * a numeric count value)
161
     *
162
     * @param mixed $value
163
     * @param array $values
164
     * @param array $callbacks Array of column callbacks, {@see column::add_callback} for definition
165
     * @param int $columntype The original type of the column, to ensure it is preserved for callbacks
166
     * @return mixed
167
     */
1441 ariadna 168
    public function format_value($value, array $values, array $callbacks, int $columntype) {
1 efrain 169
        foreach ($callbacks as $callback) {
170
            [$callable, $arguments] = $callback;
171
            $value = ($callable)($value, (object) $values, $arguments, static::get_class_name());
172
        }
173
 
174
        return $value;
175
    }
176
}