Files
atahango/internal/services/home_service.go
Beyhan Oğur bbbf76b184 first commit
2026-04-26 21:35:24 +03:00

264 lines
5.4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package services
import (
"errors"
"fmt"
"regexp"
"strings"
"gauth-central/internal/database"
"gauth-central/internal/models"
"gorm.io/gorm"
)
const defaultHomeVideoURL = "https://www.youtube.com/watch?v=6zM4p_A0ISk"
type HomeService struct{}
func NewHomeService() *HomeService {
return &HomeService{}
}
// CreateHome creates a new home entry with optional tag relations.
func (s *HomeService) CreateHome(
name string,
title string,
button1 string,
button2 string,
video string,
keywords string,
image string,
tagIDs []string,
isActive bool,
) (*models.Home, error) {
if strings.TrimSpace(video) == "" {
video = defaultHomeVideoURL
}
slug := s.generateUniqueSlug(slugify(name), "")
home := models.Home{
Name: name,
Title: title,
Button1: button1,
Button2: button2,
Video: video,
Keywords: keywords,
Image: image,
Slug: slug,
IsActive: isActive,
}
if len(tagIDs) > 0 {
tags, err := s.fetchTagsByIDs(tagIDs)
if err != nil {
return nil, err
}
home.Tags = tags
}
if err := database.DB.Create(&home).Error; err != nil {
return nil, err
}
return s.GetHomeByID(home.ID.String())
}
// GetAllHomes retrieves all homes. Use onlyActive to filter public data.
func (s *HomeService) GetAllHomes(onlyActive bool) ([]models.Home, error) {
var homes []models.Home
query := database.DB.Preload("Tags").Order("created_at desc")
if onlyActive {
query = query.Where("is_active = ?", true)
}
if err := query.Find(&homes).Error; err != nil {
return nil, err
}
return homes, nil
}
// GetHomeByID retrieves a home by ID.
func (s *HomeService) GetHomeByID(id string) (*models.Home, error) {
var home models.Home
if err := database.DB.Preload("Tags").Where("id = ?", id).First(&home).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("home not found")
}
return nil, err
}
return &home, nil
}
// GetHomeBySlug retrieves a home by slug. Use onlyActive to limit public access.
func (s *HomeService) GetHomeBySlug(slug string, onlyActive bool) (*models.Home, error) {
var home models.Home
query := database.DB.Preload("Tags").Where("slug = ?", slug)
if onlyActive {
query = query.Where("is_active = ?", true)
}
if err := query.First(&home).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("home not found")
}
return nil, err
}
return &home, nil
}
// UpdateHome updates an existing home entry and its tag relations.
func (s *HomeService) UpdateHome(
id string,
name *string,
title *string,
button1 *string,
button2 *string,
video *string,
keywords *string,
image *string,
slug *string,
tagIDs *[]string,
isActive *bool,
) (*models.Home, error) {
home, err := s.GetHomeByID(id)
if err != nil {
return nil, err
}
updates := map[string]interface{}{}
if name != nil {
updates["name"] = *name
}
if title != nil {
updates["title"] = *title
}
if button1 != nil {
updates["button1"] = *button1
}
if button2 != nil {
updates["button2"] = *button2
}
if video != nil {
updates["video"] = *video
}
if keywords != nil {
updates["keywords"] = *keywords
}
if image != nil {
updates["image"] = *image
}
if slug != nil {
clean := slugify(*slug)
if clean == "" {
return nil, errors.New("slug cannot be empty")
}
if s.slugExists(clean, id) {
return nil, errors.New("slug already exists")
}
updates["slug"] = clean
}
if isActive != nil {
updates["is_active"] = *isActive
}
if len(updates) > 0 {
if err := database.DB.Model(home).Updates(updates).Error; err != nil {
return nil, err
}
}
if tagIDs != nil {
tags, err := s.fetchTagsByIDs(*tagIDs)
if err != nil {
return nil, err
}
if err := database.DB.Model(home).Association("Tags").Replace(tags); err != nil {
return nil, err
}
}
return s.GetHomeByID(id)
}
// DeleteHome deletes a home by ID.
func (s *HomeService) DeleteHome(id string) error {
result := database.DB.Delete(&models.Home{}, "id = ?", id)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return errors.New("home not found")
}
return nil
}
func (s *HomeService) fetchTagsByIDs(tagIDs []string) ([]models.Tag, error) {
var tags []models.Tag
if len(tagIDs) == 0 {
return tags, nil
}
if err := database.DB.Where("id IN ?", tagIDs).Find(&tags).Error; err != nil {
return nil, err
}
if len(tags) != len(tagIDs) {
return nil, errors.New("one or more tags not found")
}
return tags, nil
}
func (s *HomeService) generateUniqueSlug(baseSlug string, excludeID string) string {
slug := baseSlug
counter := 1
for s.slugExists(slug, excludeID) {
slug = fmt.Sprintf("%s-%d", baseSlug, counter)
counter++
}
return slug
}
func (s *HomeService) slugExists(slug string, excludeID string) bool {
var count int64
query := database.DB.Model(&models.Home{}).Where("slug = ?", slug)
if excludeID != "" {
query = query.Where("id <> ?", excludeID)
}
query.Count(&count)
return count > 0
}
func slugify(input string) string {
clean := strings.TrimSpace(input)
if clean == "" {
return ""
}
replacer := strings.NewReplacer(
"ı", "i",
"İ", "i",
"ş", "s",
"Ş", "s",
"ğ", "g",
"Ğ", "g",
"ç", "c",
"Ç", "c",
"ö", "o",
"Ö", "o",
"ü", "u",
"Ü", "u",
)
clean = strings.ToLower(replacer.Replace(clean))
re := regexp.MustCompile(`[^a-z0-9]+`)
clean = re.ReplaceAllString(clean, "-")
clean = strings.Trim(clean, "-")
if clean == "" {
return "home"
}
return clean
}