Forums | Mahara Community

Developers /
Failed to save in database


Noraini's profile picture
Posts: 13

02 November 2017, 2:02 PM

Hi everyone,

i'm new in using mahara template and I'm having problem to save form in database. The error that i get is "Failed to update your evaluation ".

i'm not really understand the step for saving data in database. so i just copy form from artefact/resume/personalinformation and modify the code.

i create new form in file admin/users/view_testimoni.php and display in file artefact/resume/index.tpl. 

This is the code for field in the form:

$personalinformationform = pieform(array(
    'name'        => 'testimonial',
    'plugintype'  => 'artefact',
    'pluginname'  => 'resume',
    'jsform'      => true,
    'method'      => 'post',
    'class'       => 'form-group-nested',
    'elements'    => array(
        'studentname' => array(
                    'type' => 'text',
                    'defaultvalue' => param_integer('id'),
                    'title' => get_string('studentname', 'artefact.resume'),
                    'size' => 30,
                    'readonly' => true,
                ),
        'testimony' => array(
            'type' => 'wysiwyg',
            'rows' => 10,
            'cols' => 50,
            'rules' => array('maxlength' => 65536),
            'title' => get_string('testimony', 'artefact.resume'),
        ),
        'save' => array(
            'type'  => 'submitcancel',
            'value' => array(get_string('save'), get_string('back')),
            'goto'  => get_config('wwwroot') . 'admin/users/testimonial.php',
        ),
    ),
));

 

This is the function when submit form:

function testimonial_submit(Pieform $form, $values) {
    global $personalinformation, $USER;
    $userid = $USER->get('id');
    $errors = array();

    try {
        if (empty($personalinformation)) {
            $personalinformation = new ArtefactTypeTestimonial(0, array(
                'owner' => $userid,
                'title' => get_string('testimonial', 'artefact.resume'),
            ));
        }
        foreach (array_keys(ArtefactTypeTestimonial::get_composite_fields()) as $field) {
            $personalinformation->set_composite($field, $values[$field]);
        }
        $personalinformation->commit();
    }
    catch (Exception $e) {
        $errors['testimonial'] = true;
    }
    
    if (empty($errors)) {
        $form->json_reply(PIEFORM_OK, get_string('testimonialsaved','artefact.resume'));
    }
    else {
        $message = '';
        foreach (array_keys($errors) as $key) {
            $message .= get_string('testimonialsavefailed', 'artefact.resume')."\n";
            // $message .= print_r($key);
        }
        $form->json_reply(PIEFORM_ERR, $message);
    }
}

This is the class i added in file artefact/resume/lib.php :

class ArtefactTypeTestimonial extends ArtefactTypeResume {

    protected $composites;

    public function __construct($id=0, $data=null) {
        if (empty($id)) {
            $data['title'] = get_string('testimonial', 'artefact.resume');
        }
        parent::__construct($id, $data);
        $this->composites = ArtefactTypeTestimonial::get_composite_fields();
        if (!empty($id)) {
            $this->composites = (array)get_record('artefact_resume_testimonial', 'artefact', $id,
                null, null, '*, ');
        }
    }

    public function set_composite($field, $value) {
        if (!array_key_exists($field, $this->composites)) {
            throw new InvalidArgumentException("Tried to set a non existant composite, $field");
        }
        if ($this->composites[$field] == $value) {
            return true;
        }
        // only set it to dirty if it's changed
        $this->dirty = true;
        $this->mtime = time();
        $this->composites[$field] = $value;
    }

    public function get_composite($field) {
        return $this->composites[$field];
    }

    public function commit() {
        if (empty($this->dirty)) {
            return true;
        }

        db_begin();

        $data = new StdClass;
        $have_composites = false;
        foreach ($this->composites as $field => $value) {
            if ($field != 'artefact' && !empty($value)) {
                $have_composites = true;
            }
            $data->{$field} = $value;
        }
        if (!$have_composites) {
            if (!empty($this->id)) {
                // need to delete empty personal information
                $this->delete();
            }
            db_commit();
            return true;
        }
        $inserting = empty($this->id);
        parent::commit();
        $data->artefact = $this->id;
        if ($inserting) {
            insert_record('artefact_resume_testimonial', $data);
        }
        else {
            update_record('artefact_resume_testimonial', $data, 'artefact');
        }

        db_commit();
    }

    public static function get_composite_fields() {
        static $composites = array(
            'usr_id' => null,
            'testimony' => null,
        );
        return $composites;
    }

    public static function is_singular() {
        return true;
    }

    public static function render_fields(ArtefactTypeTestimonial $a=null, $options=array(), $values=null) {
        $smarty = smarty_core();
        $fields = array();
        foreach (array_keys(ArtefactTypeTestimonial::get_composite_fields()) as $field) {
            if ($values && isset($values[$field])) {
                $value = $values[$field];
            }
            else if ($a) {
                $value = $a->get_composite($field);
            }
            else {
                continue;
            }
            $fields[get_string($field, 'artefact.resume')] = $value;
        }
        $smarty->assign('fields', $fields);
        if ($a) {
            $a->render_license($options, $smarty);
        }
        return $smarty->fetch('admin:users:fragments/testimonial.tpl');
    }

    public function render_self($options) {
        return array('html' => self::render_fields($this, $options), 'javascript' => '');
    }

    public static function render_import_entry_request($entry_content, $renderfields=array()) {
        return self::render_fields(null, array(), $entry_content);
    }

    public function delete() {
        db_begin();

        delete_records('artefact_resume_testimonial', 'artefact', $this->id);
        parent::delete();

        db_commit();
    }

    public static function bulk_delete($artefactids, $log=false) {
        if (empty($artefactids)) {
            return;
        }

        $idstr = join(',', array_map('intval', $artefactids));

        db_begin();
        delete_records_select('artefact_resume_testimonial', 'artefact IN (' . $idstr . ')');
        parent::bulk_delete($artefactids);
        db_commit();
    }
}

and this is table structure artefact_resume_testimonial:

artefact_resume_testimonial.JPG

 

Really appreciate if someone can guide me.

Thank you.

Noraini

Cecilia Vela's profile picture
Posts: 19

03 November 2017, 3:42 PM

Hi Noraini,

What I can see from the code, it might not be working because the artefact is not installed in the DB.

To see the exact place in the code, please check in the __construct() function of the ArtefactTypeTestimonial class that you have the following line that fails:

    parent::__construct($id, $data);

If we look into the __construct() function of the parent class (ArtefactTypeResume), we find that it calls

    get_artefact_type()

This function will throw an exception if the artefact is not installed in the DB in table 'artefact_installed_type'.

Please see the example here https://reviews.mahara.org/#/c/7434 of a way to define an artefact in the system.

I hope this helps you,
Cecilia

Noraini's profile picture
Posts: 13

08 November 2017, 5:48 PM

Hi Cecilia,

 Sorry for late response.

Yeah that's solved my problem. Just like you said the artefact is not installed in db. So i just add data as below in table 'artefact_installed_type':

name : testimonial

plugin : resume

 

Thank you Cecilia for your help. Really appreciate it.

3 results