Sitecore Bulk create items with event disablers taking more time to visible in CM content editor tree - sitecore8

HI
I am trying to create bulk items in CM server using the below code. This code runs on a windows service based application, once this code completes all the newly created items can be viewed in sitecore search only,`enter code here but it is not displayed in content editor tree, it is taking some more hours like 6hrs to display in content editor tree. please let me know whether any other code is necessary to populate the items immediately in CM - master server once the items are created.
Sitecore.Context.SetActiveSite("shell");
using (new SecurityDisabler())
using (new SyncOperationContext())
using (new ProxyDisabler())
using (new EventDisabler())
using (new DatabaseCacheDisabler())
using (new BulkUpdateContext())
{
Sitecore.Configuration.Settings.Indexing.Enabled = false;
//Business operations starts here
Sitecore.Configuration.Settings.Indexing.Enabled = true;
}

Related

EmberJS client side record management (ember-data)

I have just started trying to use ember-data. I have an ember app for which I need to produce all the data on the client side and then save it all at once. So my object graph has a "Project" as the root object, then a project can have many "Sections" and then each section can have many "Items".
I am up to the stage where I am trying to create Item records on the client side and add them to the correct Section. When I am ready to save the data I just want to use project.save() and have it go and save the object graph instead of saving every time the model changes.
I am trying to look up the section to place the items in by name using store.filter({name:"section1"}) but ember keeps trying to go to the server to look them up. I see this in the console: GET http://localhost:4200/sections?name=Section1 404 (Not Found).
This is what I am trying to do:
store.filter('section', {name:'Section1'}, function(section) {
return section;
}).then(function(section)
{
var record;
//create a record
section.pushObject(record);
});
You are doing server side filtering and you want client side filtering.
Please read this article carefully.
In short, you should do
store.filter('section', function(section) {
return section.get('name') == 'Section1';
});

Bulk content load and Page Creation in Sitecore

I have a process where i am getting xml resultset , from which i can process the data and programmatically create pages in Sitecore. This is simple if we have to few pages that even once .
Now my problem is that i have to create minimum 50k pages in Sitecore twice a day from xml.So to load that much data in sitecore once is really slow process.
Is there is a optimum way to create these pages in Sitecore .
I am using Sitecore 7.
process for page creation
using (new Sitecore.SecurityModel.SecurityDisabler())
{
for (int i = 0; i < item.count; i++)
{
Item newCityItem = parentCityItem.Add("Page_" + i, template1);
newCityItem.Editing.BeginEdit();
try
{
newCityItem.Fields["html"].Value = mPages[i].ToString();
newCityItem.Editing.EndEdit();
}
catch (System.Exception ex)
{
// The update failed, write a message to the log
Sitecore.Diagnostics.Log.Error("Could not update item " + newCityItem.Paths.FullPath + ": " + ex.Message, this);
// Cancel the edit (not really needed, as Sitecore automatically aborts // the transaction on exceptions, but it wont hurt your code)
newCityItem.Editing.CancelEdit();
}
}
}
Any help ...
Wrap your loop in a BulkUpdateContext which disables events, indexes, etc
using(new BulkUpdateContext())
{
// code here
}
I don't think it's another way to create Sitecore Items.
What I suggest you, to disable indexing on master database, because it will slow a little bit when new items are created. If you need to index after creating your items you can enable again the indexes and start reindexing.
If these items are being replaced twice a day in Sitecore, I assume that they're not being edited and you're using Sitecore for the presentation layer.
If so, you could map your xml as a Sitecore DataProvider. This way, the xml is used as the source of the items - although they can still be read in Sitecore, and the Sitecore presentation layer sees them as regular sitecore items.
There's a blog post explaining it at http://blog.horizontalintegration.com/2013/03/17/an-introduction-to-sitecore-data-providers/, as well as some documentation in the SDN.
Edit (thanks to jammykam)
I wouldn't map direct to an xml file - maybe put that into a db and then map that into sitecore.
Everytime when you save an item, the statistics were updated (like modified user, modified date etc.) and all the events were fired (item saved, index building, etc). You can disable both of these:
item.Editing.BeginEdit();
item["Title"] = "My new title";
item.Editing.EndEdit(false, true);
Depending on your requirements you may need to rebuild the index at the end of your import.

How to prevent Sitecore modal dialog from redirecting user to new item?

I’m stuck with a little development annoyance. I have crated an application to extend Sitecore authoring interface.
The application queries some internal services and asks few additional questions from a content author before creating an new content item in Sitecore.
I have modeled the app on (Sitecore.Shell.Applications.Templates.CreateTemplate.CreateTemplateForm).
The problem I’m having is, as soon as an item is created my WizardForm is reloaded to load newly created item.
What I want is for the wizard to go through to the “Final” page and reload the main UI once the modal dialog is closed.
Exactly how new OOTB template wizard works. I know that if I comment my item creation code out the UI behaves as expected.
Looks like a create of an item generates some events in the background that UI is responding to and reloads my modal dialog with the newly created item. (I have tried the following solutions http://sdn.sitecore.net/Forum/ShowPost.aspx?postid=29092, http://sdn.sitecore.net/Forum/ShowPost.aspx?postid=29968, however this does not seem to solve it for me).
The original code seems to disable events like so:
this.CreateTemplatePicker.DisableEvents();
TemplateItem templateItem = Client.ContentDatabase.Templates.CreateTemplate(this.TemplateName.Value, selectionItem);
this.CreateTemplatePicker.EnableEvents();
I have tried the following:
Client.Site.Notifications.Disabled = true;
var item = container.Add(ItemUtil.ProposeValidItemName(this.Title.Value), Settings.ProductImageTemplateID);
Client.Site.Notifications.Disabled = false;
AND OLSO
Item item;
using (new EventDisabler())
{
item = container.Add(ItemUtil.ProposeValidItemName(this.Title.Value), Settings.ProductImageTemplateID);
}
All with the same result. The wizard modal dialog is reloaded as soon as I get to the page where the item is created.
Using fiddler I can see the command to reload the windows is sent to the client. I just cant figure out how do I tell Sitecore UI to ignore the event(s) or alternatively prevent event(s) from being generated in the first place. The first command being sent to the UI below tells the page to load Content Editor, exactly the thing I'm trying to prevent.
{"commands":[
{"command":"SetLocation","value":"/sitecore/shell/sitecore/content/Applications/Content%20Editor.aspx?fo=%7b186F686E-A8FF-4303-B59F-4D284A5A0196%7d&db=master&id=%7B186F686E-A8FF-4303-B59F-4D284A5A0196%7D&la=en&vs=1"},
{"command":"SetDialogValue","value":"{186F686E-A8FF-4303-B59F-4D284A5A0196}"},
{"command":"SetStyle","value":"none","id":"Constraints","name":"display"},
{"command":"SetStyle","value":"","id":"LastPage","name":"display"},
{"command":"SetAttribute","value":true,"id":"NextButton","name":"disabled"},
{"command":"SetOuterHtml","value":"<button id=\"CancelButton\" class=\"scButton\" TabIndex=\"0\" onclick=\"javascript:return scForm.postEvent(this,event)\" onkeydown=\"javascript:scForm.handleKey(this, event, null, '32')\">Finish</button>","id":"CancelButton"},
{"command":"Focus","value":"CancelButton","scrollintoview":"0"},{"command":"Eval","value":"scUpdateWizardControls();"},
{"command":"SetAttribute","value":true,"id":"BackButton","name":"disabled"},{"command":"Eval","value":"scAlignWizardButtons()"}
]}
Just a little info about my Sitecore environment:
Sitecore started
Sitecore.NET 7.0. (rev. 130810)
C:\Inetpub\wwwroot\sc71\Website\bin\Sitecore.Client.dll (Sitecore CMS, Sitecore Client Application, 7.0 rev. 130810)
C:\Inetpub\wwwroot\sc71\Website\bin\Sitecore.Kernel.dll (Sitecore CMS, Sitecore CMS Kernel Library, 7.0 rev. 130810)
C:\Inetpub\wwwroot\sc71\Website\bin\Sitecore.Nexus.dll (Sitecore.Nexus)
Operating system Microsoft Windows NT 6.2.9200.0
Microsoft.NET version 4.0.30319.18051
Process id: 8040
Windows identity used by the process: NT AUTHORITY\NETWORK SERVICE. Impersonation: False
Managed pipeline mode: Integrated
In the end the problem only affected bucketable items. No need to disable event or anything, that was a red herring. However, in my case I am working with buckets and bucketable items, so I needed to get it fixed.
The offending code ended being Sitecore.Buckets.Commands.AddFromTemplateCommand(). Thanks to Sitecore support engineers for getting to the bottom of this. A proposed workaround, that worked for me is as follow. This have been reported to Sitecore development team and I guess will be resolved at some stage in a future release of Sitecore. The current (at the time of writing) version Sitecore.NET 7.0. (rev. 130810) is affected.
You will need to substitute existing implementation with your own (see code below). To replace existing implementation overwrite the following configuration /App_Config/Includes/Sitecore.Buckets.config file at /sitecore/databases/database[#id="master"]. I ended up creating a configuration patch file that looked like this.
Configuration:
<?xml version="1.0"?>
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<databases>
<database id="master" singleInstance="true" type="Sitecore.Data.Database, Sitecore.Kernel">
<Engines.DataEngine.Commands.AddFromTemplatePrototype>
<obj patch:instead="obj[#type='Sitecore.Buckets.Commands.AddFromTemplateCommand, Sitecore.Buckets']"
type="Sitecore.Support.Buckets.Commands.AddFromTemplateCommand, MyAssembly"/>
</Engines.DataEngine.Commands.AddFromTemplatePrototype>
</database>
</databases>
</sitecore>
</configuration>
Code:
using Sitecore.Data.Items;
using Sitecore.Text;
using Sitecore.Web.UI.Sheer;
using System;
using System.Web;
namespace Sitecore.Support.Buckets.Commands
{
public class AddFromTemplateCommand : Sitecore.Buckets.Commands.AddFromTemplateCommand
{
protected override Sitecore.Data.Engines.DataCommands.AddFromTemplateCommand CreateInstance()
{
return new AddFromTemplateCommand();
}
protected override void SetLocation(Data.Items.Item item)
{
if ((HttpContext.Current != null) && (Context.ClientPage != null))
{
// This condition is set to go around an issue when a bucket item is created from within a custom wizard app.
// Replace the specified path with your own one.
if (Sitecore.Context.RawUrl != null && !Sitecore.Context.RawUrl.Contains("/sitecore/shell/Applications/Issues/Create Product Bucket.aspx"))
{
UrlString str = new UrlString(Sitecore.Buckets.Util.Constants.ContentEditorRawUrlAddress);
str.Add(Sitecore.Buckets.Util.Constants.OpenItemEditorQueryStringKeyName, item.ID.ToString());
item.Uri.AddToUrlString(str);
UIUtil.AddContentDatabaseParameter(str);
SheerResponse.SetLocation(str.ToString());
}
}
}
}
}

How to execute workflows in code?

Scenario:
User clicks a command on the workflow
Workflow custom action carry out a number of checks
Workflow custom action executes another command on the same workflow dependant on results
The code I have so far is:
Database db = Factory.GetDatabase("master");
if (Request.QueryString["_id"] != null)
{
var itm = db.GetItem(new ID(Request.QueryString["_id"]));
WorkflowCommand[] availableCommands = wf.GetCommands(itm.Fields["__Workflow state"].Value);
wf.Execute(Request.QueryString["command"], itm, "Testing working flow new screens", false, new object[] { }); // Execute the workflow step.
}
However, I get a Object not set to an instance error on the wf.Execute line - but with no meaningful stack trace or anything :(
I've put in the wf.GetCommands line just to check that things are actually where I expect them, and availableCommands is populated with a nice list of commands that exist.
I've checked the commandId is valid, and exists.
Itm is not null, and is the Content Item that the workflow is associated to (that I want the workflow to run in context with).
I've checked that the user context etc is valid, and there are no permission issues.
The only difference is that I am running this code within an .aspx page that is executing within sitecore - hopeever, I wouldn't have expected this to cause a problem unless there is a context item that isn't being set properly.
Workflow needs to be run within a SiteContext that has a ContentDatabase and workflow enabled. The easiest way to do this within your site is to use a SiteContextSwitcher to change to the "shell" site.
using (new SiteContextSwitcher(SiteContextFactory.GetSiteContext("shell")))
{
wf.Execute(Request.QueryString["command"], itm, "Testing working flow new screens", false, new object[] { }); // Execute the workflow step.
}
An example of this can be found within the code for the WeBlog Sitecore module.
http://svn.sitecore.net/WeBlog/Trunk/Website/Pipelines/CreateComment/WorkflowSubmit.cs

SharePoint List item BRIEFLY appears as edited by 'System Account' after item.update

I have a shopping cart like application running on SharePoint 2007.
I'm running a very standard update procedure on a list item:
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Quotes"];
SPListItem item = list.GetItemById(_id);
item["Title"] = _quotename;
item["RecipientName"] = _quotename;
item["RecipientEmail"] = recipientemail;
item["IsActive"] = true;
item.Update();
site.Dispose();
}
This item updates properly, however it briefly appears as modified by System Account. If I wait a second and refresh the page, it shows up again as modified by CurrentUser.
This is an issue because on Page_Load I am retrieving the item that is marked as Active AND is listed as Modified By the CurrentUser. This means as a user updates his list, when the PostBack finishes, it shows he has no active items.
Is it the web.AllowUnsafeUpdates? This is necessary because I was getting a security error before.
What am I missing?
First off, it's not AllowUnsafeUpdates. This simply allows modifying of items from your code.
It's a bit hard to tell what's going on without understanding more of the flow of your application. I would suggest though that using Modified By to associate an item to a user may not be a great idea. This means, as you have discovered, that any modification by the system or even potentially an administrator will break that link.
I would store the current user in a custom field. That should solve your problem and would be a safer design choice.
There could be some other code running in Event Receivers and updating the item. Because event recievers runs in context of system user account, and if you update item from event reciever, the modified field will show just that: the system account has modified the item.