mnjstwins
12/9/2016 - 6:35 PM

Caché DTI ContentPublisher: Tested in 7.6, 7.7.2: DEMO: Sorting search results by CMSStory property (in this case, I'm using publishedToWebD

Caché DTI ContentPublisher: Tested in 7.6, 7.7.2: DEMO: Sorting search results by CMSStory property (in this case, I'm using publishedToWebDate")...

/// Sort ListObjects based on a property.<br>
/// obj = A list object.<br>
/// dir = Direction, 1 ascending, -1 descending.<br>
/// prp = A property name.<br>
/// (c) 2008 J.Kavay
/// Ref: http://groups.google.com/group/intersystems-public-cache/browse_thread/thread/289bc2e02e4875ff
ClassMethod rgSortListObj(
	obj,
	dir = 1,
	prp)
{
	s tmp=##class(%ListOfObjects).%New(),nul=$s(dir>0:-1E20,1:1E20),dir=$s(dir>0:1,1:-1)
	f i=1:1:obj.Size s val=$zobjproperty(obj.GetAt(i),prp),tmp.Oref($s(val]"":val,1:nul),i)=obj.GetAt(i)
	d obj.Clear() s ref=$na(tmp.Oref("")) f  s ref=$q(@ref,dir) q:ref=""  d obj.Insert(@ref)
}

/// Sort ListObjects based on one or more properties.<br>
/// obj = A list object.<br>
/// dir = Direction, 1 ascending, -1 descending.<br>
/// prp = A property name.<br>
/// (c) 2008 J.Kavay
/// Ref: http://groups.google.com/group/intersystems-public-cache/browse_thread/thread/289bc2e02e4875ff
ClassMethod rgMultiSortListObj(
	obj,
	dir = 1,
	prp...)
{
	s tmp=##class(%ListOfObjects).%New(),nul=$s(dir>0:-1E20,1:1E20),dir=$s(dir>0:1,1:-1)
	f i=1:1:obj.Size { s ref=$na(tmp.Oref(0))
		f j=1:1:prp s val=$zobjproperty(obj.GetAt(i),prp(j)),ref=$na(@ref@($s(val]"":val,1:nul)))
		s @ref@(i)=obj.GetAt(i) }
	d obj.Clear() s ref=$na(tmp.Oref("")) f  s ref=$q(@ref,dir) q:ref=""  d obj.Insert(@ref)
}

/// This method will sort a list of mapping or cmsStory objects based on "named" priority ID.
/// See custom.rg.legacy.webUtilities for generic sort methods: "rgSortListObj()" and "rgMultiSortListObj()".
ClassMethod rgSortPrioritySpecial(
	object As %ListOfObjects = "",
	dir As %Integer = 1,
	getWhat As %Integer = 0)
{
	set tmp = ##class(%ListOfObjects).%New()
	set nul = $select(dir>0:-1E20, 1:1E20)
	set dir = $select(dir>0:1, 1:-1)
	for i=1:1:object.Size {
		set get = $case(getWhat, 1:object.GetAt(i).cmsStory, :object.GetAt(i)) // 1 = mappingObj.cmsStory object, 2 = cmsStory object (default)
		set val = +$zobjclassmethod("custom.rg.legacy.webUtilities", "rgGetPriorityName", get.story.priorityId) // Get the actual priority from the "name".
		set tmp.Oref($select(val]"":val, 1:nul), i) = object.GetAt(i)
	}
	do object.Clear()
	set ref = $name(tmp.Oref(""))
	for {
		set ref = $query(@ref, dir)
		quit:(ref = "")
		do object.Insert(@ref)
	}
}

/// This method will sort a list of mapping objects by "publishedToWebDate" property.
/// See custom.rg.legacy.webUtilities for generic sort methods: "rgSortListObj()" and "rgMultiSortListObj()".
ClassMethod rgListAreaObjsSorter(
	object As %ListOfObjects = "",
	dir As %Integer = 1)
{
	set tmp = ##class(%ListOfObjects).%New()
	set nul = $select(dir>0:-1E20, 1:1E20)
	set dir = $select(dir>0:1, 1:-1)
	for i=1:1:object.Size {
		set val = $zobjproperty(object.GetAt(i).cmsStory, "publishedToWebDate")
		set tmp.Oref($select(val]"":val, 1:nul), i) = object.GetAt(i)
	}
	do object.Clear()
	set ref = $name(tmp.Oref(""))
	for {
		set ref = $query(@ref, dir)
		quit:(ref = "")
		do object.Insert(@ref)
	}
}

/// Helps sort rgListAreaObjs() by publishedtoWebDate and priority. 
ClassMethod rgListAreaObjsHelper(
	objList As %ListOfObjects = "",
	order) As %ListOfObjects
{
	set methodName = "rgListAreaObjsHelper"
	
	set (temp, final, obj, size, slotObj, mappingObj) = ""
	set (i, objid, mappingId, slotId) = 0
	
	set temp = ##class(%ListOfObjects).%New()
	set final = ##class(%ListOfObjects).%New()
	
	// Get mapping objects (every other list item, starting at key 2) and insert into temp object list:
	for i=2:2:objList.Size {
		s obj = objList.GetAt(i)
		do temp.InsertAt(obj, 1)
	}
	set (obj, size) = ""
	
	// Sort mapping obj by cmsStory publishedToWebDate:
	//do ##class(rg.webRules).rgListAreaObjsSorter(temp, -1)
	// Sort mapping obj by dbo.story priority name:
	do ..rgSortPrioritySpecial(temp, 1, 1)
	
	for i=1:1:temp.Size {
		s obj = temp.GetAt(i)
		s objId = obj.%Id()
		s mappingId = objList.FindObjectId(objId)
		set slotId = mappingId - 1
		set slotObj = objList.GetAt(slotId)
		set mappingObj = objList.GetAt(mappingId)
		do final.InsertAt(slotObj, 1)
		do final.InsertAt(mappingObj, 2)
	}
	
	quit final // Return the sorted objects.
}
<csp:comment>
	/// Sort ListObjects based on one or more properties.<br>
	/// obj: A list object.<br>
	/// dir: Direction, 1 ascending, -1 descending.<br>
	/// prp: A property name.<br>
	/// (c) 2008 J.Kavay<br>
	/// Ref: http://groups.google.com/group/intersystems-public-cache/browse_thread/thread/289bc2e02e4875ff
</csp:comment>

<script language="cache" method="multiSortListObj" arguments='obj:%ListOfObjects=-1, dir:%Integer=1, prp...' returntype="%ListOfObjects" procedureblock="1">
	
	set tmp = ##class(%ListOfObjects).%New()
	set nul = $select(dir > 0:-1E20, 1:1E20)
	set dir = $select(dir > 0:1, 1:-1)
	for i=1:1:obj.Size {
		set ref = $name(tmp.Oref(0))
		for j=1:1:prp {
			set val = $zobjproperty(obj.GetAt(i), prp(j))
			set ref = $name(@ref@($select(val]"":val, 1:nul)))
		}
		set @ref@(i) = obj.GetAt(i)
	}
	do obj.Clear()
	set ref = $name(tmp.Oref(""))
	for {
		set ref = $query(@ref, dir)
		quit:(ref = "")
		do obj.Insert(@ref)
	}
	
</script>

<csp:comment>
	/// Wrapper CSP method for DTI's built-in search.<br>
	/// pid: Only search for stories in this publication (ID). The default is the current publication.<br>
	/// hits: The number of hits to return. The default is 50.<br>
	/// days: Only Search stories that have run in the last <days> days. If no value is specified, then all stories are searched.<br>
	/// statusList: Only search stories with one of these statuses. If no statuses are specifed, then stories with any status are searched.<br>
	/// deskList: Only search for stories on one of these desks. If no desks are specified, then stories on any desk are searched.<br>
	/// priorityList: Only search stories with a priorityId that matches on in priorityList. If no priorities are specified then stories with any priority are searched.<br>
	/// language: Search for stories indexed in <language>.
</csp:comment>

<script language="cache" method="search" arguments='pid:%Integer=0, searchPhrase:%String="", hits:%Integer=50, days:%Integer=0, statusList:%String="", deskList:%String="", priorityList:%String="", language:%String=""' returntype="%ListOfObjects" procedureblock="1">
	
	set return = ##class(%ListOfObjects).%New()
	
	if ($case($isvalidnum(pid) && (pid > 0), 1:1, :0)) {
		
		if ($length(searchPhrase)) {
			
			set cmsStory = -1
			set rs = ##class(%ResultSet).%New("dt.cms.support.Search:Stories") // Returns CMSStory IDs.
			set sc = rs.Execute(searchPhrase, hits, days, statusList, deskList, pid, language, priorityList)
			
			if ($$$ISOK(sc)) {
				
				while (rs.Next()) {
					
					set cmsStory = ##class(dt.cms.schema.CMSStory).%OpenId(rs.GetData(1)) // CMS Story Object.
					do:($isobject(cmsStory)) return.Insert(cmsStory) // Add cmsStoryObject to the beginning of the object list.
					
				}
				
			}
			
		} else {
			
			// Argument "searchPhrase" not valid.
			
		}
		
	} else {
		
		// Argument "pid" not a valid integer.
		
	}
	
	quit return
	
</script>

<dti:publication:set name="web" />

<csp:if condition=($isobject(gPublication))>
	
	<ul>
		<li>Publication ID: #(gPublication.%Id())#</li>
		<li>Publication name: #(gPublication.getName())#</li>
	</ul>
	
	<hr>
	
	<script language="cache" runat="server">
		
		new stories, count
		set stories = ..search(gPublication.%Id(), "ducks")
		do ..multiSortListObj(stories, -1, "publishedToWebDate")
		set count = stories.Count()
		
	</script>
	
	<csp:if condition='count>0'>
		
		<ul>
			<csp:loop counter="x" from="1" to="#(count)#">
				
				<dti:story:use storyobj="#(stories.GetAt(x))#">
					
					<csp:if condition=($isobject(gStory))>
						
						<li>#(gStory.publishedToWebDate)#</li>
						
					</csp:if>
					
				</dti:story:use>
				
			</csp:loop>
		</ul>
		
	<csp:else>
		
		<p>Your search returned no results.</p>
		
	</csp:if>
	
</csp:if>