Tutorial : How to create a Filter?

1. Creating the generic method

Let's start by writing a function to handle our requests and responses via the languages SOAP library.

<?php
	//We're going to structure this to look very similar to the WSDL
	function handleRequest($contextId, $className, $processName, $entityData, $processData){
		//Let's instantiate a soapClient object, using the wsdl as a blueprint and setup a trace
		$soapClient = new SoapClient('http://paint.pure360.com/paint.pure360.com/ctrlPaint.wsdl', array('trace' => TRUE));
		//Now let's send the request via the handleRequest specified in the wsdl
		$RESULT = $soapClient->handleRequest($contextId, $className,	$processName, $entityData, $processData);
		return $RESULT;
	}
?>
	

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using com.pure360.paint;
/*
 *  As this is .NET we're going to have to do this in objects and classes, as a bit of pre-pre ground work
 *  don't forget to Add a service, click advanced, and add the wsdl as a web service reference 
 *  http://paint.pure360.com/paint.pure360.com/ctrlPaintLiteral.wsdl (NOT as simply a service reference)
 *  For a how to follow this link : Configuring VS with .NET
 */
public class Pure360API
{
	public Pure360API()
	{
	}
    //We're going to structure this to look very similar to the WSDL
    public Hashtable sendRequest(   String contextId, 
    								String className, 
    								String processName, 
    								Hashtable entityData, 
    								Hashtable processData)
    {
        /* As we're using pairs (we can't use associative arrays) we need to use a method of this class to 
           apply a quick conversion */
        paintKeyValuePair[] entityPairs = this.convertDataToPairs(entityData);
        paintKeyValuePair[] processPairs = this.convertDataToPairs(processData);
   
       /* We also need to instantiate the paintService we referenced earlier - like the SoapClient in php this is structured
        * based on the WSDL, and uses this blueprint, this will be handling our requests and responses
        */
        paintService API = new paintService();
        //So as we're using pairs, the result will come back as an array of pairs
        paintKeyValuePair[] resultPairs =  API.handleRequest(contextId,
                                                className,
                                                processName,
                                                entityPairs,
                                                processPairs
                                            );
        //So again we need to do a bit of converting
        Hashtable resultData = this.convertPairsToHashtable(resultPairs);
        //and we're going to return the hashtable
        return resultData;

    }

    //The two following methods are used to convert the data to and from pairs
    protected paintKeyValuePair[] convertDataToPairs(Hashtable source)
    {
    	//if the source is null, let's just create a new Hashtable preventing errors
        if (source == null) { source = new Hashtable(); }
        //We also need to create a destination for our pairs as we create them of the same size as the source
        paintKeyValuePair[] convertedPairs = new paintKeyValuePair[source.Count];
        //And we need a counter to know which element we're on
        int i = 0;
        foreach (String key in source.Keys)
        {
            paintKeyValuePairValue newValue = new paintKeyValuePairValue();
            paintKeyValuePair newPair = new paintKeyValuePair();
            //If we come across a hashtable, use a recursive function to convert this
            if (source[key] is Hashtable)
            {
                newValue.arr = this.convertDataToPairs((Hashtable)source[key]);
            }
            //if not let's cast it as a string
            else
            {
                newValue.str = source[key].ToString();
            }
            //create the new paintKeyValuePair from these
            newPair.key = key;
            newPair.value = newValue;
            //and push this on to the new convertedPairs array at index assigned by the counter
            convertedPairs[i] = newPair;
            //finally let's increment that counter so we don't overwrite anything
            i++;
        }
        //and return those convertedPairs
        return convertedPairs;
    }
   protected Hashtable convertPairsToHashtable(paintKeyValuePair[] source)
    {
        if (source != null)
        {
            Hashtable convertedHashtable = new Hashtable();
            for (int i = 0; i < source.Length; i++)
            {
                paintKeyValuePair item = source[i];
                String key = item.key;
                String valueStr = item.value.str;
                paintKeyValuePair[] valueArr = item.value.arr;
                if (valueArr != null)
                {
                    convertedHashtable.Add(item.key, convertPairsToHashtable(valueArr));
                }
				else
				{
					convertedHashtable.Add(item.key, valueStr);
				}
            }
            return convertedHashtable;
        }
        else
        {
            return null;
        }
    }

The .NET code has more setup required, mainly due to the nature of the language, and the data structures it can handle being more strictly typed
As the WSDL is defined to handle only associative arrays or pairs, we need to do some converting to and from pairs, as they are not a native type

As you can see this function follows the blueprint of the WSDL and uses the handleRequest generic function in the WSDL, and receives the Result response.

2. Creating a login method


<?php
	//So this is going to take in a username and password as the parameters and hopefully return the contextId
	function login($userName, $password){
		//ok, this facade therefore takes in a username and password as the entityData (parameters) for the process "Login"
		$entityData = array(
							'userName' => $userName,
							'password' => $password
						);
		/* We're going to send this without a context id, as we don't have one, to the context facade bean, with the process 
		  login, and the entity data  */
		$result = handleRequest(null, "bus_facade_context", "login", $entityData, null);
		/* In the result data of the response is the context entity, and in here is a variable called bean id.
		   This is used to tie the whole session together in the bean store */
		$contextId = $result['resultData']['bus_entity_context']['beanId'];
		//And finally let's send back the contextId
		return $contextId;
	}
?>

//So this is going to take in a username and password as the parameters and hopefully return the contextId
public String login(String userName, String password){
	//ok, this facade therefore takes in a username and password as the entityData (parameters) for the process "Login"
	Hashtable entityData = new Hashtable();
	entityData.Add("userName", userName);
	entityData.Add("password", password);
	/* We're going to send this without a context id, as we don't have one, to the context facade bean, with the process 
	login, and the entity data  */
	Hashtable result = this.sendRequest(null, "bus_facade_context", "login", entityData, null);
	/* In the result data of the response is the context entity, and in here is a variable called bean id.
	This is used to tie the whole session together in the bean store */
	Hashtable resultData = (Hashtable)result["resultData"];
	String contextId = (String)((Hashtable)resultData["bus_entity_context"])["beanId"];
	//And finally let's send back the contextId
	return contextId;
}
As this is .NET we're going to be adding this as a method to the object we created in the first step.

3. Searching for the listId to add the filter to


<?php
	//Our two parameters are our contextID, tying the session together, and our listName search parameter
	function searchListId($contextId, $listName){
		/* So let's call the handle request with our contextId.
		   We're using the list facade bean class.
		   We want to call the "search" process.
		   We want to load the entityData on to the search bean, in this case the "listName" */
		  $entityData = array('listName' => $listName);
		$result = handleRequest($contextId, "bus_facade_campaign_list", "search", $entityData, null);
		/* The result data of the response is the list search bean, and in here is a an array called "idData" that should contain a single element.
		   The value of this element is our listId */
		$listId = $result['resultData']['bus_search_campaign_list']['idData'][0];

		//Let's return just the listId value
		return $listId['listId'];
	}
?>

//We're going to call this with our newly created contextId, therefore applying it to our current session. Also we're going to pass in the name of the list that we want to search for.
public String searchListId(String contextId, String listName)
{
   /* So let's call the handle request with our contextId.
	  We're using the list facade bean class.
	  We want to call the "search" process.
	  We want to load the entityData on to the search bean, in this case the "listName".
*/
   Hashtable entityData = new Hashtable();
   entityData.add('listName', listName);
   Hashtable result = this.sendRequest(contextId, "bus_facade_campaign_list", "search", entityData, null);
   /* The result data of the response is the list search bean, and in here is a an hashtable called "idData" that should contain a single element.
		   The value of this element is our listId */
    Hashtable resultData = (Hashtable)result["resultData"];
    
    Hsahtable listId = (Hashtable)((Hashtable)resultData["bus_search_campaign_list"])["idData"][0];
   
    //So let's return just the listId value
    return String listId["listId"];
 }
As this is .NET we're going to be adding this as a method to the object we created in the first step.

4. Generating a filter bean in the temporary store


<?php
	//We're going to call this with our contextId, and the listId we retrieved in the previous step
	function generateFilterBean($contextId, $listId){
		$entityData = array('listId' => $listId);
		/* So let's call the handle request with our contextId.
		   We're handling filter beans so need to reference the filter facade class.
		   We're calling a "create" process to generate a new filter entity bean.
		   We're loading onto that filter bean a reference to the parent list */
		$result = handleRequest($contextId, "bus_facade_campaign_filter", "create", $entityData, null);
		/* The result data of the response is the filter entity, and in here is a variable called bean id
		   This is used to reference our newly generated bean in the bean store. */
		$filterBean = $result['resultData']['bus_entity_campaign_filter']['beanId'];	

		/* We also need to return the filterItem id's that will make up the ruleset of our filter
		   Each of these filter items will be a rule such as __EMAIL__ contains "pure360.com" */
		$filterItems =  $result['resultData']['bus_entity_campaign_filter']['filterItems'];
		
		/*Let's make a returnable array out of the filterbean and the filterItems. */
		$filterDetails = array(
							'filterBean' => $filterBean,
							'filterItems' => array_keys($filterItems)
						);
		//And return this....
		return $filterDetails;
	}
?>

//We're going to call this with our newly created contextId, therefore applying it to our current session.
public Hashtable generateFilterBean(String contextId, String listId)
{
	Hashtable entityData = new Hashtable();
	entityData.add('listId', listId)
   /* So let's call the handle request with our contextId.
      We're handling filter beans so need to reference the filter facade class.
	  We're calling a "create" process to generate a new filter entity bean.
	  We're loading onto that filter bean a reference to the parent list */
   Hashtable result = this.sendRequest(contextId, "bus_facade_campaign_filter", "create", entityData, null);
   /* The result data of the response is the filter entity, and in here is a variable called bean id
	  This is used to reference our newly generated bean in the bean store. */
    Hashtable resultData = (Hashtable)result["resultData"];
    String filterBean = (String)((Hashtable)resultData["bus_entity_campaign_filter"])["beanId"];
    
    /* We also need to return the filterItem id's that will make up the ruleset of our filter
		   Each of these filter items will be a rule such as __EMAIL__ contains "pure360.com" */
    Hashtable filterItems = new Hashtable();
    filterItems = (Hashtable)((Hashtable) resultData["bus_entity_campaign_filter"])["filterItems"];

	/*Let's make a returnable hashtable out of the filterbean and the filterItems. */
    Hashtable filterDetails = new Hashtable();
    filterDetails.Add("filterBean", filterBean);
    List<string> filterItemIds = filterItems.Keys.Cast<string>.ToList();
    filterDetails.Add("filterItems", filterItemIds);
    
    //And return this...
    return filterDetails;
 }
As this is .NET we're going to be adding this as a method to the object we created in the first step.

5. Updating the filter bean in the bean store

Here is the filter configuration:

<?php
	//First our filter is going to contain a single rule, so let's grab a filterItem id
	$filterItemId = array_pop($filterDetails['filterItems']);
	
		$filterConfiguration = array(

							//We need a unique name for our filter
							"filterName_base64" => base64_encode("Pure360-Addresses"),

							//We need our listId we generated in (3)
							"listId"	 => $listId,

							//We want to match on all filter items in this case
							"matchAllInd" => "Y",

							//For our filter items...
							"filterItems" => array(
												//We're going to use a filterItem id returned in (4)
												"filterItemId" => $filterItemId,
												//Look in the reserved field EMAIL
												"fieldName" => "__EMAIL__",
												//for each record in the list does it "contain"
												"conditionType" => "CONTAIN"
												//the value "pure360"
												"matchValue" => "pure360"
											);
						);
?>

//First we need to create a method for encoding strings to base 64
public static String Base64_encode(String PlainText){
	var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(PlainText);
	return System.Convert.ToBase64String(plainTextBytes);
}

//Next our filter is going to contain a single rule, so let's grab a filterItem id
String filterItemId = (String)(List<string>)filterDetails["filterItems"])[0];
(List<string>)filterDetails["filterItems"].removeAt(0);

Hashtable 	filterConfiguration = new Hashtable();

			//The name for our filter
			filterConfiguration.add("filterName_base64", Pure360API.Base64_encode("Pure360-Addresses"));
			
			//Our listId we generated in (3)
			filterConfiguration.add("listId", listId);
	
			//We want to match on all filter items in this case
			filterConfiguration.add("matchAllInd", "Y");

//For out filter items...
Hashtable 	filterItems = new Hashtable();

			//We're going to use a filterItem ID returned in (4)
			filterItems.add("filterItemId", filterItemId);

			//Look in the reserved field EMAIL
			filterItems.add("fieldName", "__EMAIL__");

			//For each record in the list does it CONTAIN
			filterItems.add("conditionType", "CONTAIN");

			//the value "Pure360"
			filterItems.add("matchValue", "pure360");

//Add this filter items hashtable to the filterConfiguration
filterConfiguration.add("filterItems", filterItems);

<?php
	function updateFilterBean($contextId, $beanId, $filterConfiguration){
		//Let's make sure our entityData is set, by assigning the filterConfiguration to this
		$entityData = $filterConfiguration;
	 	// Don't forget to add the beanId to the entityData to update the new entity bean in the bean store!
		$entityData['beanId'] = $beanId;
		//Now we want to update the entity bean in the bean store we've created with this configuration
		$result = handleRequest($contextId, "bus_facade_campaign_filter", "update", $entityData, null);
		return $result['result'];
	}
?>

public String updateFilterBean(String contextId, String beanId, Hashtable filterConfiguration){
	//Let's make sure our entityData is set, by assigning the filterConfiguration to this
	Hashtable entityData = filterConfiguration;
	// Don't forget to add the beanId to the entityData to update the new entity bean in the bean store! 
	entityData.add("beanId", beanId);
	//Now we want to update the entity bean in the bean store we've created with this configuration
	Hashtable result = this.sendRequest(contextId, "bus_facade_campaign_filter", "update" entityData, null);
	return (String)result['result'];
}
As this is .NET we're going to be adding this as a method to the object we created in the first step.

6. Storing the filter bean


<?php
	function storeFilterBean($contextId, $beanId){
		//The entity data is a reference to our bean in the bean store
		$entityData = array('beanId' => $beanId);
		//Now we want to store the entity bean, validating the configuration fields and writing this back to the platform
		$result = handleRequest($contextId, "bus_facade_campaign_filter", "store", $entityData, null);
		return $result['result'];
	}
?>

public String storeFilterBean(String contextId, String beanId){
	//The entity data is a reference to our bean in the bean store
	Hashtable entityData = new Hashtable();
	entityData.add("beanId", beanId);
	//Now we want to store the entity bean, validating the configuration fields and writing this back to the platform
	Hashtable result = this.sendRequest(contextId, "bus_facade_campaign_filter", "update" entityData, null);
	return (String)result['result'];
}
As this is .NET we're going to be adding this as a method to the object we created in the first step.

7. End the session


<?php
	function logout($contextId){
		//Let's finish by calling the login process on the context facade, removing this session from the bean store...
		$result = handleRequest($contextId, "bus_facade_context", "logout", null, null);
		return $result['result'];
	}

?>

public String logout(String contextId)
{
    //Let's finish by calling the login process on the context facade, removing this session from the bean store...
    Hashtable result = this.sendRequest(contextId, "bus_facade_context", "logout", null, null);
    return (String)result["result"];
}
As this is .NET we're going to be adding this as a method to the object we created in the first step.

Hey Presto! We've created a filter in the system, this is attached to a list and looks for records that contain "Pure360"

Things to remember