Repository-Based Service in Concrete CMS
February 1, 2025 | by biplob.ice

Repository-Based Service in Concrete CMS
In Concrete CMS, using repositories for data access is a best practice when working with Doctrine ORM. This approach keeps the service layer clean and focused on business logic while the repository handles database queries.
Step 1: Create the Entity (Database Table)
Concrete CMS uses Doctrine entities for database mapping. Let’s define a UserProfile entity.
File: packages/my_package/src/Entity/UserProfile.php
namespace MyPackage\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity(repositoryClass="MyPackage\Repository\UserProfileRepository")
* @ORM\Table(name="UserProfiles")
*/
class UserProfile {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
protected $id;
/** @ORM\Column(type="string") */
protected $name;
/** @ORM\Column(type="string", unique=true) */
protected $email;
// Getters and setters...
public function getId(): int { return $this->id; }
public function getName(): string { return $this->name; }
public function setName(string $name): void { $this->name = $name; }
public function getEmail(): string { return $this->email; }
public function setEmail(string $email): void { $this->email = $email; }
}
✅ This creates a table UserProfiles with columns id, name, and email.
Step 2: Create the Repository (Handles Database Queries)
A repository acts as an abstraction layer between Doctrine and your service class.
File: packages/my_package/src/Repository/UserProfileRepository.php
namespace MyPackage\Repository;
use Doctrine\ORM\EntityRepository;
use MyPackage\Entity\UserProfile;
class UserProfileRepository extends EntityRepository {
public function findByEmail(string $email): ?UserProfile {
return $this->findOneBy(['email' => $email]);
}
public function save(UserProfile $user): void {
$this->_em->persist($user);
$this->_em->flush();
}
}
✅ The repository provides methods to fetch and save user profiles.
Step 3: Create the Service (Uses Repository for Business Logic)
The service interacts with UserProfileRepository to perform actions.
File: packages/my_package/src/Service/UserProfileService.php
namespace MyPackage\Service;
use Doctrine\ORM\EntityManagerInterface;
use MyPackage\Entity\UserProfile;
use MyPackage\Repository\UserProfileRepository;
class UserProfileService {
protected $repository;
public function __construct(EntityManagerInterface $em) {
$this->repository = $em->getRepository(UserProfile::class);
}
public function getUserByEmail(string $email): ?UserProfile {
return $this->repository->findByEmail($email);
}
public function createUser(string $name, string $email): UserProfile {
$user = new UserProfile();
$user->setName($name);
$user->setEmail($email);
$this->repository->save($user);
return $user;
}
}
✅ The service class handles business logic like creating users or fetching by email.
Step 4: Register the Service in the Service Provider
Now, we need to register UserProfileService
in Concrete CMS.
File: packages/my_package/src/ServiceProvider.php
namespace MyPackage;
use Concrete\Core\Foundation\Service\Provider as ServiceProvider;
use MyPackage\Service\UserProfileService;
use Concrete\Core\Support\Facade\Application;
use Doctrine\ORM\EntityManagerInterface;
class MyServiceProvider extends ServiceProvider {
public function register() {
$this->app->singleton(UserProfileService::class, function($app) {
return new UserProfileService($app->make(EntityManagerInterface::class));
});
}
}
✅ This registers UserProfileService in Concrete CMS’s DI container.
Step 5: Use the Service in a Controller
Now, let’s use the service in a controller to manage users.
File: packages/my_package/controllers/single_page/dashboard/user_profiles.php
namespace Concrete\Package\MyPackage\Controller\SinglePage\Dashboard;
use Concrete\Core\Page\Controller\DashboardPageController;
use Concrete\Core\Support\Facade\Application;
use MyPackage\Service\UserProfileService;
class UserProfiles extends DashboardPageController {
public function view() {
$app = Application::getFacadeApplication();
$userProfileService = $app->make(UserProfileService::class);
// Create a new user
$newUser = $userProfileService->createUser('John Doe', 'john@example.com');
// Fetch a user by email
$existingUser = $userProfileService->getUserByEmail('john@example.com');
if ($existingUser) {
echo "User found: " . $existingUser->getName();
} else {
echo "User not found.";
}
}
}
✅ The controller uses the UserProfileService
to create and fetch user profiles.
Recap
- Entity → Represents the database table (
UserProfile
). - Repository → Handles database operations (
UserProfileRepository
). - Service → Contains business logic (
UserProfileService
). - Service Provider → Registers the service in Concrete CMS.
This keeps the MVC structure clean and maintainable. 🚀
RELATED POSTS
View all