How to clear Sitecore item from cache - sitecore

I believe Sitecore is caching an item's workflow value and I need to be able to clear it.
The scenario is that I issue an ajax request to determine whether a specific item exists and if it does exist retrieve its Workflow field value. The user fills out a form and they have the options to Save or Submit that form; when they submit the form it enters a Workflow state. However, even if I switch browsers the LoiHasNoWorkflow keeps the previous value unless I publish again. I have a method to clear some caches but I'm not sure which might be actually caching the field.
public static bool ClearCache()
{
foreach (DictionaryEntry entry in HttpContext.Current.Cache)
{
HttpContext.Current.Cache.Remove((string)entry.Key);
}
Context.Database.Engines.TemplateEngine.Reset();
Context.ClientData.RemoveAll();
CacheManager.ClearAllCaches();
return true;
}
public bool LoiHasNoWorkflow => CBUtility.ClearCache() && string.IsNullOrEmpty(loi?.Fields["__Workflow"].Value);
How can I determine why the item's __Workflow value won't clear? I can even delete the item through Sitecore UI, refresh the page, and issue the same request but get the value when the item did exist.

Actually the issue turned out to be not related to the cache but my own mistake. My loi object was a static variable within that class and so it wasn't getting cleared out on every page refresh. Here is the SO deeper explanation that led me to this realization. Actually learned a bit more about how static variables.
Lifetime of ASP.NET Static Variable

Related

peekRecord() is not working but peekAll() is working

My backend always responds with all available data and it took a considerably amount of time. So I'm reloading store periodically and I plan to use peekAll() and peekRecord().
My code is:
model: function() {
return Ember.RSVP.hash({
'clusters': this.store.peekAll('cluster'),
'single': this.store.peekRecord('cluster', 'cluster::My')
});
When code is executed, at first I can see that both of these items do not contain content. After few seconds data are loaded to store and I can see content 'clusters' on template as expected. But 'single' is still completely without content ({{model.single}} does not return nothing in template). But when I have a button with action:
alert(this.store.peekRecord('cluster', 'cluster::My'));
I can see that the record was found. Records are also available via Ember Inspector. What am I doing wrong that only peekAll() works in model for me.
The semantics of both methods are:
store.peekAll returns a live array that is updated as the store is updated.
store.peekRecord returns the corresponding object in the current cache, or null, and it does not update.
So the behaviour you're observing is the expected one. If you want to use the peek methods, my advise is to make sure that the initial request has finished loading before fetching any data from the store.

How to get all goals triggered during Sitecore session in commitDataSet Analytics pipeline?

I have an Analytics pipeline added just before the standard one in section to delete duplicate triggered pageevents before submitting all to database so I can have unique triggered events as there seems to be a bug on android/ios devices that triggers several events within few seconds interval.
In this custom pipeline I need to get the list of all goals/events the current user triggered in his session so I can compare with the values in dataset obtained from args parameter and delete the ones already triggered.
The args.DataSet.Tables["PageEvents"] only returns the set to be submitted to database and that doesn't help since it is changing each time this pipeline runs. I also tried Sitecore.Analytics.Tracker.Visitor.DataSet but I get a null value for these properties.
Does anyone knows a way how to get a list with all goals the user triggered so far in his session without requesting it directly to the database ?
Some code:
public class CommitUniqueAnalytics : CommitDataSetProcessor
{
public override void Process(CommitDataSetArgs args)
{
Assert.ArgumentNotNull(args, "args");
var table = args.DataSet.Tables["PageEvents"];
if (table != null)
{
//Sitecore.Analytics.Tracker.Visitor.DataSet.PageEvents - this list always empty
...........
}
}
}
I had a similar question.
In Sitecore 7.5 I found that this worked:
Tracker.Current.Session.Interaction.Pages.SelectMany(x=>x.PageEvents)
However I'm a little worried that this will be inefficient if the Pages collection is very large.

ember.js ember-data initiale state of new created model record

Ember.data 2.2.0
The state of just created object is dirty (get('hasDirtyAttributes' return true), cause the new ID is set every time.
I need to know when the record is created, not saved and the "user" not modified it. So, I can't use the dirty state cause the store change it.
If I modified the internal state just after create the record, I will broke somthing inner the record?
My real need, is when I create the record I need a initiale state and I want detect when a user change it. So, I saw in the record source code, it's use the "setProperties" methode to set the ID and optionaly the data passed to the createRecord method.
So, I want override the createRecord store metod to set the dirty state to false after created it. And the principal, how I can do that?
I saw the doc of DS.RootState Class and it just talk about that states : (deleted, saved, uncommitted, inFlight, empty, loaded, created, updated, loading) and the method translateTo but nothing to change the dirty state.
In the doc say :
Flags are Boolean values that can be used to introspect a record's
current state in a more user-friendly way than examining its state
path
So... I set currentState.parentState.isDirty to false and that it
Edit: After set the flag directly, the record doesn't change state, stay in no dorty. So, how what I can do?
The only solution I found is test if the object is new. If is it, re-create a new one.
If not, I call the rollbackAttributes().
And use the that method on model for detect a change :
isChanged : function() {
return this._internalModel.hasChangedAttributes();
}

Can I guarantee publishing of an item I've just created?

I've got a situation where I want end-users to be able to create new Sitecore items... and then immediately be able to navigate to the Item's URL. Obviously the item will have to be published... but this happens in something of a black box. Is there a way to guarantee an item has been published from Master to Web?
Alternately, I could create the Item in the Web DB... then re-create/copy a Master version at some point. But this strategy seems fraught with peril. And maybe just a bad idea in general.
Suggestions? Am I being needlessly paranoid about creating items directly in Web?
I'll start by saying my answer is not necessarily advisable. However, depending on your situation it should work.
If the items that users are creating always have the same template you could try creating a custom item resolver that falls back to using the Master database.
Allow Sitecore to attempt to resolve the item normally.
When it fails, look in the Master database.
If the item is in there, make sure it has the correct template
Set the found item as the context item.
Using this method, you can publish the items from Master->Web s normal, but you don't have to wait until publishing is completed to see it.
Once again, this should solve the problem, but it's up to you to weigh the risks of serving up Master DB content.
You can't "guarantee" because publishing may be queued and won't go live instantly. Instead if you need instant access, I recommend a preview site that points to the master database:
How to Setup a Sitecore Preview Site to Review Content Before Publishing
You could create a event mapping to a class with the code to publish the item. In the code you can define any rule you want regarnding whether to publish or not.
<event name="item:saved">
<handler type="YourType.ItemEventHandler, YourType" method="OnItemSaved" />
</event>
And the OnItemSaved would look like this: (not tested)
protected void OnItemSaved(object sender, EventArgs args)
{
if (args == null)
{
return;
}
Item item = Event.ExtractParameter(args, 0) as Item;
var webDb = Sitecore.Configuration.Factory.GetDatabase("web");
var masterDb = Sitecore.Configuration.Factory.GetDatabase("master");
foreach (Language language in masterDb.Languages)
{
var options = new PublishOptions(masterDb, webDb, PublishMode.SingleItem, language, DateTime.Now)
{ RootItem = item, Deep = true };
var myPublisher = new Publisher(options);
myPublisher.Publish();
}
}
And about creating the item in the web db, I also wouldn`t go that way. It would be replaced by the default publishing process unexpectedly.
Personally i don't like front-end user creating items in master database, i feel only content authors/editors should be the ones who create items from either content editor or page editor.
There is no guarantee the item gets published instantly, I would recommend you to store any user-created data in a separate database and on the redirect URL just read the data from this database.

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.