help.axcms.net Axinom Logo

Adding Publish, Delete and Recover Activities

This article describes how to create your own activities, implement bulk operations and add them to the overview page.

Activities

An activity (or CmsActivity) is an operation applicable for a particular element. Examples of such activities are classifying a document, checking in text, and publishing a page. An older name for activities is Bulk Operations, which goes back to the intention of having operations applicable for multiple objects. You can read more about CmsActivities in the Activities article.

Activities can be added to the overview page. For instance, if we need to use the publish activity, we need to create the ArticlePublishActivity class based on CmsActivity. We then override Operations in the overview helper class by adding the articlePublish string to it (there is a property for it in the AxOverviewBaseHelper - Operations).

In this tutorial we will create activites for the following actions:

  • Publish
  • Unpublish
  • Delete
  • Recover

PublishActivity

Let’s start by creating the PublishActivity. This will serve as an example for other activities as their implementation is similar to this.

First we need to register 2 controls on the overview page:


<%@ Register TagPrefix="AxCMS" TagName="PublicationMessage" Src="../admin/controls/PublicationMessages.ascx" %>
<%@ Register TagPrefix="AxCMS" TagName="BulkOperationButtons" Src="../admin/controls/BulkOperationButtons.ascx" %>

Now the ASPX side of the article overview page will look like this:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
<%@ Page Language="c#" CodeBehind="ArticleOverview.aspx.cs" AutoEventWireup="false"
    Inherits="Extras.ArticleOverview" %>

<%@ Register TagPrefix="AxMP" Namespace="Axinom.AECMS.Backend" Assembly="AxCMS.BL" %>
<%@ Register TagPrefix="Ax" Namespace="AxCMS.AxCMSweb.admin.templates" Assembly="AxCMSweb" %>
<%@ Register TagPrefix="AxCMS" TagName="Filter" Src="ArticleFilter.ascx" %>
<%@ Register TagPrefix="AxCMS" TagName="BaseGridTemplate" Src="../admin/templates/BaseGridTemplate.ascx" %>
<%@ Register TagPrefix="AxCMS" TagName="PublicationMessage" Src="../admin/controls/PublicationMessages.ascx" %>
<%@ Register TagPrefix="AxCMS" TagName="BulkOperationButtons" Src="../admin/controls/BulkOperationButtons.ascx" %>
<%@ Register TagPrefix="AxCMS" TagName="PageCall" Src="../admin/templates/PageCall.ascx" %>
<AxMP:ContentContainer runat="server" ID="ctlContentContainer">
    <AxMP:Content id="Filter" runat="server">
        <AxCMS:Filter runat="server" ID="_filter"/>
    </AxMP:Content>
    <AxMP:Content id="List" runat="server">
        <AxCMS:BaseGridTemplate runat="server" ID="_grid"/>
        <AxCMS:PublicationMessage runat="server" ID="publicationMessagesControl" />
    </AxMP:Content>
    <AxMP:Content id="Buttons" runat="server">
        <Ax:AxinomPanel id="actionsPanel" runat="server" Headline="Aktionen" width="100%" CssClass="keyarea">
            <table cellpadding="0" cellspacing="5">
                <AxCMS:BulkOperationButtons runat="server" id="bulkOperationButtons" />
            </table>
        </Ax:AxinomPanel>
    </AxMP:Content>
</AxMP:ContentContainer>

To use PublishActivity, we will create the ArticlePublishActivity class, which will extend the CmsActivity class. Below is the list of the most important methods and properties of the CmsActivity class that can be overwritten:

  • Text - The name of the operation that will be displayed on the button.
  • DoExecute - The method that will operate with our object.
  • IsApplicable - Determines if the operation is applicable for elements of the specified type.
  • IsAllowed - Determines if the user has enough permission for the operation with the given element.
  • IsAllowedInGeneral - Determines if the user has enough permission for the operation in general.

In DoExecute we need to change the publication date and the publication state of the article. We also need to check if the article is already published. If it is, then we need to update the record in the LS database. If not, then we need to add a new record. If we publish a deleted article, then we try to delete it everywhere (from MS and LS database).

For all operations we have to create DbQueries and run them via IAxWebQueryService, because the service is configured to run queries on the live database.

The full ArticlePublishActivity will now look like shown below. For the sake of simplicity we will implement publishing in such a way that SQL statements are sent directly to the live system using WebQueryService. It is advisable to either use a pusher (send the dataset via PublishWebService and provide custom processing on the live side) or create a custom web service especially for publishing. Read more about this topic in the Publishing MS/LS elements section in Creating custom objects in AxCMS.net.

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 
82 
83 
84 
85 
86 
87 
88 
89 
90 
91 
92 
93 
94 
95 
96 
97 
public class ArticlePublishActivity : CmsActivity
{
    public override string Text
    {
        get
        {
            return "Publish";
        }
    }

    protected override bool DoExecute(Axinom.AECMS.Category.IClassifiable element)
    {
        IAxWebQueryService service = AxCmsWebApi.WebQueryService;

        AxDbAdapter adapter = new AxDbAdapter(typeof(Article));

        Article current = (Article)element;
           
        DbSelectQuery select = new DbSelectQuery();
        select = adapter.GetSelectQuery();
        select.AddParameter("@AxID", element.ID);

        DbDeleteQuery delete = new DbDeleteQuery();
        delete = adapter.GetDeleteQuery();
        delete.AddWhere("[AxID] = @AxID");
        delete.AddParameter("@AxID", element.ID);

        DbInsertQuery insert = new DbInsertQuery();
        insert = adapter.GetInsertQuery();
        insert.AddParameter("@AxID", element.ID);
        insert.AddParameter("@Name", current.Name);
        insert.AddParameter("@Price", current.Price);
        insert.AddParameter("@Description", current.Description);
        insert.AddParameter("@Created", current.Created);
        insert.AddParameter("@PublicationState", PublicationState.Active);
        insert.AddParameter("@Published", current.Published);
        insert.AddParameter("@PublishingRequested", current.PublishingRequested);
        insert.AddParameter("@Url", current.Url);

        DbUpdateQuery update = new DbUpdateQuery();
        update = adapter.GetUpdateQuery();
        update.AddWhere("[AxID] = @itemID");
        update.AddParameter("@AxID", element.ID);
        update.AddParameter("@itemID", element.ID);
        update.AddParameter("@Name", current.Name);
        update.AddParameter("@Price", current.Price);
        update.AddParameter("@Description", current.Description);
        update.AddParameter("@Created", current.Created);
        update.AddParameter("@PublicationState", PublicationState.Active);
        update.AddParameter("@Published", current.Published);
        update.AddParameter("@PublishingRequested", current.PublishingRequested);
        update.AddParameter("@Url", current.Url);

        if (service.ExecuteDataTable(new AxDbWebQuery(select)).Tables[0].Rows.Count > 0)
        {
            if (current.PublicationState == PublicationState.Deleted)
            {
                service.ExecuteNonQuery(new AxDbWebQuery(delete));
                adapter.DeleteSafe(current);
            }
            else
            {
                service.ExecuteNonQuery(new AxDbWebQuery(update));

                current.Published = DateTime.Now;
                current.PublicationState = PublicationState.Active;

                adapter.Save(current);
            }
        }
        else
        {
            service.ExecuteNonQuery(new AxDbWebQuery(insert));

            current.Published = DateTime.Now;
            current.PublicationState = PublicationState.Active;

            adapter.Save(current);
        }
        return true;
    }

    public override bool IsApplicable(short type)
    {
        return true;
    }

    public override bool IsAllowed(Axinom.AECMS.Category.IClassifiable element)
    {
        return true;
    }

    public override bool IsAllowedInGeneral(short type)
    {
        return true;
    }
}

The next step is to register our operation on the overview page. To do this, we need to add override string[] Operations in the OverviewHelper and add the "articlePublish" string in it.









  public class ArticleOverviewHelper : Axinom.AECMS.AxOverviewBaseHelper
{
   ...
   public override string[] Operations()
   {
      return new string[] { "articlePublish"};
   }
   ...
)

Article overview page will now have the Publish button in the Tools box:

UnpublishActivity

This is a very simple operation. We just need to delete the record from the live database and set publication state to Never Published in the management system database.

First, we need to create the ArticleUnpublishActivity class which extends CmsActivity. Then we add the following code to DoExecute:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
IAxWebQueryService service = AxCmsWebApi.WebQueryService;

AxDbAdapter adapter = new AxDbAdapter(typeof(Article));

Article current = (Article)element;

current.PublicationState = PublicationState.NeverPublished;

adapter.Save(current);

DbDeleteQuery delete = new DbDeleteQuery();
delete = adapter.GetDeleteQuery();
delete.AddWhere("[AxID] = @AxID");
delete.AddParameter("@AxID", element.ID);

service.ExecuteNonQuery(new AxDbWebQuery(delete));
return true;

In the Operations array we need to register the following:









  public class ArticleOverviewHelper : Axinom.AECMS.AxOverviewBaseHelper
{
   ...
   public override string[] Operations()
   {
      return new string[] { "articlePublish", "articleUnpublish"};
   }
   ...
)

DeleteActivity

This activity either marks the selected object for deletion or removes it from the databases permanently. If the object's status is either Published or Changed, then this activity will change its status to Deleted. However, the deleted object is still visible and recoverable in the management system until the deletion is published. If the object's status is Never Published, then this activity will remove it permanently.

We will create the ArticleDeleteActivity. The code for DoExecute is:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
AxDbAdapter adapter = new AxDbAdapter(typeof(Article));

Article current = (Article)element;

if (current.PublicationState == PublicationState.Active || current.PublicationState == PublicationState.Changed)
{
    current.PublicationState = PublicationState.Deleted;
    adapter.Save(current);
}
else if (current.PublicationState != PublicationState.Deleted)
{
    adapter.DeleteSafe(current);
}
return true;

RecoverActivity

This operation recovers objects that are still visible in MS and have status Deleted. Recovering sets the object’s status from Deleted to Edited in the management system database.

The code for DoExecute is:

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
AxDbAdapter adapter = new AxDbAdapter(typeof(Article));

Article current = (Article)element;

if (current.PublicationState == PublicationState.Deleted)
{
    current.PublicationState = PublicationState.Changed;
    adapter.Save(current);
}
return true;