function groupquotasform_submit(Pieform $form, $values) { global $SESSION; $oldquota = get_field('group', 'quota', 'id', $values['groupid']); $group = new StdClass(); $group->id = $values['groupid']; $group->quota = $values['quota']; update_record('group', $group); if (!empty($values['quota']) && $values['quota'] != $oldquota) { // We need to alert group admins that the group may now be over the threshold $quotanotifylimit = get_config_plugin('artefact', 'file', 'quotanotifylimit'); $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 . " >= ? AND id = ?", array($quotanotifylimit, $values['groupid']))) { require_once get_config('docroot') . 'artefact/file/lib.php'; ArtefactTypeFile::notify_groups_threshold_exceeded($groups); } } $SESSION->add_ok_msg(get_string('groupquotaupdated', 'admin')); redirect(get_config('wwwroot') . 'admin/groups/groups.php'); }
public function render_self($options) { $result = parent::render_self($options); $result['html'] = '<div class="fr filedata-icon" style="text-align: center;"><h4>' . get_string('Preview', 'artefact.file') . '</h4><a href="' . hsc(get_config('wwwroot') . 'artefact/file/download.php?file=' . $this->id . '&view=' . (isset($options['viewid']) ? $options['viewid'] : 0)) . '"><img src="' . hsc(get_config('wwwroot') . 'artefact/file/download.php?file=' . $this->id . '&view=' . (isset($options['viewid']) ? $options['viewid'] : 0) . '&maxwidth=400&maxheight=180') . '" alt=""></a></div>' . $result['html']; return $result; }
list($blogs->count, $blogs->data) = ArtefactTypeBlog::get_blog_list($blogs->limit, $blogs->offset); foreach ($blogs->data as $blog) { if (!$blog->locked) { $blogs_arr[] = array("id" => $blog->id, "blog" => $blog->title); $blogposts = ArtefactTypeBlogpost::get_posts($blog->id, $blogs->limit, $blogs->offset, null); foreach ($blogposts['data'] as $blogpost) { if (!$blogpost->locked) { $blogposts_arr[] = array("id" => $blogpost->id, "blogpost" => $blogpost->title); } } } } if (count($blogs_arr) > 0) { $json['blogs'] = $blogs_arr; } if (count($blogposts_arr) > 0) { $json['blogposts'] = $blogposts_arr; } // OK - let's add folders $folders_arr = array(); $folders = ArtefactTypeFile::get_my_files_data(0, $USER->id, null, null, array("artefacttype" => array("folder"))); foreach ($folders as $folder) { if (!$folder->locked) { $folders_arr[] = array("id" => $folder->id, "folder" => $folder->title); } } if (count($folders_arr) > 0) { $json['folders'] = $folders_arr; } // Here we need to create a new hash - update our own store of it and return it to the handset mobile_api_json_reply(array('success' => $USER->refresh_mobileuploadtoken($token), 'sync' => $json));
/** * Attaches a file to a blogpost entry that was just linked directly, rather than having a Leap2a entry * See http://wiki.leapspecs.org/2A/files * * @param SimpleXMLElement $blogpostentry * @param SimpleXMLElement $blogpostlink * @param PluginImportLeap $importer */ private static function attach_linked_file($blogpostentry, $blogpostlink, PluginImportLeap $importer) { $importer->trace($blogpostlink); $pathname = urldecode((string) $blogpostlink['href']); $dir = dirname($importer->get('filename')); $pathname = $dir . '/' . $pathname; if (!file_exists($pathname)) { return false; } // Note: this data is passed (eventually) to ArtefactType->__construct, // which calls strtotime on the dates for us require_once 'file.php'; $data = (object) array('title' => (string) $blogpostentry->title . ' ' . get_string('attachment', 'artefact.blog'), 'owner' => $importer->get('usr')); $data->oldextension = end(explode('.', $data->title)); return ArtefactTypeFile::save_file($pathname, $data, $importer->get('usrobj'), true); }
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 add_feedback_form_submit(Pieform $form, $values) { global $view, $artefact, $USER; $data = (object) array('title' => get_string('Comment', 'artefact.comment'), 'description' => $values['message']); if ($artefact) { $data->onartefact = $artefact->get('id'); $data->owner = $artefact->get('owner'); $data->group = $artefact->get('group'); $data->institution = $artefact->get('institution'); } else { $data->onview = $view->get('id'); $data->owner = $view->get('owner'); $data->group = $view->get('group'); $data->institution = $view->get('institution'); } if ($author = $USER->get('id')) { $anonymous = false; $data->author = $author; } else { $anonymous = true; $data->authorname = $values['authorname']; } if (isset($values['moderate']) && $values['ispublic'] && !$USER->can_edit_view($view)) { $data->private = 1; $data->requestpublic = 'author'; $moderated = true; } else { $data->private = (int) (!$values['ispublic']); $moderated = false; } $private = $data->private; if (get_config('licensemetadata')) { $data->license = $values['license']; $data->licensor = $values['licensor']; $data->licensorurl = $values['licensorurl']; } if (isset($values['rating'])) { $data->rating = valid_rating($values['rating']); } $comment = new ArtefactTypeComment(0, $data); db_begin(); $comment->commit(); $url = $comment->get_view_url($view->get('id'), true, false); $goto = get_config('wwwroot') . $url; if (isset($data->requestpublic) && $data->requestpublic === 'author' && $data->owner) { $arg = $author ? display_name($USER, null, true) : $data->authorname; $moderatemsg = (object) array('subject' => false, 'message' => false, 'strings' => (object) array('subject' => (object) array('key' => 'makepublicrequestsubject', 'section' => 'artefact.comment', 'args' => array()), 'message' => (object) array('key' => 'makepublicrequestbyauthormessage', 'section' => 'artefact.comment', 'args' => array(hsc($arg))), 'urltext' => (object) array('key' => 'Comment', 'section' => 'artefact.comment')), 'users' => array($data->owner), 'url' => $url); } if (!empty($values['attachments']) && is_array($values['attachments']) && !empty($data->author)) { require_once get_config('libroot') . 'uploadmanager.php'; safe_require('artefact', 'file'); $ownerlang = empty($data->owner) ? get_config('lang') : get_user_language($data->owner); $folderid = ArtefactTypeFolder::get_folder_id(get_string_from_language($ownerlang, 'feedbackattachdirname', 'artefact.comment'), get_string_from_language($ownerlang, 'feedbackattachdirdesc', 'artefact.comment'), null, true, $data->owner, $data->group, $data->institution); $attachment = (object) array('owner' => $data->owner, 'group' => $data->group, 'institution' => $data->institution, 'author' => $data->author, 'allowcomments' => 0, 'parent' => $folderid, 'description' => get_string_from_language($ownerlang, 'feedbackonviewbyuser', 'artefact.comment', $view->get('title'), display_name($USER))); foreach ($values['attachments'] as $filesindex) { $originalname = $_FILES[$filesindex]['name']; $attachment->title = ArtefactTypeFileBase::get_new_file_title($originalname, $folderid, $data->owner, $data->group, $data->institution); try { $fileid = ArtefactTypeFile::save_uploaded_file($filesindex, $attachment); } catch (QuotaExceededException $e) { if ($data->owner == $USER->get('id')) { $form->reply(PIEFORM_ERR, array('message' => $e->getMessage())); } redirect($goto); } catch (UploadException $e) { $form->reply(PIEFORM_ERR, array('message' => $e->getMessage())); redirect($goto); } $comment->attach($fileid); } } require_once 'activity.php'; $data = (object) array('commentid' => $comment->get('id'), 'viewid' => $view->get('id')); activity_occurred('feedback', $data, 'artefact', 'comment'); if (isset($moderatemsg)) { activity_occurred('maharamessage', $moderatemsg); } db_commit(); $newlist = ArtefactTypeComment::get_comments(10, 0, 'last', $view, $artefact); // If you're anonymous and your message is moderated or private, then you won't // be able to tell what happened to it. So we'll provide some more explanation in // the feedback message. if ($anonymous && $moderated) { $message = get_string('feedbacksubmittedmoderatedanon', 'artefact.comment'); } else { if ($anonymous && $private) { $message = get_string('feedbacksubmittedprivateanon', 'artefact.comment'); } else { $message = get_string('feedbacksubmitted', 'artefact.comment'); } } $form->reply(PIEFORM_OK, array('message' => $message, 'goto' => $goto, 'data' => $newlist)); }
function importskinform_submit(Pieform $form, $values) { global $USER, $SESSION; require_once get_config('docroot') . 'artefact/file/lib.php'; // Open XML file and import Skin(s)... $filename = $values['file']['tmp_name']; $contents = file_get_contents($filename); $xmldoc = new DOMDocument('1.0', 'UTF-8'); //$xmldoc->load($filename); $xmldoc->loadXML($contents); $skinsdata = $xmldoc->getElementsByTagName('skin'); $siteskin = $values['skintype'] == 'site'; // A non-admin can't create a site skin. if ($siteskin && !$USER->get('admin')) { $values['skintype'] = 'private'; $siteskin = false; } foreach ($skinsdata as $skindata) { db_begin(); // Join all view skin css/formating data to array... $skin = array(); // Body element... $items = $skindata->getElementsByTagName('body'); foreach ($items as $item) { $skin = array_merge($skin, array('body_background_color' => $item->getAttribute('background-color'))); $skin = array_merge($skin, array('body_background_image' => 0)); $skin = array_merge($skin, array('body_background_repeat' => Skin::background_repeat_value_to_number($item->getAttribute('background-repeat')))); $skin = array_merge($skin, array('body_background_attachment' => $item->getAttribute('background-attachment'))); $skin = array_merge($skin, array('body_background_position' => Skin::background_position_value_to_number($item->getAttribute('background-position')))); } // Header element... $items = $skindata->getElementsByTagName('header'); foreach ($items as $item) { $skin = array_merge($skin, array('header_background_color' => $item->getAttribute('background-color'))); $skin = array_merge($skin, array('header_text_font_color' => $item->getAttribute('font-color'))); $skin = array_merge($skin, array('header_link_normal_color' => $item->getAttribute('normal-color'))); if ($item->getAttribute('normal-decoration') == 'none') { $skin = array_merge($skin, array('header_link_normal_underline' => 0)); } else { $skin = array_merge($skin, array('header_link_normal_underline' => 1)); } $skin = array_merge($skin, array('header_link_hover_color' => $item->getAttribute('hover-color'))); if ($item->getAttribute('hover-decoration') == 'none') { $skin = array_merge($skin, array('header_link_hover_underline' => 0)); } else { $skin = array_merge($skin, array('header_link_hover_underline' => 1)); } $skin = array_merge($skin, array('header_logo_image' => $item->getAttribute('logo-image'))); } // View element... $items = $skindata->getElementsByTagName('view'); foreach ($items as $item) { $skin = array_merge($skin, array('view_background_color' => $item->getAttribute('background-color'))); $skin = array_merge($skin, array('view_background_image' => 0)); $skin = array_merge($skin, array('view_background_repeat' => Skin::background_repeat_value_to_number($item->getAttribute('background-repeat')))); $skin = array_merge($skin, array('view_background_attachment' => $item->getAttribute('background-attachment'))); $skin = array_merge($skin, array('view_background_position' => Skin::background_position_value_to_number($item->getAttribute('background-position')))); $skin = array_merge($skin, array('view_background_width' => str_replace("%", "", $item->getAttribute('width')))); // odstrani znak %! $skin = array_merge($skin, array('view_background_margin' => $item->getAttribute('margin-top'))); } // Text element... $items = $skindata->getElementsByTagName('text'); foreach ($items as $item) { $skin = array_merge($skin, array('view_text_font_family' => $item->getAttribute('text-font'))); $skin = array_merge($skin, array('view_heading_font_family' => $item->getAttribute('heading-font'))); $skin = array_merge($skin, array('view_text_font_size' => $item->getAttribute('font-size'))); $skin = array_merge($skin, array('view_text_font_color' => $item->getAttribute('font-color'))); $skin = array_merge($skin, array('view_text_heading_color' => $item->getAttribute('heading-color'))); $skin = array_merge($skin, array('view_text_emphasized_color' => $item->getAttribute('emphasized-color'))); } // Link element... $items = $skindata->getElementsByTagName('link'); foreach ($items as $item) { $skin = array_merge($skin, array('view_link_normal_color' => $item->getAttribute('normal-color'))); if ($item->getAttribute('normal-decoration') == 'none') { $skin = array_merge($skin, array('view_link_normal_underline' => 0)); } else { $skin = array_merge($skin, array('view_link_normal_underline' => 1)); } $skin = array_merge($skin, array('view_link_hover_color' => $item->getAttribute('hover-color'))); if ($item->getAttribute('hover-decoration') == 'none') { $skin = array_merge($skin, array('view_link_hover_underline' => 0)); } else { $skin = array_merge($skin, array('view_link_hover_underline' => 1)); } } // Table element... $items = $skindata->getElementsByTagName('table'); foreach ($items as $item) { $skin = array_merge($skin, array('view_table_border_color' => $item->getAttribute('border-color'))); $skin = array_merge($skin, array('view_table_odd_row_color' => $item->getAttribute('odd-row-color'))); $skin = array_merge($skin, array('view_table_even_row_color' => $item->getAttribute('even-row-color'))); } // Custom CSS element... $items = $skindata->getElementsByTagName('customcss'); foreach ($items as $item) { $skin['view_custom_css'] = clean_css(unserialize($item->getAttribute('contents')), $preserve_css = true); } // Image element... // TODO: Background image file support for site skins if ($siteskin) { $skin['body_background_image'] = 0; $skin['view_background_image'] = 0; } else { $items = $skindata->getElementsByTagName('image'); foreach ($items as $item) { // Write necessary data in 'artefact' table... // TODO: When we rework the file upload code to make it more general, // rewrite this to reuse content from filebrowser.php $now = date("Y-m-d H:i:s"); $artefact = (object) array_merge((array) unserialize($item->getAttribute('artefact')), (array) unserialize($item->getAttribute('artefact_file_files')), (array) unserialize($item->getAttribute('artefact_file_image'))); unset($artefact->id); unset($artefact->fileid); $artefact->owner = $USER->get('id'); $artefact->author = $USER->get('id'); $artefact->atime = $now; $artefact->ctime = $now; $artefact->mtime = $now; $artobj = new ArtefactTypeImage(0, $artefact); $artobj->commit(); $id = $artobj->get('id'); // Create folder and file inside it. then write contents into it... $imagedir = get_config('dataroot') . ArtefactTypeFile::get_file_directory($id); if (!check_dir_exists($imagedir, true, true)) { throw new SystemException("Unable to create folder {$imagedir}"); } else { // Write contents to a file... $imagepath = $imagedir . '/' . $id; $contents = base64_decode($item->getAttribute('contents')); $fp = fopen($imagepath, 'w'); fwrite($fp, $contents); fclose($fp); // We can keep going, but the skin will be missing one of its files if ($clamerror = mahara_clam_scan_file($imagepath)) { $SESSION->add_error_msg($clamerror); } chmod($imagepath, get_config('filepermissions')); } $type = $item->getAttribute('type'); if ($type == 'body-background-image') { $skin['body_background_image'] = $id; } if ($type == 'view-background-image') { $skin['view_background_image'] = $id; } } } $viewskin = array(); if ($skindata->getAttribute('title') != '') { $viewskin['title'] = $skindata->getAttribute('title'); } $viewskin['description'] = $skindata->getAttribute('description'); $viewskin['owner'] = $USER->get('id'); $viewskin['type'] = $values['skintype']; $viewskin['viewskin'] = $skin; // Fonts element... // Only admins can install site fonts if ($USER->get('admin')) { $fonts = $skindata->getElementsByTagName('font'); foreach ($fonts as $font) { $fontname = preg_replace("#[^A-Za-z0-9]#", "", $font->getAttribute('name')); $fontname = Skin::new_font_name($fontname); // Only upload font if it doesn't already exist on the site if (!Skin::font_exists($font->getAttribute('title'))) { $fontdata = array('name' => $fontname, 'title' => $font->getAttribute('title'), 'licence' => $font->getAttribute('font-licence'), 'previewfont' => $font->getAttribute('font-preview'), 'variants' => base64_decode($font->getAttribute('font-variants')), 'fonttype' => $font->getAttribute('font-type'), 'onlyheading' => $font->getAttribute('heading-font-only'), 'fontstack' => $font->getAttribute('font-stack'), 'genericfont' => $font->getAttribute('generic-font')); insert_record('skin_fonts', $fontdata); $fontpath = get_config('dataroot') . 'skins/fonts/' . $fontdata['name'] . '/'; if (!check_dir_exists($fontpath, true, true)) { throw new SystemException("Unable to create folder {$fontpath}"); } else { $files = $font->getElementsByTagName('file'); foreach ($files as $file) { // Read the filename and the contents of each file from XML... $filename = $file->getAttribute('name'); $contents = base64_decode($file->getAttribute('contents')); // Import and copy each file to the appropriate folder... $fp = fopen($fontpath . $filename, 'wb'); fwrite($fp, $contents); fclose($fp); // We can keep going, but the skin will be missing one of its files if ($clamerror = mahara_clam_scan_file($fontpath . $filename)) { $SESSION->add_error_msg($clamerror); } chmod($fontpath . $filename, get_config('filepermissions')); } } } } } Skin::create($viewskin); db_commit(); } $SESSION->add_ok_msg(get_string('skinimported', 'skin')); if ($values['skintype'] == 'site') { redirect('/admin/site/skins.php'); } else { redirect('/skin/index.php'); } }
$artefact_id = ''; // our resulting artefact id on creation if ($_FILES) { $file_title = $title; if ($blog || !$title) { // set the filename to be the title of the artefact $file_title = basename($_FILES['userfile']['name']); } try { $data->title = ArtefactTypeFileBase::get_new_file_title($file_title, $data->parent, $data->owner); if (!$blog) { // only set a description if it's an artefact upload $data->description = $description; } $data->tags = $tags; $artefact_id = ArtefactTypeFile::save_uploaded_file('userfile', $data); if ($artefact_id) { $json['id'] = $artefact_id; } } catch (QuotaExceededException $e) { jsonreply(array('fail' => 'Quota exceeded')); } catch (UploadException $e) { jsonreply(array('fail' => 'Failed to save file')); } } // -- Next create a blog entry -- $postobj = ''; // our resulting blog post object on creation if ($blog) { if (!($title && $description)) { jsonreply(array('fail' => 'Journal posts must have a title and entry (description).'));
oAAAAAAAAAD4DR1+AAGgmQaxAAAAAElFTkSuQmCC'), 'text/html' => 'te<b>xt/h</b>tml', 'text/plain' => 'text/plain', 'video/x-flv' => file_get_contents(get_config('docroot') . 'junk.flv'), 'application/octet-stream' => '??'); $profileicons = get_records_sql_array("\n SELECT f.*, a.artefacttype\n FROM {artefact_file_files} f JOIN {artefact} a ON f.artefact = a.id\n WHERE a.artefacttype = 'profileicon'", null); db_begin(); foreach ($profileicons as $r) { $filetype = isset($samples[$r->filetype]) ? $r->filetype : 'application/octet-stream'; $dir = get_config('dataroot') . 'artefact/file/profileicons/originals/' . $r->artefact % 256; check_dir_exists($dir); $file = $dir . '/' . $r->artefact; if (!file_exists($file)) { file_put_contents($dir . '/' . $r->artefact, $samples[$filetype]); execute_sql("UPDATE {artefact_file_files} SET size = ?, fileid = ?, filetype = ? WHERE artefact = ?", array(filesize($dir . '/' . $r->artefact), $r->artefact, $filetype, $r->artefact)); } } safe_require('artefact', 'file'); $files = array(); $ids = array(); foreach ($samples as $k => $v) { $n = 'a.' . get_random_key(); $fn = "/tmp/{$n}"; file_put_contents($fn, $v); $d = (object) array('title' => $n, 'owner' => $USER->get('id'), 'filetype' => $k); $id = ArtefactTypeFile::save_file($fn, $d, $USER, true); $ids[$id] = $id; $files[$k] = artefact_instance_from_id($id); } $records = get_records_sql_array("\n SELECT f.*, a.artefacttype\n FROM {artefact_file_files} f JOIN {artefact} a ON f.artefact = a.id\n WHERE a.artefacttype != 'profileicon' AND NOT a.id IN (" . join(',', $ids) . ')', null); foreach ($samples as $k => $v) { execute_sql("\n UPDATE {artefact_file_files} SET size = ?, fileid = ? WHERE filetype = ?", array($files[$k]->get('size'), $files[$k]->get('fileid'), $k)); } db_commit(); set_config('samplefiles', 1);
public function extract($progresscallback = null) { global $USER; $quotauser = $this->owner ? $USER : null; $this->data['basefolderid'] = $this->create_base_folder(); $this->data['folderids'] = array('.' => $this->data['basefolderid']); $this->data['folderscreated'] = 1; $this->data['filescreated'] = 0; $this->data['template'] = (object) array('owner' => $this->get('owner'), 'group' => $this->get('group'), 'institution' => $this->get('institution')); $tempdir = get_config('dataroot') . 'artefact/file/temp'; check_dir_exists($tempdir); if ($this->archivetype == 'tar') { $this->read_archive(); // Untar everything into a temp directory first $tempsubdir = tempnam($tempdir, ''); unlink($tempsubdir); mkdir($tempsubdir); if (!$this->handle->extract($tempsubdir)) { throw new SystemException("Unable to extract archive into {$tempsubdir}"); } $i = 0; foreach ($this->info->names as $name) { $folder = dirname($name); $this->data['template']->parent = $this->data['folderids'][$folder]; $this->data['template']->title = basename($name); if (substr($name, -1) == '/') { $this->create_folder($folder); } else { ArtefactTypeFile::save_file($tempsubdir . '/' . $name, $this->data['template'], $quotauser, true); $this->data['filescreated']++; } if ($progresscallback && ++$i % 5 == 0) { call_user_func_array($progresscallback, $i); } } } else { if ($this->archivetype == 'zip') { $this->open_archive(); $tempfile = tempnam($tempdir, ''); $i = 0; while ($entry = zip_read($this->handle)) { $name = zip_entry_name($entry); $folder = dirname($name); // Create parent folders if necessary if (!isset($this->data['folderids'][$folder])) { $parent = '.'; $child = ''; $path = split('/', $folder); for ($i = 0; $i < count($path); $i++) { $child .= $path[$i] . '/'; if (!isset($this->data['folderids'][$child])) { $this->data['template']->parent = $this->data['folderids'][$parent]; $this->data['template']->title = $path[$i]; $this->create_folder($parent); } $parent = $child; } } $this->data['template']->parent = $this->data['folderids'][$folder]; $this->data['template']->title = basename($name); if (substr($name, -1) == '/') { $this->create_folder($folder); } else { $h = fopen($tempfile, 'w'); $size = zip_entry_filesize($entry); $contents = zip_entry_read($entry, $size); fwrite($h, $contents); fclose($h); ArtefactTypeFile::save_file($tempfile, $this->data['template'], $quotauser, true); $this->data['filescreated']++; } if ($progresscallback && ++$i % 5 == 0) { call_user_func_array($progresscallback, $i); } } } } return $this->data; }
public function add_artefacts() { // we're just adding them as files into an 'incoming' directory in the user's file area. safe_require('artefact', 'file'); try { $this->importdir = ArtefactTypeFolder::get_folder_id('incoming', get_string('incomingfolderdesc'), null, true, $this->get('usr')); } catch (Exception $e) { throw new ImportException($e->getMessage()); } $savedfiles = array(); // to put files into so we can delete them should we encounter an exception foreach ($this->files as $f) { try { $data = (object) array('title' => $f->wantsfilename, 'description' => $f->wantsfilename . ' (' . get_string('importedfrom', 'mahara', $this->get('importertransport')->get_description()) . ')', 'parent' => $this->importdir, 'owner' => $this->get('usr'), 'container' => 0, 'locked' => 0); if ($imagesize = getimagesize($this->tempdir . 'extract/' . $f->actualfilename)) { $mime = $imagesize['mime']; $data->filetype = $mime; } $id = ArtefactTypeFile::save_file($this->tempdir . 'extract/' . $f->actualfilename, $data, $this->get('usrobj'), true); if (empty($id)) { throw new ImportException("Failed to create new artefact for {$f->sha1}"); } $savedfiles[] = $id; } catch (Exception $e) { foreach ($savedfiles as $fileid) { $tmp = artefact_instance_from_id($fileid); $tmp->delete(); } throw new ImportException('Failed to create some new artefacts'); } } $this->artefacts = $savedfiles; }
/** * Creates a file artefact based on the given entry. * * @param SimpleXMLElement $entry The entry to base the file's data on * @param PluginImportLeap $importer The importer * @param int $parent The ID of the parent artefact for this file * @throws ImportException If the given entry is not detected as being a file * @return ArtefactTypeFile The file artefact created */ public static function create_file(SimpleXMLElement $entry, PluginImportLeap $importer, $parent = null) { if (!self::is_file($entry, $importer)) { throw new ImportException($importer, "create_file(): Cannot create a file artefact from an entry we don't recognise as a file"); } // TODO: make sure there's no arbitrary file inclusion // TODO: the src attribute must be an IRI, according to the ATOM spec. // This means that it could have UTF8 characters in it, and the PHP // documentation doesn't sound hopeful that urldecode will work with // UTF8 characters $pathname = false; $description = ''; if (isset($entry->content['src'])) { $pathname = urldecode((string) $entry->content['src']); $filetype = (string) $entry->content['type']; } else { foreach ($entry->link as $link) { if ($importer->curie_equals($link['rel'], '', 'enclosure') && isset($link['href']) && !$importer->entry_exists((string) $link['href'])) { $pathname = urldecode((string) $link['href']); $filetype = (string) $link['type']; $description = strip_tags(PluginImportLeap::get_entry_content($entry, $importer)); // TODO do we have a better way of stripping tags? and why isn't this html anyway? } } } if (!$pathname) { $importer->trace("WARNING: couldn't find a file for {$entry->id} "); return; } // TODO: might want to make it easier to get at the directory where the import files are $dir = dirname($importer->get('filename')); // Note: this data is passed (eventually) to ArtefactType->__construct, // which calls strtotime on the dates for us $data = (object) array('title' => (string) $entry->title, 'description' => $description, 'owner' => $importer->get('usr'), 'filetype' => $filetype); if (isset($entry->summary) && empty($description)) { $data->description = (string) $entry->summary; } if ($published = strtotime((string) $entry->published)) { $data->ctime = (string) $entry->published; } if ($updated = strtotime((string) $entry->updated)) { $data->mtime = (string) $entry->updated; } if ($parent) { $data->parent = $parent; } $pathname = $dir . DIRECTORY_SEPARATOR . $pathname; // This API sucks, but that's not my problem if (!($id = ArtefactTypeFile::save_file($pathname, $data, $importer->get('usrobj'), true))) { $importer->trace("WARNING: the file for entry {$entry->id} does not exist in the import (path={$pathname})"); return; } $artefact = artefact_instance_from_id($id); $artefact->set('tags', PluginImportLeap::get_entry_tags($entry)); // Work out if the file was really a profile icon $isprofileicon = false; if ($artefact->get('artefacttype') == 'image') { $match = $entry->xpath('mahara:artefactplugin[@mahara:plugin="file" and @mahara:type="profileicon"]'); if (count($match) == 1) { $isprofileicon = true; } else { if ($importer->get('persondataid')) { $persondata = $importer->get_entry_by_id($importer->get('persondataid')); if (count($persondata->xpath('a:link[@rel="related" and @href="' . (string) $entry->id . '"]')) == 1) { $isprofileicon = true; } } } } // Work around that save_file doesn't let us set the mtime $artefact->set('mtime', strtotime((string) $entry->updated)); if ($isprofileicon) { $artefact->set('artefacttype', 'profileicon'); $artefact->set('parent', null); // Sadly the process for creating a profile icon is a bit dumb. To // be honest, it shouldn't even be a separate artefact type $basedir = get_config('dataroot') . 'artefact/file/'; $olddir = 'originals/' . $id % 256 . '/'; $newdir = 'profileicons/originals/' . $id % 256 . '/'; check_dir_exists($basedir . $newdir); if (!rename($basedir . $olddir . $id, $basedir . $newdir . $id)) { throw new ImportException($importer, 'TODO: get_string: was unable to move profile icon'); } } $artefact->commit(); return $artefact; }
/** * Logic shared by create_file_from_request() and create_file(). This actually takes the data and processes it into a file artefact * @param object $data * @param PluginImportLeap $importer * @param int $parent * @param SimplexMLElement $entry * @param unknown_type $entry_request * @return PluginArtefactFile * @throws ImportException */ private static function create_file_from_entry_data($data, PluginImportLeap $importer, $entryid, $fromrequest = false) { global $USER; if ($fromrequest) { $usr = $USER; } else { $usr = $importer->get('usrobj'); } $data->oldextension = end(explode('.', $data->title)); // This API sucks, but that's not my problem if (!($id = ArtefactTypeFile::save_file($data->pathname, $data, $usr, true))) { $importer->trace("WARNING: the file for entry {$entryid} does not exist in the import (path={$data->pathname})"); return false; } $artefact = artefact_instance_from_id($id); $artefact->set('tags', $data->tags); if ($fromrequest) { $artefact->set('mtime', $data->mtime); } else { // Work around that save_file doesn't let us set the mtime $artefact->set('mtime', strtotime($data->mtime)); } // Now that we've actually imported the file, let's check to see whether it was an image, before making it a real profile icon $isprofileicon = $data->isprofileicon && $artefact->get('artefacttype') == 'image'; if ($isprofileicon) { $artefact->set('artefacttype', 'profileicon'); // Put profile pic in 'profile pics' folder $artefact->set('parent', ArtefactTypeFolder::get_folder_id(get_string('imagesdir', 'artefact.file'), get_string('imagesdirdesc', 'artefact.file'), null, true, $importer->get('usr'))); // Sadly the process for creating a profile icon is a bit dumb. To // be honest, it shouldn't even be a separate artefact type $basedir = get_config('dataroot') . 'artefact/file/'; $olddir = 'originals/' . $id % 256 . '/'; $newdir = 'profileicons/originals/' . $id % 256 . '/'; check_dir_exists($basedir . $newdir); if (!rename($basedir . $olddir . $id, $basedir . $newdir . $id)) { throw new ImportException($importer, 'TODO: get_string: was unable to move profile icon'); } } $artefact->commit(); return $artefact; }
/** * Test that an artefact gets a new path when moved. */ public function testArtefactHierarchyMove() { // Create folder. $folderdata = array('owner' => $this->testuserid, 'title' => 'Test folder', 'description' => 'Test folder description'); $folder = new ArtefactTypeFolder(0, $folderdata); $folder->commit(); // Create a file. $filedata = array('owner' => $this->testuserid, 'title' => 'Test file', 'description' => 'Test file description'); $file = new ArtefactTypeFile(0, $filedata); $file->commit(); // Check that path is root. $fileid = $file->get('id'); $this->assertEquals('/' . $fileid, $file->get('path')); // "Move" file to a folder. $folderid = $folder->get('id'); $file = new ArtefactTypeFile($fileid); $file->move($folderid); $newpath = "/{$folderid}/{$fileid}"; $this->assertEquals($newpath, $file->get('path')); }
private static function get_download_link(ArtefactTypeFile $artefact, BlockInstance $instance, $wmp = false) { return get_config('wwwroot') . 'artefact/file/download.php?file=' . $artefact->get('id') . '&view=' . $instance->get('view') . ($wmp ? '&download=1' : ''); }
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); }
function pieform_element_filebrowser_upload(Pieform $form, $element, $data) { global $USER; $parentfolder = $data['uploadfolder'] ? (int) $data['uploadfolder'] : null; $institution = $form->get_property('institution'); $group = $form->get_property('group'); $uploadnumber = (int) $data['uploadnumber']; $editable = (int) $element['config']['edit']; $selectable = (int) $element['config']['select']; $querybase = $element['page'] . (strpos($element['page'], '?') === false ? '?' : '&'); $prefix = $form->get_name() . '_' . $element['name']; $result = array('error' => false, 'uploadnumber' => $uploadnumber); if ($parentfolder == 0) { $parentfolder = null; } $data = new StdClass(); $data->parent = $parentfolder; $data->owner = null; if ($parentfolder) { $parentartefact = artefact_instance_from_id($parentfolder); if (!$USER->can_edit_artefact($parentartefact)) { $result['error'] = true; $result['message'] = get_string('cannoteditfolder', 'artefact.file'); return $result; } else { if ($parentartefact->get('locked')) { $result['error'] = true; $result['message'] = get_string('cannoteditfoldersubmitted', 'artefact.file'); return $result; } } $parentfoldername = $parentartefact->get('title'); } else { $parentfoldername = null; } if ($institution) { if (!$USER->can_edit_institution($institution)) { $result['error'] = true; $result['message'] = get_string('notadminforinstitution', 'admin'); return $result; } $data->institution = $institution; } else { if ($group) { require_once get_config('libroot') . 'group.php'; if (!$parentfolder) { $role = group_user_access($group); if (!$role) { $result['error'] = true; $result['message'] = get_string('usernotingroup', 'mahara'); return $result; } // Use default grouptype artefact permissions to check if the // user can upload a file to the group's root directory $permissions = group_get_default_artefact_permissions($group); if (!$permissions[$role]->edit) { $result['error'] = true; $result['message'] = get_string('cannoteditfolder', 'artefact.file'); return $result; } } $data->group = $group; } else { $data->owner = $USER->get('id'); } } $data->container = 0; $originalname = $_FILES['userfile']['name']; $originalname = $originalname ? basename($originalname) : get_string('file', 'artefact.file'); $data->title = ArtefactTypeFileBase::get_new_file_title($originalname, $parentfolder, $data->owner, $group, $institution); try { $newid = ArtefactTypeFile::save_uploaded_file('userfile', $data); } catch (QuotaExceededException $e) { prepare_upload_failed_message($result, $e, $parentfoldername, $originalname); // update the file listing $result['quota'] = $USER->get('quota'); $result['quotaused'] = $USER->get('quotaused'); $result['newlist'] = pieform_element_filebrowser_build_filelist($form, $element, $parentfolder); return $result; } catch (UploadException $e) { prepare_upload_failed_message($result, $e, $parentfoldername, $originalname); return $result; } // Upload succeeded if (isset($element['filters'])) { $artefacttypes = isset($element['filters']['artefacttype']) ? $element['filters']['artefacttype'] : null; $filetypes = isset($element['filters']['filetype']) ? $element['filters']['filetype'] : null; if (!empty($artefacttypes) || !empty($filetypes)) { // Need to check the artefacttype or filetype (mimetype) of the uploaded file. $file = artefact_instance_from_id($newid); if (is_array($artefacttypes) && !in_array($file->get('artefacttype'), $artefacttypes) || is_array($filetypes) && !in_array($file->get('filetype'), $filetypes)) { $result['error'] = true; $result['uploaded'] = true; $result['message'] = get_string('wrongfiletypeforblock', 'artefact.file'); return $result; } } } if ($parentfoldername) { if ($data->title == $originalname) { $result['message'] = get_string('uploadoffiletofoldercomplete', 'artefact.file', $originalname, $parentfoldername); } else { $result['message'] = get_string('fileuploadedtofolderas', 'artefact.file', $originalname, $parentfoldername, $data->title); } } else { if ($data->title == $originalname) { $result['message'] = get_string('uploadoffilecomplete', 'artefact.file', $originalname); } else { $result['message'] = get_string('fileuploadedas', 'artefact.file', $originalname, $data->title); } } $result['highlight'] = $newid; $result['uploaded'] = true; $result['newlist'] = pieform_element_filebrowser_build_filelist($form, $element, $parentfolder, $newid); $result['quota'] = $USER->get('quota'); $result['quotaused'] = $USER->get('quotaused'); return $result; }
/** * Ensures that the given value for the given composite is present * TODO: expand on these docs. * @param unknown_type $values * @param unknown_type $compositetype * @param unknown_type $owner * @return int If successful, the ID of the composite artefact * @throws SystemException */ public static function ensure_composite_value($values, $compositetype, $owner) { global $USER; if (!in_array($compositetype, self::get_composite_artefact_types())) { throw new SystemException("ensure_composite_value called with invalid composite type"); } try { $a = artefact_instance_from_type($compositetype, $owner); $a->set('mtime', time()); } catch (Exception $e) { $classname = generate_artefact_class_name($compositetype); $a = new $classname(0, array('owner' => $owner, 'title' => get_string($compositetype, 'artefact.resume'))); } $a->commit(); $values['artefact'] = $a->get('id'); $table = 'artefact_resume_' . $compositetype; if (!empty($values['id'])) { $itemid = $values['id']; update_record($table, (object) $values, 'id'); } else { if (isset($values['displayorder'])) { $values['displayorder'] = intval($values['displayorder']); } else { $max = get_field($table, 'MAX(displayorder)', 'artefact', $values['artefact']); $values['displayorder'] = is_numeric($max) ? $max + 1 : 0; } $itemid = insert_record($table, (object) $values, 'id', true); } // If there are any attachments, attach them to your Resume... if ($compositetype == 'educationhistory' || $compositetype == 'employmenthistory') { $goto = get_config('wwwroot') . 'artefact/resume/employment.php'; } else { $goto = get_config('wwwroot') . 'artefact/resume/achievements.php'; } // Attachments via 'files' pieform element // This happens when adding new resume composite... if (array_key_exists('attachments', $values)) { require_once get_config('libroot') . 'uploadmanager.php'; safe_require('artefact', 'file'); $folderid = null; $attachment = (object) array('owner' => $owner, 'group' => null, 'institution' => null, 'author' => $owner, 'allowcomments' => 0, 'parent' => $folderid, 'description' => null); foreach ($values['attachments'] as $filesindex) { $originalname = $_FILES[$filesindex]['name']; $attachment->title = ArtefactTypeFileBase::get_new_file_title($originalname, $folderid, $owner, null, null); try { $fileid = ArtefactTypeFile::save_uploaded_file($filesindex, $attachment); } catch (QuotaExceededException $e) { return array('message' => $e->getMessage(), 'goto' => $goto); } catch (UploadException $e) { return array('message' => $e->getMessage(), 'goto' => $goto); } $a->attach($fileid, $itemid); } } // Attachments via 'filebrowser' pieform element // This happens when editing resume composite... if (array_key_exists('filebrowser', $values)) { $old = $a->attachment_id_list_with_item($itemid); $new = is_array($values['filebrowser']) ? $values['filebrowser'] : array(); // only allow the attaching of files that exist and are editable by user foreach ($new as $key => $fileid) { $file = artefact_instance_from_id($fileid); if (!$file instanceof ArtefactTypeFile || !$USER->can_publish_artefact($file)) { unset($new[$key]); } } if (!empty($new) || !empty($old)) { foreach ($old as $o) { if (!in_array($o, $new)) { try { $a->detach($o, $itemid); } catch (ArtefactNotFoundException $e) { } } } $is_error = false; foreach ($new as $n) { if (!in_array($n, $old)) { // check the new item is not already attached to the // artefact under a different $itemid if (record_exists('artefact_attachment', 'artefact', $a->get('id'), 'attachment', $n)) { $artefactfile = artefact_instance_from_id($n); $is_error[] = $artefactfile->get('title'); } else { try { $a->attach($n, $itemid); } catch (ArtefactNotFoundException $e) { } } } } if (!empty($is_error)) { if (sizeof($is_error) > 1) { $error = get_string('duplicateattachments', 'artefact.resume', implode('\', \'', $is_error)); } else { $error = get_string('duplicateattachment', 'artefact.resume', implode(', ', $is_error)); } return array('message' => $error); } } } return $a->id; }
function add_feedback_form_submit(Pieform $form, $values) { global $view, $artefact, $USER; $data = new StdClass(); $data->view = $view->get('id'); if ($artefact) { $data->artefact = $artefact->get('id'); $table = 'artefact_feedback'; } else { $table = 'view_feedback'; } $data->message = $values['message']; $data->public = (int) $values['ispublic']; $data->author = $USER->get('id'); if (!$data->author) { unset($data->author); $data->authorname = $values['authorname']; } $data->ctime = db_format_timestamp(time()); db_begin(); if (is_array($values['attachment'])) { require_once get_config('libroot') . 'group.php'; require_once get_config('libroot') . 'uploadmanager.php'; safe_require('artefact', 'file'); $groupid = $view->get('submittedgroup'); if (group_user_can_assess_submitted_views($groupid, $USER->get('id'))) { $um = new upload_manager('attachment'); if ($error = $um->preprocess_file()) { throw new UploadException($error); } $owner = $view->get('owner'); $ownerlang = get_user_language($owner); $folderid = ArtefactTypeFolder::get_folder_id(get_string_from_language($ownerlang, 'feedbackattachdirname', 'view'), get_string_from_language($ownerlang, 'feedbackattachdirdesc', 'view'), null, true, $owner); $attachment = (object) array('owner' => $owner, 'parent' => $folderid, 'title' => ArtefactTypeFileBase::get_new_file_title($values['attachment']['name'], $folderid, $owner), 'size' => $values['attachment']['size'], 'filetype' => $values['attachment']['type'], 'oldextensin' => $um->original_filename_extension(), 'description' => get_string_from_language($ownerlang, 'feedbackonviewbytutorofgroup', 'view', $view->get('title'), display_name($USER), get_field('group', 'name', 'id', $groupid))); try { $data->attachment = ArtefactTypeFile::save_uploaded_file('attachment', $attachment); } catch (QuotaExceededException $e) { } } } insert_record($table, $data, 'id', true); require_once 'activity.php'; unset($data->id); activity_occurred('feedback', $data); db_commit(); if ($artefact) { $goto = get_config('wwwroot') . 'view/artefact.php?artefact=' . $artefact->get('id') . '&view=' . $view->get('id'); } else { $goto = get_config('wwwroot') . 'view/view.php?id=' . $view->get('id'); } $form->reply(PIEFORM_OK, array('message' => get_string('feedbacksubmitted', 'view'), 'goto' => $goto)); }
* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * @package mahara * @subpackage admin * @author Catalyst IT Ltd * @license http://www.gnu.org/copyleft/gpl.html GNU GPL * @copyright (C) 2006-2009 Catalyst IT Ltd http://catalyst.net.nz * */ define('INTERNAL', 1); define('ADMIN', 1); define('JSON', 1); require dirname(dirname(dirname(__FILE__))) . '/init.php'; $public = param_boolean('public'); safe_require('artefact', 'file'); $result = array(); $result['adminfiles'] = ArtefactTypeFile::get_admin_files($public); if (empty($result['adminfiles'])) { $result['adminfiles'] = null; } $result['error'] = false; $result['message'] = false; json_headers(); echo json_encode($result);
/** * Attaches a file to a blogpost entry that was just linked directly, rather than having a Leap2a entry * See http://wiki.leapspecs.org/2A/files * * @param SimpleXMLElement $entry * @param SimpleXMLElement $link */ private function create_linked_file(SimpleXMLElement $entry, SimpleXMLElement $link) { $this->trace($link); $pathname = urldecode((string) $link['href']); $dir = dirname($this->get('filename')); $pathname = $dir . '/' . $pathname; if (!file_exists($pathname)) { return false; } // Note: this data is passed (eventually) to ArtefactType->__construct, // which calls strtotime on the dates for us require_once 'file.php'; $data = (object) array('title' => (string) $entry->title . ' ' . get_string('attachment'), 'owner' => $this->get('usr')); $data->oldextension = end(explode('.', $data->title)); return ArtefactTypeFile::save_file($pathname, $data, $this->get('usrobj'), true); }
/** * Creates a file artefact based on the given entry. * * @param SimpleXMLElement $entry The entry to base the file's data on * @param PluginImport $importer The importer * @param int $parent The ID of the parent artefact for this file * @throws ImportException If the given entry is not detected as being a file * @return ArtefactTypeFile The file artefact created */ public static function create_file(SimpleXMLElement $entry, PluginImport $importer, $parent = null) { if (!self::is_file($entry, $importer)) { throw new ImportException($importer, "create_file(): Cannot create a file artefact from an entry we don't recognise as a file"); } // TODO: make sure there's no arbitrary file inclusion // TODO: the src attribute must be an IRI, according to the ATOM spec. // This means that it could have UTF8 characters in it, and the PHP // documentation doesn't sound hopeful that urldecode will work with // UTF8 characters $pathname = urldecode((string) $entry->content['src']); // TODO: might want to make it easier to get at the directory where the import files are $data = $importer->get('data'); $dir = dirname($data['filename']); // Note: this data is passed (eventually) to ArtefactType->__construct, // which calls strtotime on the dates for us $data = (object) array('title' => (string) $entry->title, 'owner' => $importer->get('usr'), 'filetype' => (string) $entry->content['type']); if (isset($entry->summary)) { $data->description = (string) $entry->summary; } if ($published = strtotime((string) $entry->published)) { $data->ctime = (string) $entry->published; } if ($updated = strtotime((string) $entry->updated)) { $data->mtime = (string) $entry->updated; } if ($parent) { $data->parent = $parent; } $pathname = $dir . DIRECTORY_SEPARATOR . $pathname; // This API sucks, but that's not my problem if (!($id = ArtefactTypeFile::save_file($pathname, $data, $importer->get('usrobj')))) { throw new ImportException($importer, 'TODO: get_string: was unable to import file'); } // Work out if the file was really a profile icon $isprofileicon = false; $match = $entry->xpath('mahara:artefactplugin[@mahara:plugin="file" and @mahara:type="profileicon"]'); if (count($match) == 1) { $isprofileicon = true; } $artefact = artefact_instance_from_id($id); // Work around that save_file doesn't let us set the mtime $artefact->set('mtime', strtotime((string) $entry->updated)); if ($isprofileicon) { $artefact->set('artefacttype', 'profileicon'); $artefact->set('parent', null); // Sadly the process for creating a profile icon is a bit dumb. To // be honest, it shouldn't even be a separate artefact type $basedir = get_config('dataroot') . 'artefact/file/'; $olddir = 'originals/' . $id % 256 . '/'; $newdir = 'profileicons/originals/' . $id % 256 . '/'; check_dir_exists($basedir . $newdir); if (!rename($basedir . $olddir . $id, $basedir . $newdir . $id)) { throw new ImportException($importer, 'TODO: get_string: was unable to move profile icon'); } // Unconditionally set as default, even if there is more than one $importer->get('usrobj')->profileicon = $id; $importer->get('usrobj')->commit(); } $artefact->commit(); return $artefact; }
public function __construct($id = 0, $data = null) { parent::__construct($id, $data); if ($this->id) { $descriptions = self::video_file_descriptions(); $validtypes = self::video_mime_types(); $this->videotype = $descriptions[$validtypes[$this->filetype]->description]; } }
function pieform_element_filebrowser_upload(Pieform $form, $element, $data) { global $USER; $parentfolder = $data['uploadfolder'] ? (int) $data['uploadfolder'] : null; $institution = !empty($element['institution']) ? $element['institution'] : $form->get_property('institution'); $group = !empty($element['group']) ? $element['group'] : $form->get_property('group'); if (get_config('licensemetadata')) { $license = $data['license']; $licensor = $data['licensor']; $licensorurl = $data['licensorurl']; } $uploadnumber = (int) $data['uploadnumber']; $editable = (int) $element['config']['edit']; $selectable = (int) $element['config']['select']; $querybase = $element['page'] . (strpos($element['page'], '?') === false ? '?' : '&'); $prefix = $form->get_name() . '_' . $element['name']; $userfileindex = isset($data['userfileindex']) ? $data['userfileindex'] : null; $resizeonuploadenable = get_config_plugin('artefact', 'file', 'resizeonuploadenable'); $resizeonuploaduseroption = get_config_plugin('artefact', 'file', 'resizeonuploaduseroption'); $resizeonuploaduserenable = (int) $data['resizeonuploaduserenable']; $result = array('error' => false, 'uploadnumber' => $uploadnumber); if ($parentfolder == 0) { $parentfolder = null; } $data = new StdClass(); $data->parent = $parentfolder; $data->owner = $data->group = $data->institution = null; if (get_config('licensemetadata')) { $data->license = $license; $data->licensor = $licensor; $data->licensorurl = $licensorurl; } if ($parentfolder) { $parentartefact = artefact_instance_from_id($parentfolder); if (!$USER->can_edit_artefact($parentartefact)) { $result['error'] = true; $result['message'] = get_string('cannoteditfolder', 'artefact.file'); return $result; } else { if ($parentartefact->get('locked')) { $result['error'] = true; $result['message'] = get_string('cannoteditfoldersubmitted', 'artefact.file'); return $result; } } $parentfoldername = $parentartefact->get('title'); } else { $parentfoldername = null; } if ($institution) { if (!$USER->can_edit_institution($institution)) { $result['error'] = true; $result['message'] = get_string('notadminforinstitution', 'admin'); return $result; } $data->institution = $institution; } else { if ($group) { if (!group_within_edit_window($group)) { return array('error' => true, 'message' => get_string('cannoteditfolder', 'artefact.file')); } if (!$parentfolder) { if (!pieform_element_filebrowser_edit_group_folder($group, 0)) { return array('error' => true, 'message' => get_string('cannoteditfolder', 'artefact.file')); } } $data->group = $group; } else { $data->owner = $USER->get('id'); } } $data->container = 0; if (isset($userfileindex)) { $originalname = $_FILES['userfile']['name'][$userfileindex]; } else { $originalname = $_FILES['userfile']['name']; } $originalname = $originalname ? basename($originalname) : get_string('file', 'artefact.file'); $data->title = ArtefactTypeFileBase::get_new_file_title($originalname, $parentfolder, $data->owner, $group, $institution); // Overwrite image file with resized version if required $resized = false; $resizeattempted = false; // resize specified if (resizing is enabled AND user has enabled resizing) OR (resizing is enabled AND user is not given an option to enable/disable) if ($resizeonuploadenable && $resizeonuploaduserenable || $resizeonuploadenable && !$resizeonuploaduseroption) { require_once 'file.php'; require_once 'imageresizer.php'; $file = $_FILES['userfile']; if (isset($userfileindex)) { $tmpname = $file['tmp_name'][$userfileindex]; } else { $tmpname = $file['tmp_name']; } if (is_image_file($tmpname)) { $imageinfo = getimagesize($tmpname); $mimetype = $imageinfo['mime']; $width = $imageinfo[0]; $height = $imageinfo[1]; $bmptypes = array('image/bmp', 'image/x-bmp', 'image/ms-bmp', 'image/x-ms-bmp'); // resize image if necessary $resizeonuploadmaxwidth = get_config_plugin('artefact', 'file', 'resizeonuploadmaxwidth'); $resizeonuploadmaxheight = get_config_plugin('artefact', 'file', 'resizeonuploadmaxheight'); // Don't support bmps for now if (($width > $resizeonuploadmaxwidth || $height > $resizeonuploadmaxheight) && !in_array($mimetype, $bmptypes)) { $resizeattempted = true; $imgrs = new ImageResizer($tmpname, $mimetype); $img = $imgrs->get_image(); if (!empty($img)) { $imgrs->resize_image(array('w' => $resizeonuploadmaxwidth, 'h' => $resizeonuploadmaxheight), $mimetype); //auto $saveresize = $imgrs->save_image($tmpname, $mimetype, 85); if (!$saveresize) { return array('error' => true, 'message' => get_string('problemresizing', 'artefact.file')); } $resized = true; } } } } try { $newid = ArtefactTypeFile::save_uploaded_file('userfile', $data, $userfileindex, $resized); } catch (QuotaExceededException $e) { prepare_upload_failed_message($result, $e, $parentfoldername, $originalname); // update the file listing if (defined('GROUP')) { $group = group_current_group(); $result['quota'] = $group->quota; $result['quotaused'] = $group->quotaused; } else { $result['quota'] = $USER->get('quota'); $result['quotaused'] = $USER->get('quotaused'); } $result['newlist'] = pieform_element_filebrowser_build_filelist($form, $element, $parentfolder, null, $data->owner, $data->group, $data->institution); return $result; } catch (UploadException $e) { prepare_upload_failed_message($result, $e, $parentfoldername, $originalname); if (defined('GROUP')) { $group = group_current_group(); $result['quota'] = $group->quota; $result['quotaused'] = $group->quotaused; } return $result; } // Upload succeeded if (isset($element['filters'])) { $artefacttypes = isset($element['filters']['artefacttype']) ? $element['filters']['artefacttype'] : null; $filetypes = isset($element['filters']['filetype']) ? $element['filters']['filetype'] : null; if (!empty($artefacttypes) || !empty($filetypes)) { // Need to check the artefacttype or filetype (mimetype) of the uploaded file. $file = artefact_instance_from_id($newid); if (is_array($artefacttypes) && !in_array($file->get('artefacttype'), $artefacttypes) || is_array($filetypes) && !in_array($file->get('filetype'), $filetypes)) { $result['error'] = true; $result['uploaded'] = true; $result['message'] = get_string('wrongfiletypeforblock', 'artefact.file'); return $result; } } } if ($parentfoldername) { if ($data->title == $originalname) { $result['message'] = get_string('uploadoffiletofoldercomplete', 'artefact.file', $originalname, $parentfoldername); } else { $result['message'] = get_string('fileuploadedtofolderas', 'artefact.file', $originalname, $parentfoldername, $data->title); } } else { if ($data->title == $originalname) { $result['message'] = get_string('uploadoffilecomplete', 'artefact.file', $originalname); } else { $result['message'] = get_string('fileuploadedas', 'artefact.file', $originalname, $data->title); } } if ($resizeattempted && !$resized) { $result['message'] .= get_string('insufficientmemoryforresize', 'artefact.file'); } $result['highlight'] = $newid; $artefact = artefact_instance_from_id($newid); $result['artefacttype'] = $artefact->get('artefacttype'); $result['uploaded'] = true; $result['newlist'] = pieform_element_filebrowser_build_filelist($form, $element, $parentfolder, $newid, $data->owner, $data->group, $data->institution); if (defined('GROUP')) { $group = group_current_group(false); $result['quota'] = $group->quota; $result['quotaused'] = $group->quotaused; } else { $result['quota'] = $USER->get('quota'); $result['quotaused'] = $USER->get('quotaused'); } $result['maxuploadsize'] = display_size(get_max_upload_size(!$institution && !$group)); return $result; }
function add_feedback_form_submit(Pieform $form, $values) { global $view, $artefact, $USER; require_once 'embeddedimage.php'; $data = (object) array('title' => get_string('Comment', 'artefact.comment'), 'description' => $values['message']); if ($artefact) { $data->onartefact = $artefact->get('id'); $data->owner = $artefact->get('owner'); $data->group = $artefact->get('group'); $data->institution = $artefact->get('institution'); $onvieworartefactstr = "onartefact = {$data->onartefact}"; } else { $data->onview = $view->get('id'); $data->owner = $view->get('owner'); $data->group = $view->get('group'); $data->institution = $view->get('institution'); $onvieworartefactstr = "onview = {$data->onview}"; } $owner = $data->owner; $author = null; if ($author = $USER->get('id')) { $anonymous = false; $data->author = $author; } else { $anonymous = true; $data->authorname = $values['authorname']; } if (isset($values['moderate']) && $values['ispublic'] && !$USER->can_edit_view($view)) { $data->private = 1; $data->requestpublic = 'author'; $moderated = true; } else { $data->private = (int) (!$values['ispublic']); $moderated = false; } $private = $data->private; if (get_config('licensemetadata')) { $data->license = $values['license']; $data->licensor = $values['licensor']; $data->licensorurl = $values['licensorurl']; } if (isset($values['rating'])) { $data->rating = valid_rating($values['rating']); } if ($values['replyto'] && ($pcomment = artefact_instance_from_id($values['replyto']))) { $data->parent = $pcomment->get('id'); $grandparentid = $pcomment->get('parent'); // Find the position for the new comment // Find the last offspring of the parent $parentid = $data->parent; $data->threadedposition = $pcomment->get('threadedposition'); while ($lastchild = get_records_sql_array(' SELECT c.artefact, c.threadedposition FROM {artefact_comment_comment} c INNER JOIN {artefact} a ON a.id = c.artefact WHERE ' . $onvieworartefactstr . ' AND a.parent = ? ORDER BY c.threadedposition DESC LIMIT 1', array($parentid))) { $parentid = $lastchild[0]->artefact; $data->threadedposition = $lastchild[0]->threadedposition; } $data->threadedposition++; // Increase the threaded position of following comments by 1 execute_sql(' UPDATE {artefact_comment_comment} SET threadedposition = threadedposition + 1 WHERE ' . $onvieworartefactstr . ' AND threadedposition >= ?', array($data->threadedposition)); } if (!isset($data->threadedposition)) { $lastcomment = get_record_sql(' SELECT max(threadedposition) AS lastposition FROM {artefact_comment_comment} c WHERE ' . $onvieworartefactstr); $data->threadedposition = $lastcomment->lastposition ? $lastcomment->lastposition + 1 : 1; } $comment = new ArtefactTypeComment(0, $data); db_begin(); $comment->commit(); $newdescription = EmbeddedImage::prepare_embedded_images($values['message'], 'comment', $comment->get('id'), $data->group); if ($newdescription !== $values['message']) { $updatedcomment = new stdClass(); $updatedcomment->id = $comment->get('id'); $updatedcomment->description = $newdescription; update_record('artefact', $updatedcomment, 'id'); } $url = $comment->get_view_url($view->get('id'), true, false); $goto = get_config('wwwroot') . $url; if (isset($data->requestpublic) && $data->requestpublic === 'author' && $data->owner) { $arg = $author ? display_name($USER, null, true) : $data->authorname; $moderatemsg = (object) array('subject' => false, 'message' => false, 'strings' => (object) array('subject' => (object) array('key' => 'makepublicrequestsubject', 'section' => 'artefact.comment', 'args' => array()), 'message' => (object) array('key' => 'makepublicrequestbyauthormessage', 'section' => 'artefact.comment', 'args' => array(hsc($arg))), 'urltext' => (object) array('key' => 'Comment', 'section' => 'artefact.comment')), 'users' => array($data->owner), 'url' => $url); } if (!empty($values['attachments']) && is_array($values['attachments']) && !empty($data->author)) { require_once get_config('libroot') . 'uploadmanager.php'; safe_require('artefact', 'file'); $ownerlang = empty($data->owner) ? get_config('lang') : get_user_language($data->owner); $folderid = ArtefactTypeFolder::get_folder_id(get_string_from_language($ownerlang, 'feedbackattachdirname', 'artefact.comment'), get_string_from_language($ownerlang, 'feedbackattachdirdesc', 'artefact.comment'), null, true, $data->owner, $data->group, $data->institution); $attachment = (object) array('owner' => $data->owner, 'group' => $data->group, 'institution' => $data->institution, 'author' => $data->author, 'allowcomments' => 0, 'parent' => $folderid, 'description' => get_string_from_language($ownerlang, 'feedbackonviewbyuser', 'artefact.comment', $view->get('title'), display_name($USER))); foreach ($values['attachments'] as $filesindex) { $originalname = $_FILES[$filesindex]['name']; $attachment->title = ArtefactTypeFileBase::get_new_file_title($originalname, $folderid, $data->owner, $data->group, $data->institution); try { $fileid = ArtefactTypeFile::save_uploaded_file($filesindex, $attachment); } catch (QuotaExceededException $e) { if ($data->owner == $USER->get('id')) { $form->reply(PIEFORM_ERR, array('message' => $e->getMessage())); } redirect($goto); } catch (UploadException $e) { $form->reply(PIEFORM_ERR, array('message' => $e->getMessage())); redirect($goto); } $comment->attach($fileid); } } require_once 'activity.php'; $data = (object) array('commentid' => $comment->get('id'), 'viewid' => $view->get('id')); // We want to add the user placing the comment to the watchlist so they // can get notified about future comments to the page. // @TODO Add a site/institution preference to override this. $updatelink = false; if (!get_field('usr_watchlist_view', 'ctime', 'usr', $author, 'view', $view->get('id')) && $author != $owner) { insert_record('usr_watchlist_view', (object) array('usr' => $author, 'view' => $view->get('id'), 'ctime' => db_format_timestamp(time()))); $updatelink = $artefact ? get_string('removefromwatchlistartefact', 'view', $view->get('title')) : get_string('removefromwatchlist', 'view'); } activity_occurred('feedback', $data, 'artefact', 'comment'); if (isset($moderatemsg)) { activity_occurred('maharamessage', $moderatemsg); } db_commit(); $commentoptions = ArtefactTypeComment::get_comment_options(); $commentoptions->showcomment = $comment->get('id'); $commentoptions->view = $view; $commentoptions->artefact = $artefact; $newlist = ArtefactTypeComment::get_comments($commentoptions); $newlist->updatelink = $updatelink; // If you're anonymous and your message is moderated or private, then you won't // be able to tell what happened to it. So we'll provide some more explanation in // the feedback message. if ($anonymous && $moderated) { $message = get_string('feedbacksubmittedmoderatedanon', 'artefact.comment'); } else { if ($anonymous && $private) { $message = get_string('feedbacksubmittedprivateanon', 'artefact.comment'); } else { $message = get_string('feedbacksubmitted', 'artefact.comment'); } } $form->reply(PIEFORM_OK, array('message' => $message, 'goto' => $goto, 'data' => $newlist)); }