AEM 6 SP1 - Classic UI Restrict Large or Small Files Upload

Goal


In Classic UI of AEM 6 SP1 Restrict Upload of Large Files (or file sizes that do not fall in a min-max range)

Please leave a comment if you find bug, have fix...

Demo | Package Install


Upload File Limit Set to 2MB





Error shown when > 2 MB files are uploaded





Upload File Limit Set to Min 2KB, Max 2 MB





Error shown when > 2 MB or < 2 KB files are uploaded




Solution


1) Login to CRXDE Lite (http://localhost:4502/crx/de) and create folder /apps/classic-ui-dam-set-upload-limit

2) Create node /apps/classic-ui-dam-set-upload-limit/clientlib of type cq:ClientLibraryFolder and add a String property categories with value cq.widgets

3) Create file (nt:file) /apps/classic-ui-dam-set-upload-limit/clientlib/js.txt and add

                       upload-limit.js

4) Create file (nt:file) /apps/classic-ui-dam-set-upload-limit/clientlib/upload-limit.js and add the following code.

(function () {
    if (window.location.pathname !== "/damadmin") {
        return;
    }

    //id set in /libs/wcm/core/content/damadmin
    var DAM_ADMIN_ID = "cq-damadmin";
    var CREATE_FILE_ICON = "cq-damadmin-create-file-icon";
    var PROP_ALLOWED_FILE_SIZE_BYTES = "allowedFileSizeBytes";

    var getRange = function (afsb) {
        var isRange = afsb.indexOf("[") !== -1, min, max;

        if (isRange) {
            afsb = afsb.replace("[", "").replace("]", "");

            min = parseInt(afsb.substring(0, afsb.lastIndexOf("-")), 10);
            max = parseInt(afsb.substring(afsb.lastIndexOf("-") + 1), 10);
        } else {
            min = 0;
            max = parseInt(afsb, 10);
        }

        return [ min, max ];
    };

    var getOverLimitFiles = function (afsb, files) {
        var range = getRange(afsb);
        var min = range[0], max = range[1];

        var message = "", overLimit = [];

        for (var i = 0; i < files.length; i++) {
            if (files[i].size > max) {
                message = message + "File " + files[i].name
                    + " size must be less than " + max + " bytes (" + (max / 1024) + " kb)";
                overLimit.push(files[i].name);
            } else if (files[i].size < min) {
                message = message + "File " + files[i].name
                    + " size must be greater than " + min + " bytes (" + (min / 1024) + " kb)";
                overLimit.push(files[i].name);
            }
        }

        return {
            message: message,
            files: overLimit
        }
    };

    var addFileSizeHandler = function (button) {
        var attach = function (uploadWin, afsb) {
            uploadWin.on('fileselected', function (uploadField, files) {
                var overLimit = getOverLimitFiles(afsb, files);

                if (overLimit.files.length == 0) {
                    return;
                }

                CQ.Ext.Msg.alert("Error", overLimit.message, function () {
                    var uploadFields = uploadWin.findByType("html5fileuploadfield");

                    for (var i = 0; i < uploadFields.length; i++) {
                        if (!uploadFields[i].file) {
                            continue;
                        }

                        if (overLimit.files.indexOf(uploadFields[i].file.name) != -1) {
                            uploadWin.onFileRemoved(uploadFields[i].file.name);
                            uploadFields[i].clearFile();
                        }
                    }
                });
            });
        };

        button.on("click", function () {
            var wMgr = CQ.Ext.WindowMgr, uWin;

            var W_INTERVAL = setInterval(function () {
                try {
                    wMgr.each(function (win) {
                        if (win.xtype !== "html5uploaddialog") {
                            return;
                        }

                        clearInterval(W_INTERVAL);

                        //make sure you get the last (active) upload dialog window, if there are multiple
                        uWin = win;
                    });

                    CQ.Ext.Ajax.request({
                        url: uWin.displayPath + ".json",
                        success: function (response) {
                            var obj = $.parseJSON(response.responseText);

                            if (!obj[PROP_ALLOWED_FILE_SIZE_BYTES]) {
                                return;
                            }

                            attach(uWin, obj[PROP_ALLOWED_FILE_SIZE_BYTES].trim());
                        }
                    });
                } catch (err) {
                }
            }, 250);
        });
    };

    var addToNewButton = function (grid) {
        var toolBar = grid.getTopToolbar();

        var newMenu = toolBar.findBy(function (comp) {
            return comp["iconCls"] == CREATE_FILE_ICON;
        }, toolBar);

        if (!newMenu || newMenu.length == 0) {
            return;
        }

        addFileSizeHandler(newMenu[0]);

        var newFileButton = newMenu[0].menu.findBy(function (comp) {
            return comp["iconCls"] == CREATE_FILE_ICON;
        }, toolBar);

        if (!newFileButton || newFileButton.length == 0) {
            return;
        }

        addFileSizeHandler(newFileButton[0]);
    };

    var handleDrops = function () {
        var damAdmin = CQ.Ext.getCmp(DAM_ADMIN_ID);

        var handle = function (response, files) {
            var obj = $.parseJSON(response.responseText);

            if (!obj[PROP_ALLOWED_FILE_SIZE_BYTES]) {
                return;
            }

            var overLimit = getOverLimitFiles(obj[PROP_ALLOWED_FILE_SIZE_BYTES].trim(), files);

            if (overLimit.files.length == 0) {
                CQ.wcm.SiteAdmin.prototype.html5UploadFiles.call(damAdmin, files);
                return;
            }

            overLimit.message = overLimit.message + "No Files are uploaded";

            CQ.Ext.Msg.alert("Drop Error", overLimit.message);
        };

        damAdmin.html5UploadFiles = function (files) {
            var path = damAdmin.treePathEncoded;

            if (!path) {
                return;
            }

            CQ.Ext.Ajax.request({
                url: path + ".json",
                success: function (response) {
                    try {
                        handle(response, files);
                    } catch (e) {
                        console.log("error executing drop limit extension");
                    }
                }
            });
        };

    };

    var INTERVAL = setInterval(function () {
        var grid = CQ.Ext.getCmp(DAM_ADMIN_ID + "-grid");

        if (!grid) {
            return;
        }

        clearInterval(INTERVAL);

        try {
            addToNewButton(grid);

            handleDrops();
        } catch (err) {
            console.log("error executing upload limit extension");
        }

    }, 250);

})();

19 comments:

  1. Hi Sreekanth,

    Will this work for cq version 5.6.1 too,without any issues? Please let us know

    ReplyDelete
    Replies
    1. Hi, it should work as there is no major difference between 561 and 60 wrt classic ui. if you try it out please leave a comment...

      Delete
    2. Hi Sreekanth,

      Thank you for your reply.

      Basically I come from a support background. But I want to try this out and have gone through the entire code.

      Few doubts I have is as below :

      - There is a json file being referred in the program.So in case I want to setup a limit of say 10 kb, I should create json file and may be enter
      "PROP_ALLOWED_FILE_SIZE_BYTES = 10" in that file,which the program will read and make use?
      - If yes, where should I place that file.
      - Any other step, which I might have to follow, which probably is not mentioned explicitly in the article?

      Will try this out now and post back the results.

      Delete
    3. Hi Sreekanth,

      I did try the four steps as mentioned in the article. But I am stuck as to how I proceed further.

      - Where should I be providing the size limit.
      - In the first screenshot of the article, allowedFileSizeBytes property is to be seen in backend/content explorer. So, this program itself, will probably add that property to all the assets in DAM or something?
      - Any other step, which I might have to follow, which probably is not mentioned explicitly in the article.

      Your inputs on this will be really really helpful.

      Delete
    4. hi, download & install "package install" (available above with the demo) using package manager (http://localhost:4502/crx/packmgr/index.jsp) and set the "allowedFileSizeBytes" on any folder (that should not allow large files as a property) using CRX explorer http://localhost:4502/crx/de/index.jsp

      Delete
  2. Hi Sreekanth,

    Tried the steps you mentioned in CQ version 5.6.1, but doesn't seem to be working.

    Not sure, what exactly is the reason.

    ReplyDelete
  3. Hi Sreekanth,

    If you can provide any pointers/workaround it would be really helpful.

    ReplyDelete
  4. Hi Sreekanth,

    Any thoughts on the above will be helpful.

    ReplyDelete
  5. HI Sreekanth,

    Any thoughts on the above will be helpful.

    ReplyDelete
    Replies
    1. Hi, sorry i am currently occupied with project work, not finding time to check on 561...

      Delete
  6. Hi Sreekanth,

    Thank you for your reply. Will try and see if any error is getting logged or something.

    ReplyDelete
  7. Hi Sreekanth,

    I could not find anything much, as to why it is not working.

    Any thoughts/pointers from your end will be helpful.

    ReplyDelete
  8. Hi Sreekanth,

    Any thoughts on this will be helpful.

    ReplyDelete
  9. This works in 5.6.1 just fine. Just make sure the pathname in the js file is right.
    In my case there is a context root being used, hence i had to change the pathname to (window.location.pathname !== "/author/damadmin") and it worked fine

    ReplyDelete
  10. how to do it for specific mime types such as jpeg png etc

    ReplyDelete
  11. Hi Sreekanth,

    thanks a lot for giving this artical. Actvally am looking for TOUCH UI same requirment.
    Can you please post for TOUCH UI also.

    ReplyDelete
  12. Hi Sreekanth,

    I believe there is an issue with this code. It works as described when authors use the new button to upload asset, however it also disables the drag-and-drop functionality in the DAM. I tested in new AEM install to make sure issue wasn't related to my code base.

    Any ideas on how to fix this?

    Thanks!

    ReplyDelete
  13. This seems to be working great in AEM 6.3 Classic UI. I edited upload-limit.js to alert users in megabytes since it's easier for most to understand.

    I commented out lines 36 and 40 and replaced with:

    36 + " size must be less than " + max / 1000000 + " MB " + "
    ";
    40 + " size must be greater than " + min / 1000000 + " MB " + "
    ";

    What is the purpose of min? Is there a property that could be set on the folder to enforce a minimum upload size?

    It looks like the allowedFileSizeBytes needs to be set on each folder where it is wanted ... is there some way to make it recursive, or automate this property being set (with a default value) for all newly created folders?

    Konko: In AEM 6.3 (Classic UI) I found drag and drop still works and the limit is still enforced.

    ReplyDelete
  14. Hi Sreekanth,

    Tried it which is successful, but somehow it is not working if the path-characters size exceeds 40.
    Ex: It works for path /content/dam/test/offers-landing-large-b which is of size 40
    but it does not work for /content/dam/test/offers-landing-large-ba which exceeds 40.

    May I know if there is any configuration which sets this limit?

    Any resolution would be really helpful.

    ReplyDelete