Adds or updates a submission.

@param stdClass $submission The submissin data (via form or via WS).
@return the new or updated submission id.
@since  Moodle 3.4
541127
public function edit_submission($submission) {
        global $USER, $DB;

        if ($submission->example == 0) {
            // This was used just for validation, it must be set to zero when dealing with normal submissions.
            unset($submission->example);
        } else {
            throw new coding_exception('Invalid submission form data value: example');
        }
        $timenow = time();
        if (is_null($submission->id)) {
            $submission->workshopid     = $this->id;
            $submission->example        = 0;
            $submission->authorid       = $USER->id;
            $submission->timecreated    = $timenow;
            $submission->feedbackauthorformat = editors_get_preferred_format();
        }
        $submission->timemodified       = $timenow;
        $submission->title              = trim($submission->title);
        $submission->content            = '';          // Updated later.
        $submission->contentformat      = FORMAT_HTML; // Updated later.
        $submission->contenttrust       = 0;           // Updated later.
        $submission->late               = 0x0;         // Bit mask.
        if (!empty($this->submissionend) and ($this->submissionend < time())) {
            $submission->late = $submission->late | 0x1;
        }
        if ($this->phase == self::PHASE_ASSESSMENT) {
            $submission->late = $submission->late | 0x2;
        }

        // Event information.
        $params = array(
            'context' => $this->context,
            'courseid' => $this->course->id,
            'other' => array(
                'submissiontitle' => $submission->title
            )
        );
        $logdata = null;
        if (is_null($submission->id)) {
            $submission->id = $DB->insert_record('workshop_submissions', $submission);
            $params['objectid'] = $submission->id;
            $event = \mod_workshop\event\submission_created::create($params);
            $event->trigger();
        } else {
            if (empty($submission->id) or empty($submission->id) or ($submission->id != $submission->id)) {
                throw new moodle_exception('err_submissionid', 'workshop');
            }
        }
        $params['objectid'] = $submission->id;

        // Save and relink embedded images and save attachments.
        if ($this->submissiontypetext != WORKSHOP_SUBMISSION_TYPE_DISABLED) {
            $submission = file_postupdate_standard_editor($submission, 'content', $this->submission_content_options(),
                    $this->context, 'mod_workshop', 'submission_content', $submission->id);
        }

        $submission = file_postupdate_standard_filemanager($submission, 'attachment', $this->submission_attachment_options(),
            $this->context, 'mod_workshop', 'submission_attachment', $submission->id);

        if (empty($submission->attachment)) {
            // Explicit cast to zero integer.
            $submission->attachment = 0;
        }
        // Store the updated values or re-save the new submission (re-saving needed because URLs are now rewritten).
        $DB->update_record('workshop_submissions', $submission);
        $event = \mod_workshop\event\submission_updated::create($params);
        $event->add_record_snapshot('workshop', $this->dbrecord);
        $event->trigger();

        // Send submitted content for plagiarism detection.
        $fs = get_file_storage();
        $files = $fs->get_area_files($this->context->id, 'mod_workshop', 'submission_attachment', $submission->id);

        $params['other']['content'] = $submission->content;
        $params['other']['pathnamehashes'] = array_keys($files);

        $event = \mod_workshop\event\assessable_uploaded::create($params);
        $event->set_legacy_logdata($logdata);
        $event->trigger();

        return $submission->id;
    }
460010
public function submitLabel()
    {
        if ($this->submitLabel === null) {
            $this->submitLabel = $this->defaultSubmitLabel();
        }

        return $this->submitLabel;
    }
1039808
public function mapFormSubmissionToDto(array $submission)
    {
        $stagedFormObject = $this->stagedFormObject->submitNew($submission);

        return new ObjectActionParameter(
                $stagedFormObject->getObject(),
                $stagedFormObject
        );
    }
412306
public function get_feedbackauthor_form($actionurl, stdclass $submission, $options=array()) {
        global $CFG;
        require_once(__DIR__ . '/feedbackauthor_form.php');

        $current = new stdclass();
        $current->submissionid          = $submission->id;
        $current->published             = $submission->published;
        $current->grade                 = $this->real_grade($submission->grade);
        $current->gradeover             = $this->real_grade($submission->gradeover);
        $current->feedbackauthor        = $submission->feedbackauthor;
        $current->feedbackauthorformat  = $submission->feedbackauthorformat;
        if (is_null($current->grade)) {
            $current->grade = get_string('nullgrade', 'workshop');
        }
        if (!isset($options['editable'])) {
            $editable = true;   // by default
        } else {
            $editable = (bool)$options['editable'];
        }

        // prepare wysiwyg editor
        $current = file_prepare_standard_editor($current, 'feedbackauthor', array());

        return new workshop_feedbackauthor_form($actionurl,
                array('workshop' => $this, 'current' => $current, 'editoropts' => array(), 'options' => $options),
                'post', '', null, $editable);
    }
254239
public function add_submission_form_elements(MoodleQuickForm $mform, stdClass $data) {
        global $USER;

        $userid = $data->userid;
        // Team submissions.
        if ($this->get_instance()->teamsubmission) {
            $submission = $this->get_group_submission($userid, 0, false);
        } else {
            $submission = $this->get_user_submission($userid, false);
        }

        // Submission statement.
        $adminconfig = $this->get_admin_config();
        $requiresubmissionstatement = $this->get_instance()->requiresubmissionstatement;

        $draftsenabled = $this->get_instance()->submissiondrafts;
        $submissionstatement = '';

        if ($requiresubmissionstatement) {
            $submissionstatement = $this->get_submissionstatement($adminconfig, $this->get_instance(), $this->get_context());
        }

        // If we get back an empty submission statement, we have to set $requiredsubmisisonstatement to false to prevent
        // that the submission statement checkbox will be displayed.
        if (empty($submissionstatement)) {
            $requiresubmissionstatement = false;
        }

        // Only show submission statement if we are editing our own submission.
        if ($requiresubmissionstatement && !$draftsenabled && $userid == $USER->id) {
            $mform->addElement('checkbox', 'submissionstatement', '', $submissionstatement);
            $mform->addRule('submissionstatement', get_string('required'), 'required', null, 'client');
        }

        $this->add_plugin_submission_elements($submission, $mform, $data, $userid);

        // Hidden params.
        $mform->addElement('hidden', 'id', $this->get_course_module()->id);
        $mform->setType('id', PARAM_INT);

        $mform->addElement('hidden', 'userid', $userid);
        $mform->setType('userid', PARAM_INT);

        $mform->addElement('hidden', 'action', 'savesubmission');
        $mform->setType('action', PARAM_ALPHA);
    }
530427
public function prepare_submission_summary(stdClass $record, $showauthor = false) {

        $summary        = new workshop_submission_summary($this, $record, $showauthor);
        $summary->url   = $this->submission_url($record->id);

        return $summary;
    }
174672
public function delete_submission(stdclass $submission) {
        global $DB;

        $assessments = $DB->get_records('workshop_assessments', array('submissionid' => $submission->id), '', 'id');
        $this->delete_assessment(array_keys($assessments));

        $fs = get_file_storage();
        $fs->delete_area_files($this->context->id, 'mod_workshop', 'submission_content', $submission->id);
        $fs->delete_area_files($this->context->id, 'mod_workshop', 'submission_attachment', $submission->id);

        $DB->delete_records('workshop_submissions', array('id' => $submission->id));

        // Event information.
        $params = array(
            'context' => $this->context,
            'courseid' => $this->course->id,
            'relateduserid' => $submission->authorid,
            'other' => array(
                'submissiontitle' => $submission->title
            )
        );
        $params['objectid'] = $submission->id;
        $event = \mod_workshop\event\submission_deleted::create($params);
        $event->add_record_snapshot('workshop', $this->dbrecord);
        $event->trigger();
    }
329641
public function remove_submission($userid) {
        global $USER;

        if (!$this->can_edit_submission($userid, $USER->id)) {
            print_error('nopermission');
        }

        if ($this->get_instance()->teamsubmission) {
            $submission = $this->get_group_submission($userid, 0, false);
        } else {
            $submission = $this->get_user_submission($userid, false);
        }

        if (!$submission) {
            return false;
        }

        // Tell each submission plugin we were saved with no data.
        $plugins = $this->get_submission_plugins();
        foreach ($plugins as $plugin) {
            if ($plugin->is_enabled() && $plugin->is_visible()) {
                $plugin->remove($submission);
            }
        }

        if ($submission->userid != 0) {
            \mod_assign\event\submission_status_updated::create_from_submission($this, $submission)->trigger();
        }
        return true;
    }
884901
protected function getGerritSubmitRecordLabelByIdentifier($submitRecordId, $label)
    {
        $dbHandle = $this->getDatabase()->getDatabaseConnection();

        $query = 'SELECT `id`, `submit_record`, `label`, `status`, `by`
                  FROM ' . Database::TABLE_SUBMIT_RECORD_LABELS . '
                  WHERE `submit_record` = :submit_record_id
                        AND `label` = :label';
        $statement = $dbHandle->prepare($query);

        $statement->bindParam(':submit_record_id', $submitRecordId, \PDO::PARAM_INT);
        $statement->bindParam(':label', $label, \PDO::PARAM_STR);
        $executeResult = $statement->execute();

        $statement = $this->getDatabase()->checkQueryError($statement, $executeResult);
        return $statement->fetch(\PDO::FETCH_ASSOC);
    }
1321462
protected function add_plugin_submission_elements($submission,
                                                    MoodleQuickForm $mform,
                                                    stdClass $data,
                                                    $userid) {
        foreach ($this->submissionplugins as $plugin) {
            if ($plugin->is_enabled() && $plugin->is_visible() && $plugin->allow_submissions()) {
                $plugin->get_form_elements_for_user($submission, $mform, $data, $userid);
            }
        }
    }
594336
public function format_submission_for_log(stdClass $submission) {
        global $DB;

        $info = '';
        if ($submission->userid) {
            $user = $DB->get_record('user', array('id' => $submission->userid), '*', MUST_EXIST);
            $name = fullname($user);
        } else {
            $group = $this->get_submission_group($submission->userid);
            if ($group) {
                $name = $group->name;
            } else {
                $name = get_string('defaultteam', 'assign');
            }
        }
        $status = get_string('submissionstatus_' . $submission->status, 'assign');
        $params = array('id'=>$submission->userid, 'fullname'=>$name, 'status'=>$status);
        $info .= get_string('submissionlog', 'assign', $params) . ' <br>';

        foreach ($this->submissionplugins as $plugin) {
            if ($plugin->is_enabled() && $plugin->is_visible()) {
                $info .= '<br>' . $plugin->format_for_log($submission);
            }
        }

        return $info;
    }
1033299
public static function delete_submission($submissionid) {
        global $USER, $DB;

        $params = self::validate_parameters(self::delete_submission_parameters(), array('submissionid' => $submissionid));
        $warnings = array();

        // Get and validate the submission and workshop.
        $submission = $DB->get_record('workshop_submissions', array('id' => $params['submissionid']), '*', MUST_EXIST);
        list($workshop, $course, $cm, $context) = self::validate_workshop($submission->workshopid);

        // Check if we can delete the submission.
        if (!has_capability('mod/workshop:deletesubmissions', $context)) {
            require_capability('mod/workshop:submit', $context);
            // We can delete our own submission, on time and not yet assessed.
            $candeletesubmission = $submission->authorid == $USER->id;
            $candeletesubmission = $candeletesubmission && $workshop->modifying_submission_allowed($USER->id);
            $candeletesubmission = $candeletesubmission && count($workshop->get_assessments_of_submission($submission->id)) == 0;
            if (!$candeletesubmission) {
                throw new moodle_exception('nopermissions', 'error', '', 'delete submission');
            }
        }

        $workshop->delete_submission($submission);

        return array(
            'status' => true,
            'warnings' => $warnings
        );
    }
599055
public static function create_from_submission(\assign $assign, \stdClass $submission) {
        $data = array(
            'context' => $assign->get_context(),
            'objectid' => $submission->id
        );
        self::$preventcreatecall = false;
        /** @var statement_accepted $event */
        $event = self::create($data);
        self::$preventcreatecall = true;
        $event->set_assign($assign);
        $event->add_record_snapshot('assign_submission', $submission);
        return $event;
    }
903100
public function addSubmitButton($value = 'Save', array $classes = null)
    {
        $this->add(
            [
                'name'       => 'submit',
                'type'       => Submit::class,
                'attributes' => [
                    'value' => $value,
                    'class' => (! is_null($classes) ? join(' ', $classes) : 'btn btn-primary'),
                ],
            ]
        );
    }
335588
public function save(stdClass $submission, stdClass $data) {
        global $USER, $DB;

        $fileoptions = $this->get_file_options();

        $data = file_postupdate_standard_filemanager($data,
                                                     'files',
                                                     $fileoptions,
                                                     $this->assignment->get_context(),
                                                     'assignsubmission_file',
                                                     ASSIGNSUBMISSION_FILE_FILEAREA,
                                                     $submission->id);

        $filesubmission = $this->get_file_submission($submission->id);

        // Plagiarism code event trigger when files are uploaded.

        $fs = get_file_storage();
        $files = $fs->get_area_files($this->assignment->get_context()->id,
                                     'assignsubmission_file',
                                     ASSIGNSUBMISSION_FILE_FILEAREA,
                                     $submission->id,
                                     'id',
                                     false);

        $count = $this->count_files($submission->id, ASSIGNSUBMISSION_FILE_FILEAREA);

        $params = array(
            'context' => context_module::instance($this->assignment->get_course_module()->id),
            'courseid' => $this->assignment->get_course()->id,
            'objectid' => $submission->id,
            'other' => array(
                'content' => '',
                'pathnamehashes' => array_keys($files)
            )
        );
        if (!empty($submission->userid) && ($submission->userid != $USER->id)) {
            $params['relateduserid'] = $submission->userid;
        }
        if ($this->assignment->is_blind_marking()) {
            $params['anonymous'] = 1;
        }
        $event = \assignsubmission_file\event\assessable_uploaded::create($params);
        $event->set_legacy_files($files);
        $event->trigger();

        $groupname = null;
        $groupid = 0;
        // Get the group name as other fields are not transcribed in the logs and this information is important.
        if (empty($submission->userid) && !empty($submission->groupid)) {
            $groupname = $DB->get_field('groups', 'name', array('id' => $submission->groupid), MUST_EXIST);
            $groupid = $submission->groupid;
        } else {
            $params['relateduserid'] = $submission->userid;
        }

        // Unset the objectid and other field from params for use in submission events.
        unset($params['objectid']);
        unset($params['other']);
        $params['other'] = array(
            'submissionid' => $submission->id,
            'submissionattempt' => $submission->attemptnumber,
            'submissionstatus' => $submission->status,
            'filesubmissioncount' => $count,
            'groupid' => $groupid,
            'groupname' => $groupname
        );

        if ($filesubmission) {
            $filesubmission->numfiles = $this->count_files($submission->id,
                                                           ASSIGNSUBMISSION_FILE_FILEAREA);
            $updatestatus = $DB->update_record('assignsubmission_file', $filesubmission);
            $params['objectid'] = $filesubmission->id;

            $event = \assignsubmission_file\event\submission_updated::create($params);
            $event->set_assign($this->assignment);
            $event->trigger();
            return $updatestatus;
        } else {
            $filesubmission = new stdClass();
            $filesubmission->numfiles = $this->count_files($submission->id,
                                                           ASSIGNSUBMISSION_FILE_FILEAREA);
            $filesubmission->submission = $submission->id;
            $filesubmission->assignment = $this->assignment->get_instance()->id;
            $filesubmission->id = $DB->insert_record('assignsubmission_file', $filesubmission);
            $params['objectid'] = $filesubmission->id;

            $event = \assignsubmission_file\event\submission_created::create($params);
            $event->set_assign($this->assignment);
            $event->trigger();
            return $filesubmission->id > 0;
        }
    }
670858
public function save_submission(stdClass $data, & $notices) {
        global $CFG, $USER, $DB;

        $userid = $USER->id;
        if (!empty($data->userid)) {
            $userid = $data->userid;
        }

        $user = clone($USER);
        if ($userid == $USER->id) {
            require_capability('mod/assign:submit', $this->context);
        } else {
            $user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
            if (!$this->can_edit_submission($userid, $USER->id)) {
                print_error('nopermission');
            }
        }
        $instance = $this->get_instance();

        if ($instance->teamsubmission) {
            $submission = $this->get_group_submission($userid, 0, true);
        } else {
            $submission = $this->get_user_submission($userid, true);
        }

        if ($this->new_submission_empty($data)) {
            $notices[] = get_string('submissionempty', 'mod_assign');
            return false;
        }

        // Check that no one has modified the submission since we started looking at it.
        if (isset($data->lastmodified) && ($submission->timemodified > $data->lastmodified)) {
            // Another user has submitted something. Notify the current user.
            if ($submission->status !== ASSIGN_SUBMISSION_STATUS_NEW) {
                $notices[] = $instance->teamsubmission ? get_string('submissionmodifiedgroup', 'mod_assign')
                                                       : get_string('submissionmodified', 'mod_assign');
                return false;
            }
        }

        if ($instance->submissiondrafts) {
            $submission->status = ASSIGN_SUBMISSION_STATUS_DRAFT;
        } else {
            $submission->status = ASSIGN_SUBMISSION_STATUS_SUBMITTED;
        }

        $flags = $this->get_user_flags($userid, false);

        // Get the flags to check if it is locked.
        if ($flags && $flags->locked) {
            print_error('submissionslocked', 'assign');
            return true;
        }

        $pluginerror = false;
        foreach ($this->submissionplugins as $plugin) {
            if ($plugin->is_enabled() && $plugin->is_visible()) {
                if (!$plugin->save($submission, $data)) {
                    $notices[] = $plugin->get_error();
                    $pluginerror = true;
                }
            }
        }

        $allempty = $this->submission_empty($submission);
        if ($pluginerror || $allempty) {
            if ($allempty) {
                $notices[] = get_string('submissionempty', 'mod_assign');
            }
            return false;
        }

        $this->update_submission($submission, $userid, true, $instance->teamsubmission);

        if ($instance->teamsubmission && !$instance->requireallteammemberssubmit) {
            $team = $this->get_submission_group_members($submission->groupid, true);

            foreach ($team as $member) {
                if ($member->id != $userid) {
                    $membersubmission = clone($submission);
                    $this->update_submission($membersubmission, $member->id, true, $instance->teamsubmission);
                }
            }
        }

        // Logging.
        if (isset($data->submissionstatement) && ($userid == $USER->id)) {
            \mod_assign\event\statement_accepted::create_from_submission($this, $submission)->trigger();
        }

        $complete = COMPLETION_INCOMPLETE;
        if ($submission->status == ASSIGN_SUBMISSION_STATUS_SUBMITTED) {
            $complete = COMPLETION_COMPLETE;
        }
        $completion = new completion_info($this->get_course());
        if ($completion->is_enabled($this->get_course_module()) && $instance->completionsubmit) {
            $completion->update_state($this->get_course_module(), $complete, $userid);
        }

        if (!$instance->submissiondrafts) {
            $this->notify_student_submission_receipt($submission);
            $this->notify_graders($submission);
            \mod_assign\event\assessable_submitted::create_from_submission($this, $submission, true)->trigger();
        }
        return true;
    }
1315869
public static function save_submission_parameters() {
        global $CFG;
        $instance = new assign(null, null, null);
        $pluginsubmissionparams = array();

        foreach ($instance->get_submission_plugins() as $plugin) {
            if ($plugin->is_visible()) {
                $pluginparams = $plugin->get_external_parameters();
                if (!empty($pluginparams)) {
                    $pluginsubmissionparams = array_merge($pluginsubmissionparams, $pluginparams);
                }
            }
        }

        return new external_function_parameters(
            array(
                'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
                'plugindata' => new external_single_structure(
                    $pluginsubmissionparams
                )
            )
        );
    }