I see what you mean, I was forgetting about the status settings. Also, I do the same thing with page 'name', but admittedly have never had a problem with a client changing it when they weren't supposed to. But this is all easy to overcome with a module. I think this will accomplish what you want to do. I've also tested this to confirm, so it should work out of the box. As it is now, it'll deny access to editing of name, parent, template, status for everyone except superuser. But I put in variables at the top where you can add additional templates or roles that should fall-back to the default permission checks as if the module wasn't here.
One thing I want to note is that PageEdit doesn't perform a permission check before displaying the status checkboxes. However, it does perform a check before saving them. So the user may see them, but they won't be able to change them (which is probably just as good).
Code is pasted below, but I'm also attaching the file if you prefer to download it instead:
CustomPagePermissions.module
class CustomPagePermissions extends WireData implements Module {
public static function getModuleInfo() {
return array(
'title' => 'Custom Page Permissions',
'version' => 1,
'summary' => 'Starter/example module to enable customization to page field permissions.',
'singular' => true,
'autoload' => true,
);
}
// names of fields that you want to deny access to
protected $denyFields = array('name', 'status', 'template', 'parent');
// optionally specify names of templates that will be excluded from these permission checks
protected $skipTemplates = array();
// optionally specify names of user roles that will be excluded from these permission checks
protected $skipRoles = array('superuser');
// attach the hook
public function init() {
$this->addHookAfter('Page::editable', $this, 'hookPageEditable');
}
// perform the editable() check
public function hookPageEditable($event) {
// if editable() already denied access, then don't continue
if(!$event->return) return;
// if user has one of the 'skip' roles identified above, then skip permission check
foreach($this->skipRoles as $name) if($this->user->hasRole($name)) return;
$page = $event->object;
$fieldName = $event->arguments(0);
// if page template is one you want to skip, then we'll return
if(in_array($page->template->name, $this->skipTemplates)) return;
// if fieldName is one of those listed, we'll deny access
if(in_array($fieldName, $this->denyFields)) $event->return = false;
}
}