Reputation: 41
At the moment I have User entity with predefined statuses as constants. User has STATUS_NOT_CONFIRMED by default.
interface UserInterface
{
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 2;
const STATUS_BANNED = 3;
const STATUS_NOT_CONFIRMED = 4;
}
But I'm stuck with a question of what the best (or better) way to manage User statuses:
using just one method like $user->changeStatusTo($status) which is similar to $user->setStatus($status);
create methods like $user->enable(), $user->disable(), $user->ban() which is more eloquent but can lead to the problem if I have more statuses in the future;
I'll glad to see any answers and advices, thanks!
Upvotes: 0
Views: 48
Reputation: 8496
I can suggest to use magic method __get() with userInterface and check constant dynamically in below way
<?php
interface UserInterface
{
const STATUS_ENABLE = 1;
const STATUS_DISABLE = 2;
const STATUS_BAN = 3;
const STATUS_NOT_CONFIRM = 4;
const STATUS_DEFAULT = self::STATUS_NOT_CONFIRM;
}
class User implements UserInterface{
public $status = UserInterface::STATUS_DEFAULT;
private function setStatus($status) {
if ($status < 0 || $status > UserInterface::STATUS_DEFAULT) {
throw InvalidArgumentException('status');
}
$this->status = $status;
}
public function getStatus() {
return $this->status;
}
function __call($fn_name,$args)
{
if(strpos($fn_name,'make')==0)
{
$statusChangeTo = "STATUS_".strtoupper(substr($fn_name,4));
$constant= 'UserInterface::'.$statusChangeTo;
if(defined($constant))
{
$this->setStatus(constant($constant));
}
else
{
throw new Exception("Invalid method ".$fn_name);
}
}
else
{
throw new Exception("Invalid method ".$fn_name);
}
}
}
$user= new User();
var_dump($user->getStatus());
$user->makeBan();
var_dump($user->getStatus());
?>
Upvotes: 0
Reputation: 15629
I would create both variants and let them call each other. So calling ban
would call setStatus
. If you later add new statuses, you could extend setStatus and if really needed, add a new method.
For convinience reasons, I would also extend the UserInterface
interface to save the max value. That way, you could change the interface without touching your setStatus
method.
interface UserInterface
{
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 2;
const STATUS_BANNED = 3;
const STATUS_NOT_CONFIRMED = 4;
const STATUS_MAX = self::STATUS_NOT_CONFIRMED;
}
class User implements UserInterface {
// ...
function setStatus($status) {
if ($status < 0 || $status > UserInterface::STATUS_MAX) {
throw InvalidArgumentException('status');
}
$this->status = $status;
}
function ban() {
$this->setStatus(UserInterface::STATUS_BAN);
}
// ...
}
Upvotes: 1