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>