This repository contains a Testimonial module with GraphQL API support and Hyvä Theme compatibility for managing customer testimonials with complete CRUD operations, admin panel, and frontend display.
- Complete database schema with optimized indexes
- Full Admin CRUD using Magento UI Components
- Frontend testimonial listing and submission pages
- GraphQL endpoints (queries & mutations)
- Strong validation and security best practices
- LESS-based styling following Magento 2 standards (Luma)
- Hyvä theme compatible frontend (no RequireJS / no jQuery)
- Repository pattern and service layer architecture
- Magento Open Source 2.4.5+
- PHP 8.1+
- Module Name:
Ashokdubariya_Testimonial - Package Name:
ashokdubariya/module-testimonial - Module Type: Magento 2 Custom Module
- API Type: GraphQL
- License: MIT
composer require ashokdubariya/module-testimonial
php bin/magento module:enable Ashokdubariya_Testimonial
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flush- Copy the module to Magento:
mkdir -p app/code/Ashokdubariya/Testimonial
# Copy module files to app/code/Ashokdubariya/Testimonial- Run Magento commands:
php bin/magento module:enable Ashokdubariya_Testimonial
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy -f
php bin/magento cache:flushAfter installation, the GraphQL endpoint is available at:
https://your-magento-site.com/graphql
File: etc/schema.graphqls
query {
testimonials(currentPage: 1, pageSize: 10) {
total_count
items {
testimonial_id
customer_name
customer_email
message
rating
status
created_at
updated_at
}
}
}query {
testimonials(
currentPage: 1
pageSize: 10
filter: {
status: { eq: "1" }
}
) {
total_count
items {
testimonial_id
customer_name
message
rating
created_at
}
}
}query {
testimonials(
filter: {
rating: { eq: "5" }
}
) {
total_count
items {
testimonial_id
customer_name
message
rating
}
}
}query {
testimonials(
filter: {
customer_name: { like: "John" }
}
) {
total_count
items {
testimonial_id
customer_name
message
}
}
}query {
testimonials(
filter: {
rating: { in: ["4", "5"] }
}
) {
total_count
items {
testimonial_id
customer_name
rating
}
}
}query {
testimonials(
filter: {
created_at: {
from: "2026-01-01"
to: "2026-01-31"
}
}
) {
total_count
items {
testimonial_id
customer_name
created_at
}
}
}query {
testimonials(
currentPage: 1
pageSize: 20
filter: {
status: { eq: "1" }
rating: { in: ["4", "5"] }
customer_name: { like: "John" }
}
) {
total_count
items {
testimonial_id
customer_name
message
rating
status
created_at
}
}
}query {
testimonial(id: 5) {
testimonial_id
customer_name
customer_email
message
rating
status
created_at
updated_at
}
}{
"data": {
"testimonial": {
"testimonial_id": 5,
"customer_name": "John Doe",
"customer_email": "john@example.com",
"message": "Excellent service!",
"rating": 5,
"status": 1,
"created_at": "2026-01-06 15:00:00",
"updated_at": "2026-01-06 16:30:00"
}
}
}mutation {
addTestimonial(
input: {
customer_name: "John Doe"
customer_email: "john@example.com"
message: "Excellent service! Highly recommended."
rating: 5
}
) {
testimonial_id
status
message
}
}{
"data": {
"addTestimonial": {
"testimonial_id": 6,
"status": "success",
"message": "Testimonial submitted successfully. It will be reviewed by our team."
}
}
}Update one or more fields of an existing testimonial.
mutation {
updateTestimonial(
id: 5
input: {
customer_name: "John Smith"
customer_email: "john.smith@example.com"
message: "Updated message - Still excellent!"
rating: 5
status: 1
}
) {
testimonial_id
status
message
testimonial {
testimonial_id
customer_name
customer_email
message
rating
status
updated_at
}
}
}mutation {
updateTestimonial(
id: 5
input: {
status: 1
}
) {
testimonial_id
status
message
testimonial {
testimonial_id
status
updated_at
}
}
}mutation {
updateTestimonial(
id: 5
input: {
message: "Updated testimonial message"
rating: 4
}
) {
testimonial_id
status
message
}
}{
"data": {
"updateTestimonial": {
"testimonial_id": 5,
"status": "success",
"message": "Testimonial updated successfully.",
"testimonial": {
"testimonial_id": 5,
"customer_name": "John Smith",
"customer_email": "john.smith@example.com",
"message": "Updated message - Still excellent!",
"rating": 5,
"status": 1,
"updated_at": "2026-01-06 16:50:00"
}
}
}
}mutation {
deleteTestimonial(id: 5) {
status
message
}
}{
"data": {
"deleteTestimonial": {
"status": "success",
"message": "Testimonial deleted successfully."
}
}
}{
"errors": [
{
"message": "Testimonial with ID 999 not found.",
"extensions": {
"category": "graphql-no-such-entity"
}
}
]
}customer_name- Filter by customer namecustomer_email- Filter by emailrating- Filter by rating (1-5)status- Filter by status (0=Disabled, 1=Enabled)created_at- Filter by creation date
| Filter Type | Description | Example |
|---|---|---|
eq |
Equal to | { eq: "1" } |
in |
In array | { in: ["4", "5"] } |
like |
Pattern match | { like: "John" } |
from |
Greater than or equal | { from: "2026-01-01" } |
to |
Less than or equal | { to: "2026-01-31" } |
curl -X POST https://your-magento-site.com/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "query { testimonials(filter: { status: { eq: \"1\" }, rating: { in: [\"4\", \"5\"] } }) { total_count items { testimonial_id customer_name rating } } }"
}'curl -X POST https://your-magento-site.com/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { updateTestimonial(id: 5, input: { status: 1 }) { testimonial_id status message } }"
}'curl -X POST https://your-magento-site.com/graphql \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { deleteTestimonial(id: 5) { status message } }"
}'query {
testimonials(filter: { rating: { eq: "5" }, status: { eq: "1" } }) {
items {
customer_name
message
created_at
}
}
}query {
testimonials(
filter: {
created_at: { from: "2025-12-07" }
status: { eq: "1" }
}
) {
items {
customer_name
message
rating
created_at
}
}
}query {
testimonials(filter: { customer_email: { like: "@example.com" } }) {
items {
testimonial_id
customer_name
customer_email
message
}
}
}mutation {
updateTestimonial(id: 10, input: { status: 1 }) {
status
message
testimonial {
testimonial_id
status
}
}
}# Step 1: Get disabled testimonials
query {
testimonials(filter: { status: { eq: "0" } }) {
items {
testimonial_id
customer_name
message
}
}
}
# Step 2: Update each one
mutation {
updateTestimonial(id: 10, input: { status: 1 }) {
status
message
}
}- customer_name: Required (for add), max 255 characters
- customer_email: Required (for add), valid email format, max 255 characters
- message: Required (for add), no length limit
- rating: Required (for add), integer 1-5
- status: Optional, 0 or 1
- All filter values should be strings (even numbers)
- Date format:
YYYY-MM-DDorYYYY-MM-DD HH:MM:SS - Use
likefor partial matches (automatically adds % wildcards)
0= Disabled (default for customer submissions)1= Enabled (visible in public queries)
| Operation | Type | Description |
|---|---|---|
testimonials |
Query | Get paginated list with filtering |
testimonial |
Query | Get single testimonial by ID |
addTestimonial |
Mutation | Create new testimonial |
updateTestimonial |
Mutation | Update existing testimonial |
deleteTestimonial |
Mutation | Delete testimonial |
- Navigate to:
https://your-magento-site.com/graphql - Use the schema explorer to see all available fields
- Test queries and mutations interactively
- View auto-complete suggestions
- Admin Panel:
/admin/testimonial/testimonial/index - Frontend Listing:
/testimonial - Submit Form:
/testimonial/submit - Module Location:
/app/code/Ashokdubariya/Testimonial
- Source: GitHub Repository
- Issues: GitHub Issues
This project is licensed under the MIT License - see the LICENSE file for details.