Problem copying text to DB

Problem copying text to DB

by Lloyd Thomas -
Number of replies: 31

My plugin has a template option where you can copy the settings from one plugin instance to another. For some reason I cannot copy the text ($template_get->intro) from the original instance ($template_get). All the other columns are inserted correctly. Even if I statically set the var it wont install, but the text sent from the form will insert. Confused!

$template_get = $DB->get_record('simplefeedback', array('id'=>$simplefeedback->prev));
        $tempdata->name = $simplefeedback->name;
        $tempdata->section = $simplefeedback->section;
        $tempdata->fbtemplate = '0';
        $tempdata->introformat = $simplefeedback->introformat;
        $tempdata->fbcreatorid = $simplefeedback->fbcreatorid;
        $tempdata->course = $simplefeedback->course; 
           //$simplefeedback->intro enters fine but $template_get->intro is empty even though I can print it.
         //$template_get->intro = 'Test text<br><p><br></p>';
           if(!empty($simplefeedback->intro)){
                $tempdata->intro = $simplefeedback->intro; //this works!
            }
            else{
                $tempdata->intro = $template_get->intro;
            } 
            if($simplefeedback->fbanon > 0){
                $tempdata->fbanon = $simplefeedback->fbanon;
            }
            else{
               $tempdata->fbanon = $template_get->fbanon;
            }
$status = $DB->insert_record("simplefeedback", $tempdata);


Average of ratings: -
In reply to Lloyd Thomas

Re: Problem copying text to DB

by Lloyd Thomas -
Any takers? I am absolutely stumped! Only text from input form seems to go in.
In reply to Lloyd Thomas

Re: Problem copying text to DB

by Davo Smith -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Have you tried using xdebug to set a breakpoint on the $DB->insert_record() line of code and then step into the function?

That's usually the best way to figure out what is going wrong with strange bugs like this.


In reply to Davo Smith

Re: Problem copying text to DB

by Lloyd Thomas -

Thanks for that, never used xdebug before. in the meantime I wrote a new function to sql copy from one one to another and it still didn't work within Moodle.

 //hack to clone feedback intro *** sooooo bad
function simplefeedback_clone_intro($newId,$oldId){
    global $DB;
    $result = false;
    $DB->set_debug(true);
    $result = $DB->execute('UPDATE {simplefeedback} AS target
    LEFT JOIN {simplefeedback} AS source ON source.id = '.$oldId.'
      SET target.intro = source.intro
    WHERE target.id ='.$newId);
    $DB->set_debug(false);
   
    return $result;
}

The resulting sql works fine if I run it natively (MySQL Workbench)

UPDATE mdl_simplefeedback AS target LEFT JOIN mdl_simplefeedback AS source ON source.id = 1 SET target.intro = source.intro WHERE target.id =52

So confused!!!!

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Can you show the structure of the table and the contents of the record you are using?

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Table Structure

CREATE TABLE `mdl_simplefeedback` (
  `id` bigint(10) NOT NULL AUTO_INCREMENT,
  `course` bigint(10) NOT NULL DEFAULT '0',
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `intro` longtext COLLATE utf8_unicode_ci,
  `introformat` smallint(4) NOT NULL DEFAULT '0',
  `timecreated` bigint(10) NOT NULL,
  `timemodified` bigint(10) NOT NULL DEFAULT '0',
  `fbstart` bigint(10) NOT NULL,
  `fbend` bigint(10) NOT NULL,
  `fbcreatorid` bigint(10) NOT NULL,
  `fbanon` bigint(10) NOT NULL DEFAULT '0',
  `fbanonlimit` int(10) NOT NULL DEFAULT '0',
  `fbqualratio` int(11) NOT NULL DEFAULT '0',
  `fbrespgrp` bigint(10) NOT NULL DEFAULT '0',
  `fbtemplate` bigint(10) NOT NULL DEFAULT '0',
  `fbalert` bigint(10) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  KEY `mdl_simp_cou_ix` (`course`)
) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Main Simple Feedback table.';


The record I am coping

# id, course, name, intro, introformat, timecreated, timemodified, fbstart, fbend, fbcreatorid, fbanon, fbanonlimit, fbqualratio, fbrespgrp, fbtemplate, fbalert
'1', '14', 'Test 13', 'Test text<br><p><br></p>', '1', '1464271622', '1475068824', '0', '0', '191', '1', '50', '50', '1', '1', '0'

I am just wondering if there is some kind of sanity check that compares the initial input to the what is being entered into the DB.

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers
I think there's something more happening in your code than we can see... I created this test file:

<?php
require_once("config.php");

$record = new stdClass();
$record->course = 14;
$record->name = 'Test 13';
$record->intro = 'Test text<br><p><br></p>';
$record->introformat = 1;
$record->timecreated = 1464271622;
$record->timemodified = 1475068824;
$record->fbstart = 0;
$record->fbend = 0;
$record->fbcreatorid = 191;
$record->fbanon = 1;
$record->fbanonlimit = 50;
$record->fbqualratio = 50;
$record->fbrespgrp = 1;
$record->fbtemplate = 1;
$record->fbalert = 0;

$newid = $DB->insert_record('simplefeedback', $record);

$oldrecord = $DB->get_record('simplefeedback', ['id' => $newid]);
print_object($oldrecord);

$newrecord = new stdClass();
$newrecord->course = $oldrecord->course;
$newrecord->name = $oldrecord->name;
$newrecord->intro = $oldrecord->intro;
$newrecord->introformat = $oldrecord->introformat;
$newrecord->timecreated = $oldrecord->timecreated;
$newrecord->timemodified = $oldrecord->timemodified;
$newrecord->fbstart = $oldrecord->fbstart;
$newrecord->fbend = $oldrecord->fbend;
$newrecord->fbcreatorid = $oldrecord->fbcreatorid;
$newrecord->fbanon = $oldrecord->fbanon;
$newrecord->fbanonlimit = $oldrecord->fbanonlimit;
$newrecord->fbqualratio = $oldrecord->fbqualratio;
$newrecord->fbrespgrp = $oldrecord->fbrespgrp;
$newrecord->fbtemplate = $oldrecord->fbtemplate;
$newrecord->fbalert = $oldrecord->fbalert;

$newid = $DB->insert_record('simplefeedback', $newrecord);

$oldrecord = $DB->get_record('simplefeedback', ['id' => $newid]);
print_object($oldrecord);

The output looks like this:
stdClass Object
(
    [id] => 59
    [course] => 14
    [name] => Test 13
    [intro] => Test text<br><p><br></p>
    [introformat] => 1
    [timecreated] => 1464271622
    [timemodified] => 1475068824
    [fbstart] => 0
    [fbend] => 0
    [fbcreatorid] => 191
    [fbanon] => 1
    [fbanonlimit] => 50
    [fbqualratio] => 50
    [fbrespgrp] => 1
    [fbtemplate] => 1
    [fbalert] => 0
)
stdClass Object
(
    [id] => 60
    [course] => 14
    [name] => Test 13
    [intro] => Test text<br><p><br></p>
    [introformat] => 1
    [timecreated] => 1464271622
    [timemodified] => 1475068824
    [fbstart] => 0
    [fbend] => 0
    [fbcreatorid] => 191
    [fbanon] => 1
    [fbanonlimit] => 50
    [fbqualratio] => 50
    [fbrespgrp] => 1
    [fbtemplate] => 1
    [fbalert] => 0
)
Seems like what you are doing should work fine?

mike
In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Could be. Just seems really strange that it is only affecting the 'intro' field. I tried tagging some extra charaters onto the submitted and the extra characters were striped away. Maybe I should be dealing with this in lib.php instead of the locallib.php?!

$tempdata->intro = $simplefeedback->intro; // this works
$tempdata->intro = $simplefeedback->intro.'Hello'; //the additioanl 'Hello' is striped away.
In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Do you have full developer debugging enabled with message being displayed? Maybe there's a useful message there somewhere?

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Yes. I have fixed every instance if intro to just 'test' and still the submited textarea is entered into DB

Debug messages below. Nothing I wasn't expecting. sad


Trying to add help buttons to non-existent form elements : respondenttype
  • line 1913 of /lib/formslib.php: call to debugging()
  • line 88 of /mod/simplefeedback/mod_form.php: call to MoodleQuickForm->addHelpButton()
  • line 192 of /lib/formslib.php: call to mod_simplefeedback_mod_form->definition()
  • line 86 of /course/moodleform_mod.php: call to moodleform->__construct()
  • line 254 of /course/modedit.php: call to moodleform_mod->__construct()
Trying to add help buttons to non-existent form elements : respondenttype
  • line 1913 of /lib/formslib.php: call to debugging()
  • line 90 of /mod/simplefeedback/mod_form.php: call to MoodleQuickForm->addHelpButton()
  • line 192 of /lib/formslib.php: call to mod_simplefeedback_mod_form->definition()
  • line 86 of /course/moodleform_mod.php: call to moodleform->__construct()
  • line 254 of /course/modedit.php: call to moodleform_mod->__construct()
Trying to add help buttons to non-existent form elements : respondenttype
  • line 1913 of /lib/formslib.php: call to debugging()
  • line 92 of /mod/simplefeedback/mod_form.php: call to MoodleQuickForm->addHelpButton()
  • line 192 of /lib/formslib.php: call to mod_simplefeedback_mod_form->definition()
  • line 86 of /course/moodleform_mod.php: call to moodleform->__construct()
  • line 254 of /course/modedit.php: call to moodleform_mod->__construct()

Notice: Trying to get property of non-object in /var/www/moodle/html/mod/simplefeedback/mod_form.php on line 104

Trying to add help buttons to non-existent form elements : respondenttype
  • line 1913 of /lib/formslib.php: call to debugging()
  • line 163 of /mod/simplefeedback/mod_form.php: call to MoodleQuickForm->addHelpButton()
  • line 192 of /lib/formslib.php: call to mod_simplefeedback_mod_form->definition()
  • line 86 of /course/moodleform_mod.php: call to moodleform->__construct()
  • line 254 of /course/modedit.php: call to moodleform_mod->__construct()

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Michael Aherne -
Picture of Core developers Picture of Peer reviewers Picture of Plugin developers

Have you tried doing a var_dump() on the original intro value to check it's definitely a string? If the intro has come from a text editor it might be an array of text and format, which could cause strange behaviour if you try to concatenate a string with it.

In reply to Michael Aherne

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

You can also use Moodle's "print_object" helper function. It formats the output of "print_r", similar to "var_dump".

I would use one of these before and after the line in question to see what is happening.

By the way, I added ".'Hello'" to my intro assignment line in the test code above and it worked as expected.

You asked about putting the code in "lib.php" vs. "locallib.php". There is nothing in Moodle that would care about that.

The onlu other think I can suggest is to post the entire plugin as a zip file here and we can take a better look at it.

mike

Average of ratings: Useful (1)
In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

print_object result

object Object
(
    [name] => clone 55555
    [section] => 1
    [fbtemplate] => 0
    [timecreated] => 1475315819
    [timemodified] => 1475315819
    [intro] => <p>test text<br></p>
    [introformat] => 1
    [fbcreatorid] => 191
    [fbanon] => 0
    [fbanonlimit] => 0
    [fbqualratio] => 0
    [course] => 14
    [fbrespgrp] => 0
    [fbstart] => 0
    [fbend] => 0
    [create] => 1
    [coursemodule] => 3453
)

var_dump result

object(object)#656 (17) {
  ["name"]=>
  string(8) "clone 66"
  ["section"]=>
  int(1)
  ["fbtemplate"]=>
  string(1) "0"
  ["timecreated"]=>
  int(1475316258)
  ["timemodified"]=>
  int(1475316258)
  ["intro"]=>
  string(22) "<p>test text 2<br></p>"
  ["introformat"]=>
  string(1) "1"
  ["fbcreatorid"]=>
  string(3) "191"
  ["fbanon"]=>
  string(1) "0"
  ["fbanonlimit"]=>
  string(1) "0"
  ["fbqualratio"]=>
  string(1) "0"
  ["course"]=>
  string(2) "14"
  ["fbrespgrp"]=>
  int(0)
  ["fbstart"]=>
  int(0)
  ["fbend"]=>
  int(0)
  ["create"]=>
  string(1) "1"
  ["coursemodule"]=>
  int(3456)
}

var_dump with cloned data // not working

object(object)#658 (17) {
  ["name"]=>
  string(10) "Clone 6666"
  ["section"]=>
  int(0)
  ["fbtemplate"]=>
  string(1) "0"
  ["timecreated"]=>
  int(1475317054)
  ["timemodified"]=>
  int(1475317054)
  ["introformat"]=>
  string(1) "1"
  ["fbcreatorid"]=>
  string(3) "191"
  ["fbanon"]=>
  string(1) "0"
  ["fbanonlimit"]=>
  string(1) "0"
  ["fbqualratio"]=>
  string(1) "0"
  ["course"]=>
  string(2) "14"
  ["fbrespgrp"]=>
  int(0)
  ["fbstart"]=>
  int(0)
  ["fbend"]=>
  int(0)
  ["create"]=>
  string(1) "1"
  ["coursemodule"]=>
  int(3457)
  ["intro"]=>
  string(24) "Test text<br><p><br></p>"
}



In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Looks like this problem is something to do with JS that is overriding whatever I set 'intro' to. I have set intro to a normal textarea and it works. I would prefer to use the text editor and may have to think of some way to override the element in mod_form.php

//description textbox
        //$this->standard_intro_elements(false, get_string('description'));
        $mform->addElement('textarea', 'intro', get_string('description'), 'wrap="virtual" rows="10" cols="60"');
In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

It really sounds like there is a lot more going on in your script than just the PHP assignment lines. I believe in order to provide any more help, we will need to see the entire script you are using.

mike

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Very far from finished, but apprecite the offer to look at my problem.

Line 57 of mod_form.php is where my problem starts.

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

I'll take a look at this, but some initial questions...

  1. This is an activity module, correct?
  2. Do you have a public git repo with the code in it?
  3. This is for Moodle 3.1?

mike

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

1. Yes

2. No

3. 3.0 (so far)

Here is a temporary link to a zip containing all files

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

First link may not work try THIS one

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Hi Lloyd -

Because you  built this based on two other plugins' code, and haven't completely modified all of the code to the new plugin, I think you should minimize the plugin you are testing to the code you are working on. So, get rid of all of the code that's not relevant yet, and clean up the notification errors. Turn off everything you don't support yet in the 'simplefeedback_supports' function, so that none of that API code gets called. Then test what you are working on bit by bit. As you are ready to add the other features, add back the code and test.

I have a minimal test plugin I use when I run into strange issues like this. It allows me to rule out any API issues. I started to wonder if there was a strange issue revolving around the fact that you weren't using the passed in 'simplefeedback' object to create the new record, and that you didn't change the 'intro' variable in it. I wondered if the create instance API was somehow writing over your new record with that object.

But, I used my minimal plugin to do a quick test, and there is something odd happening there. Here is what I wrote:

function mystream_add_instance($mystream, $mform) {
    global $DB;

    $mystream->timemodified = time();

    $newdata = new stdClass();
    $newdata->course = $mystream->course;
    $newdata->name = $mystream->name;
    $newdata->intro = '<p>Inserted text</p>';
    $newdata->introformat = $mystream->introformat;
    $newdata->timemodified = $mystream->timemodified;

    $id = $DB->insert_record('mystream', $newdata);

    return $id;
}

The record that was created does not contain the text "Inserted text", but contains the text I entered into the intro box!

So I rewrote the add_instance as follows:

function mystream_add_instance($mystream, $mform) {
    global $DB;

    $mystream->timemodified = time();

    $mystream->intro = '<p>Inserted text</p>';
    $mystream->id = $DB->insert_record('mystream', $mystream);

    return $mystream->id;
}

But, same problem. Something in the API is updating the newly created record with the form data.

I created a new discussion to ask about this issue.

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Obviously I willl be following with great interest. Thank you for identifing this bug (or feature).

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Okay. I can see this is still a work in progress, so I won't comment on things not related to the reported issue you are having.

I looked at line 57 of "mod_form.php". That is where you add a textarea element for the intro. I added an instance of the activity and populated the intro box. That seems to have worked.

What do I need to do to see where the problem you are having is?

One thing I did notice is that you had a line to use "standard_intro_elements" in there that was commented out. But the line is wrong. It has an extra parameter in it that shouldn't be there.

Currently, it looks like:  $this->standard_intro_elements(false, get_string('description'));

There should be no "false". It should be:  $this->standard_intro_elements(get_string('description'));

mike

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Ok. while creating one instance of the plugin make it a template in 'content options' by selecting 'private'.

Then create a second a second instance leaving the text area empty and in content options you should be able to select the first instance to copy. My goal is to populate this second instance with data from the first, but I am unable to copy over the 'intro' data.

Just one thing you will probably need to chnage line 70 to $sdata->introformat = $simplefeedback->introformat;

Thanks again for looking.

In reply to Lloyd Thomas

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Okay. Well first, you need to use the 'standard_intro_elements' function as I specified previously (remove the 'false' parameter). If you don't use that function, and add the intro elements manually, you need to add more than the single text box. You see this problem when you edit the settings and save from the warning about the missing "introformat". This is causing the "intro" field to not save correctly.

Next, I added a lot of debug statements. At the end of 'simplefeedback_add_instance' I added a get_record call on the newly created record id. The returned record contained the expected intro text. But, after the execution the text was gone. It seems something runs after that that erases that field.

I also noticed that I could not delete any instance of "simplefeedback". So I ran tests with other modules. I likewise could not delete any instances of them. A Javascript error kept popping up on the console.  I completely uninstalled "simplefeedback" and I was able to delete other module instances.

I'm guessing you have some code in there, javascript or other, that is triggered by edit events in the course? I didn't go looking for it, but something must be there. Wherever it is, it is somehow changing the value of the intro field after the record is created and interfering with all module deletion actions.

mike

In reply to Mike Churchward

Re: Problem copying text to DB

by Dimitar Ivanov -

I also noticed that I could not delete any instance of "simplefeedback". So I ran tests with other modules. I likewise could not delete any instances of them. A Javascript error kept popping up on the console.  I completely uninstalled "simplefeedback" and I was able to delete other module instances.


The cause of this is actually a fatal PHP error.

PHP Fatal error:  Cannot redeclare class restore_feedback_activity_task in <...>mod/simplefeedback/backup/moodle2/restore_simplefeedback_activity_task.class.php on line 114

You should rename all backup_ and restore_ classes in simplefeedback/backup/moodle2/ to fix this.

And I managed to successfully clone the activity using the steps you provided. And the cloned activities had the "intro" text.

But what didn't work was editing an activity. After an edit and save, the intro text is lost.


Hope this helps a little smile



In reply to Dimitar Ivanov

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Hi Dimitar -

How did you locate that error? I wasn't receiving any notice except for the console pop-up.

Are you able to delete any of the simplefeedback instances? After removing the backup files, I could delete other modules, but not simplefeedback.

mike

In reply to Mike Churchward

Re: Problem copying text to DB

by Dimitar Ivanov -

Hi MIke -

>How did you locate that error? I wasn't receiving any notice except for the console pop-up.

This was in the error_log of the web server, I am running Moodle  with debug level DEVELOPER, but pretty sure that FATAL errors would be reported in the lower levels too.

And yes i was able to delete all modules in a course, including simplefeedback.


> Pretty sure this is because the form is not using the "standard_intro_elements" function correctly. If you uncomment that and get rid of the "false" parameter and delete the other "intro" form element, I think you'll be able to edit.


You were correct. Here is what happened after I made these changes.

- Editing an activity now works, and saves the "Intro text" correctly

- Creating a new activity using another one as template does not work anymore.


In summary, using  the non-standard intro form element, works for creating new activity,  and creating activities using another one as template.

Using the standard elements, creating and editing works, creating from template does not.


I don't have much time digging further into this, but it seems the problem lies somewhere in the difference between how those two form elements work.

In reply to Dimitar Ivanov

Re: Problem copying text to DB

by Mike Churchward -
Picture of Core developers Picture of Plugin developers Picture of Testers

Hi Ivan -

But what didn't work was editing an activity. After an edit and save, the intro text is lost.

Pretty sure this is because the form is not using the "standard_intro_elements" function correctly. If you uncomment that and get rid of the "false" parameter and delete the other "intro" form element, I think you'll be able to edit.

In reply to Mike Churchward

Re: Problem copying text to DB

by Lloyd Thomas -

Thanks Mike, will try in the morning and let you know. I didn't think the backup folder would affect things and did not pay much attention to it, was a job for later date.

In reply to Dimitar Ivanov

Re: Problem copying text to DB

by Lloyd Thomas -

Thanks Dimitar for looking. Funny enough I started tidying that up earlier today but did not get time to test. Will let you know how things go.