tags.php 9.51 KB
Newer Older
1
<?php
2
require_once(get_config('docroot') . 'lib/form/elements/autocomplete.php');
3
/**
4
 *
5
6
 * @package    mahara
 * @subpackage form-element
7
 * @author     Catalyst IT Ltd
8
9
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
 * @copyright  For copyright information on Mahara, please see the README file distributed with this software.
10
11
12
13
14
15
16
17
18
19
20
 *
 */

/**
 * Provides a tag input field
 *
 * @param Pieform  $form    The form to render the element for
 * @param array    $element The element to render
 * @return string           The HTML for the element
 */
function pieform_element_tags(Pieform $form, $element) {
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
    $newelement = array(
        'type' => 'autocomplete',
        'title' => $element['title'],
        'id' => $element['id'],
        'name' => $element['name'],
        'defaultvalue' => isset($element['defaultvalue']) ? $element['defaultvalue'] : null,
        'description' => isset($element['description']) ? $element['description'] : null,
        'help' => isset($element['help']) ? $element['help'] : false,
        'ajaxurl' => get_config('wwwroot') . 'json/taglist.php',
        'multiple' => true,
        'allowclear' => false,
        'initfunction' => 'translate_tags_to_names',
        'ajaxextraparams' => array(),
        'extraparams' => array('tags' => true),
        'width' => '280px',
36
        'institution' => isset($element['institution']) ? $element['institution'] : null,
37
38
39
    );
    return pieform_element_autocomplete($form, $newelement);
}
40

41
42
43
44
function translate_tags_to_names(array $ids) {
    global $USER;
    // for an empty list, the element '' is transmitted
    $ids = array_diff($ids, array(''));
45
46
47
48
49
    $institutions = $USER->get('institutions');
    if (!empty($institutions)) {
        $institutions = array_keys($institutions);
        // Fetch valid institution tags
        $validinstitutiontags = get_column_sql("SELECT tag FROM {tag}
50
51
52
53
54
55
56
57
                                                WHERE ownertype = 'institution'
                                                ANd resourcetype = 'institution'
                                                AND ownerid IN ('" . join("','", $institutions) . "')");
    }
    else if ($USER->get('admin')) {
        $validinstitutiontags = get_column_sql("SELECT tag FROM {tag}
                                                WHERE ownertype = 'institution'
                                                ANd resourcetype = 'institution'");
58
59
60
61
    }
    else {
        $validinstitutiontags = array();
    }
62

63
64
65
66
67
68
    $ids = array_map(function($a) use ($validinstitutiontags) {
        if (strpos($a, ': ')) {
            if (in_array($a, $validinstitutiontags)) {
                $arr = explode(': ', $a);
                return trim($arr[1]);
            }
69
70
71
72
        }
        return $a;
    }, $ids);

73
74
    $results = array();
    $alltags = get_all_tags_for_user();
75

76
    foreach ($ids as $id) {
77
78
79
80
        // if institution tag, we need to remove the prefix
        $tagname = remove_prefix($id);

        if (isset($alltags['tags'][$tagname])) {
81
            $results[] = (object) array('id' => $tagname, 'text' => display_tag($tagname, $alltags['tags'], true));
82
83
        }
        else {
84
            $results[] = (object) array('id' => $tagname, 'text' => $tagname);
85
        }
86
    }
87
88
    return $results;
}
89

90
91
92
93
/**
 * Display formatted tag
 * Currently is tag name plus the usage count
 *
94
95
96
 * @param string  $name       Tag name
 * @param string  $alltags    Array of tags to get the information from
 * @param boolean $showcount  Whether or not to add the tag count to output
97
98
 * @return $tag Formatted tag
 */
99
function display_tag($name, $alltags, $showcount = false) {
100
101
    if ($alltags[$name]->prefix && !empty($alltags[$name]->prefix)) {
        $prefix = $alltags[$name]->prefix;
102
        $tag = $prefix . ': '. $alltags[$name]->tag;
103
    }
104
105
106
107
108
109
110
    else {
        $tag = $alltags[$name]->tag;
    }
    if ($showcount) {
        $tag .= ' (' . $alltags[$name]->count . ')';
    }
    return $tag;
111
}
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
 * Return a tag name without institution prefix if it has one
 * @param string $tagname  the tag name
 * @return string Institution tag without prefix or same tagname if it not an institution tag
 */
function remove_prefix($tagname) {
    $institutions = get_column_sql('SELECT displayname FROM {institution} WHERE name != ?', array('mahara'));
    foreach ($institutions as $institution) {
        $prefix = $institution . ': ';
        if (substr($tagname, 0, strlen($prefix)) == $prefix) {
            $tagname = substr($tagname, strlen($prefix));
            break;
        }
    }
    return $tagname;
}

130
/**
131
 * Get all tags available for this user
132
133
134
135
 *
 * @param string $query Search option
 * @param int $limit
 * @param int $offset
136
 * @param string $institution name
137
138
 * @retun array $tags  The tags this user has created
 */
139
function get_all_tags_for_user($query = null, $limit = null, $offset = null, $institution = null) {
140
141
142
    global $USER;
    if ($USER->is_logged_in()) {
        $userid = $USER->get('id');
143
        $typecast = is_postgres() ? '::varchar' : '';
144
145
146

        // get all the institution tags the user can use
        $values = array($userid);
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
        if ($USER->get('institutions')) {
            $userinstitutiontags = "
                UNION ALL
                SELECT t.tag, 0 AS count, NULL AS prefix
                FROM {tag} t
                JOIN {institution} i ON i.name = t.ownerid AND t.ownertype = 'institution'
                JOIN {usr_institution} ui ON ui.institution = i.name AND ui.usr = ?
                WHERE t.resourcetype IN ('artefact', 'view', 'collection', 'blocktype') AND tag NOT LIKE ('tagid_%')";
            $values[] = $userid;
        }
        else if ($USER->get('admin')) {
            $userinstitutiontags = "
                UNION ALL
                SELECT t.tag, 0 AS count, NULL AS prefix
                FROM {tag} t
                WHERE t.ownertype = 'institution'
                AND t.resourcetype IN ('artefact', 'view', 'collection', 'blocktype') AND tag NOT LIKE ('tagid_%')";
        }
        else {
            $userinstitutiontags = "
                UNION ALL
                SELECT t.tag, 0 AS count, NULL AS prefix
                FROM {tag} t
                WHERE t.ownertype = 'institution' AND t.ownerid = 'mahara'
                AND t.resourcetype IN ('artefact', 'view', 'collection', 'blocktype') AND tag NOT LIKE ('tagid_%')";
        }
        $values[] = $userid;
174
175
176
177
178
179
        if ($USER->get('admin') && isset($institution)) {
          $values[] = $institution;
          $insttagsforuser = "
              UNION ALL
              SELECT t.tag, 0 AS count, i.displayname AS prefix
              FROM {tag} t
180
              JOIN {institution} i ON i.name = t.ownerid AND i.tags = 1 AND t.resourcetype='institution' AND i.name = ?";
181
182
183
184
185
186
187
188
        }
        else {
          $values[] = $userid;
          $insttagsforuser = "
              UNION ALL
              SELECT t.tag, 0 AS count, i.displayname AS prefix
              FROM {tag} t
              JOIN {institution} i ON i.name = t.ownerid AND i.tags = 1 AND t.resourcetype='institution'
189
              JOIN {usr_institution} ui ON ui.institution = i.name AND ui.usr = ?";
190
191
        }

192
193
        $querystr = '';
        if ($query) {
194
            $querystr = " WHERE tag " . db_ilike() . " '%' || ? || '%'";
195
            $values[] = $query;
196
197
            // Also do matching by institution name so we can list valid institution tags
            // if we only know institution name
198
            $querystr .= " OR prefix " . db_ilike() . " '%' || ? || '%'";
199
            $values[] = $query;
200
        }
201
202

        // get all the tags the logged in user already has
203
        $sql = "
204
            SELECT tag, SUM(count) AS count, prefix
205
            FROM (
206
                -- Selecting tags used in user section that you own
207
208
209
210
211
212
213
                SELECT
                  (CASE
                    WHEN t.tag LIKE 'tagid_%' THEN t2.tag
                   ELSE t.tag
                  END) AS tag, COUNT(*) AS count, i.displayname AS prefix
                FROM {tag} t
                LEFT JOIN {tag} t2 ON t2.id" . $typecast . " = SUBSTRING(t.tag, 7)
214
                LEFT JOIN {institution} i ON i.name = t2.ownerid AND t2.resourcetype = 'institution'
215
                WHERE t.editedby=? AND t.resourcetype IN ('artefact', 'view', 'collection', 'blocktype')
216
                GROUP BY 1, 3
217
218
219
220
221
222
223
224
225
226
                -- Selecting tags used in institution section that you belong to
                " . $userinstitutiontags . "
                -- Selecting tags used in groups that you belong to
                UNION ALL
                SELECT t.tag, 0 AS count, NULL AS prefix
                FROM {tag} t
                JOIN {group} g ON g.id" . $typecast . " = t.ownerid AND t.ownertype='group'
                JOIN {group_member} gm ON gm.group = g.id AND gm.member = ?
                WHERE t.resourcetype IN ('artefact', 'view', 'collection', 'blocktype') AND tag NOT LIKE ('tagid_%')
                -- Selecting the special 'Institution tags' tags that you can see
227
                " . $insttagsforuser . "
228
229
            ) tags
            " . $querystr . "
230
            GROUP BY tag, prefix
231
232
233
            ORDER BY LOWER(tag)
            ";
        $result = get_records_sql_assoc($sql, $values, $offset, $limit);
234
    }
235

236
237
238
239
    $results = !empty($result) ? $result : array();
    $return = array('tags' => $results,
                    'count' => count($results),
    );
240

241
242
    return $return;
}
243

244
245
function pieform_element_tags_get_headdata($element) {
    return pieform_element_autocomplete_get_headdata($element);
246
247
248
}

function pieform_element_tags_get_value(Pieform $form, $element) {
249
    return pieform_element_autocomplete_get_value($form, $element);
250
}