profileicons.php 12.9 KB
Newer Older
1 2 3 4 5
<?php
/**
 *
 * @package    mahara
 * @subpackage core
6
 * @author     Catalyst IT Ltd
7 8
 * @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.
9 10 11 12
 *
 */

define('INTERNAL', 1);
13
define('MENUITEM', 'content/profileicons');
14
define('SECTION_PLUGINTYPE', 'artefact');
15
define('SECTION_PLUGINNAME', 'file');
16
define('SECTION_PAGE', 'profileicons');
17

18
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
19
define('TITLE', get_string('profileicons', 'artefact.file'));
20 21 22 23 24 25 26 27 28

$settingsform = new Pieform(array(
    'name'      => 'settings',
    'renderer'  => 'oneline',
    'autofocus' => false,
    'presubmitcallback' => '',
    'elements' => array(
        'default' => array(
            'type'  => 'submit',
29
            'value' => get_string('Default', 'artefact.file'),
30 31
        ),
        'delete' => array(
32
            'type'  => 'submit',
33
            'value' => get_string('Delete', 'artefact.file'),
34
        ),
35 36 37 38 39
    )
));

$uploadform = pieform(array(
    'name'   => 'upload',
40
    'class'  => 'form-upload',
41 42 43
    'jsform' => true,
    'presubmitcallback'  => 'preSubmit',
    'postsubmitcallback' => 'postSubmit',
44
    'plugintype' => 'artefact',
45
    'pluginname' => 'file',
46 47 48
    'elements' => array(
        'file' => array(
            'type' => 'file',
49
            'title' => get_string('profileicon', 'artefact.file'),
50 51
            'rules' => array('required' => true),
            'maxfilesize'  => get_max_upload_size(false),
52 53 54
        ),
        'title' => array(
            'type' => 'text',
55
            'title' => get_string('imagetitle', 'artefact.file'),
56 57 58
        ),
        'submit' => array(
            'type' => 'submit',
59
            'class' => 'btn-primary',
60 61 62 63 64
            'value' => get_string('upload')
        )
    )
));

65 66
$strnoimagesfound = json_encode(get_string('noimagesfound', 'artefact.file'));
$struploadingfile = json_encode(get_string('uploadingfile', 'artefact.file'));
67
$wwwroot = get_config('wwwroot');
68
$notfound = $THEME->get_image_url('no_userphoto');
69 70 71 72 73 74
if (!get_config('remoteavatars')) {
    $ravatar = $notfound;
}
else {
    $ravatar = remote_avatar($USER->get('email'), array('maxw' => '100', 'maxh' => '100'), $notfound);
}
75 76
$profileiconattachedtoportfolioitems = json_encode(get_string('profileiconattachedtoportfolioitems', 'artefact.file'));
$profileiconappearsinviews = json_encode(get_string('profileiconappearsinviews', 'artefact.file'));
77
$profileiconappearsinskins = json_encode(get_string('profileiconappearsinskins', 'artefact.file'));
78
$confirmdeletefile = json_encode(get_string('confirmdeletefile', 'artefact.file'));
79 80
$setdefault = json_encode(get_string('setdefault', 'artefact.file'));
$markfordeletion = json_encode(get_string('markfordeletion', 'artefact.file'));
81
$IJS = <<<EOF
82 83 84 85
formchangemanager.add('settings');

var profileiconschecker = formchangemanager.find('settings');

86 87 88 89 90
var table = new TableRenderer(
    'profileicons',
    'profileicons.json.php',
    [
        function(rowdata) {
91
            if (rowdata.id) {
92
                return TD({'class': 'profileiconcell'}, null, IMG({'src': '{$wwwroot}thumb.php?type=profileiconbyid&maxsize=100&id=' + rowdata.id, 'alt': rowdata.title ? rowdata.title : rowdata.note}));
93 94
            }
            else {
95
                return TD({'class': 'profileiconcell'}, null, IMG({'src': '{$ravatar}', 'alt': rowdata.title ? rowdata.title : rowdata.note}));
96
            }
97 98 99 100 101 102
        },
        function(rowdata) {
            return TD(null, rowdata.title ? rowdata.title : rowdata.note);
        },
        function(rowdata) {
            var options = {
103
                'id': 'setdefault_' + rowdata.id,
104 105 106 107
                'type': 'radio',
                'name': 'd',
                'value': rowdata.id
            };
Penny Leach's avatar
Penny Leach committed
108
            if (rowdata['isdefault'] == 't' || rowdata['isdefault'] == 1) {
109 110
                options.checked = 'checked';
            }
Pat Kira's avatar
Pat Kira committed
111
            var label = LABEL({'class': 'accessible-hidden sr-only', 'for': 'setdefault_' + rowdata.id}, {$setdefault});
112
            return TD({'class': 'defaultcell'}, INPUT(options), label);
113 114
        },
        function(rowdata) {
115 116 117 118 119
            var options = {
                'id'      : 'markdelete_' + rowdata.id,
                'type'    : 'checkbox',
                'class'   : 'checkbox',
                'name'    : 'icons[' + rowdata.id + ']',
120
                'value'   : rowdata.attachcount + ',' + rowdata.viewcount + ',' + rowdata.skincount
121 122 123
            };
            if (!rowdata.id) {
                options.disabled = 'disabled';
124
            }
Pat Kira's avatar
Pat Kira committed
125
            var label = LABEL({'class': 'accessible-hidden sr-only', 'for': 'markdelete_' + rowdata.id}, {$markfordeletion});
126
            return TD({'class': 'deletecell'}, INPUT(options), label);
127 128 129 130 131 132
        }
    ]
);
table.updateOnLoad();
table.emptycontent = {$strnoimagesfound};
table.paginate = false;
133 134 135 136 137 138 139 140 141 142 143 144
table.updatecallback = function(response) {
    var defaultIcon = filter(function (i) { return i.isdefault == 't'; }, response.data);

    if (defaultIcon.length) {
        defaultIcon = defaultIcon[0].id;
        forEach(getElementsByTagAndClassName('img', null, 'column-right'), function(i) {
            if (i.src.match(/thumb\.php\?type=profileiconbyid/)) {
                i.src = i.src.replace(/id=[0-9]+/, 'id=' + String(defaultIcon));
            }
        });
    }
};
145

146 147 148 149
table.postupdatecallback = function(response) {
    profileiconschecker.init();
};

150
var uploadingMessage = TR(null,
151
    TD(null, {$struploadingfile})
152 153 154 155 156 157 158 159
);

function preSubmit(form, data) {
    formStartProcessing(form, data);
    insertSiblingNodesAfter($('upload_submit_container'), uploadingMessage);
}

function postSubmit(form, data) {
Naomi Guyer's avatar
Naomi Guyer committed
160
    // removeElement(uploadingMessage);
161 162 163
    table.doupdate();
    formStopProcessing(form, data);
    quotaUpdate();
164 165
    $(form).reset();
    $('upload_title').value = '';
166 167
}

168 169
addLoadEvent( function() {
    connect('settings_delete', 'onclick', function(e) {
170 171
        profileiconschecker.set(FORM_SUBMITTED);

172
        // Find form
173
        var form = getFirstParentByTagAndClassName(this, 'form', 'pieform');
174 175 176
        forEach (getElementsByTagAndClassName('input', 'checkbox', form), function (profileicon) {
            var id = getNodeAttribute(profileicon, 'name').match(/\d+/)[0];
            if (profileicon.checked == true) {
177
                var counts = profileicon.value.split(',', 3);
178 179 180 181 182 183 184
                var warn = '';
                if (counts[0] > 0) {
                    warn += {$profileiconattachedtoportfolioitems} + ' ';
                }
                if (counts[1] > 0) {
                    warn += {$profileiconappearsinviews} + ' ';
                }
185 186 187
                if (counts[2] > 0) {
                    warn += {$profileiconappearsinskins} + ' ';
                }
188 189 190 191 192 193 194 195 196 197 198 199
                if (warn != '') {
                    warn += {$confirmdeletefile};
                    if (!confirm(warn)) {
                        e.stop();
                        return false;
                    }
                }
            }
        });
    });
});

200
EOF;
201

202
$filesize = 0;
203
function upload_validate(Pieform $form, $values) {
204
    global $USER, $filesize;
205
    require_once('file.php');
206 207 208 209 210 211 212 213
    require_once('uploadmanager.php');

    $um = new upload_manager('file');
    if ($error = $um->preprocess_file()) {
        $form->set_error('file', $error);
        return false;
    }

214 215
    $imageinfo = getimagesize($values['file']['tmp_name']);
    if (!$imageinfo || !is_image_type($imageinfo[2])) {
216
        $form->set_error('file', get_string('filenotimage'));
217
        return false;
218 219
    }

220
    if (get_field('artefact', 'COUNT(*)', 'artefacttype', 'profileicon', 'owner', $USER->id) >= 5) {
221
        $form->set_error('file', get_string('onlyfiveprofileicons', 'artefact.file'));
222
        return false;
223
    }
224

225
    $filesize = $um->file['size'];
226
    if (!$USER->quota_allowed($filesize)) {
227
        $form->set_error('file', get_string('profileiconuploadexceedsquota', 'artefact.file', get_config('wwwroot')));
228
        return false;
229 230
    }

231
    // Check the file isn't greater than the max allowable size
232 233
    $width          = $imageinfo[0];
    $height         = $imageinfo[1];
234 235 236
    $imagemaxwidth  = get_config('imagemaxwidth');
    $imagemaxheight = get_config('imagemaxheight');
    if ($width > $imagemaxwidth || $height > $imagemaxheight) {
237
        $form->set_error('file', get_string('profileiconimagetoobig', 'artefact.file', $width, $height, $imagemaxwidth, $imagemaxheight));
238
    }
239 240 241
}

function upload_submit(Pieform $form, $values) {
242
    global $USER, $filesize;
243
    safe_require('artefact', 'file');
244

245 246 247 248 249
    try {
        $USER->quota_add($filesize);
    }
    catch (QuotaException $qe) {
        $form->json_reply(PIEFORM_ERR, array(
250
            'message' => get_string('profileiconuploadexceedsquota', 'artefact.file', get_config('wwwroot'))
251 252 253
        ));
    }

254
    // Entry in artefact table
255 256 257 258 259 260 261
    $data = new stdClass;
    $data->owner = $USER->id;
    $data->parent = ArtefactTypeFolder::get_folder_id(get_string('imagesdir', 'artefact.file'), get_string('imagesdirdesc', 'artefact.file'), null, true, $USER->id);
    $data->title = $values['title'] ? $values['title'] : $values['file']['name'];
    $data->title = ArtefactTypeFileBase::get_new_file_title($data->title, (int)$data->parent, $USER->id);  // unique title
    $data->note = $values['file']['name'];
    $data->size = $filesize;
262 263 264 265
    $imageinfo = getimagesize($values['file']['tmp_name']);
    $data->width    = $imageinfo[0];
    $data->height   = $imageinfo[1];
    $data->filetype = $imageinfo['mime'];
266 267
    $data->description = get_string('uploadedprofileicon', 'artefact.file');

268
    $artefact = new ArtefactTypeProfileIcon(0, $data);
269 270 271
    if (preg_match("/\.([^\.]+)$/", $values['file']['name'], $saved)) {
        $artefact->set('oldextension', $saved[1]);
    }
272 273 274 275 276
    $artefact->commit();

    $id = $artefact->get('id');

    // Move the file into the correct place.
277
    $directory = get_config('dataroot') . 'artefact/file/profileicons/originals/' . ($id % 256) . '/';
278 279 280
    check_dir_exists($directory);
    move_uploaded_file($values['file']['tmp_name'], $directory . $id);

281 282
    $USER->commit();

283
    $form->json_reply(PIEFORM_OK, get_string('profileiconaddedtoimagesfolder', 'artefact.file', get_string('imagesdir', 'artefact.file')));
284 285 286 287 288 289 290
}

function settings_submit_default(Pieform $form, $values) {
    global $USER, $SESSION;

    $default = param_integer('d');

291 292 293 294
    if ($default) {
        if (1 != get_field('artefact', 'COUNT(*)', 'id', $default, 'artefacttype', 'profileicon', 'owner', $USER->id)) {
            throw new UserException(get_string('profileiconsetdefaultnotvalid', 'artefact.file'));
        }
295

296 297 298 299 300
        $USER->profileicon = $default;
    }
    else {
        $USER->profileicon = null;
    }
301 302 303 304
    $USER->commit();

    $SESSION->add_ok_msg(get_string('profileiconsdefaultsetsuccessfully', 'artefact.file'));
    redirect('/artefact/file/profileicons.php');
305 306 307 308 309 310 311 312 313 314
}

function settings_submit_delete(Pieform $form, $values) {
    require_once('file.php');
    global $USER, $SESSION;

    $icons = param_variable('icons', array());
    $icons = array_keys($icons);

    if ($icons) {
315
        db_begin();
316 317 318 319
        foreach ($icons as $icon) {
            $iconartefact = artefact_instance_from_id($icon);
            // Just to be sure
            if ($iconartefact->get('artefacttype') == 'profileicon' && $iconartefact->get('owner') == $USER->get('id')) {
320 321 322
                // Remove the skin background and update the skin thumbs
                require_once(get_config('libroot') . 'skin.php');
                Skin::remove_background($iconartefact->get('id'));
323 324 325 326 327 328
                $iconartefact->delete();
            }
            else {
                throw new AccessDeniedException();
            }
        }
329

330
        if (in_array($USER->get('profileicon'), $icons)) {
331
            $USER->profileicon = null;
332
            $USER->commit();
333 334 335 336
        }

        db_commit();

337 338 339
        $SESSION->add_ok_msg(
            get_string('filethingdeleted', 'artefact.file', get_string('nprofilepictures', 'artefact.file', count($icons)))
        );
340 341
    }
    else {
342
        $SESSION->add_info_msg(get_string('profileiconsnoneselected', 'artefact.file'));
343 344
    }

345
    redirect('/artefact/file/profileicons.php');
346 347
}

348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
$smarty = smarty(
    array('tablerenderer'),
    array(),
    array(),
    array(
        'sideblocks' => array(
            array(
                'name'   => 'quota',
                'weight' => -10,
                'data'   => array(),
            ),
        ),
    )
);
$smarty->assign('INLINEJAVASCRIPT', $IJS);
363 364 365 366 367
$smarty->assign('uploadform', $uploadform);
// This is a rare case where we don't actually care about the form, because
// it only contains submit buttons (which we can just write as HTML), and
// the buttons need to be inside the tablerenderer.
$smarty->assign('settingsformtag', $settingsform->get_form_tag());
368
$smarty->assign('imagemaxdimensions', array(get_config('imagemaxwidth'), get_config('imagemaxheight')));
369
$smarty->assign('PAGEHEADING', TITLE);
370
$smarty->display('artefact:file:profileicons.tpl');