Getting unused objects

Brijesh Singh asked on October 31, 2017 18:52

Do we have any process to collect all those objects which are not being used or un-published? I believe this can be done though database and same can be deleted through DB Script as well.

Objects like Page layout, css, templates, web parts etc.

Correct Answer

Brenden Kehren answered on October 31, 2017 21:41

Unfortunately, I won't support a direct delete query of the page templates for reasons I've already explained. I'd suggest using the API approach I already mentioned.

Here is a sample for the page templates. You'd need to do something similar for webparts and checking if they are used by a widget and/or a page template.

// get a list of all non-ui and non-dashboard page templates
var pageTemplates = PageTemplateInfoProvider.GetTemplates().Where("PageTemplateType NOT IN ('ui', 'dashboard')");

foreach (PageTemplateInfo pt in pageTemplates)
{
    var pages = DocumentHelper.GetDocuments().WhereEquals("DocumentPageTemplateID", pt.PageTemplateId).Or().WhereEquals("NodeTemplateID", pt.PageTemplateId).Or().WhereEquals("NodeWireFrameTemplateID", pt.PageTemplateId);
    if (pages.Count <= 0)
    {
        // no pages assigned so could be safe to delete.
        PageTemplateInfoProvider.DeletePageTemplate(pt);
        // this will fail if there are objects in the recycle bin so I suggest wrapping in a try/catch and writing to the event log if the delete fails.
    }
}
1 votesVote for this answer Unmark Correct answer

Recent Answers


Brenden Kehren answered on October 31, 2017 19:01

I'd recommend NOT deleting these objects from the database directly especially if you have workflow and versioning enabled. You will quickly create a mess of your database if you do this.

On most objects you can view a "where used" tab to show you where the object is being used. If an object is not used, you can simply delete it from the UI right there.

0 votesVote for this answer Mark as a Correct answer

Brijesh Singh answered on October 31, 2017 19:09

We have several(500+) such objects. It would be huge time consuming job to delete one by one. Is there any work around to it quickly?

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on October 31, 2017 19:27

Then look through each of the objects configuration or source code and find out how Kentico gets the information as to where the object is used or not and use those api calls. For instance, you can see in Modules>Design>User Interface>Expand Development-Page templates-Edit page template-Pages that in this files code behind ~/CMSModules/PortalEngine/UI/PageTemplates/PageTemplate_Documents.aspx there is a query generated using a where statement for getting the pages using those templates. It does NOT however, allow you to delete those templates directly there.

So your method would look through all the page templates, see if there is a count of documents using that given template, if not, delete the template using the API.

So, no straight sql query will do this work effectively as if you were to use the API.

0 votesVote for this answer Mark as a Correct answer

Brijesh Singh answered on October 31, 2017 20:05

Thanks for the reply but not able to get those points. I could see below code on said page but not select query.

protected void UniGrid_OnBeforeDataReload() { // Generate where condition string where = String.Format("DocumentPageTemplateID = {0} OR NodeTemplateID = {0} OR NodeWireframeTemplateID = {0}", PageTemplateID);

    where = SqlHelper.AddWhereCondition(where, filterDocuments.WhereCondition);
    docElem.UniGrid.WhereCondition = SqlHelper.AddWhereCondition(docElem.UniGrid.WhereCondition, where);
}


protected void UniGrid_OnAfterDataReload()
{
    // Filter data by permissions
    DataSet ds = docElem.UniGrid.GridView.DataSource as DataSet;
    ds = TreeSecurityProvider.FilterDataSetByPermissions(ds, NodePermissionsEnum.Read, currentUser);
    plcFilter.Visible = docElem.UniGrid.DisplayExternalFilter(filterDocuments.FilterIsSet);
}

Also, not able to navigate Modules>Design>User Interface>Expand Development-Page templates-Edit page template-Pages .

0 votesVote for this answer Mark as a Correct answer

Brijesh Singh answered on October 31, 2017 21:22 (last edited on October 31, 2017 21:36)

Can you please review below query to confirm if it will return all unused templates and it is safe to delete these templates.

SELECT PageTemplateDisplayName AS [Template Name],DocumentNamePath AS [Page], PageTemplateID FROM CMS_PageTemplate LEFT JOIN View_CMS_Tree_Joined ON CMS_PageTemplate.PageTemplateID = View_CMS_Tree_Joined.DocumentPageTemplateID WHERE DocumentNamePath is null and PageTemplateType!='dashboard' ORDER BY PageTemplateDisplayName

0 votesVote for this answer Mark as a Correct answer

Brijesh Singh answered on November 1, 2017 15:03

Thank you for quick response. I verified and found corresponding sql for var pageTemplates = PageTemplateInfoProvider.GetTemplates().Where("PageTemplateType NOT IN ('ui', 'dashboard')") is

SELECT * FROM CMS_PageTemplate WHERE (PageTemplateType NOT IN ('ui', 'dashboard'));

I could also see, it is covering page template layout type ascx. Do we still need to change something for web part.

New to Kentico so making sure I am performing correct steps.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on November 1, 2017 15:24

Using sql is not supported to perform the CRUD activities you're explaining, especially if you are new to Kentico. You have a 100% chance of seriously corrupting your data by doing this. Which is why I suggest using the API to handle this.

All of these objects have many relationships in the background, some of which are handled by the database and some which are handled in code. Using the API will only help you.

For instance, a page template is dependent on a layout. The layout can be individual to the page or be a shared layout. Each page layout (shared or not) has webpart zones. In the page template you assign a page layout (shared or not). Then in the webpart zones you place webparts. These webparts are specific per page template (not page or layout). Now you assign a page template to a single or multiple pages.

Using T-SQL in Kentico to perform CRUD actions IS A LAST RESORT that should only happen if you're experienced with Kentico and/or have contacted Kentico Support prior!

0 votesVote for this answer Mark as a Correct answer

Brijesh Singh answered on November 1, 2017 15:29

Agree with you that CRUD actions is risky from sql. Wondering if your provided code will cover webpart also so that given code will be used to delete unused objects.

0 votesVote for this answer Mark as a Correct answer

Brenden Kehren answered on November 1, 2017 15:50

It will get you the templates but not get you the webparts. You have to start with the webparts and then view which tempaltes they are associated with. With webparts, you only want to check webparts which are NOT UI webparts. Deleting those webpart references will break the Kentico UI.

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.