public static function save_config_options($form, $values) { global $USER; $updatingquota = false; $oldquotalimit = get_config_plugin('artefact', 'file', 'quotanotifylimit'); if ($values['updateuserquotas'] && $values['defaultquota']) { set_field('usr', 'quota', $values['defaultquota'], 'deleted', 0); $updatingquota = true; } if ($values['updategroupquotas'] && $values['defaultgroupquota']) { set_field('group', 'quota', $values['defaultgroupquota'], 'deleted', 0); // We need to alert group admins that the group may now be over the threshold that wasn't before $sqlwhere = " ((g.quotaused / g.quota) * 100) "; if (is_postgres()) { $sqlwhere = " ((CAST(g.quotaused AS float) / CAST(g.quota AS float)) * 100) "; } if ($groups = get_records_sql_assoc("SELECT g.id, g.name, g.quota, " . $sqlwhere . " AS quotausedpercent FROM {group} g WHERE " . $sqlwhere . " >= ?", array($values['quotanotifylimit']))) { ArtefactTypeFile::notify_groups_threshold_exceeded($groups); } } set_config_plugin('artefact', 'file', 'defaultquota', $values['defaultquota']); set_config_plugin('artefact', 'file', 'defaultgroupquota', $values['defaultgroupquota']); set_config_plugin('artefact', 'file', 'institutionaloverride', $values['institutionaloverride']); set_config_plugin('artefact', 'file', 'maxquota', $values['maxquota']); set_config_plugin('artefact', 'file', 'maxquotaenabled', $values['maxquotaenabled']); set_config_plugin('artefact', 'file', 'profileiconwidth', $values['profileiconwidth']); set_config_plugin('artefact', 'file', 'profileiconheight', $values['profileiconheight']); set_config_plugin('artefact', 'file', 'uploadagreement', $values['uploadagreement']); set_config_plugin('artefact', 'file', 'usecustomagreement', $values['usecustomagreement']); set_config_plugin('artefact', 'file', 'resizeonuploadenable', $values['resizeonuploadenable']); set_config_plugin('artefact', 'file', 'resizeonuploaduseroption', $values['resizeonuploaduseroption']); set_config_plugin('artefact', 'file', 'resizeonuploadmaxwidth', $values['resizeonuploadmaxwidth']); set_config_plugin('artefact', 'file', 'resizeonuploadmaxheight', $values['resizeonuploadmaxheight']); set_config_plugin('artefact', 'file', 'folderdownloadkeepzipfor', $values['folderdownloadkeepzipfor']); set_config_plugin('artefact', 'file', 'quotanotifylimit', $values['quotanotifylimit']); set_config_plugin('artefact', 'file', 'quotanotifyadmin', $values['quotanotifyadmin']); if ($oldquotalimit != $values['quotanotifylimit'] || $updatingquota) { // We need to alert anyone that may now be over the threshold that wasn't before $sqlwhere = " ((u.quotaused / u.quota) * 100) "; if (is_postgres()) { $sqlwhere = " ((CAST(u.quotaused AS float) / CAST(u.quota AS float)) * 100) "; } if ($users = get_records_sql_assoc("SELECT u.id, u.quota, " . $sqlwhere . " AS quotausedpercent FROM {usr} u WHERE " . $sqlwhere . " >= ?", array($values['quotanotifylimit']))) { $notifyadmin = get_config_plugin('artefact', 'file', 'quotanotifyadmin'); ArtefactTypeFile::notify_users_threshold_exceeded($users, $notifyadmin); } else { if ($users = get_records_sql_assoc("SELECT * FROM {usr} u, {usr_account_preference} uap WHERE " . $sqlwhere . " < ? AND uap.usr = u.id AND uap.field = ? AND uap.value = ?", array($values['quotanotifylimit'], 'quota_exceeded_notified', '1'))) { foreach ($users as $user) { set_account_preference($user->id, 'quota_exceeded_notified', false); } } } } $data = new StdClass(); $data->name = 'uploadcopyright'; $data->content = $values['customagreement']; $data->mtime = db_format_timestamp(time()); $data->mauthor = $USER->get('id'); $data->institution = 'mahara'; if (record_exists('site_content', 'name', $data->name, 'institution', $data->institution)) { update_record('site_content', $data, array('name', 'institution')); } else { $data->ctime = db_format_timestamp(time()); insert_record('site_content', $data); } foreach (PluginArtefactFile::get_artefact_types() as $at) { set_config_plugin('artefact', 'file', 'commentsallowed' . $at, (int) in_array($at, $values['commentdefault'])); } }
function edituser_site_submit(Pieform $form, $values) { global $USER, $authobj, $SESSION; if (!($user = get_record('usr', 'id', $values['id']))) { return false; } if (is_using_probation()) { // Value should be between 0 and 10 inclusive $user->probation = ensure_valid_probation_points($values['probationpoints']); } if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { $user->quota = $values['quota']; // check if the user has gone over the quota notify limit $quotanotifylimit = get_config_plugin('artefact', 'file', 'quotanotifylimit'); if ($quotanotifylimit <= 0 || $quotanotifylimit >= 100) { $quotanotifylimit = 100; } $user->quotausedpercent = $user->quotaused / $user->quota * 100; $overlimit = false; if ($quotanotifylimit <= $user->quotausedpercent) { $overlimit = true; } $notified = get_field('usr_account_preference', 'value', 'field', 'quota_exceeded_notified', 'usr', $user->id); if ($overlimit && '1' !== $notified) { require_once get_config('docroot') . 'artefact/file/lib.php'; ArtefactTypeFile::notify_users_threshold_exceeded(array($user), false); // no need to email admin as we can alert them right now $SESSION->add_error_msg(get_string('useroverquotathreshold', 'artefact.file', display_name($user))); } else { if ($notified && !$overlimit) { set_account_preference($user->id, 'quota_exceeded_notified', false); } } } $unexpire = $user->expiry && strtotime($user->expiry) < time() && (empty($values['expiry']) || $values['expiry'] > time()); $newexpiry = db_format_timestamp($values['expiry']); if ($user->expiry != $newexpiry) { $user->expiry = $newexpiry; if ($unexpire) { $user->expirymailsent = 0; $user->lastaccess = db_format_timestamp(time()); } } // Try to kick the user from any active login sessions, before saving data. require_once get_config('docroot') . 'auth/session.php'; remove_user_sessions($user->id); if ($USER->get('admin')) { // Not editable by institutional admins $user->staff = (int) ($values['staff'] == 'on'); $user->admin = (int) ($values['admin'] == 'on'); if ($user->admin) { activity_add_admin_defaults(array($user->id)); } } if ($values['maildisabled'] == 0 && get_account_preference($user->id, 'maildisabled') == 1) { // Reset the sent and bounce counts otherwise mail will be disabled // on the next send attempt $u = new StdClass(); $u->email = $user->email; $u->id = $user->id; update_bounce_count($u, true); update_send_count($u, true); } set_account_preference($user->id, 'maildisabled', $values['maildisabled']); // process the change of the authinstance and or the remoteuser if (isset($values['authinstance']) && isset($values['remoteusername'])) { // Authinstance can be changed by institutional admins if both the // old and new authinstances belong to the admin's institutions $authinst = get_records_select_assoc('auth_instance', 'id = ? OR id = ?', array($values['authinstance'], $user->authinstance)); // But don't bother if the auth instance doesn't take a remote username $authobj = AuthFactory::create($values['authinstance']); if ($USER->get('admin') || $USER->is_institutional_admin($authinst[$values['authinstance']]->institution) && ($USER->is_institutional_admin($authinst[$user->authinstance]->institution) || $user->authinstance == 1)) { if ($authobj->needs_remote_username()) { // determine the current remoteuser $current_remotename = get_field('auth_remote_user', 'remoteusername', 'authinstance', $user->authinstance, 'localusr', $user->id); if (!$current_remotename) { $current_remotename = $user->username; } // if the remoteuser is empty if (strlen(trim($values['remoteusername'])) == 0) { delete_records('auth_remote_user', 'authinstance', $user->authinstance, 'localusr', $user->id); } // what should the new remoteuser be $new_remoteuser = get_field('auth_remote_user', 'remoteusername', 'authinstance', $values['authinstance'], 'localusr', $user->id); // save the remotename for the target existence check $target_remotename = $new_remoteuser; if (!$new_remoteuser) { $new_remoteuser = $user->username; } if (strlen(trim($values['remoteusername'])) > 0) { // value changed on page - use it if ($values['remoteusername'] != $current_remotename) { $new_remoteuser = $values['remoteusername']; } } // only update remote name if the input actually changed on the page or it doesn't yet exist if ($current_remotename != $new_remoteuser || !$target_remotename) { // only remove the ones related to this traget authinstance as we now allow multiple // for dual login mechanisms delete_records('auth_remote_user', 'authinstance', $values['authinstance'], 'localusr', $user->id); insert_record('auth_remote_user', (object) array('authinstance' => $values['authinstance'], 'remoteusername' => $new_remoteuser, 'localusr' => $user->id)); } } // update the ai on the user master $user->authinstance = $values['authinstance']; // update the global $authobj to match the new authinstance // this is used by the password/username change methods // if either/both has been requested at the same time $authobj = AuthFactory::create($user->authinstance); } } // Only change the pw if the new auth instance allows for it if (method_exists($authobj, 'change_password')) { $user->passwordchange = (int) (isset($values['passwordchange']) && $values['passwordchange'] == 'on' ? 1 : 0); if (isset($values['password']) && $values['password'] !== '') { $userobj = new User(); $userobj = $userobj->find_by_id($user->id); $user->password = $authobj->change_password($userobj, $values['password']); $user->salt = $userobj->salt; unset($userobj); } } else { // inform the user that the chosen auth instance doesn't allow password changes // but only if they tried changing it if (isset($values['password']) && $values['password'] !== '') { $SESSION->add_error_msg(get_string('passwordchangenotallowed', 'admin')); // Set empty pw with salt $user->password = ''; $user->salt = auth_get_random_salt(); } } if (isset($values['username']) && $values['username'] !== '') { $userobj = new User(); $userobj = $userobj->find_by_id($user->id); if ($userobj->username != $values['username']) { // Only change the username if the auth instance allows for it if (method_exists($authobj, 'change_username')) { // check the existence of the chosen username try { if ($authobj->user_exists($values['username'])) { // set an error message if it is already in use $SESSION->add_error_msg(get_string('usernameexists', 'account')); } } catch (AuthUnknownUserException $e) { // update the username otherwise $user->username = $authobj->change_username($userobj, $values['username']); } } else { // inform the user that the chosen auth instance doesn't allow username changes $SESSION->add_error_msg(get_string('usernamechangenotallowed', 'admin')); } } unset($userobj); } // OVERWRITE 4: insert if (isset($values['email']) && !empty($values['email']) && $values['email'] != $user->email) { global $CFG; $user->email = $values['email']; $mhr_user = $CFG->current_app->getUserById($user->id); $mhr_user->setEmailAddress($values['email']); } // END OVERWRITE 4 db_begin(); update_record('usr', $user); delete_records('usr_tag', 'usr', $user->id); if (is_array($values['tags'])) { $values['tags'] = check_case_sensitive($values['tags'], 'usr_tag'); foreach (array_unique($values['tags']) as $tag) { if (empty($tag)) { continue; } insert_record('usr_tag', (object) array('usr' => $user->id, 'tag' => strtolower($tag))); } } db_commit(); $SESSION->add_ok_msg(get_string('usersitesettingschanged', 'admin')); redirect('/admin/users/edit.php?id=' . $user->id); }
function institution_submit(Pieform $form, $values) { global $SESSION, $institution, $add, $instancearray, $USER, $authinstances, $customthemedefaults; db_begin(); // Update the basic institution record... if ($add) { $newinstitution = new Institution(); $newinstitution->initialise($values['name'], $values['displayname']); $institution = $newinstitution->name; } else { $newinstitution = new Institution($institution); $newinstitution->displayname = $values['displayname']; $oldinstitution = get_record('institution', 'name', $institution); // Clear out any cached menus for this institution clear_menu_cache($institution); } $newinstitution->showonlineusers = !isset($values['showonlineusers']) ? 2 : $values['showonlineusers']; if (get_config('usersuniquebyusername')) { // Registering absolutely not allowed when this setting is on, it's a // security risk. See the documentation for the usersuniquebyusername // setting for more information $newinstitution->registerallowed = 0; } else { $newinstitution->registerallowed = $values['registerallowed'] ? 1 : 0; $newinstitution->registerconfirm = $values['registerconfirm'] ? 1 : 0; } if (!empty($values['lang'])) { if ($values['lang'] == 'sitedefault') { $newinstitution->lang = null; } else { $newinstitution->lang = $values['lang']; } } $newinstitution->theme = empty($values['theme']) || $values['theme'] == 'sitedefault' ? null : $values['theme']; $newinstitution->dropdownmenu = !empty($values['dropdownmenu']) ? 1 : 0; $newinstitution->skins = !empty($values['skins']) ? 1 : 0; require_once get_config('docroot') . 'artefact/comment/lib.php'; $commentoptions = ArtefactTypeComment::get_comment_options(); $newinstitution->commentsortorder = empty($values['commentsortorder']) ? $commentoptions->sort : $values['commentsortorder']; $newinstitution->commentthreaded = !empty($values['commentthreaded']) ? 1 : 0; if ($newinstitution->theme == 'custom') { if (!empty($oldinstitution->style)) { $styleid = $oldinstitution->style; delete_records('style_property', 'style', $styleid); } else { $record = (object) array('title' => get_string('customstylesforinstitution', 'admin', $newinstitution->displayname)); $styleid = insert_record('style', $record, 'id', true); } $properties = array(); $record = (object) array('style' => $styleid); foreach (array_keys($customthemedefaults) as $name) { $record->field = $name; $record->value = $values[$name]; insert_record('style_property', $record); $properties[$name] = $values[$name]; } // Cache the css $smarty = smarty_core(); $smarty->assign('data', $properties); set_field('style', 'css', $smarty->fetch('customcss.tpl'), 'id', $styleid); $newinstitution->style = $styleid; } else { $newinstitution->style = null; } if (get_config('licensemetadata')) { $newinstitution->licensemandatory = !empty($values['licensemandatory']) ? 1 : 0; $newinstitution->licensedefault = isset($values['licensedefault']) ? $values['licensedefault'] : ''; } if (!empty($values['resetcustom']) && !empty($oldinstitution->style)) { $newinstitution->style = null; } if ($USER->get('admin') || get_config_plugin('artefact', 'file', 'institutionaloverride')) { if (!empty($values['updateuserquotas']) && !empty($values['defaultquota'])) { execute_sql("UPDATE {usr} SET quota = ? WHERE id IN (SELECT usr FROM {usr_institution} WHERE institution = ?)", array($values['defaultquota'], $institution)); // get all the users from the institution and make sure that they are still below // their quota threshold if ($users = get_records_sql_array('SELECT * FROM {usr} u LEFT JOIN {usr_institution} ui ON u.id = ui.usr AND ui.institution = ?', array($institution))) { $quotanotifylimit = get_config_plugin('artefact', 'file', 'quotanotifylimit'); if ($quotanotifylimit <= 0 || $quotanotifylimit >= 100) { $quotanotifylimit = 100; } foreach ($users as $user) { $user->quota = $values['defaultquota']; // check if the user has gone over the quota notify limit $user->quotausedpercent = $user->quotaused / $user->quota * 100; $overlimit = false; if ($quotanotifylimit <= $user->quotausedpercent) { $overlimit = true; } $notified = get_field('usr_account_preference', 'value', 'field', 'quota_exceeded_notified', 'usr', $user->id); if ($overlimit && '1' !== $notified) { require_once get_config('docroot') . 'artefact/file/lib.php'; ArtefactTypeFile::notify_users_threshold_exceeded(array($user), false); // no need to email admin as we can alert them right now $SESSION->add_error_msg(get_string('useroverquotathreshold', 'artefact.file', display_name($user))); } else { if ($notified && !$overlimit) { set_account_preference($user->id, 'quota_exceeded_notified', false); } } } } } $newinstitution->defaultquota = empty($values['defaultquota']) ? get_config_plugin('artefact', 'file', 'defaultquota') : $values['defaultquota']; } if ($institution != 'mahara') { $newinstitution->defaultmembershipperiod = $values['defaultmembershipperiod'] ? intval($values['defaultmembershipperiod']) : null; if ($USER->get('admin')) { $newinstitution->maxuseraccounts = $values['maxuseraccounts'] ? intval($values['maxuseraccounts']) : null; $newinstitution->expiry = db_format_timestamp($values['expiry']); } } $newinstitution->allowinstitutionpublicviews = isset($values['allowinstitutionpublicviews']) && $values['allowinstitutionpublicviews'] ? 1 : 0; // TODO: Move handling of authentication instances within the Institution class as well? if (!empty($values['authplugin'])) { $allinstances = array_merge($values['authplugin']['instancearray'], $values['authplugin']['deletearray']); if (array_diff($allinstances, $instancearray)) { throw new ConfigException('Attempt to delete or update another institution\'s auth instance'); } if (array_diff($instancearray, $allinstances)) { throw new ConfigException('One of your instances is unaccounted for in this transaction'); } foreach ($values['authplugin']['instancearray'] as $priority => $instanceid) { if (in_array($instanceid, $values['authplugin']['deletearray'])) { // Should never happen: throw new SystemException('Attempt to update AND delete an auth instance'); } $record = new StdClass(); $record->priority = $priority; $record->id = $instanceid; update_record('auth_instance', $record, array('id' => $instanceid)); } foreach ($values['authplugin']['deletearray'] as $instanceid) { // If this authinstance is the only xmlrpc authinstance that references a host, delete the host record. $hostwwwroot = null; foreach ($authinstances as $ai) { if ($ai->id == $instanceid && $ai->authname == 'xmlrpc') { $hostwwwroot = get_field_sql("SELECT \"value\" FROM {auth_instance_config} WHERE \"instance\" = ? AND field = 'wwwroot'", array($instanceid)); if ($hostwwwroot && count_records_select('auth_instance_config', "field = 'wwwroot' AND \"value\" = ?", array($hostwwwroot)) == 1) { // Unfortunately, it's possible that this host record could belong to a different institution, // so specify the institution here. delete_records('host', 'wwwroot', $hostwwwroot, 'institution', $institution); // We really need to fix this, either by removing the institution from the host table, or refusing to allow the // institution to be changed in the host record when another institution's authinstance is still pointing at it. } break; } } delete_records('auth_remote_user', 'authinstance', $instanceid); delete_records('auth_instance_config', 'instance', $instanceid); delete_records('auth_instance', 'id', $instanceid); // Make it no longer be the parent authority to any auth instances delete_records('auth_instance_config', 'field', 'parent', 'value', $instanceid); } } // Store plugin settings. plugin_institution_prefs_submit($form, $values, $newinstitution); // Save the changes to the DB $newinstitution->commit(); if ($add) { // Automatically create an internal authentication authinstance $authinstance = (object) array('instancename' => 'internal', 'priority' => 0, 'institution' => $newinstitution->name, 'authname' => 'internal'); insert_record('auth_instance', $authinstance); // We need to add the default lines to the site_content table for this institution // We also need to set the institution to be using default static pages to begin with // so that using custom institution pages is an opt-in situation $pages = site_content_pages(); $now = db_format_timestamp(time()); foreach ($pages as $name) { $page = new stdClass(); $page->name = $name; $page->ctime = $now; $page->mtime = $now; $page->content = get_string($page->name . 'defaultcontent', 'install', get_string('staticpageconfiginstitution', 'install')); $page->institution = $newinstitution->name; insert_record('site_content', $page); $institutionconfig = new stdClass(); $institutionconfig->institution = $newinstitution->name; $institutionconfig->field = 'sitepages_' . $name; $institutionconfig->value = 'mahara'; insert_record('institution_config', $institutionconfig); } } if (is_null($newinstitution->style) && !empty($oldinstitution->style)) { delete_records('style_property', 'style', $oldinstitution->style); delete_records('style', 'id', $oldinstitution->style); } // Set the logo after updating the institution, because the institution // needs to exist before it can own the logo artefact. if (!empty($values['logo'])) { safe_require('artefact', 'file'); // Entry in artefact table $data = (object) array('institution' => $institution, 'title' => 'logo', 'description' => 'Institution logo', 'note' => $values['logo']['name'], 'size' => $values['logo']['size']); $imageinfo = getimagesize($values['logo']['tmp_name']); $data->width = $imageinfo[0]; $data->height = $imageinfo[1]; $data->filetype = $imageinfo['mime']; $artefact = new ArtefactTypeProfileIcon(0, $data); if (preg_match("/\\.([^\\.]+)\$/", $values['logo']['name'], $saved)) { $artefact->set('oldextension', $saved[1]); } $artefact->commit(); $id = $artefact->get('id'); // Move the file into the correct place. $directory = get_config('dataroot') . 'artefact/file/profileicons/originals/' . $id % 256 . '/'; check_dir_exists($directory); move_uploaded_file($values['logo']['tmp_name'], $directory . $id); // Delete the old logo if (!empty($oldinstitution->logo)) { $oldlogo = new ArtefactTypeProfileIcon($oldinstitution->logo); $oldlogo->delete(); } set_field('institution', 'logo', $id, 'name', $institution); } if (!empty($values['deletelogo'])) { execute_sql("UPDATE {institution} SET logo = NULL WHERE name = ?", array($institution)); } delete_records('institution_locked_profile_field', 'name', $institution); foreach (ArtefactTypeProfile::get_all_fields() as $field => $type) { if ($values[$field]) { $profilefield = new StdClass(); $profilefield->name = $institution; $profilefield->profilefield = $field; insert_record('institution_locked_profile_field', $profilefield); } } db_commit(); if ($add) { if (!$newinstitution->registerallowed) { // If registration is not allowed, then an authinstance will not // have been created, and thus cause the institution page to add // its own error message on the next page load $SESSION->add_ok_msg(get_string('institutionaddedsuccessfully2', 'admin')); } $nexturl = '/admin/users/institutions.php?i=' . urlencode($institution); } else { $message = get_string('institutionupdatedsuccessfully', 'admin'); if (isset($values['theme'])) { $changedtheme = $oldinstitution->theme != $values['theme'] && (!empty($oldinstitution->theme) || $values['theme'] != 'sitedefault'); if ($changedtheme || $values['theme'] == 'custom') { $message .= ' ' . get_string('usersseenewthemeonlogin', 'admin'); } $USER->reset_institutions(); } $SESSION->add_ok_msg($message); $nexturl = '/admin/users/institutions.php'; } redirect($nexturl); }