How to force creation of new ContentPartRecords for existing content items? - orchardcms

I have created a new ContentPart with a ContentPartRecord in a custom module and attached it to an existing content type on my website that already has hundreds of content items.
Now when I perform queries of the format contentManager.Query<MyPart, MyPartRecord>().List() I don't get any results since no MyPartRecords actually exist in the database yet.
Is there a way to make sure this happens for all content as soon as my part gets attached to a content type, or will I have to manually interact with all of the items before they become queryable?

This query is asking for all content items that have that part, which is not the case of items created before you added the part to the type definition. See the type definition as a blueprint more than a schema. Depending on what exactly you're trying to do, you may want to try to query by content type instead.
The part will get attached next time the item gets updated, pretty much. You could build something that scripts the operation on existing items, but nothing out of the box will do that.

Related

Update Kentico document field regardless of versioning

I have a field on one of my base page types which I need to update programmatically from an external data feed, so that it can be included in my Smart Search index.
The documents are versioned, but I want to update the published value of this field regardless of checkout state, and obviously avoid any sort of overwrite when documents are checked in.
The field will not appear on the editor form -- or ideally, would conditionally display for Global Admins.
It appears that using the API to update the document without doing a CheckOut fails silently. However if I do a Checkout/Update/CheckIn on a checkout-out page, the author will lose their work I assume?
Any way to handle this "versionless" field via the Kentico data model and API?
I don't think there is a way around updating checked out pages. You can update the page type table directly, but as you mentioned, it will be overwritten when they check in. You could update the version history I believe to make changes to the current data that is checked out, but again, I think that will be lost if the user cancels.
The only way I can think of to solve your issue is to create another table that maps the values you want to the page. Then you don't have to worry about the pages being checked out, you just need to grab the documentID or something. Since the value isn't displayed to the editor, you just have a field that does a lookup on this table.
The preferred and right way is using the API but as you stated, it causes problems if a user has something already checked out and working on it or it's in workflow and not published yet.
If the field you're updating is page type specific, there is one thing specifically I can think of and that's going directly to the database to the page type's database field and perform an update to that field.
Note: this is not recommended unless you know specifically what you're doing and have done full testing on it
The down side of going direct to the database is this will not update the current version since you're using check in/out and workflow. You will also need to update the checked out and current version which means you need to:
Go to the Document itself in the cms_documents table and get the document you are working with.
Then using the fields DocumentCheckedOutVersionHistoryID and DocumentPublishedVersionHistoryID' you can get the version history IDs of the document from theCMS_VersionHistory` table.
Then you can perform an update to the CMS_VersionHistory and your custom page type fields.
You will then need to look in the CMS_WorkflowHistory table and find out if that document is in workflow and in what step.
After you have that workflow history step, use the VersionHistoryID field to go back to the CMS_VersionHistory table and update that record with your data.
Again, not an elegant solution since you are using check in/out and workflow but after some trial and error and testing you should be able to figure it out.
UPDATE
You may also be able to add a custom table or some other linked database table which will allow you to create a global handler. The linked table would be where you perform your updates via API and other calls without versioning or workflow. Then when a user updates a specific page type you could do a check to see when the last time that linked table was updated and update the field(s) you need on update of that particular page (of course by node and document IDs).
Unfortunately you'll have to check it in and out with API. See examples here.
Also you might need to publish it in order to reflect changes on the live site.

update netsuite parent field via suitescript in view mode

I have scripts that react off of, for example, a client Recalc client event. For example, on my form I have a subtab that users may add or remove items from. Based on actions on this subtab (housing a child record of the parent) I would like a field on the parent to update (say to show a total from the children records).
As I was saying, these events seem to work fine if in edit mode but they do not work correctly in view mode. (even in view mode these child records have a "Delete" option at the end of each row in the subtab. This was provided by netsuite by default.
I wondered if anyone had any tips to best allow this parent field to update real time while in updating the subtab rows with the form in view mode.
Thanks.
You can make a custom field on the parent (header) whose value is determined by saved search. For instance, make a saved search that totals the line values by transaction. Be sure to make it filter by transaction in the Available Filters tab. Make the search public so everyone can use it.
Create the custom field that sources the total from the saved search. Make sure to uncheck the "Store Value" checkbox, as you don't want to store the data, you want to reference the search results. You do this on the Validation and Defaulting tab. You'll see a field for Saved Search there. Choose the search you created above.
As you remove/add/change lines on the transaction, the field updates accordingly. In essence, you don't need a single line of code to make this work - it's all in how you create the search and the custom field that references it.
I have a similar situation posted here.
The NetSuite team answered me by email, and it happens you can't really achieve this on the view mode: some API methods are not available. Their suggestion to my case (and I think it applies to yours too) was really to force a refresh on the whole page.
Of course, you can always achieve this accessing the DOM elements directly, but this isn't a best practice, as your code can stop working if these elements change on a version update.
I had the same problem, I'm not able to restrict on view or remove edit button. But, there was one alternative solution with workflows, you can deploy workflow on child record edit mode restrictions, then if the user clicks edit on view then the record will not be available to edit. This concern will apply to custom record as well.

UIA - AutomationElement doesn't return correct name when list view changes

I'm trying to read the contents of a "list view" using automation. The first time I navigate to it, I'm able to go from item to item, getting the correct text for each list item. However, when I display a different screen (which is apparently reusing this display object), the text on the screen is different, but automation gets the same text as the first set. From then on I can only get the text for the first view I looked at. It's like the text is being cached and I'm only able to look at the cached view. UISpy, however, seems to grab the right values every time, and if I use it while my automation is paused, I end up getting the right values.
In my automation, I use Find to grab the header, and walk the tree to the List View and get the text for each element. I thought if you used the Current property, you got the live data. Apparently I was mistaken. How do I either refresh the tree or get the REAL data?
Yes, the Current property on a certain AutomationElement will return its current, 'live', value. UIA will not cache anything automatically, you'll have to declare it yourself and explicitly access the Cached properties.
What's probably happening is that the new tree items you're seeing after selecting a different screen, are actually re-created (and that actually makes sense, UI-wise), not just updated. You could easily determine if this is the problem by selecting the first screen and writing down the tree items' RuntimeId property (you can see it in UI Spy). Then, select the second screen and check if the RuntimeId has changed. If it has, then it's just not the same object instance.
If this is the case, all you need to do is get the items again. It'll be easier to do this using AutomationElement.FindAll with a ClassName property condition.

Autofilling Part Values in an Orchard Controller

I'm very new to Orchard (and ASP.NET MVC) and I'm having some difficulty wrapping my head around how Orchard part properties can be automatically set in a controller. I have a "Gallery" content type, consisting of the stock Title, Container and Owner parts. I'm creating a controller with a Create method that hides all of the details of the Container part since I'm going to set the default page length, the item type, et cetera in the HttpPost version of the Create method. My problem is I don't know how to set those values on the http Post.
My general plan was as follows:
I created a CreateGalleryViewModel containing the title and admin username, both as a string. IN the view those two are represented as form fields. On the submit, I could run TryUpdateModel in the controller to update the CreateGalleryViewModel with the form values. But then how do I update the Part properties? I think I'm supposed to run IContentManager.UpdateEditor(, this) but I don't think this ca, work because I never ran IContentManager.BuildEditor in the first place. Here's where I'm stuck because I don't see how the content parts get validated and updated properly.
Am I looking at this at the wrong level of abstraction? How do I make a simplified editor for my Gallery content type?
What you basically need to know here is the following:
You can build the editor of a content item with IContentManager.BuildEditor()
You can updated an item's parts' values from the POST data with IContentManager.UpdateEditor()
You can also access parts by "casting" content items with the As() method (needs the Orchard.ContentManagement namespace).
When you're dealing with content items because of their dynamic nature it's rarely a good approach to create a view model where you recreate some of the parts' properties. If you have such static view models for what's contained in a content item then you'll miss the extensibility and flexibility that comes with Orchard's content model. E.g. if you add a new part to that content type since you're using a static view model the new part won't be handled.
For a complete example of how to manage content items from code, see the Training Demo module.

Is the OnAdded field event fired when a content type is added to a list?

Say I have a custom field type called MyCoolField that I have deployed in a solution. This solution also contains a SPEventReceivers that has overridden ItemAdded, ItemUpdated, and ItemDeleting. All the specifics of this particular field type are probably not super relevant, but one thing to note is that inside of the OnAdded method it attempts to add a series of event receivers to its ParentList.
After this solution has been deployed, I activate a site-scoped feature that does nothing except add a new site content type - MyContentType. Now, I would not expect any event receivers registered anywhere, since ParentList is supposed to be null for site content types.
So in yet another feature, I go add this MyContentType to a list. The question I have is whether I should expect the OnAdded method to get called now (when adding a content type to the list) or does it only get called when adding the field to list/content type? It seems like it is not getting added (the event receivers are not getting registered), but I wanted to make sure that is truly expected behavior and not something else odd going on in this environment.

Resources