services

Documents OrangeHRM's service layer conventions for business logic between endpoints and DAOs.

Updated Jul 23, 2026
One-click install
npx skills add https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone --skill services-snow-gift111
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: services
Source: https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone/tree/main/.agents/skills/services
Command: npx skills add https://github.com/snow-gift111/orangehrm-ai-sdlc-capstone --skill services-snow-gift111

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? When adding business logic to OrangeHRM, developers must decide where code belongs — service, DAO, entity Decorator, or validator — and follow the framework's DI and trait conventions. This Skill provides the reference for structuring, registering, and composing service classes correctly. ## Core Features & Use Cases - Service Structure Reference: Documents the plain-class service shape with lazy-getter DAO access, paired test-injection setters, and trait-based cross-cutting concerns like EventDispatcherTrait and ConfigServiceTrait. - DI Registration Guide: Explains registering services in PluginConfigurationInterface::initialize(), adding Services::* constants, and creating matching *ServiceTrait accessors. - Placement Decision Rules: Clarifies what belongs in a service versus a DAO, entity Decorator, or validation rule, with recipes for new services, service composition, and transaction wrapping. - Use Case: When adding a new WidgetService that must persist an entity, dispatch an event, and call another plugin's UserService, follow the recipes to create the class, trait, service ID constant, and container registration. ## Quick Start Ask the AI to create a new OrangeHRM service class with its matching ServiceTrait and container registration for a given plugin resource.

Frequently Asked Questions about services

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I create a new service class in OrangeHRM?

Create a plain PHP class in src/plugins/orangehrm{X}Plugin/Service/ with a lazy-getter for its DAO and a paired setter for tests. Then add a matching *ServiceTrait, a Services::* constant, and register it in the plugin's PluginConfiguration::initialize() method.

Where should business logic go in OrangeHRM: service, DAO, or entity?

Multi-step operations with events or side effects belong in a service, pure single-entity queries belong in the DAO, and convenience methods bound to one entity instance belong on an entity Decorator. Input validation belongs in API endpoint ParamRules, not services.

How do OrangeHRM services access other services?

Cross-plugin access uses the target plugin's *ServiceTrait, which resolves the service from the DI container via its Services::* constant. In-plugin composition typically uses a lazy getter that instantiates the sub-service with new.

Why does my OrangeHRM service fail with a container lookup error?

This happens when the service class exists but was never registered in the plugin's PluginConfiguration::initialize() via getContainer()->register(). Also verify the Services::* constant is used consistently in both registration and the Trait's get() call.

Are OrangeHRM services singletons within a request?

No. Services composed via lazy getters using new create a fresh instance per call, so per-instance state is not shared. Services should be stateless; store shared state elsewhere or pass it through method parameters.