Way to suppress [Item not found] in Sitecore multilist selected items if due to permissions? - permissions

Our Sitecore content tree is generally split up into global and local (or country-specific) pages to serve customers of our branches. As you'd expect, the global pages show up for all viewers of our site, regardless of their geographic locale, but we have implemented certain fields on the global pages that are localizable, e.g. banner ads, featured content, etc.
We've set up security already so that, for a multilist, a given content editor only sees items on the left-hand side to which they have access. The thing that we're running into is that items chosen by other branch content editors are showing up in the right-hand "selected" area of the multilist and, if the content editor currently viewing the item doesn't have permissions to those, they're showing up as [Item not found]. We've had well-intentioned content editors mistakenly double-click those to remove them, not realizing they're removing content intentionally placed there by other editors. A screenshot of how this looks, using the view of one of our German content editors, is below:
What I am trying to determine is if there's a way, using security or other methods, to suppress the [Item not found] messages entirely for items to which the current content editor doesn't have permissions. Any hints for a good way to do this (if it's doable) would be appreciated.

You can create your own Multilist class inheriting from Sitecore.Shell.Applications.ContentEditor.MultilistEx class and override DoRender() method of this class. In a place where text [Item Not Found] is displayed, check if the item exists but user doesn't have access rights (by trying to retrieve the item with SecurityDisabler) and display proper message.
Then you need to go to core database and register your field type:
And finally switch the type of your field to the newly created type - your field will look like this:
The code below is the original reflected MultilistEx code which the changes you need:
using System.Collections;
using System.Web.UI;
using Sitecore;
using Sitecore.Data.Items;
using Sitecore.Diagnostics;
using Sitecore.Globalization;
using Sitecore.Resources;
using Sitecore.SecurityModel;
namespace My.Assembly.Namespace
{
public class MyMultilistEx : Sitecore.Shell.Applications.ContentEditor.MultilistEx
{
protected override void DoRender(HtmlTextWriter output)
{
Assert.ArgumentNotNull(output, "output");
ArrayList selected;
IDictionary unselected;
GetSelectedItems(GetItems(Sitecore.Context.ContentDatabase.GetItem(ItemID)), out selected, out unselected);
ServerProperties["ID"] = ID;
string disabledMessage = string.Empty;
if (ReadOnly)
disabledMessage = " disabled=\"disabled\"";
output.Write("<input id=\"" + ID + "_Value\" type=\"hidden\" value=\"" + StringUtil.EscapeQuote(Value) + "\" />");
output.Write("<table" + GetControlAttributes() + ">");
output.Write("<tr>");
output.Write("<td class=\"scContentControlMultilistCaption\" width=\"50%\">" + Translate.Text("All") + "</td>");
output.Write("<td width=\"20\">" + Images.GetSpacer(20, 1) + "</td>");
output.Write("<td class=\"scContentControlMultilistCaption\" width=\"50%\">" + Translate.Text("Selected") + "</td>");
output.Write("<td width=\"20\">" + Images.GetSpacer(20, 1) + "</td>");
output.Write("</tr>");
output.Write("<tr>");
output.Write("<td valign=\"top\" height=\"100%\">");
output.Write("<select id=\"" + ID + "_unselected\" class=\"scContentControlMultilistBox\" multiple=\"multiple\" size=\"10\"" + disabledMessage + " ondblclick=\"javascript:scContent.multilistMoveRight('" + ID + "')\" onchange=\"javascript:document.getElementById('" + ID + "_all_help').innerHTML=selectedIndex>=0?options[selectedIndex].innerHTML:''\" >");
foreach (DictionaryEntry dictionaryEntry in unselected)
{
Item unselectedItem = dictionaryEntry.Value as Item;
if (unselectedItem != null)
output.Write("<option value=\"" + GetItemValue(unselectedItem) + "\">" + unselectedItem.DisplayName + "</option>");
}
output.Write("</select>");
output.Write("</td>");
output.Write("<td valign=\"top\">");
RenderButton(output, "Core/16x16/arrow_blue_right.png", "javascript:scContent.multilistMoveRight('" + ID + "')");
output.Write("<br />");
RenderButton(output, "Core/16x16/arrow_blue_left.png", "javascript:scContent.multilistMoveLeft('" + ID + "')");
output.Write("</td>");
output.Write("<td valign=\"top\" height=\"100%\">");
output.Write("<select id=\"" + ID + "_selected\" class=\"scContentControlMultilistBox\" multiple=\"multiple\" size=\"10\"" + disabledMessage + " ondblclick=\"javascript:scContent.multilistMoveLeft('" + ID + "')\" onchange=\"javascript:document.getElementById('" + ID + "_selected_help').innerHTML=selectedIndex>=0?options[selectedIndex].innerHTML:''\">");
for (int index = 0; index < selected.Count; ++index)
{
Item selectedItem = selected[index] as Item;
if (selectedItem != null)
{
output.Write("<option value=\"" + GetItemValue(selectedItem) + "\">" + selectedItem.DisplayName + "</option>");
}
else
{
string path = selected[index] as string;
if (path != null)
{
string optionDisabled = string.Empty;
Item linkedItem = Sitecore.Context.ContentDatabase.GetItem(path);
Item notAccessibleItem;
using (new SecurityDisabler())
{
notAccessibleItem = Sitecore.Context.ContentDatabase.GetItem(path);
}
string text;
if (linkedItem == null && notAccessibleItem != null)
{
text = notAccessibleItem.DisplayName + " [You don't have access rights to this item]";
optionDisabled = " disabled=\"disabled\"";
}
else
{
text = linkedItem == null
? path + ' ' + Translate.Text("[Item not found]")
: linkedItem.DisplayName + ' ' + Translate.Text("[Not in the selection List]");
}
output.Write("<option value=\"" + path + "\"" + optionDisabled + ">" + text + "</option>");
}
}
}
output.Write("</select>");
output.Write("</td>");
output.Write("<td valign=\"top\">");
RenderButton(output, "Core/16x16/arrow_blue_up.png", "javascript:scContent.multilistMoveUp('" + ID + "')");
output.Write("<br />");
RenderButton(output, "Core/16x16/arrow_blue_down.png", "javascript:scContent.multilistMoveDown('" + ID + "')");
output.Write("</td>");
output.Write("</tr>");
output.Write("<tr>");
output.Write("<td valign=\"top\">");
output.Write("<div style=\"border:1px solid #999999;font:8pt tahoma;padding:2px;margin:4px 0px 4px 0px;height:14px\" id=\"" + ID + "_all_help\"></div>");
output.Write("</td>");
output.Write("<td></td>");
output.Write("<td valign=\"top\">");
output.Write("<div style=\"border:1px solid #999999;font:8pt tahoma;padding:2px;margin:4px 0px 4px 0px;height:14px\" id=\"" + ID + "_selected_help\"></div>");
output.Write("</td>");
output.Write("<td></td>");
output.Write("</tr>");
output.Write("</table>");
}
private void RenderButton(HtmlTextWriter output, string icon, string click)
{
Assert.ArgumentNotNull(output, "output");
Assert.ArgumentNotNull(icon, "icon");
Assert.ArgumentNotNull(click, "click");
ImageBuilder imageBuilder = new ImageBuilder();
imageBuilder.Src = icon;
imageBuilder.Width = 16;
imageBuilder.Height = 16;
imageBuilder.Margin = "2px";
if (!ReadOnly)
imageBuilder.OnClick = click;
output.Write((imageBuilder).ToString());
}
}
}

Related

Is it possible to set up a carousel/slide show to a list of 150 items which are retrieved from an external source

So I created a Pokedex (for my portfolio), anyhow I was wondering if it is possible to include a carousel within a modal that activates once it is clicked and the item data will be retrieved from an external API. Anyhow every time you call a new item it erased the modal body to fetch the new data.
//Function modal
let modalContainer = document.querySelector("#pokemon-modal");
function showModal(pokemon) {
let modalBody = $(".modal-body");
let modalTitle = $(".modal-title");
modalTitle.empty();
modalBody.empty();
// data-target ='#myCarousel'
//creating element for name
let nameElement = $("<h1>" + capitalizeFirstLetter(pokemon.name) + "</h1>");
//creating new img
let imageElementFront = $(
`<img alt="pokemon-image" src="${pokemon.imageUrl}" class="modal-img"
style="width:40%">`
);
//creating elemnt for height
let heightElement = $("<p>" + "Height: " + pokemon.height + "</p>");
//creating element for weight
let weightElement = $("<p>" + "Weight: " + pokemon.weight + "</p>");
//creating element for types
let pokemonTypes = [];
Object.keys(pokemon.types).forEach((key) => {
pokemonTypes.push(" " + pokemon.types[key].type.name);
});
let typesElement = $("<p>" + "Type(s): " + pokemonTypes + "</p>");
modalTitle.append(nameElement);
modalBody.append(imageElementFront);
modalBody.append(heightElement);
modalBody.append(weightElement);
modalBody.append(typesElement);
modalContainer.classList.add("is-visible");
$("#pokemonModal").modal("show");
}
This is just a portion of the code, but where I believe the problem exists to create such slideshow...
Any thoughts?

RDLC report Index was outside the bounds of the array asp net core

I got Index was outside the bounds of the array error when use debug mode in asp net core mvc, but its ok when run in non-debug mode (Shift+F5).
Here details of error description :
An unhandled exception occurred while processing the request.
IndexOutOfRangeException: Index was outside the bounds of the array.
AspNetCore.ReportingServices.RdlExpressions.ExpressionHostObjectModel.RemoteArrayWrapper.get_Item(int
index)
ReportProcessingException: An unexpected error occurred in Report
Processing. Index was outside the bounds of the array.
AspNetCore.ReportingServices.ReportProcessing.Execution.RenderReport.Execute(IRenderingExtension
newRenderer)
LocalProcessingException: An error occurred during local report
processing.;An unexpected error occurred in Report Processing. Index
was outside the bounds of the array.
AspNetCore.Reporting.InternalLocalReport.InternalRender(string format,
bool allowInternalRenderers, string deviceInfo, PageCountMode
pageCountMode, CreateAndRegisterStream createStreamCallback, out
Warning[] warnings)
Here my export to pdf code :
int extension = 1;
var path = $"{this._webHostEnvironment.WebRootPath}\\Report\\RptDO2.rdlc";
Dictionary<string, string> parameters = new Dictionary<string, string>();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
Encoding.GetEncoding("windows-1252");
parameters.Add("txtto", inv.Quotation.CustomerContact.Customer.CompanyName);
parameters.Add("txtaddress_detail", inv.Quotation.CustomerContact.Customer.Address1 + "\r\n"
+ inv.Quotation.CustomerContact.Customer.Address2 + "- "
+ inv.Quotation.CustomerContact.Customer.City + "- "
+ inv.Quotation.CustomerContact.Customer.State + " ("
+ inv.Quotation.CustomerContact.Customer.Zip + ")\r\n"
+ "Phone : " + inv.Quotation.CustomerContact.Customer.PhoneNumber
+ ", Email : " + inv.Quotation.CustomerContact.Customer.Email);
parameters.Add("txtdo_no", inv.Id.Replace("INV", "DO"));
parameters.Add("txtdate", inv.Quotation.CreatedAt.ToShortDateString());
parameters.Add("txtrefnum", inv.QuotationId);
parameters.Add("txtfrom", us.FirstName + " " + us.LastName);
parameters.Add("txtUP", TextUp);
parameters.Add("kop_nama", c.CpName);
parameters.Add("kop_alamat", c.CpStreetAddress);
parameters.Add("kop_alamat2", c.CpCity + " " + c.CpState + " (" + c.CpZip + ")");
parameters.Add("kop_contact", c.CpPhone);
parameters.Add("kop_email", c.CpEmail);
parameters.Add("kop_logo", Convert.ToBase64String(c.CpFoto));
parameters.Add("txtjabatan", us.Designation);
parameters.Add("txtPrintedBy", lgnuser.FirstName + " " + lgnuser.LastName);
List<vwQuotationDetail> vwQuotationDetails = new List<vwQuotationDetail>();
foreach (TblquotationDetail quos in inv.Quotation.TblquotationDetail.OrderBy(o => o.Id))
{
vwQuotationDetail quotationDetail = new vwQuotationDetail
{
id = quos.Id,
quotation_id = quos.QuotationId,
order_number = quos.OrderNumber,
product_name = quos.Product.ProductName,
product_id = quos.ProductId,
product_comments = string.IsNullOrEmpty(quos.ProductComments) ? "" : quos.ProductComments,
quantity = quos.Quantity,
unit_price = quos.UnitPrice,
unit_name = quos.Product.Unit.UnitName,
sub_total = quos.SubTotal,
product_desc = quos.Product.ProductDesc,
category_name = quos.Product.Category.CategoryName
};
vwQuotationDetails.Add(quotationDetail);
}
LocalReport localReport = new LocalReport(path);
localReport.AddDataSource("dsDO", vwQuotationDetails.ToArray());
//var result = localReport.Execute(RenderType.Pdf, extension, parameters, mimtype);
var result = localReport.Execute(RenderType.Pdf, extension, parameters);
return File(result.MainStream, "application/pdf");
Any suggestion will appreciated, thanks in advance.
Just Dont Pass extension as 1 in:
var result = localReport.Execute(RenderType.Pdf, extension, parameters);
The Solution is:
int ext = (int)(DateTime.Now.Ticks >> 10);
var result = localReport.Execute(RenderType.Pdf, ext, param);
In other words, Extension should not be same for every report.

VTD-XML element fragment incorrect

When parsing a XML document (in UTF-8) containing a special character like © using VTD-XML I now encounter an issue that the returned element fragment (getElementFragment) is not correct.
Example code:
VTDGen vg = new VTDGen();
String xmlDocument =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<Root>\r\n" +
" <!-- © -->\r\n" +
" <SomeElement/>\r\n" +
"</Root>";
// For some reason with US_ASCII it does work, although the file is UTF-8.
vg.setDoc(xmlDocument.getBytes(StandardCharsets.UTF_8));
// True or false doesn't matter here, some result.
vg.parse(false);
// Find the element and its fragment.
VTDNav nv = vg.getNav();
AutoPilot ap = new AutoPilot(nv);
ap.selectXPath("//SomeElement");
while ((ap.evalXPath()) != -1) {
long elementOffset = nv.getElementFragment();
int contentStartIndex = (int)elementOffset;
int contentEndIndex = contentStartIndex + (int)(elementOffset>>32);
System.out.println("Returned fragment: " + contentStartIndex + ":" + contentEndIndex + ":\n'" + xmlDocument.substring(contentStartIndex, contentEndIndex) + "'");
}
This returns:
Returned fragment: 65:79:
'SomeElement/>
'
While when changing the StandardCharsets.UTF_8 into StandardCharsets.US_ASCII it does work:
Returned fragment: 64:78:
'<SomeElement/>'
When the input file is a UTF-8 file, this leads to incorrect behaviour. Can this be a bug in VTD-XML, or am I doing something wrong here?
The "©" is a two-word unicode char which causes the starting/ending unicode offset to drift from the starting/ending byte offset by 1. This is not a bug... below is the fix
while ((ap.evalXPath()) != -1) {
long elementOffset = nv.getElementFragment();
int contentStartIndex = (int)elementOffset;
int contentEndIndex = contentStartIndex + (int)(elementOffset>>32);
System.out.println("Returned fragment: " + contentStartIndex + ":" + contentEndIndex + ":\n'"
+ nv.toString(contentStartIndex,(int)(elementOffset>>32)));
//+ xmlDocument.substring(contentStartIndex, contentEndIndex) + "'");
}

SharePoint 2010 Custom List and Attachments

I have created Custom List with few columns namely:
Title
Description
HrefLink
And optionally upload Attachments to the list item.
My scenario is as following, fetch the data from the list and print the data in list with hyperlink. Here, for hyperlink I should attach the any attachment is there for an item else pull the HrefLink field value.
How can I find if a list item has an attachment and how can I pull the path of attachment and print it?
I have achived fetching the attachments using the following login and printed to literal:
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite currentSite = new SPSite(siteUrl))
{
using (SPWeb currentWeb = currentSite.OpenWeb())
{
/*Footer - Hotspot Links */
//Define string builder to attach the fetched content
StringBuilder strFooterHotspotLinks = new StringBuilder();
SPList lstFooterHotspotLinks = currentWeb.Lists["Footer Hotspot Links"];
//Difine list query
SPQuery spQryFooterHotspotLinks = new SPQuery();
spQryFooterHotspotLinks.Query = "<OrderBy><FieldRef Name='Hotspot_x0020_Order' Ascending='True' /></OrderBy>";
spQryFooterHotspotLinks.RowLimit = 5;
SPListItemCollection lstItmFooterHotspotLinks = lstFooterHotspotLinks.GetItems(spQryFooterHotspotLinks);
int lnkCount = 1;
if (lstItmFooterHotspotLinks.Count > 0)
{
foreach (SPListItem itmFooterHotspotLinks in lstItmFooterHotspotLinks)
{
String qlAttachmentAbsUrl = itmFooterHotspotLinks.Attachments.UrlPrefix; //gets the containing directory URl
SPAttachmentCollection qlAttachments = itmFooterHotspotLinks.Attachments; //check the attachment exists or not for list item
//If list attachmetns are existing
if (qlAttachments.Count > 0)
{
//Loop the list to find the attachments exist ot not and attach to the link
foreach (String qlAttachmentName in qlAttachments)
{
strFooterHotspotLinks.Append("<li><a href='" + qlAttachmentAbsUrl + qlAttachmentName + "'><span class='icn-" + lnkCount + "'></span>" + itmFooterHotspotLinks["Hotspot Title"] + "</a></li>");
lnkCount++;
}
}
else
{
strFooterHotspotLinks.Append("<li><a href='" + itmFooterHotspotLinks["Hotspot Link"] + "'><span class='icn-" + lnkCount + "'></span>" + itmFooterHotspotLinks["Hotspot Title"] + "</a></li>");
lnkCount++;
}
}
}

Get web methods dynamically for an asmx service

We have number of asmx services. I want to give an user a page with a textbox to input service url like http://abc.win.com/myservice/customerdata.asmx. When user hit "Load" button, dynamically I add all the web methods to the dropdown. I need some pointers:
1. How to dynamically get all the methods?
2. How can I get the SOAP request for the method selected? So that, we can replace the parameter values with actual values?
Appreciate your help.
Kuul13 : You need to modify your webservice URL like http://abc.win.com/myservice/customerdata.asmx?wsdl when user clicks on load button. then you can use we "ServiceDescription" class to get wsdl description and then iterate that to get method names in 'WebMethodInfoCollection' class.
To get SOAP request you need to use SOAPExtension class.This will give you SOAP Request and Response XML.Refere this link for that : http://blog.encoresystems.net/articles/how-to-capture-soap-envelopes-when-consuming-a-web-service.aspx?www.microsoft.com
For dynamically calling webservice look a this V.Good article
http://www.codeproject.com/KB/webservices/webservice_.aspx
Please reply me for any comment.
System.Net.WebClient client = new System.Net.WebClient();
System.IO.Stream stream = client.OpenRead("http://www.webservicex.net/globalweather.asmx?wsdl");
ServiceDescription description = ServiceDescription.Read(stream);
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap12";
importer.AddServiceDescription(description, null, null);
importer.Style = ServiceDescriptionImportStyle.Client;
importer.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions.GenerateProperties;
CodeNamespace nmspace = new CodeNamespace();
CodeCompileUnit unit1 = new CodeCompileUnit();
unit1.Namespaces.Add(nmspace);
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit1);
if (warning == 0)
{
CodeDomProvider provider1 = CodeDomProvider.CreateProvider("CSharp");
string[] assemblyReferences = new string[2] { "System.Web.Services.dll", "System.Xml.dll" };
CompilerParameters parms = new CompilerParameters(assemblyReferences);
CompilerResults results = provider1.CompileAssemblyFromDom(parms, unit1);
object[] args = new object[1];
args[0] = "India";
object wsvcClass = results.CompiledAssembly.CreateInstance("GlobalWeather");
MethodInfo mi = wsvcClass.GetType().GetMethod("GetCitiesByCountry");
RegExpForCountryCity(mi.Invoke(wsvcClass, args).ToString());
}
else
{
Console.WriteLine("Warning: " + warning);
}
void RegExpForCountryCity(string strHTML)
{
Regex qariRegex = new Regex(#"<Table>\s*<Country>(?<Country>[\s\S]*?)</Country>\s*<City>(?<City>[\s\S]*?)</City>\s*</Table>", RegexOptions.IgnoreCase | RegexOptions.Multiline);
MatchCollection mc = qariRegex.Matches(strHTML);
string strCountryCity = "";
for (int i = 0; i < mc.Count; i++)
{
if (string.IsNullOrEmpty(strCountryCity))
strCountryCity = "Country: " + "<b>" + mc[i].Groups["Country"].Value + "</b>" + " " + "City: " + "<b>" + mc[i].Groups["City"].Value + "</b>" + "</br>";
else
strCountryCity += "</br>" + "Country: " + "<b>" + mc[i].Groups["Country"].Value + "</b>" + " " + "City: " + "<b>" + mc[i].Groups["City"].Value + "</b>" + "</br>";
}
Response.Write(strCountryCity);
}