1+ component extends = " app.Models.Model" {
2+ function config () {
3+ table (" testimonials" );
4+
5+ // ID Property
6+ property (
7+ name = " id" ,
8+ column = " id" ,
9+ dataType = " integer" ,
10+ automaticValidations = false
11+ );
12+
13+ // User ID Property (Foreign Key)
14+ property (
15+ name = " userId" ,
16+ column = " user_id" ,
17+ dataType = " integer" ,
18+ label = " User ID" ,
19+ automaticValidations = true
20+ );
21+
22+ // Company Name Property
23+ property (
24+ name = " companyName" ,
25+ column = " company_name" ,
26+ dataType = " string" ,
27+ label = " Company Name" ,
28+ defaultValue = " "
29+ );
30+
31+ // Logo Path Property
32+ property (
33+ name = " logoPath" ,
34+ column = " logo_path" ,
35+ dataType = " string" ,
36+ label = " Logo Path" ,
37+ defaultValue = " "
38+ );
39+
40+ // Experience Level Property
41+ property (
42+ name = " experienceLevel" ,
43+ column = " experience_level" ,
44+ dataType = " string" ,
45+ label = " Experience Level" ,
46+ defaultValue = " Beginner"
47+ );
48+
49+ // Testimonial Text Property
50+ property (
51+ name = " testimonialText" ,
52+ column = " testimonial_text" ,
53+ dataType = " text" ,
54+ label = " Testimonial Text" ,
55+ defaultValue = " "
56+ );
57+
58+ // Rating Property
59+ property (
60+ name = " rating" ,
61+ column = " rating" ,
62+ dataType = " integer" ,
63+ label = " Rating" ,
64+ defaultValue = 0
65+ );
66+
67+ // Display Permission Property
68+ property (
69+ name = " displayPermission" ,
70+ column = " display_permission" ,
71+ dataType = " boolean" ,
72+ label = " Display Permission" ,
73+ defaultValue = false
74+ );
75+
76+ // Social Media Links Property
77+ property (
78+ name = " socialMediaLinks" ,
79+ column = " social_media_links" ,
80+ dataType = " string" ,
81+ label = " Social Media Links" ,
82+ defaultValue = " "
83+ );
84+
85+ // Website URL Property
86+ property (
87+ name = " websiteUrl" ,
88+ column = " website_url" ,
89+ dataType = " string" ,
90+ label = " Website URL" ,
91+ defaultValue = " "
92+ );
93+
94+ // Is Featured Property
95+ property (
96+ name = " isFeatured" ,
97+ column = " is_featured" ,
98+ dataType = " boolean" ,
99+ label = " Is Featured" ,
100+ defaultValue = false
101+ );
102+
103+ // Is Approved Property
104+ property (
105+ name = " isApproved" ,
106+ column = " is_approved" ,
107+ dataType = " boolean" ,
108+ label = " Is Approved" ,
109+ defaultValue = false
110+ );
111+
112+ // Timestamps with custom column names
113+ property (
114+ name = " createdAt" ,
115+ column = " createdat" ,
116+ dataType = " timestamp" ,
117+ label = " Created On"
118+ );
119+
120+ property (
121+ name = " updatedAt" ,
122+ column = " updatedat" ,
123+ dataType = " timestamp" ,
124+ label = " Last Updated"
125+ );
126+
127+ // Relationships
128+ belongsTo (name = " User" , foreignKey = " userId" );
129+
130+ // Validations
131+ validatesPresenceOf (properties = " companyName,experienceLevel,testimonialText,rating" );
132+ validatesLengthOf (property = " testimonialText" , minimum = 20 , maximum = 500 , message = " Testimonial text must be between 20 and 500 characters." );
133+ validatesNumericalityOf (property = " rating" , minimum = 1 , maximum = 5 , message = " Rating must be between 1 and 5." );
134+ }
135+
136+ // Get all approved testimonials
137+ public function getApprovedTestimonials (struct options = {}) {
138+ // Default options
139+ local .defaultOptions = {
140+ page = 1 ,
141+ perPage = 10 ,
142+ sortBy = " createdAt" ,
143+ sortOrder = " DESC" ,
144+ onlyFeatured = false
145+ };
146+
147+ // Merge provided options
148+ local .mergedOptions = structAppend (local .defaultOptions , arguments .options );
149+
150+ // Build where clause
151+ local .whereClause = " isApproved = 1 AND displayPermission = 1" ;
152+
153+ // Add featured filter if specified
154+ if (local .mergedOptions .onlyFeatured ) {
155+ local .whereClause & = " AND isFeatured = 1" ;
156+ }
157+
158+ // Find testimonials
159+ return findAll (
160+ where = local .whereClause ,
161+ order = " #local .mergedOptions .sortBy # #local .mergedOptions .sortOrder #" ,
162+ page = local .mergedOptions .page ,
163+ perPage = local .mergedOptions .perPage ,
164+ include = " User"
165+ );
166+ }
167+
168+ // Format testimonial for display
169+ public function formatForDisplay () {
170+ local .user = this .user ();
171+
172+ return {
173+ id = this .id ,
174+ companyName = this .companyName ,
175+ logoPath = this .logoPath ,
176+ testimonialText = this .testimonialText ,
177+ rating = this .rating ,
178+ experienceLevel = this .experienceLevel ,
179+ websiteUrl = this .websiteUrl ,
180+ socialMediaLinks = this .socialMediaLinks ,
181+ userFullName = local .user .fullName ,
182+ userProfilePicture = local .user .profilePicture ,
183+ isFeatured = this .isFeatured ,
184+ submittedOn = this .createdAt
185+ };
186+ }
187+ }
0 commit comments