Storing image "attachements" with text fields -- hard problem!

Storing image "attachements" with text fields -- hard problem!

by Martín Langhoff -
Number of replies: 8

Mihai Sucan is doing an amazing job with his Paintweb GSoC project. It is really outstanding, Paintweb has gotten much better, it works (fast!) on the XO, he's gotten it integrated with TinyMCE and it has all been fantastic.

Until now, and we're going in circles with something that has turned out to be much much harder than expected. Personally, I am a bit lost.

With Paintweb enabled, tinymce users can create or edit an image with their HTML. This is great -- except that we now have "attachments" to all these textareas... where do we save them?

  • Naturally, we want to add this support to any code that uses moodleforms with textareas, without having to add explicit support in every location in the code that defines a form. Unfortunately, I can't see how to do it...

  • We can post the images base64 encoded with the form, or save them ahead of time with an ajaxy entry point.

  • We need to keep them with the textarea. Modern HTML supports 'dataURLs' which means that the image is base64-encoded in the HTML. That makes resource management easy -- backup, restore, deletion, copy all work. But from a performance PoV it is a mess -- just the traffic from PHP to the DB goes insane. And we would have to "upgrade" all our textfiedls to a really large datatype because the images are big.

  • Even if we use dataURLs to store things -- which resolves the resource management, but is murder on our DB -- we can serve them separately by using a filter to extract the dataURLs and serve them as images, so they are cacheable, etc.

  • The images don't belong in course files, because only some teachers can store files there -- and this is fun for kids!

  • The images don't belong in user files -- they are clearly beign used in a particular resource - a modinstance for example.

  • If we are to store them separately, we need to figure out what 'data object' they belong to. How?

  • Naturally, there are security issues. Only serve the image when appropriate. Only store an image when the form submission was received and saved successfully.

  • Moodleforms is not a lot of help because it doesn't know what table and id we are editing (when editing) and in the case of new records, we don't have an id. And of course it may be a complex bit of data that lands in 3 tables.

Mihai hasn't been short on ideas, but I had to shoot them all down -- which I definitely don't enjoy doing.

...What to do?

My only "bright" idea is to have a single call right after every successful insert/update, where we say

update_image_blobs($tablename, $recid, array( $rec->sometextfield, $rec->othertextfield))

And that would feed into a "reference trcking" table. Backup/restore code would then be able to take hints from there.

We could also run through the whole DB on a cronob to build or 'reference tracking' table. That sound? It's my teeth grinding at the idea mixed

Or we could use a content filter to build the ref tracking... except that the flter code has no idea about the table-and-recid.

On the access control front we do have a reasonably good approach to ensure we only serve images to users who can see the HTML that they are associated with. The images are named (and served) with the sha1 of their content, and are not browsable. Because of that, you can only know the url of an image if you have seen the image.

Naturally, someone can share the URL with others... but that would be equivalent to sharing the image itself, which people can do anyway. This is the one case where obscurity seems to be a good mechanism for security. (Until Petr beats me up about it wink )

Overall, we need a reasonable plan that doesn't involve ripping apart all the forms in moodle.

Ideas? Please?

Average of ratings: -
In reply to Martín Langhoff

Re: Storing image "attachements" with text fields -- hard problem!

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
This is EXACTLY what the new File API in Moodle 2.0 is about, storing and serving files securely attached to images and modules. It sounds like you are reinventing some wheels there!

Every textarea now has a "filearea" associated with it, and this information is given to the HTML editor (and is thus accessible to the paint editor).

You basically just have to get the save button in paint program to call a script to save the data in the filearea of the current text, in just the same way as the File picker works.

Some of the finer details of the API may yet change (Petr is actively working on it), but these should get you started:

http://docs.moodle.org/en/Development:Using_the_File_API

http://docs.moodle.org/en/Development:Using_the_File_API_in_Moodle_forms (not as relevant to you)

...and especially see my midterm feedback http://docs.moodle.org/en/Development_talk:Paint_tool wink
In reply to Martin Dougiamas

Re: Storing image "attachements" with text fields -- hard problem!

by Mihai Sucan -
First of all, thanks to Martin Langhoff for his words of appreciation about my work. I enjoy working and I really want to have a very good paint tool which is properly integrated into Moodle 1.9 and 2.0.

I do not mind at all having my ideas "shot down" - you have certainly provided valid technical arguments.

Martin Dougiamas: I am glad to hear that the new File API specifically solves this problem in Moodle 2 - it's great. I looked into the API and once I'll work on the Moodle 2 integration I will certainly use the new functionality.

However, we are currently working with Moodle 1.9 to complete the integration. Do you have any ideas what we could do? You're indeed correct saying we are almost going for "reinventing some wheels". Still, we should find a solution which is sufficiently acceptable.

If you want to see what I did, you can check out the following wiki page:

http://docs.moodle.org/en/Development:Paint_tool_integration#Results:_Moodle_1.9_integration

You can also get the code from the Git repo I have published. (details in the wiki page)

Thanks for your reply.
In reply to Mihai Sucan

Re: Storing image "attachements" with text fields -- hard problem!

by Martin Dougiamas -
Picture of Core developers Picture of Documentation writers Picture of Moodle HQ Picture of Particularly helpful Moodlers Picture of Plugin developers Picture of Testers
If you are making it as a patch for 1.9 then it's pretty much for the OLPC project only. We can't add new features like this to the stable branch.

However, if the integration was done in the next couple of months with 2.0 in mind then it COULD make it into Moodle 2.0 (and I would very much like to see that). Personally I would target 2.0 first and port it backwards to 1.9 later.

For a 1.9 patch the URLs for displaying the images should be exactly the same (and you should provide some sane sort of upgrade script to upgrade the file locations in 2.0), otherwise people will lose their images when they upgrade to 2.0.
In reply to Martin Dougiamas

Re: Storing image "attachements" with text fields -- hard problem!

by Martín Langhoff -
Great to hear the File API has support for this -- I talked with Petr early in the game, but haven't kept in touch about it.

Happy to work w Mihai on getting it going on 2.0.

I think both Mihai and I are keen on hacking something up for 1.9. The 1.9 implementation doesn't need to be the prettiest thing as long as it works.
In reply to Martín Langhoff

Re: Storing image "attachements" with text fields -- hard problem!

by Mihai Sucan -
This sounds like a plan in the works.

Shall I now focus on making the PaintWeb integration work in Moodle 2? With the new File API and the new WYSIWYG editor embedding API (is it done?).

Once that's done we'll return to Moodle 1.9 and see what we can hack. Agreed?

Or I complete the integration work on Moodle 1.9 now? If yes, please email me the details on what you've decided I should hack to make image file saving work sufficiently nice.

I'd quite like very much to complete the PaintWeb integration work in time for the Moodle 2.0 release. I believe I can do it. I just need the WYSIWYG editor embedding API.

Thanks for the replies to both.
In reply to Mihai Sucan

Re: Storing image "attachements" with text fields -- hard problem!

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
The only workable solution I can see for 1.9 is data urls, and you will just have to live with all the suckiness.

Can you make it less bad by crushing the PNGs to limited colours somehow?
In reply to Tim Hunt

Re: Storing image "attachements" with text fields -- hard problem!

by Mihai Sucan -
Hmm, ok then. I'll see what Martin Langhoff decides, but in my opinion using data URLs is far worse than having a half-baked solution server-side. The paint tool will end up pretty much unusable on the OLPC XO (perf issues and perhaps even browser crashes - too much memory usage or such).

Crushing PNGs to limited colors is not an option given by browsers. It could be "hard-coded" from JS, but that would run very slow (pixel-by-pixel processing).
In reply to Mihai Sucan

Re: Storing image "attachements" with text fields -- hard problem!

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers
Ah, well if data URLs do not work on the XO, then you will have to do something else. Don't know what though. The File API changes in 2.0 are requiring us to change every form.