The model should really only concern itself with talking to your persistence layer. That said, you can extract the levels functionality into it's own class somewhere.
class Level {
const LEVEL_DISABLED = 0;
const LEVEL_STUDY = 1;
const LEVEL_GENERATE = 2;
const LEVEL_REVIEW = 3;
const LEVEL_EDIT = 4;
const LEVEL_MANAGE = 5;
protected $levels;
public function __construct()
{
$this->levels = [
self::LEVEL_DISABLED => [ 'label' => 'Disabled', 'icon' => 'lock', ],
self::LEVEL_STUDY => [ 'label' => 'Study', 'icon' => 'user', ],
self::LEVEL_GENERATE => [ 'label' => 'Generate', 'icon' => 'share', ],
self::LEVEL_REVIEW => [ 'label' => 'Review', 'icon' => 'comment', ],
self::LEVEL_EDIT => [ 'label' => 'Edit', 'icon' => 'edit', ],
self::LEVEL_MANAGE => [ 'label' => 'Manage', 'icon' => 'star-empty', ],
];
}
private function isValid($level)
{
if ( ! isset($this->levels[$level]) )
{
throw new InvalidLevelException(sprintf('The level %s does not exist.', e($level));
}
return true;
}
public function getLabel($level)
{
$this->isValid($level);
return $this->levels[$level]['label'];
}
public function getIcon($level)
{
$this->isValid($level);
return $this->levels[$level]['icon'];
}
public function getList($max = null, $validation = false)
{
$list = [ ];
foreach ($this->labels as $key => $value)
{
if ( is_null($max) || ( $key <= $max ) )
{
$list[$key] => $value['label'];
}
}
if ( $validation === true )
{
return join(',', array_keys($list));
}
return $list;
}
}
I've omitted the HTML part, that can likely be extracted to a view partial, rather than living in your class. Then just pass the label and icon to that view when rendering it.
Another option would be to initialise the Level class with a single $level passed into the constructor rather than individual methods, that way you only have to check isValid on initialisation.
This is just one way to tackle it (and the first that came to mind at 0630). It may give you a hint on a direction to take (or one to avoid!), depending on your needs. I would certainly avoid putting much of that logic in the model, though. Don't be shy about adding folders in your app structure and separating things out a bit.