This article is part of the CakeDC Advent Calendar 2024 (December 3rd 2024)
In modern PHP development, utilizing constants and enums can significantly improve code readability, maintainability, and robustness. This article explores practical implementations of constants and enums in a CakePHP application. By leveraging these features, developers can write cleaner and more efficient code. Let's dive into the specifics with code examples and practical use cases.
1.- Define a constant class of user roles:
src/Constants/UserRoles.php
namespace App\Constants;
class UserRoles
{
public const string ADMIN = 'admin';
public const string EDITOR = 'editor';
public const string VIEWER = 'viewer';
}
2.- Define an Enum class for the status of the posts:
src/Enum/PostStatus.php
namespace App\Enum;
enum PostStatus: string
{
case DRAFT = 'draft';
case PUBLISHED = 'published';
case ARCHIVED = 'archived';
public static function list(): array
{
return [
self::DRAFT->value => __('DRAFT'),
self::PUBLISHED->value => __('PUBLISHED'),
self::ARCHIVED->value => __('ARCHIVED'),
];
}
}
3.- Define an Enum class for the status of the comments:
src/Enum/CommentStatus.php
namespace App\Enum;
enum CommentStatus: string
{
case APPROVED = 'approved';
case DECLINED = 'declined';
public static function list(): array
{
return [
self::APPROVED->value => __('APPROVED'),
self::DECLINED->value => __('DECLINED'),
];
}
}
4.- Check the dynamic use in the access to the Enums values.
templates/Pages/enums.php
// Dynamic constants new in php 8.3 and php 8.4
use App\Constants\UserRoles;
use App\Enum\PostStatus;
$roleName = 'ADMIN';
$roleValue = UserRoles::{$roleName}; // Dynamically accesses UserRoles::ADMIN
echo "Role Value: " . $roleValue; // Print “Role Value: admin”
// Dynamic Enum members new in php 8.3 and php 8.4
$statusName = 'PUBLISHED';
$statusValue = PostStatus::{$statusName}->value; // Dynamically accesses PostStatus::Published
echo "Post Status: " . $statusValue; // Print “Post Status: published”
5.- We can also use its functions, for example “list” for selectors, and print its value.
//generate a select element with all status options
echo $this->Form->control('status', ['options' => PostStatus::list(), 'empty' => true]);
//print the text associated with the status value
echo h(PostStatus::list()['published']);
6.- They can be used dynamically in query operations, for example: to get a post and only your comments approved.
src/Controller/PostsController.php
$postWithCommentsApproved = $this->Posts
->find('onlyCommentsByStatusEnum', status: CommentStatus::APPROVED)
->contain(['Users'])
->where(['Posts.id' => $id])
->firstOrFail();
src/Model/Table/PostsTable.php
public function findOnlyCommentsByStatusEnum(SelectQuery $query, CommentStatus $status): SelectQuery
{
return $this->find()
->contain(['Comments' => function ($q) use ($status) {
return $q->where([
'Comments.status' => $status->value,
]);
}]);
}
You can see a complete example in https://github.com/ACampanario/advent2024.