Skip to content

Instantly share code, notes, and snippets.

@jammykam
Last active November 27, 2019 13:26
Show Gist options
  • Save jammykam/9dba9bfd321df6b49e0091bda2343163 to your computer and use it in GitHub Desktop.
Save jammykam/9dba9bfd321df6b49e0091bda2343163 to your computer and use it in GitHub Desktop.
Restrict Media Upload in Experience Editor and Content Editor in Sitecore 8.2 update-5. See following for further reference: https://stackoverflow.com/a/27956033/661447 | https://sitecore.stackexchange.com/q/9009/135 | https://sitecore.stackexchange.com/q/9060/135
using Sitecore;
using Sitecore.Exceptions;
using Sitecore.Pipelines.Attach;
namespace MyProject.MediaUpload.Pipelines.Attach
{
public class ImageCheckSize
{
public void Process(AttachArgs args)
{
if (!ImageSettings.IsRestrictedExtension(args.File.FileName))
return;
if (args.MediaItem.FileBased || args.File.InputStream.Length <= ImageSettings.MaxImageSizeInDatabase)
return;
// Unused, a generic message is displayed in non-flash mode else meesage from AttachPage.OnQueued() shown
throw new ClientAlertException(string.Format(ImageSettings.ErrorMessage, "", MainUtil.FormatSize(ImageSettings.MaxImageSizeInDatabase)));
}
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<xamlControls
xmlns:x="http://www.sitecore.net/xaml"
xmlns:ajax="http://www.sitecore.net/ajax"
xmlns:rest="http://www.sitecore.net/rest"
xmlns:javascript="http://www.sitecore.net/javascript"
xmlns:r="http://www.sitecore.net/renderings"
xmlns:xmlcontrol="http://www.sitecore.net/xmlcontrols"
xmlns:p="http://schemas.sitecore.net/Visual-Studio-Intellisense"
xmlns:asp="http://www.sitecore.net/microsoft/webcontrols"
xmlns:html="http://www.sitecore.net/microsoft/htmlcontrols"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- place this file in: /sitecore/shell/Overrides -->
<!-- BEGIN: Inherits updated -->
<Sitecore.Shell.Applications.FlashUpload.Attach x:inherits="MyProject.MediaUpload.AttachPage, MyProject.MediaUpload">
<!-- END: Inherits updated -->
<Sitecore.Controls.DialogPage Header="Attach a File CUSTOM" OKButton="Upload" runat="server">
<AjaxScriptManager runat="server"/>
<ContinuationManager runat="server" />
<Script runat="server" Src="/sitecore/shell/controls/lib/YUIupload/uploader/yui-uploader-min.js" />
<Script runat="server" Src="/sitecore/shell/applications/flashupload/Upload.js" />
<Script>
Event.observe(window, "load", function () {
window.scUpload = new SitecoreMultiUpload();
scUpload.destination = "/sitecore/shell/applications/flashupload/attach/attachtarget.aspx" + window.location.search + "&amp;uploadID=" + $$(".uploadID")[0].value;
scUpload.init();
scUpload.close = function () {
setTimeout(function () { scForm.postRequest("", "", "", "Close()"); }.bind(this), 25);
};
});
</Script>
<Style runat="server">
.filename {
height: 34px;
width: 100%;
border: solid 1px #e3e3e3;
margin: 0px 10px 5px 0;
position: relative;
}
#FilenameText {
padding: 2px;
padding-left: 4px;
line-height: 34px;
display: block;
}
.ff #FilenameText {
line-height: 34px;
position: relative;
z-index: 2;
}
.progress {
width: 0%;
height: 34px;
line-height:36px;
position: absolute;
background-color: #289BC8;
z-index: -1;
}
.ff .progress {
z-index: 1;
height: 34px;
line-height:34px;
background-color: #289BC8;
}
.ff .progressImage {
position: relative;
z-index: 3;
}
#Browse {
margin-left: 10px;
}
td {
vertical-align: top;
}
#contentWrapper{
max-height:50px;
display: block
}
.yui3-uploader-content
{
width: 100%;
height: 100%;
overflow:hidden;
}
.yui3-uploader-content button
{
opacity: 0;
cursor:pointer;
}
</Style>
<div id="contentWrapper">
<html:HtmlInputHidden class="uploadID" id="InputUploadID" runat="server" />
<html:HtmlInputHidden class="uploadSessionID" id="UploadSessionID" runat="server" />
<html:HtmlInputHidden class="uploadSessionID1" id="UploadSessionID1" runat="server" />
<GridPanel runat="server" Width="100%">
<Literal runat="server" Text="File name:" />
<GridPanel runat="server" Columns="2">
<Border runat="server" class="filename" GridPanel.Width="100%" GridPanel.Height="36px">
<Border runat="server" class="progress" />
<ThemedImage runat="server" Src="Images/blank.png" class="progressImage" style="position: absolute; right: 2px; top: 2px; display: none" />
<ThemedImage runat="server" Src="Office/16x16/check.png" class="doneImage" style="position: absolute; right: 2px; top: 2px; display: none" />
<span id="FilenameText"></span>
</Border>
<Border runat="server" id="BrowseContainer" GridPanel.Width="72px" GridPanel.Height="36px" style="position:relative">
<Button runat="server" Header="Browse" ID="Browse" style="z-index:1"/>
<div id="BrowseOverlay" style="width:77px;height:33px;position:absolute;top:1px;left:12px;z-index:2" />
</Border>
</GridPanel>
<Literal runat="server" ID="Message" />
</GridPanel>
</div>
</Sitecore.Controls.DialogPage>
</Sitecore.Shell.Applications.FlashUpload.Attach>
</xamlControls>
using Sitecore;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Web.UI.Sheer;
namespace MyProject.MediaUpload
{
public class AttachPage : Sitecore.Shell.Applications.FlashUpload.Attach.AttachPage
{
protected new void OnQueued(string filename, string lengthString)
{
Assert.ArgumentNotNullOrEmpty(filename, "filename");
Assert.ArgumentNotNullOrEmpty(lengthString, "lengthString");
int num = int.Parse(lengthString);
long maximumImageUploadSize = ImageSettings.MaxImageSizeInDatabase;
if (ImageSettings.IsRestrictedExtension(filename) && num > maximumImageUploadSize)
{
string text = Translate.Text(ImageSettings.ErrorMessage, new object[] { filename, MainUtil.FormatSize(maximumImageUploadSize) });
this.WarningMessage = text;
SheerResponse.Alert(text, new string[0]);
}
else
{
base.OnQueued(filename, lengthString);
}
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace MyProject.MediaUpload
{
public static class ImageSettings
{
public static string ErrorMessage = "The image \"{0}\" is too big to be uploaded. The maximum size for uploading images is {1}.";
public static string RestrictedImageExtensions => Sitecore.Configuration.Settings.GetSetting("Media.RestrictedImageExtensions");
public static long MaxImageSizeInDatabase => Sitecore.Configuration.Settings.GetLongSetting("Media.MaxImageSizeInDatabase", 524288000L);
private static List<string> restrictedExtensions = null;
public static bool IsRestrictedExtension(string filename)
{
if (restrictedExtensions == null)
{
restrictedExtensions = RestrictedImageExtensions.Split(new char[] { '|' }).ToList();
}
if (restrictedExtensions.Any())
return restrictedExtensions.Exists(restrictedExtension => string.Equals(restrictedExtension, Path.GetExtension(filename), StringComparison.CurrentCultureIgnoreCase));
return false;
}
}
}
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/">
<sitecore>
<processors>
<attachFile>
<processor mode="on" type="MyProject.MediaUpload.Pipelines.Attach.ImageCheckSize, MyProject.MediaUpload"
patch:before="*[contains(@type, 'Sitecore.Pipelines.Attach.CheckSize')]" />
</attachFile>
<uiUpload>
<processor mode="on" type="MyProject.MediaUpload.Pipelines.Upload.ImageCheckSize, MyProject.MediaUpload"
patch:before="*[contains(@type, 'Sitecore.Pipelines.Upload.CheckSize')]" />
</uiUpload>
</processors>
<settings>
<setting name="Media.MaxImageSizeInDatabase" value="1MB" />
<setting name="Media.RestrictedImageExtensions" value=".jpg|.jpeg|.png|.gif|.bmp|.tiff" />
</settings>
</sitecore>
</configuration>
<?xml version="1.0" encoding="utf-8" ?>
<control xmlns:def="Definition" xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense">
<MediaFolder>
<!-- place this file in: /sitecore/shell/Override/MediaFolder.xml -->
<FormPage>
<!-- BEGIN: Codebeside updated -->
<CodeBeside Type="MyProject.MediaUpload.MediaFolder.MediaFolderForm, MyProject.MediaUpload"/>
<!-- END: Codebeside updated -->
<Stylesheet Src="Media Folder Viewer.css" DeviceDependant="true"/>
<Stylesheet Src="Dialogs.css" DeviceDependant="true"/>
<Border id="SettingsContainer" style="display:none" />
<Script runat="server" Src="/sitecore/shell/controls/lib/YUIupload/uploader/yui-uploader-min.js" />
<Script type="text/JavaScript" language="javascript" src="/sitecore/shell/controls/lib/scriptaculous/scriptaculous.js?load=effects" />
<Script type="text/JavaScript" language="javascript" Src="/sitecore/shell/controls/SitecoreLightbox.js" />
<Script type="text/JavaScript" language="javascript" Src="/sitecore/shell/applications/media/mediafolder/mediafolder.js"/>
<!-- BEGIN: New JS override file added -->
<Script type="text/JavaScript" language="javascript" Src="/sitecore/shell/Override/mediafolderOverride.js"/>
<!-- END: New JS override file added -->
<div Class="scBackground" style="height:100%;">
<Scrollbox ID="FileList" Background="Transparent" Border="none" Padding="0px" ContextMenu="FileList_ContextMenu" />
</div>
<div id="UploadPanel" class="scStretchAbsolute" style="display:none; background: white;">
<div class="scFormDialogHeader">
<div class="ui-widget-header" style="color:#474747">.</div>
<div class="DialogHeader">
<Literal runat="server" Text="Upload File" />
</div>
<div class="DialogHeaderDescription" style="color:#474747">.</div>
</div>
<div id="UploadUI" style="padding:15px; height: calc(100% - 160px); min-height: 100px;">
<Literal Text="These files are ready for uploading:" style="display: none; padding: 0px 0px 15px 0; font-size:14px" ID="Header" runat="server" />
<Scrollbox ID="Scrollbox" Style="border:none; padding:0; height: calc(100% - 35px)">
<table style="display:none;" id="queue" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th class="filename">
<Literal runat="server" Text="File name" />
</th>
<th class="size">
<Literal runat="server" Text="Size" />
</th>
<th class="alt">
<Literal runat="server" Text="Alternate text" />
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</Scrollbox>
</div>
<GridPanel id="AdvancedOptions" class="options" runat="server" Columns="1" Style="display:none;">
<Checkbox Header="Unpack ZIP archives" runat="server" ID="Unpack" />
<Checkbox Header="Make uploaded media items versionable" runat="server" ID="Versioned" />
<Checkbox Header="Overwrite existing media items" runat="server" ID="Overwrite" />
<Checkbox Header="Upload as files" runat="server" ID="AsFiles" />
</GridPanel>
<div id="buttons" style="display:none" Class="scFormDialogFooter">
<img src="/sitecore/shell/themes/standard/images/sc-spinner16.gif" Class="closeProgress" style="display:none; margin-left: 8px" />
<Button id="UploadButton" runat="server" Click="OnStart" Class="scButton scButtonPrimary" Header="Upload" style="display:none" />
<Button id="CancelButton" runat="server" Click="OnCancel" Header="Cancel" />
<Button id="CloseButton" runat="server" Click="" onclick="javascript:scMediaFolder.activeUploader.close()" Header="Close" style="display:none" />
</div>
</div>
</FormPage>
</MediaFolder>
</control>
using System;
using System.Text;
using Sitecore;
using Sitecore.Abstractions;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using Sitecore.StringExtensions;
using Sitecore.Text;
using Sitecore.Web.UI.Sheer;
namespace MyProject.MediaUpload.MediaFolder
{
public class MediaFolderForm : Sitecore.Shell.Applications.Media.MediaFolder.MediaFolderForm
{
public MediaFolderForm() : base()
{
}
public MediaFolderForm(BaseTranslate translate, BaseMediaManager mediaManager)
: base(translate, mediaManager)
{
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Add additional JS parameters with image restriction settings
SitecoreMediaUploader.addMethods({
processSelectedFiles: function (files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
file.size = file.get("size");
file.name = file.get("name");
file.id = file.get("id");
if (file.size > this.uploadLimit() || this.uploadImageLimitReached(file)) {
if (this.simple || file.size > this.uploadFileLimit()) {
this.cancelledFiles.push(file);
continue;
}
else {
this.forcedFileUpload = true;
}
}
$("queue").show();
file.size = (file.size / 1000).toFixed(0) + " KB";
var html = "<tr id='#{id}' class='queued'><td class='name'>#{name}<span class='progress'><img class='filler' style='width:0px;' src='/sitecore/shell/Themes/Standard/Images/Progress/filler_media.png' alt='' /></span></td><td class='size'>#{size}</td><td class='alt'><input class='scFont alt' type='text' id='#{id}_alt' /></td></tr>".interpolate(file);
$$("#queue tbody")[0].insert({ bottom: html });
if (!this.simple) {
$("UploadButton").show();
}
this.queue.push(file);
}
},
// BEGIN: New extended helper functions
uploadImageLimitReached: function (file) {
var maxImageSize = parseInt(this.settings.uploadImageLimit);
var arrayOfExtensions = this.settings.uploadImageExtensions.split('|');
if (arrayOfExtensions.indexOf(this.getFileExtension(file.name)) > -1 && file.size > maxImageSize) {
return true;
}
return false;
},
getFileExtension: function(fileName) {
var ext = fileName.split(".");
if (ext.length === 1 || (ext[0] === "" && ext.length === 2)) {
return "";
}
return "." + ext.pop().toLowerCase();
}
// END: Extended helper functions
});
var maxImageSize = ((long) System.Math.Min(ImageSettings.MaxImageSizeInDatabase, Settings.Runtime.EffectiveMaxRequestLengthBytes)).ToString();
string imageRestrictions = "<script type='text/javascript'>scUploadSettings.uploadImageLimit = \"{0}\"; scUploadSettings.uploadImageExtensions = \"{1}\";</script>";
this.SettingsContainer.InnerHtml += imageRestrictions.FormatWith(maxImageSize, ImageSettings.RestrictedImageExtensions);
}
protected new void OnFilesCancelled(string packet)
{
Assert.ArgumentNotNullOrEmpty(packet, nameof(packet));
ListString listString = new ListString(packet);
Assert.IsTrue(listString.Count > 0, "Zero cancelled files posted");
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append("The following files are too big to be uploaded:");
stringBuilder.Append("\n\n");
foreach (string str in listString.Items)
stringBuilder.Append(str + "\n");
string str1 = MainUtil.FormatSize(Math.Min(Settings.Media.MaxSizeInDatabase, Settings.Runtime.EffectiveMaxRequestLengthBytes));
// BEGIN Following message has been added to the user alert
stringBuilder.Append(Translate.Text("The maximum image size that can be uploaded is {0}. ", MainUtil.FormatSize(ImageSettings.MaxImageSizeInDatabase)));
// END Changed Code
stringBuilder.Append(this.Translate.Text("The maximum size of a file that can be uploaded is {0}.", (object)str1));
SheerResponse.Alert(stringBuilder.ToString());
}
}
}
// This script extends the default MediaFolder.js class
// processSelectedFiles should match your Sitecore version, add in the additional check in Line 14, rest of function is copy+pasted
SitecoreMediaUploader.addMethods({
processSelectedFiles: function (files) {
for (var i = 0; i < files.length; i++) {
var file = files[i];
file.size = file.get("size");
file.name = file.get("name");
file.id = file.get("id");
if (file.size > this.uploadLimit() || this.uploadImageLimitReached(file)) { //additional check for image size
if (this.simple || file.size > this.uploadFileLimit()) {
this.cancelledFiles.push(file);
continue;
}
else {
this.forcedFileUpload = true;
}
}
$("queue").show();
file.size = (file.size / 1000).toFixed(0) + " KB";
var html = "<tr id='#{id}' class='queued'><td class='name'>#{name}<span class='progress'><img class='filler' style='width:0px;' src='/sitecore/shell/Themes/Standard/Images/Progress/filler_media.png' alt='' /></span></td><td class='size'>#{size}</td><td class='alt'><input class='scFont alt' type='text' id='#{id}_alt' /></td></tr>".interpolate(file);
$$("#queue tbody")[0].insert({ bottom: html });
if (!this.simple) {
$("UploadButton").show();
}
this.queue.push(file);
}
},
// BEGIN: New extended helper functions
uploadImageLimitReached: function (file) {
var maxImageSize = parseInt(this.settings.uploadImageLimit);
var arrayOfExtensions = this.settings.uploadImageExtensions.split('|');
if (arrayOfExtensions.indexOf(this.getFileExtension(file.name)) > -1 && file.size > maxImageSize) {
return true;
}
return false;
},
getFileExtension: function(fileName) {
var ext = fileName.split(".");
if (ext.length === 1 || (ext[0] === "" && ext.length === 2)) {
return "";
}
return "." + ext.pop().toLowerCase();
}
// END: Extended helper functions
});
using System.Web;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Diagnostics;
using Sitecore.Pipelines.Upload;
using Sitecore.Zip;
namespace MyProject.MediaUpload.Pipelines.Upload
{
public class ImageCheckSize : UploadProcessor
{
public void Process(UploadArgs args)
{
Assert.ArgumentNotNull((object)args, nameof(args));
if (args.Destination == UploadDestination.File)
return;
foreach (string file1 in args.Files)
{
HttpPostedFile file2 = args.Files[file1];
if (!string.IsNullOrEmpty(file2.FileName))
{
if (UploadProcessor.IsUnpack(args, file2))
{
ZipReader zipReader = new ZipReader(file2.InputStream);
try
{
foreach (ZipEntry entry in zipReader.Entries)
{
// updated check for file ext and size
if (!entry.IsDirectory && ImageSettings.IsRestrictedExtension(entry.Name) && entry.Size > ImageSettings.MaxImageSizeInDatabase)
{
string text = file2.FileName + "/" + entry.Name;
args.UiResponseHandler.FileTooBig(StringUtil.EscapeJavascriptString(text));
args.ErrorText = string.Format(ImageSettings.ErrorMessage, file2.FileName, MainUtil.FormatSize(ImageSettings.MaxImageSizeInDatabase));
args.AbortPipeline();
return;
}
}
}
finally
{
file2.InputStream.Position = 0L;
}
}
// updated check for file ext and size
else if (ImageSettings.IsRestrictedExtension(file2.FileName) && (long)file2.ContentLength > ImageSettings.MaxImageSizeInDatabase)
{
string fileName = file2.FileName;
// updated to resolve bug in EE mode: https://sitecore.stackexchange.com/a/9072/135
if (HttpContext.Current.Request.Url.AbsolutePath != "/sitecore/shell/api/sitecore/Media/Upload")
{
args.UiResponseHandler.FileTooBig(StringUtil.EscapeJavascriptString(fileName));
}
args.ErrorText = string.Format(ImageSettings.ErrorMessage, file2.FileName, MainUtil.FormatSize(ImageSettings.MaxImageSizeInDatabase));
args.AbortPipeline();
break;
}
}
}
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<control xmlns:def="Definition" xmlns="http://schemas.sitecore.net/Visual-Studio-Intellisense">
<UploadMedia>
<!-- place this file in: /sitecore/shell/Override/UploadMedia.xml -->
<FormDialog Icon="Business/32x32/Paperclip.png" FormTarget="sitecoreattach" Enctype="multipart/form-data" Header="Upload File"
Text="Select a file. When done click the Upload button." OKButton="Upload">
<Script Key="Upload">
function submit() {
try {
document.forms[0].submit();
}
catch(e) {
scForm.invoke("ShowError");
}
}
</Script>
<!-- Update this to match your Namespace + Class -->
<CodeBeside Type="MyProject.MediaUpload.UploadMediaForm,MyProject.MediaUpload"/>
<input id="ItemUri" name="ItemUri" type="hidden" value=""/>
<Border Padding="0px 0px 4px 0px">
<Literal Text="File name:" />
</Border>
<input id="File" name="File" type="file" style="width:100%" />
</FormDialog>
</UploadMedia>
</control>
using Sitecore;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Web.UI.Sheer;
namespace MyProject.MediaUpload
{
public class UploadMediaForm : Sitecore.Shell.Applications.Media.UploadMedia.UploadMediaForm
{
protected new void ShowFileTooBig(string filename)
{
Assert.ArgumentNotNullOrEmpty(filename, nameof(filename));
if (!ImageSettings.IsRestrictedExtension(filename))
{
base.ShowFileTooBig(filename);
return;
}
SheerResponse.Alert(Translate.Text(ImageSettings.ErrorMessage, filename, MainUtil.FormatSize(ImageSettings.MaxImageSizeInDatabase)));
this.OK.Disabled = true;
this.Cancel.Disabled = true;
this.OK.Disabled = false;
this.Cancel.Disabled = false;
}
}
}
@SoulOfUniverse
Copy link

Hi Kam,

Nice write up as usual. Just to note in few places I believe its mistakenly been added you have added MediaFolderOverride.js code into MediaFolderForm.cs file, I believe it shouldn't be there. Just verified this approach and its all good with Sitecore 9.0 Update 1

Thank you,

Regards,

Sergejs K.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment