Moodle
  1. Moodle
  2. MDL-32471

Add support for previews of stored files

    Details

    • Testing Instructions:
      Hide

      Testing difficulty: easy

      1. Embed an image into a HTML editor and save the form (eg. HTML block, module introduction etc).
      2. When the page displays the embedded image, copy the image's URL (something like http://site/pluginfile.php?file=/42/something/something/etc
      3. Paste the URL into your browser's address bar
      4. Modify the URL and append &preview=tinyicon or &preview=thumb to its end
      5. TEST: Make sure a smaller version of the image is displayed

      This is to test the basic functionality. It is not used anywhere in the code yet (to be done once integrated).

      Show
      Testing difficulty: easy 1. Embed an image into a HTML editor and save the form (eg. HTML block, module introduction etc). 2. When the page displays the embedded image, copy the image's URL (something like http://site/pluginfile.php?file=/42/something/something/etc 3. Paste the URL into your browser's address bar 4. Modify the URL and append &preview=tinyicon or &preview=thumb to its end 5. TEST: Make sure a smaller version of the image is displayed This is to test the basic functionality. It is not used anywhere in the code yet (to be done once integrated).
    • Affected Branches:
      MOODLE_23_STABLE
    • Fixed Branches:
      MOODLE_23_STABLE
    • Pull from Repository:
    • Pull Master Branch:
      MDL-32471-thumbnails
    • Rank:
      39356

      Description

      Filepicker needs to display image previews (thumbnail) of internal images.
      The work consists of following parts:

      1) We need to implement resizing of images to thumbnail size and storing them. There should be URL that returns thumbnail instead of a file. So far it seems that the best way to do it is to add parameter to pluginfile.php, something like
      http://WWWMOODLE/pluginfile.php/296/mod_folder/intro/Cloud%2C.jpg?size=thumb
      When the thumbnail is requested we check if it exists and was modified after the file was modified and return it. Otherwise generate and store new thumbnail.

      AFAIK Dongsheng was working on such temporary storages.

      There should be cron that cleans old thumbnails.

      Another question is how many thumbnail sizes do we want to store. For Filepicker we really need two: bigger thumbnail in "icon view mode" (90x90 seems to be a good size here) and smaller icon for "table/list view mode" (16x16). Probably we don't need to store 16x16, we'll just ask browser to scale bigger thumbnail image. MD was suggesting to store something in between (i.e. 75x75), scale it up for thumbnail and scale down for icon.

      2) local repositories (local, recent, user, filesystem, coursefiles) shall return for each file not only URL of filetype image ('thumbnail') but also URL of generated thumbnail (i.e. 'realthumbnail')

      3) repository/filepicker.js must implement lazy loading of the real thumbnails. When page is displayed the 'thumbnail's are shown and filepicker starts requesting in background the images of 'realthumbnail's and replace them.

        Issue Links

          Activity

          Hide
          David Mudrak added a comment -

          I discussed this with Petr today and we agreed on an approach to implement this. To summarize:

          • pluginfile.php will accept a new optional parameter called "preview". Values of the parameter determine the requested preview mode of the file, eg. "thumb" or "tinyicon". These are basically aliases of the requested preview size (like "tinyicon" always returns 16x16 image etc). If the preview parameter is passed and it contains a valid value (there is a whitelist of supported modes), an image representing the file will be served instead of the original file. For 2.3, it is enough to support preview of image files only (ie their thumbnails). However, we had a vision of possibility to generate image previews of PDFs, text documents etc. (at least, they could always display just the icon of the file's mimetype, like desktop OS usually do).
          • Generated preview images will be stored in the filepool, using the system context, component "core", file area "preview", itemid "0", filepath set to the preview mode and filename set to the contenthash of the original file. So for example, the "thumb" preview of the file with the contenthash c3e1cb5c17933d574d6670be0fda4ce73431a9e8 is to be stored in a stored_file like /core/preview/thumb/0cceb8eb37cfdeb3e8677ab5dfaaeb2d210d79d0
          • The user must pass all access checks valid for the original file to be able to see the preview. So the "preview" parameter passed to pluginfile.php must be propagated to all callbacks and at the very end, the send_stored_file() just decides whether to serve the file itself, or its preview.
          • Preview images are generated by GD, not uploaded manually by users. Hence we can consider them as "safe" and we do not need to require forcedownload for them, even if we do force download of the original file.
          • URL to get the preview of any file is unified - via simply adding the preview parameter. Repositories do not need to provide the explicit value for it.

          I implemented the working prototype today and it seems to work well. However, I would really love of Petr finds a minute and reviews the suggested implementation. Note it is not complete yet (eg. cleanup is missing) but the whole machinery should be pretty clear from the patch.

          I believe that the lazy loading of the preview should be easily doable once this is finished: the JavaScript would just try to fetch pluginfile.php?file=/blah/blah/blah&preview=thumb for all displayed files in the browser. If it gets 200 HTTP response, it will replace the icon with the preview. If it gets 404, it will leave the default icon displayed.

          Show
          David Mudrak added a comment - I discussed this with Petr today and we agreed on an approach to implement this. To summarize: pluginfile.php will accept a new optional parameter called "preview". Values of the parameter determine the requested preview mode of the file, eg. "thumb" or "tinyicon". These are basically aliases of the requested preview size (like "tinyicon" always returns 16x16 image etc). If the preview parameter is passed and it contains a valid value (there is a whitelist of supported modes), an image representing the file will be served instead of the original file. For 2.3, it is enough to support preview of image files only (ie their thumbnails). However, we had a vision of possibility to generate image previews of PDFs, text documents etc. (at least, they could always display just the icon of the file's mimetype, like desktop OS usually do). Generated preview images will be stored in the filepool, using the system context, component "core", file area "preview", itemid "0", filepath set to the preview mode and filename set to the contenthash of the original file. So for example, the "thumb" preview of the file with the contenthash c3e1cb5c17933d574d6670be0fda4ce73431a9e8 is to be stored in a stored_file like /core/preview/thumb/0cceb8eb37cfdeb3e8677ab5dfaaeb2d210d79d0 The user must pass all access checks valid for the original file to be able to see the preview. So the "preview" parameter passed to pluginfile.php must be propagated to all callbacks and at the very end, the send_stored_file() just decides whether to serve the file itself, or its preview. Preview images are generated by GD, not uploaded manually by users. Hence we can consider them as "safe" and we do not need to require forcedownload for them, even if we do force download of the original file. URL to get the preview of any file is unified - via simply adding the preview parameter. Repositories do not need to provide the explicit value for it. I implemented the working prototype today and it seems to work well. However, I would really love of Petr finds a minute and reviews the suggested implementation. Note it is not complete yet (eg. cleanup is missing) but the whole machinery should be pretty clear from the patch. I believe that the lazy loading of the preview should be easily doable once this is finished: the JavaScript would just try to fetch pluginfile.php?file=/blah/blah/blah&preview=thumb for all displayed files in the browser. If it gets 200 HTTP response, it will replace the icon with the preview. If it gets 404, it will leave the default icon displayed.
          Hide
          Marina Glancy added a comment -

          David,
          this all sounds very good.

          Please don't forget to check that generated thumbnail was modified not earlier than source file. There is another project going on replacing our local files without changing the fileid.

          One thing is that I don't want to hardcode in filepicker the thumbnail URL building. I would still prefer repositories to return the URL of lazy-loaded thumbnail and icon. There are not only local repositories we have but also external and probably some of them would also want to return their URLs for lazy-loaded thumbnails. And also try to minimize the number of AJAX requests filepicker is doing. If there is no thumbnail to load we should not even request it.

          Thank you!

          Show
          Marina Glancy added a comment - David, this all sounds very good. Please don't forget to check that generated thumbnail was modified not earlier than source file. There is another project going on replacing our local files without changing the fileid. One thing is that I don't want to hardcode in filepicker the thumbnail URL building. I would still prefer repositories to return the URL of lazy-loaded thumbnail and icon. There are not only local repositories we have but also external and probably some of them would also want to return their URLs for lazy-loaded thumbnails. And also try to minimize the number of AJAX requests filepicker is doing. If there is no thumbnail to load we should not even request it. Thank you!
          Hide
          David Mudrak added a comment -

          Please don't forget to check that generated thumbnail was modified not earlier than source file.

          That is not needed at all. Let me underline what I said above: the thumbnail is generated and linked with the contenthash of the original file via the thumbnail's filename attribute. When you change the content of the original file, the thumbnail is invalidated implicitly. That is one of the big pros of using the filepool as a storage for the thumbnails. The fileid does not play any role here (as generally it should not be used anywhere in the code outside the file storage machinery itself).

          Thanks for the good point re non-local repositories providing alternative preview URLs. That makes perfect sense and I agree with your suggestion now.

          There is still a thing I am not sure much about: how the repository would know what files in the given filearea/folder have a preview available (and therefore the previewurl should be provided for them). This is a bit tricky with the current design as the only way to know is to actually try and request that preview file...

          Show
          David Mudrak added a comment - Please don't forget to check that generated thumbnail was modified not earlier than source file. That is not needed at all. Let me underline what I said above: the thumbnail is generated and linked with the contenthash of the original file via the thumbnail's filename attribute. When you change the content of the original file, the thumbnail is invalidated implicitly. That is one of the big pros of using the filepool as a storage for the thumbnails. The fileid does not play any role here (as generally it should not be used anywhere in the code outside the file storage machinery itself). Thanks for the good point re non-local repositories providing alternative preview URLs. That makes perfect sense and I agree with your suggestion now. There is still a thing I am not sure much about: how the repository would know what files in the given filearea/folder have a preview available (and therefore the previewurl should be provided for them). This is a bit tricky with the current design as the only way to know is to actually try and request that preview file...
          Hide
          David Mudrak added a comment -

          Attaching an illustrative screenshot of the current file picker (without recent Barbara's and Marina's improvements) that displays thumbnails of JPEG images attached to a workshop submission.

          Show
          David Mudrak added a comment - Attaching an illustrative screenshot of the current file picker (without recent Barbara's and Marina's improvements) that displays thumbnails of JPEG images attached to a workshop submission.
          Hide
          Martin Dougiamas added a comment -

          Hang on guys - what are the performance hits with storing these in filepool?

          Show
          Martin Dougiamas added a comment - Hang on guys - what are the performance hits with storing these in filepool?
          Hide
          Petr Škoda added a comment -

          performance?
          1/ one extra DB call when serving for content hash lookup
          2/ eliminated very many DB calls and http requests on each forum page with image attachments thanks to caching of previously forcedownloaded images

          Show
          Petr Škoda added a comment - performance? 1/ one extra DB call when serving for content hash lookup 2/ eliminated very many DB calls and http requests on each forum page with image attachments thanks to caching of previously forcedownloaded images
          Hide
          Martin Dougiamas added a comment - - edited

          OK then. Performance is really a priority these days ... getting some reports from partners of increased load from 2.x on big sites.

          I guess thumbnails don't ever need to expire in browser cache.

          Show
          Martin Dougiamas added a comment - - edited OK then. Performance is really a priority these days ... getting some reports from partners of increased load from 2.x on big sites. I guess thumbnails don't ever need to expire in browser cache.
          Hide
          Petr Škoda added a comment -

          they do have to expire because you might replace the file beneath it and unfortunately not everything has revision counters

          Show
          Petr Škoda added a comment - they do have to expire because you might replace the file beneath it and unfortunately not everything has revision counters
          Hide
          Martin Dougiamas added a comment - - edited

          Can we use the original contenthash somehow in the URL? Then it would be automatic.

          These really must be very very fast. The filepicker can not be laggy and spam the server with too many requests.

          Show
          Martin Dougiamas added a comment - - edited Can we use the original contenthash somehow in the URL? Then it would be automatic. These really must be very very fast. The filepicker can not be laggy and spam the server with too many requests.
          Hide
          Petr Škoda added a comment -

          I think content hash can not be used in url because we would have to fetch it from the database in oder to create every link. Adding revision counters to places where the up-to-dateness matters might be easier.

          Show
          Petr Škoda added a comment - I think content hash can not be used in url because we would have to fetch it from the database in oder to create every link. Adding revision counters to places where the up-to-dateness matters might be easier.
          Hide
          David Mudrak added a comment -

          The filepicker can not be laggy and spam the server with too many requests.

          Note that the internal storage implementation does not influence the number of requests from the filepicker. If Morbo demands thumbnails, there will be one request per each thumbnail image, no matter if we use filepool or Whirlpool.

          Using standard file API is very elegant here as it solves important issues implicitly: once the original file changes, its preview is invalidated automatically (as the relationship is based on the contenthash); filepool deals well with number of files per directory and other limitations of the underlying OS (so we do not need to reinvent wheels); orphaned thumbnails can be easily detected using a single DB query etc.

          Show
          David Mudrak added a comment - The filepicker can not be laggy and spam the server with too many requests. Note that the internal storage implementation does not influence the number of requests from the filepicker. If Morbo demands thumbnails, there will be one request per each thumbnail image, no matter if we use filepool or Whirlpool. Using standard file API is very elegant here as it solves important issues implicitly: once the original file changes, its preview is invalidated automatically (as the relationship is based on the contenthash); filepool deals well with number of files per directory and other limitations of the underlying OS (so we do not need to reinvent wheels); orphaned thumbnails can be easily detected using a single DB query etc.
          Hide
          David Mudrak added a comment -

          Petr, can you please throw your left peer eye on the branch and eventually give it +1 before I submit it to cross the Durin's Bridge. Thanks in advance.

          Show
          David Mudrak added a comment - Petr, can you please throw your left peer eye on the branch and eventually give it +1 before I submit it to cross the Durin's Bridge. Thanks in advance.
          Hide
          Petr Škoda added a comment -

          I did not do a full review, but I did not see any show stoppers.

          I did not understand the file_purge_caches() and I do not like "string == string" comparisons, please use === for strings

          Show
          Petr Škoda added a comment - I did not do a full review, but I did not see any show stoppers. I did not understand the file_purge_caches() and I do not like "string == string" comparisons, please use === for strings
          Hide
          David Mudrak added a comment -

          Thanks Petr for the reviewew. I fixed the string comparison operators and removed the code that was supposed to purge all existing thumbnails (for the record, we discussed this with Petr and realized that there is no good reason for such behaviour).

          Submitting form integration now.

          Show
          David Mudrak added a comment - Thanks Petr for the reviewew. I fixed the string comparison operators and removed the code that was supposed to purge all existing thumbnails (for the record, we discussed this with Petr and realized that there is no good reason for such behaviour). Submitting form integration now.
          Hide
          Eloy Lafuente (stronk7) added a comment - - edited

          Some little details:

          1) Shouldn't this be covered by some tests?

          2) If I did not read wrongly, the deletion is exclusively performed my cron's outer join, correct? No other "links" (like automated deletion of preview on original deletion/change) between the original file and its previews exist at all, yes?

          3) In that query, the "filename <> '.'" inequality... sounds like something unnecessary and that could lead to full table scans, FYC.

          4) in create_file_preview() you are setting the mimeinfo of the stored preview file to be the mimeinfo of the original file... and that's incorrect as far as GD can decide to change the format under some circumstances. The resulting mimeinfo should be used instead.

          5) I ended a bit lost with all those send_file()/send_stored_file() changes, but some grep-s seem to indicate that all them are under control. Anyway, surely, this will need, apart from the changes in upgrade.txt, some page in docs / information in release notes, to let everybody know.

          6) WTF is the "dontdie" thingy? Tricky, tricky.

          7) I'd change the name of this issue to something like "Add support for previews of stored files" or so, as far as the integration with repos is still to land in followup issue. FYC.

          Show
          Eloy Lafuente (stronk7) added a comment - - edited Some little details: 1) Shouldn't this be covered by some tests? 2) If I did not read wrongly, the deletion is exclusively performed my cron's outer join, correct? No other "links" (like automated deletion of preview on original deletion/change) between the original file and its previews exist at all, yes? 3) In that query, the "filename <> '.'" inequality... sounds like something unnecessary and that could lead to full table scans, FYC. 4) in create_file_preview() you are setting the mimeinfo of the stored preview file to be the mimeinfo of the original file... and that's incorrect as far as GD can decide to change the format under some circumstances. The resulting mimeinfo should be used instead. 5) I ended a bit lost with all those send_file()/send_stored_file() changes, but some grep-s seem to indicate that all them are under control. Anyway, surely, this will need, apart from the changes in upgrade.txt, some page in docs / information in release notes, to let everybody know. 6) WTF is the "dontdie" thingy? Tricky, tricky. 7) I'd change the name of this issue to something like "Add support for previews of stored files" or so, as far as the integration with repos is still to land in followup issue. FYC.
          Hide
          Marina Glancy added a comment -

          David, can you also add to local repository plugins the links to those previews as 'realthumbnail' and 'realicon' (part 2 of initial task)
          I implemented lazy loading of them in filepicker in the branch under MDL-31901 (part 3)

          Show
          Marina Glancy added a comment - David, can you also add to local repository plugins the links to those previews as 'realthumbnail' and 'realicon' (part 2 of initial task) I implemented lazy loading of them in filepicker in the branch under MDL-31901 (part 3)
          Hide
          David Mudrak added a comment -

          Eloy, thanks for the review of the patch. The responses follow

          1) Correct. I just added some PHPUnit tests to cover the new functionality. They use the dependency feature of the PHPUnit framework which I found really nice.

          2) Correct, the removal of orphaned previews happens in that cron only intentionally.

          3) Without the "filename <> '.'" condition, the query would return records that represent the directories in the given filearea. The delete() call would cause removal of those records for no good reason. I believe, given all other WHERE conditions in the query, that the execution planner would be really stupid if it did full table scan. However, ff you believe it really is the issue, we can move the condition from the SQL statement and test it in PHP before executing stored_file::delete()

          4) No, I am setting the mimeinfo field to the value detected from the generated file. The generated preview file is dumped into a temporary location in moodledata and its mimetype is analyzed there (if we could use getimagesizefromstring(), no temporary file would be needed). I believe I tested this by playing with enabling/disabling PNG and JPG support in gdlib.php

          5) It's not that difficult. The basic idea is: pluginfile.php accepts &preview=xxx parameter and we just need to make sure that this parameter is propagated thru all callbacks to the send_stored_file() and the end of the chain. And of course, I plan a notice with upgrade instructions in the release notes.

          6) dontdie thing was introduced by Penny Leach when she was working on portfolios. The idea was that send_stored_file() does not die after sending the file but returns to the caller so they can do some cleanup. It is used in portfolios only and is strongly discouraged for any other use.

          7) Done.

          Show
          David Mudrak added a comment - Eloy, thanks for the review of the patch. The responses follow 1) Correct. I just added some PHPUnit tests to cover the new functionality. They use the dependency feature of the PHPUnit framework which I found really nice. 2) Correct, the removal of orphaned previews happens in that cron only intentionally. 3) Without the "filename <> '.'" condition, the query would return records that represent the directories in the given filearea. The delete() call would cause removal of those records for no good reason. I believe, given all other WHERE conditions in the query, that the execution planner would be really stupid if it did full table scan. However, ff you believe it really is the issue, we can move the condition from the SQL statement and test it in PHP before executing stored_ file::delete( ) 4) No, I am setting the mimeinfo field to the value detected from the generated file. The generated preview file is dumped into a temporary location in moodledata and its mimetype is analyzed there (if we could use getimagesizefromstring(), no temporary file would be needed). I believe I tested this by playing with enabling/disabling PNG and JPG support in gdlib.php 5) It's not that difficult. The basic idea is: pluginfile.php accepts &preview=xxx parameter and we just need to make sure that this parameter is propagated thru all callbacks to the send_stored_file() and the end of the chain. And of course, I plan a notice with upgrade instructions in the release notes. 6) dontdie thing was introduced by Penny Leach when she was working on portfolios. The idea was that send_stored_file() does not die after sending the file but returns to the caller so they can do some cleanup. It is used in portfolios only and is strongly discouraged for any other use. 7) Done.
          Hide
          Eloy Lafuente (stronk7) added a comment -

          3) The easier IMO is to move that condition out from the query and perform the check within the loop (if ($orphan->filename === '.') ==> continue). The basic rule is to avoid inequalities at all costs in queries. RDBMS analyzers can be really idiot. And the cost in the loop is small.

          4) Aha, yes, you're right about the mimeinfo being the correct (converted) one. Not sure how I did read that yesterday. Sorry.

          Ciao

          Show
          Eloy Lafuente (stronk7) added a comment - 3) The easier IMO is to move that condition out from the query and perform the check within the loop (if ($orphan->filename === '.') ==> continue). The basic rule is to avoid inequalities at all costs in queries. RDBMS analyzers can be really idiot. And the cost in the loop is small. 4) Aha, yes, you're right about the mimeinfo being the correct (converted) one. Not sure how I did read that yesterday. Sorry. Ciao
          Hide
          Eloy Lafuente (stronk7) added a comment -

          1) Nice the tests. Surely we could be checking other things (resulting sizes, types...). But fair enough for now.

          Show
          Eloy Lafuente (stronk7) added a comment - 1) Nice the tests. Surely we could be checking other things (resulting sizes, types...). But fair enough for now.
          Hide
          Eloy Lafuente (stronk7) added a comment -

          Integrated, thanks!

          Show
          Eloy Lafuente (stronk7) added a comment - Integrated, thanks!
          Hide
          Rajesh Taneja added a comment -

          Sorry David,
          It's throwing following error for tinyurl. (working fine for thumb)

          Unknown exception related to local files (Invalid preview mode requested)
          
          Stack trace:
              line 254 of /lib/filestorage/file_storage.php: file_exception thrown
              line 195 of /lib/filestorage/file_storage.php: call to file_storage->create_imagefile_preview()
              line 173 of /lib/filestorage/file_storage.php: call to file_storage->create_file_preview()
              line 1990 of /lib/filelib.php: call to file_storage->get_file_preview()
              line 4167 of /mod/forum/lib.php: call to send_stored_file()
              line 3952 of /lib/filelib.php: call to forum_pluginfile()
              line 38 of /pluginfile.php: call to file_pluginfile()
          

          I got following url from image
          http://rajesh.moodle.local/im/pluginfile.php/99/mod_forum/post/4/rajesh.png and modified it to
          http://rajesh.moodle.local/im/pluginfile.php/99/mod_forum/post/4/rajesh.png?preview=tinyurl
          and
          http://rajesh.moodle.local/im/pluginfile.php/99/mod_forum/post/4/rajesh.png?preview=thumb

          FYI:
          As you can see from the url, image was added to one forum post. I tried in different activities, but same exception appeared.

          Show
          Rajesh Taneja added a comment - Sorry David, It's throwing following error for tinyurl. (working fine for thumb) Unknown exception related to local files (Invalid preview mode requested) Stack trace: line 254 of /lib/filestorage/file_storage.php: file_exception thrown line 195 of /lib/filestorage/file_storage.php: call to file_storage->create_imagefile_preview() line 173 of /lib/filestorage/file_storage.php: call to file_storage->create_file_preview() line 1990 of /lib/filelib.php: call to file_storage->get_file_preview() line 4167 of /mod/forum/lib.php: call to send_stored_file() line 3952 of /lib/filelib.php: call to forum_pluginfile() line 38 of /pluginfile.php: call to file_pluginfile() I got following url from image http://rajesh.moodle.local/im/pluginfile.php/99/mod_forum/post/4/rajesh.png and modified it to http://rajesh.moodle.local/im/pluginfile.php/99/mod_forum/post/4/rajesh.png?preview=tinyurl and http://rajesh.moodle.local/im/pluginfile.php/99/mod_forum/post/4/rajesh.png?preview=thumb FYI: As you can see from the url, image was added to one forum post. I tried in different activities, but same exception appeared.
          Hide
          David Mudrak added a comment -

          Ah! Of course it does. There was a typo in the testing instructions. It should be "tinyicon", not tinyurl. Please retest. Thanks.

          Show
          David Mudrak added a comment - Ah! Of course it does. There was a typo in the testing instructions. It should be "tinyicon", not tinyurl. Please retest. Thanks.
          Hide
          Rajesh Taneja added a comment -

          Thanks David,

          Works Great now

          Show
          Rajesh Taneja added a comment - Thanks David, Works Great now
          Hide
          Eloy Lafuente (stronk7) added a comment -

          This has been near becoming rejected, because it's not the best code you are able to produce.

          But, luckily, at the end, it has landed and has been spread to all repos out there.

          Many thanks and, don't forget it, keep improving your skills, you can!

          Closing, ciao

          Show
          Eloy Lafuente (stronk7) added a comment - This has been near becoming rejected, because it's not the best code you are able to produce. But, luckily, at the end, it has landed and has been spread to all repos out there. Many thanks and, don't forget it, keep improving your skills, you can! Closing, ciao
          Hide
          Darcy W. Christ added a comment -

          Hi Everyone, I'm coming late to the conversation (or rather I seemed to be having a similar conversation with myself on another issue: http://tracker.moodle.org/browse/MDL-10950, which was not noticed).

          Why is this code limited to thumbnails only? It's not the only issue to be solved. If you look at my code, you'll see I do the same thing but enabled it for several sizes. And it's even possible to open the system up so that each Moodle site could develop their own sizes and use them in all sorts of plugins.

          Show
          Darcy W. Christ added a comment - Hi Everyone, I'm coming late to the conversation (or rather I seemed to be having a similar conversation with myself on another issue: http://tracker.moodle.org/browse/MDL-10950 , which was not noticed). Why is this code limited to thumbnails only? It's not the only issue to be solved. If you look at my code, you'll see I do the same thing but enabled it for several sizes. And it's even possible to open the system up so that each Moodle site could develop their own sizes and use them in all sorts of plugins.
          Hide
          Tim Hunt added a comment -

          <sarcasm>Thank you very much for making me a watcher on this issue, clearly qtype API changes are of no interest to me.</sarcasm>

          Show
          Tim Hunt added a comment - <sarcasm>Thank you very much for making me a watcher on this issue, clearly qtype API changes are of no interest to me.</sarcasm>
          Hide
          Renovation NY added a comment -

          Using the "filename <> '.'" was indeed causing me issues! This would explain why I had records disappearing. Bah! I'm glad you guys took the time to have this thread. I'm getting to the place where I am considering contracting this out. Building this site is making me lose sleep! Angela

          Show
          Renovation NY added a comment - Using the "filename <> '.'" was indeed causing me issues! This would explain why I had records disappearing. Bah! I'm glad you guys took the time to have this thread. I'm getting to the place where I am considering contracting this out. Building this site is making me lose sleep! Angela

            People

            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: