Orchard CMS ResizeMedia url from Controller. - orchardcms-1.7

I'm trying to use the
#Display.ResizeMediaUrl()
In Orchard 1.7.2, However I need to get the value of the resized Media url in a controller so I can return it to a javascript function.
I can see in there is a
[shape]
public void ResizeMediaUrl
Shape in MediaShapes.cs (Orchard.MediaProcessing.Shapes) but I'm not sure how to use this. from a controller.

You'll need a reference to IImageProfileManager in your controller which you set up in the Constructor
private readonly IImageProfileManager _imageProfileManager;
Within the Controller Action you can call GetImageProfileUrl which will resize the image for you.
I've hacked this out of the ResizeMediaUrl shape and hardcoded the Mode, Alignment and Colour settings.
e.g.
private string DoTheResize(int Width, int Height, string path)
{
var Mode = "pad";
var Alignment = "middlecenter";
var PadColor = "000000";
var state = new Dictionary<string, string> {
{"Width", Width.ToString(CultureInfo.InvariantCulture)},
{"Height", Height.ToString(CultureInfo.InvariantCulture)},
{"Mode", Mode},
{"Alignment", Alignment},
{"PadColor", PadColor},
};
var filter = new FilterRecord
{
Category = "Transform",
Type = "Resize",
State = FormParametersHelper.ToString(state)
};
var profile = "Transform_Resize"
+ "_w_" + Convert.ToString(Width)
+ "_h_" + Convert.ToString(Height)
+ "_m_" + Convert.ToString(Mode)
+ "_a_" + Convert.ToString(Alignment)
+ "_c_" + Convert.ToString(PadColor);
var resizedImagePath = _imageProfileManager.GetImageProfileUrl(path, profile, filter);
return resizedImagePath;
}

Related

Report localization in Telerik self hosted service (.trdx)

I have telerik REST web API(ASP.NET ) which is working fine. Now I need to localize the reports (report are in .trdx extension).
From documentation of telerik I found the code which have place in my BaseTelerikReportsController but this also not working, and even not show any error.
Telerik Localization Documentation
public class BaseTelerikReportsController : ReportsControllerBase
{
static readonly Telerik.Reporting.Services.ReportServiceConfiguration ConfigurationInstance;
static BaseTelerikReportsController()
{
var resolver = new CustomReportResolver();
//Create new CultureInfo
var cultureInfo = new System.Globalization.CultureInfo("aa-iq"); //<-- Line 1
// Set the language for static text (i.e. column headings, titles)
System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo; //<-- Line 2
var reportsPath = HttpContext.Current.Server.MapPath("~/Reports");
ConfigurationInstance = new Telerik.Reporting.Services.ReportServiceConfiguration
{
HostAppId = "TBReportApp",
ReportResolver = resolver,
// ReportResolver = new ReportFileResolver(reportsPath),
Storage = new Telerik.Reporting.Cache.File.FileStorage(),
};
}
public BaseTelerikReportsController()
{
ReportServiceConfiguration = ConfigurationInstance;
}
}
Note
There is a similar question but don't guide me to any right direction Here
Update 1
I have added below function in Global.asax.cs.
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
//Create new CultureInfo
var cultureInfo = new System.Globalization.CultureInfo("ar");
// Set the language for static text (i.e. column headings, titles)
System.Threading.Thread.CurrentThread.CurrentUICulture = cultureInfo;
// Set the language for dynamic text (i.e. date, time, money)
System.Threading.Thread.CurrentThread.CurrentCulture = cultureInfo;
}
After above line (see image) data under red mark is localize but i need to localize yellow one(i.e heading)
I figure out how to localize the report header. Following are the some summarized steps.
Add App_GlobalResources folder and .resx accordingly your languages (See the figure 1-1).
Send language attribute from 'HTML5 Viewer'.
var viewer = $("#report-viewer").data("telerik_ReportViewer");
var model = {
//other attributes
Language: this.selectedLanguage //Here value may be ,en Or ar
};
viewer.reportSource({
report: reportSettings,
parameters: model
});
On server side based on that attribute change label accordingly.
private static void Localization(ref Report reportInstance)
{
ResourceManager currentResource = null;
switch (_language)
{
case "en":
currentResource = new ResourceManager("Resources.en", System.Reflection.Assembly.Load("App_GlobalResources"));
break;
case "ar":
currentResource = new ResourceManager("Resources.ar", System.Reflection.Assembly.Load("App_GlobalResources"));
break;
}
// var MyResourceClass = new ResourceManager("Resources.ar", System.Reflection.Assembly.Load("App_GlobalResources"));
ResourceSet resourceSet = currentResource.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string key = entry.Key.ToString();
string value = entry.Value.ToString();
var items = reportInstance.Items.Find(key,true);
foreach (var singleItem in items)
{
var singleItemType = singleItem.GetType();
//if (singleItem.GetType().FullName == "") ;
if (singleItemType.FullName == "Telerik.Reporting.TextBox")
{
var castItem = (Telerik.Reporting.TextBox) singleItem;
castItem.Value = value;
}
}
}
}
On Telerik Standalone Report Designer
Change your report(.trdx) Textbox value which matches your .resxname value pair.
Resource file values

Is it possible to create a folder on the Alfresco site by using OpenCMIS API?

I have the Presentation Web Script (script A) and the Data Web Script (script B).
In the script A I build the dialog that interacts with the script B.
Here I am forming some path where the some file will be uploaded (group, year and number parameters define this path):
...
var submitHandler = function() {
var dataWebScriptUrl = window.location.protocol + '//' +
window.location.host + "/alfresco/s/ms-ws/script-b?guest=true";
var yearCombo = document.getElementById("year");
var year = yearCombo.options[yearCombo.selectedIndex].value;
var groupCombo = document.getElementById("group");
var group = groupCombo.options[groupCombo.selectedIndex].value;
var numberCombo = document.getElementById("number");
var number = numberCombo.value;
var uploadedFile = document.getElementById("uploadedFile");
var file = uploadedFile.files[0];
var formData = new FormData();
formData.append("year", year);
formData.append("group", group);
formData.append("number", number);
formData.append("uploadedFile", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", dataWebScriptUrl);
xhr.send(formData);
};
...
In script B, I'm using the Apache Chemistry OpenCMIS API to create a path in the CMIS-compatible Alfresco repository:
public class CustomFileUploader extends DeclarativeWebScript implements OpenCmisConfig {
...
private void retrievePostRequestParams(WebScriptRequest req) {
String groupName = null, year = null, number = null;
FormData formData = (FormData) req.parseContent();
FormData.FormField[] fields = formData.getFields();
for(FormData.FormField field : fields) {
String fieldName = field.getName();
String fieldValue = field.getValue();
if(fieldName.equalsIgnoreCase("group")) {
if(fieldValue.equalsIgnoreCase("services")) {
groupName = "Услуги";
...
}
firstLevelFolderName = "/" + groupName;
secondLevelFolderName = groupName + " " + year;
thirdLevelFolderName = number;
}
...
Folder firstLevelFolder =
createFolderIfNotExists(cmisSession, docLibFolder, firstLevelFolderName);
...
private Folder createFolderIfNotExists(Session cmisSession,
Folder parentFolder, String folderName) {
Folder subFolder = null;
for(CmisObject child : parentFolder.getChildren()) {
if(folderName.equalsIgnoreCase(child.getName())) {
subFolder = (Folder) child;
}
}
if(subFolder == null) {
Map<String, Object> props = new HashMap<>();
props.put("cmis:objectTypeId", "cmis:folder");
props.put("cmis:name", folderName);
subFolder = parentFolder.createFolder(props);
}
return subFolder;
}
private Folder getDocLibFolder(Session cmisSession, String siteName) {
String path = "/Sites/" + siteName + "/documentLibrary";
return (Folder) cmisSession.getObjectByPath(path);
}
private Session getCmisSession() {
SessionFactory factory = SessionFactoryImpl.newInstance();
Map<String, String> conf = new HashMap<>();
// http://localhost:8080/alfresco/api/-default-/public/cmis/versions/1.1/atom
conf.put(SessionParameter.ATOMPUB_URL, ATOMPUB_URL);
conf.put(SessionParameter.BINDING_TYPE, BindingType.ATOMPUB.value());
conf.put(SessionParameter.USER, USER_NAME);
conf.put(SessionParameter.PASSWORD, PASSWORD);
// "org.alfresco.cmis.client.impl.AlfrescoObjectFactoryImpl"
conf.put(SessionParameter.OBJECT_FACTORY_CLASS, OBJECT_FACTORY_CLASS);
conf.put(SessionParameter.REPOSITORY_ID, "-default-");
Session session = factory.createSession(conf);
return session;
}
...
It's all works well... But I need to create the directory structure on a specific site, e.g. "contracts-site", here:
/site/contracts-site/documentlibrary
When I specifying the following:
/Sites/contracts-site/documentLibrary/Услуги
/Sites/contracts-site/Услуги
/site/contracts-site/documentlibrary/Услуги
I get the following exception (depending on the path):
org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException: Object not found: /Sites/contracts-site/Услуги
When I specifying the following:
"/Услуги"
Everything works, but the directory structure is created outside the site...
How to create a folder on the Alfresco site by using OpenCMIS API?
Arn't you missing /company_home/ ?
This would lead to
/company_home/Sites/contracts-site/documentLibrary/Услуги
Just accidentally found the solution. Works perfectly if specify the following path:
// locate the document library
String path = "/Сайты/contracts-site/documentLibrary";
Ie, "Сайты" instead of "Sites"... (Cyrillic alphabet)
I'm using ru_RU locale and UTF-8 encoding. Then this example also works.

Is there a utility to serialise an object as HTTP content type "application/x-www-form-urlencoded"?

I've never had to do this before, because it's always only been an actual form that I've posted as that content type, but recently I had to post three variables like that, and I resorted to a sordid concatenation with & and =:
var content = new StringContent("grant_type=password&username=" + username + "&password=" + password.ToClearString(), Encoding.UTF8,
"application/x-www-form-urlencoded");
I'm sure there must be a utility method that would do that, and do it better, with any necessary encoding. What would that be?
If this is a POCO and just using the Newtonsoft library, you can use this as well:
public static class FormUrlEncodedContentExtension
{
public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj)
{
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var keyValues = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
var content = new FormUrlEncodedContent(keyValues);
return content;
}
}
And a sample usage would be:
var myObject = new MyObject {Grant_Type = "TypeA", Username = "Hello", Password = "World"};
var request = new HttpRequestMessage(HttpMethod.Post, "/path/to/post/to")
{
Content = myObject.ToFormUrlEncodedContent()
};
var client = new HttpClient {BaseAddress = new Uri("http://www.mywebsite.com")};
var response = await client.SendAsync(request);
Use reflection to get the property names and values and then use them to create a System.Net.Http.FormUrlEncodedContent
public static class FormUrlEncodedContentExtension {
public static FormUrlEncodedContent ToFormUrlEncodedContent(this object obj) {
var nameValueCollection = obj.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => (p.GetValue(obj) ?? "").ToString());
var content = new FormUrlEncodedContent(nameValueCollection);
return content;
}
}
From there it is a simple matter of calling the extension method on an object to convert it to a FormUrlEncodedContent
var model = new MyModel {
grant_type = "...",
username = "...",
password = "..."
};
var content = model.ToFormUrlEncodedContent();
You should be able to use string interpolation for that. Something like:
var content = new StringContent($"grant_type=password&username={username}&password={password}", Encoding.UTF8, "application/x-www-form-urlencoded");
Or wrap this inside a helper/factory method:
public static class StringContentFactory
{
public static StringContent Build(string username, string password)
{
return new StringContent($"grant_type=password&username={username}&password={password}", Encoding.UTF8, "application/x-www-form-urlencoded");
}
}

How to use parameters in Twitter Bootstrap loaded dynamically from the database

I have a website where I need multiple themes.
So www.mysite.com/Client1/ uses red buttons and www.mysite.com/Client2/ uses blue buttons.
The number of clients are dynamic stores in a DB, and the colors are also stored in the DB. Can be changed at anytime by the client.
Currently I am using Twitter Bootstrap LESS files and ASP MVC Optimization (bundle).
My App_Start BundleConfig looks like this:
var cssTransformer = new CssTransformer();
var stylesBundle = new StyleBundle("~/Content/bootstrap");
.Include("~/Content/less/bootstrap.less")
stylesBundle.Transforms.Add(cssTransformer);
bundles.Add(stylesBundle);
In variables.less
#btnPrimaryBackground: #linkColor;
The color of #btnPrimaryBackground should change when different urls are called.
How do I change the less variable to use a parameter from my another source (database or other)?
Since Web Optimization does not play nice with dynamic dontent, I decided to not use it.
Instead I have made am ASP MVC ActionResult for LESS, and reference that.
<link rel="stylesheet" type="text/css" href="#Url.Action("Styles", "Theme")">
My ASP MVC Controller looks like this:
public class ThemeController : Controller
{
public ActionResult Styles()
{
var parameters = new Dictionary<string, string>
{
{"themeColor1", "Get theme color 1 here"},
{"themeColor2", "Get theme color 2 here"}
};
var themeLessFilePath = Server.MapPath("~/Content/less/theme.less");
using (var stream = System.IO.File.OpenRead(themeLessFilePath))
{
return new DotLessResult(stream, parameters, true);
}
}
}
And the LESS ActionResult like this:
public class DotLessResult : ActionResult
{
public IDictionary<string, string> Parameters { get; set; }
public string Less { get; set; }
public bool Minify { get; set; }
public DotLessResult(string less, IDictionary<string, string> parameters = null, bool minify = false)
{
Less = less;
Parameters = parameters ?? new Dictionary<string, string>();
Minify = minify;
}
public DotLessResult(Stream stream, IDictionary<string, string> parameters = null, bool minify = false)
: this(new StreamReader(stream).ReadToEnd(), parameters, minify) { }
public override void ExecuteResult(ControllerContext context)
{
var output = Less;
//TODO: Not the way to do this!
foreach (var key in Parameters.Keys)
{
output = Regex.Replace(output, #"#" + key + #":\s*\S+;", "#" + key + ":" + Parameters[key] + ";");
}
var lessEngine = dotless.Core.LessWeb.GetEngine(new DotlessConfiguration { MinifyOutput = Minify, MapPathsToWeb = true, Web = true, CacheEnabled = false});
var css = lessEngine.TransformToCss(output, (string)null);
context.HttpContext.Response.ContentType = "text/css";
using (var writer = new StreamWriter(context.HttpContext.Response.OutputStream, Encoding.UTF8))
{
writer.Write(css);
writer.Flush();
}
}
}
Its NOT the best solution, but it works on my machine TM.
Dont forget to implement some kind of output caching as it will most like be hit alot, and not change very often.

Get Full name from Windows Authentication in ASP.Net BLL class

Trying to figure out how to get the current User's Full Name as entered in Active Directory from a BLL class in my ASP.Net application. So far I have:
public static string Username
{
get
{
var name = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
if (name.Contains("\\"))
{
var start = name.IndexOf("\\");
if (name.Length > start)
{
name = name.Substring(start + 1);
}
}
return name;
}
}
The problem with this is that this will return the Username, but I am also in need of the Full Name. Anyone know if this is possible?
Use a DirectorySearcher ...
var search = new DirectorySearcher( new DirectoryEntry("LDAP://YourDomain") );
search.Filter = "(sAMAccountName=UserNameHere)"; // put the identity name here
var res = search.FindOne();
var name = res["displayName"]; // I believe this is the right property

Resources