1<cfscript>
2/**
3********************************************************************************
4ContentBox - A Modular Content Platform
5Copyright 2012 by Luis Majano and Ortus Solutions, Corp
6www.gocontentbox.org | www.luismajano.com | www.ortussolutions.com
7********************************************************************************
8Apache License, Version 2.0
9
10Copyright Since [2012] [Luis Majano and Ortus Solutions,Corp]
11
12Licensed under the Apache License, Version 2.0 (the "License");
13you may not use this file except in compliance with the License.
14You may obtain a copy of the License at
15
16http://www.apache.org/licenses/LICENSE-2.0
17
18Unless required by applicable law or agreed to in writing, software
19distributed under the License is distributed on an "AS IS" BASIS,
20WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21See the License for the specific language governing permissions and
22limitations under the License.
23********************************************************************************
24* A generic content service for content objects
25*/
26component extends="coldbox.system.orm.hibernate.VirtualEntityService" singleton{
27
28	// DI
29	property name="settingService"			inject="id:settingService@cb";
30	property name="cacheBox"				inject="cachebox";
31	property name="log"						inject="logbox:logger:{this}";
32	property name="customFieldService" 	 	inject="customFieldService@cb";
33	property name="categoryService" 	 	inject="categoryService@cb";
34	property name="commentService" 	 		inject="commentService@cb";
35	property name="contentVersionService"	inject="contentVersionService@cb";
36	property name="authorService"			inject="authorService@cb";
37	property name="populator"				inject="wirebox:populator";
38	property name="systemUtil"				inject="SystemUtil@cb";
39
40	/*
41	* Constructor
42	* @entityName.hint The content entity name to bind this service to.
43	*/
44	ContentService function init(entityName="cbContent"){
45		// init it
46		super.init(entityName=arguments.entityName, useQueryCaching=true);
47
48		// Test scope coloring in pygments
49		this.colorTestVar = "Just for testing pygments!";
50		cookie.colorTestVar = "";
51		client.colorTestVar = ""
52		session.colorTestVar = "";
53		application.colorTestVar = "";
54
55		return this;
56	}
57
58	/**
59	* Clear all content caches
60	* @async.hint Run it asynchronously or not, defaults to false
61	*/
62	function clearAllCaches(boolean async=false){
63		var settings = settingService.getAllSettings(asStruct=true);
64		// Get appropriate cache provider
65		var cache = cacheBox.getCache( settings.cb_content_cacheName );
66		cache.clearByKeySnippet(keySnippet="cb-content",async=arguments.async);
67		return this;
68	}
69
70	/**
71	* Clear all page wrapper caches
72	* @async.hint Run it asynchronously or not, defaults to false
73	*/
74	function clearAllPageWrapperCaches(boolean async=false){
75		var settings = settingService.getAllSettings(asStruct=true);
76		// Get appropriate cache provider
77		var cache = cacheBox.getCache( settings.cb_content_cacheName );
78		cache.clearByKeySnippet(keySnippet="cb-content-pagewrapper",async=arguments.async);
79		return this;
80	}
81
82	/**
83	* Clear all page wrapper caches
84	* @slug.hint The slug partial to clean on
85	* @async.hint Run it asynchronously or not, defaults to false
86	*/
87	function clearPageWrapperCaches(required any slug, boolean async=false){
88		var settings = settingService.getAllSettings(asStruct=true);
89		// Get appropriate cache provider
90		var cache = cacheBox.getCache( settings.cb_content_cacheName );
91		cache.clearByKeySnippet(keySnippet="cb-content-pagewrapper-#arguments.slug#",async=arguments.async);
92		return this;
93	}
94
95	/**
96	* Clear a page wrapper cache
97	* @slug.hint The slug to clean
98	* @async.hint Run it asynchronously or not, defaults to false
99	*/
100	function clearPageWrapper(required any slug, boolean async=false){
101		var settings = settingService.getAllSettings(asStruct=true);
102		// Get appropriate cache provider
103		var cache = cacheBox.getCache( settings.cb_content_cacheName );
104		cache.clear("cb-content-pagewrapper-#arguments.slug#/");
105		return this;
106	}
107
108	/**
109	* Searches published content with cool paramters, remember published content only
110	* @searchTerm.hint The search term to search
111	* @max.hint The maximum number of records to paginate
112	* @offset.hint The offset in the pagination
113	* @asQuery.hint Return as query or array of objects, defaults to array of objects
114	* @sortOrder.hint The sorting of the search results, defaults to publishedDate DESC
115	* @isPublished.hint Search for published, non-published or both content objects [true, false, 'all']
116	* @searchActiveContent.hint Search only content titles or both title and active content. Defaults to both.
117	*/
118	function searchContent(
119		any searchTerm="",
120		numeric max=0,
121		numeric offset=0,
122		boolean asQuery=false,
123		any sortOrder="publishedDate DESC",
124		any isPublished=true,
125		boolean searchActiveContent=true){
126
127		var results = {};
128		var c = newCriteria();
129
130		// only published content
131		if( isBoolean( arguments.isPublished ) ){
132			// Published bit
133			c.isEq( "isPublished", javaCast( "Boolean", arguments.isPublished ) );
134			// Published eq true evaluate other params
135			if( arguments.isPublished ){
136				c.isLt("publishedDate", now() )
137				.$or( c.restrictions.isNull("expireDate"), c.restrictions.isGT("expireDate", now() ) )
138				.isEq("passwordProtection","");
139			}
140		}
141
142		// Search Criteria
143		if( len( arguments.searchTerm ) ){
144			// like disjunctions
145			c.createAlias("activeContent","ac");
146			// Do we search title and active content or just title?
147			if( arguments.searchActiveContent ){
148				c.$or( c.restrictions.like("title","%#arguments.searchTerm#%"),
149				  	  c.restrictions.like("ac.content", "%#arguments.searchTerm#%") );
150			}
151			else{
152				c.like( "title", "%#arguments.searchTerm#%" );
153			}
154		}
155
156		// run criteria query and projections count
157		results.count = c.count( "contentID" );
158		results.content = c.resultTransformer( c.DISTINCT_ROOT_ENTITY )
159							.list(offset=arguments.offset, max=arguments.max, sortOrder=arguments.sortOrder, asQuery=arguments.asQuery);
160
161		return results;
162	}
163
164/********************************************* PRIVATE *********************************************/
165
166
167	/**
168	* Update the content hits
169	* @contentID.hint The content id to update
170	*/
171	private function syncUpdateHits(required contentID){
172		var q = new Query(sql="UPDATE cb_content SET hits = hits + 1 WHERE contentID = #arguments.contentID#").execute();
173		return this;
174	}
175
176
177	private function closureTest(){
178		methodCall(
179			param1,
180			function( arg1, required arg2 ){
181				var settings = settingService.getAllSettings(asStruct=true);
182				// Get appropriate cache provider
183				var cache = cacheBox.getCache( settings.cb_content_cacheName );
184				cache.clear("cb-content-pagewrapper-#arguments.slug#/");
185				return this;
186			},
187			param1
188		);
189	}
190
191	private function StructliteralTest(){
192		return {
193			foo = bar,
194			brad = 'Wood',
195			func = function( arg1, required arg2 ){
196				var settings = settingService.getAllSettings(asStruct=true);
197				// Get appropriate cache provider
198				var cache = cacheBox.getCache( settings.cb_content_cacheName );
199				cache.clear("cb-content-pagewrapper-#arguments.slug#/");
200				return this;
201			},
202			array = [
203				1,
204				2,
205				3,
206				4,
207				5,
208				'test',
209				'testing',
210				'testerton',
211				{
212					foo = true,
213					brad = false,
214					wood = null
215				}
216			],
217			last = "final"
218		};
219	}
220
221	private function arrayliteralTest(){
222		return [
223			1,
224			2,
225			3,
226			4,
227			5,
228			'test',
229			'testing',
230			'testerton',
231			{
232				foo = true,
233				brad = false,
234				wood = null
235			},
236			'testy-von-testavich'
237		];
238	}
239
240}
241</cfscript>