sd shadow-docs
GitHub
shadow-docs / WordPress / Lomas un tiesības

Lomas, tiesības un admin panelis

Bieži klientu WordPress vietnēs "Redaktors" loma nedrīkst redzēt visu — nav vajadzības pēc Rakstiem, Tēmas failu redaktora vai Customizer izvēlnēm, ko tas var sabojāt. Šeit ir četri reāli paņēmieni, kā to ierobežot.

1. Pārbaude ar current_user_can()

Pamats visam zemāk — pirms jebkuras admin izmaiņas pārbaudi, vai lietotājam ir konkrēta tiesība vai loma:

if ( ! current_user_can( 'editor' ) ) {
	return; // administratoram šis kods netiek pielietots
}
current_user_can('editor') pārbauda lomu, ne tiesību
Tehniski current_user_can() ir domāts tiesībām (capabilities) — piem. edit_posts. Nosaukumi sakrīt ar lomu nosaukumiem tikai tāpēc, ka WordPress katrai standarta lomai automātiski piešķir tāda paša nosaukuma "pseudo-capability". Praksē tas strādā, bet, ja projektā ir custom lomas, precīzāk ir pārbaudīt reālu tiesību, piem. edit_theme_options.

2. Izvēlņu punktu noņemšana ar remove_menu_page

function remove_admin_menus() {
	if ( ! current_user_can( 'editor' ) ) {
		return;
	}
	remove_menu_page( 'edit.php' );                   // Raksti
	remove_menu_page( 'edit-comments.php' );           // Komentāri
	remove_menu_page( 'edit.php?post_type=page' );     // Lapas (paslēpj, jo tiek pārvaldītas citādi)
	remove_menu_page( 'tools.php' );                   // Rīki
	remove_menu_page( 'themes.php' );                  // Izskats
}
add_action( 'admin_menu', 'remove_admin_menus', 999 );
Kāpēc prioritāte 999?
Izvēlnes punktus reģistrē gan WordPress kodols, gan spraudņi (piem. Rank Math, WPForms) uz admin_menu hooka. Ja tavs remove_menu_page() izpildās pirms tiem, punkta vēl nav — nekā nenoņemsi. Augsta prioritāte (izpildās pēdējais) garantē, ka viss jau ir reģistrēts.

3. Konkrētu elementu paslēpšana ar CSS caur admin_head

Ja spraudnis nepiedāvā filtru konkrētam izvēlnes punktam (piem. WooCommerce produkti), vienkāršākais risinājums bieži ir CSS:

function hide_product_menu_css() {
	if ( ! current_user_can( 'editor' ) ) {
		return;
	}
	echo '<style>
		#menu-posts-product {
			display: none !important;
		}
	</style>';
}
add_action( 'admin_head', 'hide_product_menu_css' );

4. Customizer paneļu noņemšana ar customize_register

Ja redaktoram ir dota piekļuve Customizer (edit_theme_options tiesība), var ierobežot, kuras sadaļas tur redzamas:

// Vispirms iedod redaktoram piekļuvi Customizer vispār
add_action( 'admin_init', 'atljaut_redaktoram_customizer' );
function atljaut_redaktoram_customizer() {
	$role = get_role( 'editor' );
	if ( $role && ! $role->has_cap( 'edit_theme_options' ) ) {
		$role->add_cap( 'edit_theme_options' );
	}
}

// Tad ierobežo, kuras sadaļas redaktors redz iekšā
add_action( 'customize_register', 'ierobezot_customizer_redaktoram', 999 );
function ierobezot_customizer_redaktoram( $wp_customize ) {
	if ( ! current_user_can( 'administrator' ) ) {
		$wp_customize->remove_section( 'custom_css' );
		$wp_customize->remove_panel( 'nav_menus' );
		$wp_customize->remove_panel( 'widgets' );
		$wp_customize->remove_section( 'static_front_page' );
	}
}
add_cap() saglabājas datubāzē — izsauc tikai vienreiz pa reālu
$role->add_cap() uzreiz pieraksta izmaiņu wp_options tabulā (wp_user_roles). Nav problēmu izsaukt to katru admin_init reizi — kods iekšā jau pārbauda !$role->has_cap(...), tāpēc pēc pirmās reizes tas neko vairs nedara —, bet der zināt, ka tas nav tikai izpildlaika (runtime) iestatījums, kā, piemēram, current_user_can filtrs būtu.

Pilns, palaižams piemērs

Šis fails ierobežo "editor" lomu vienā vietā — izvēlnes, produktu CSS un divi Customizer paneļi:

<?php
add_action( 'admin_menu', function() {
	if ( ! current_user_can( 'editor' ) || current_user_can( 'administrator' ) ) return;
	remove_menu_page( 'tools.php' );
	remove_menu_page( 'themes.php' );
}, 999 );

add_action( 'admin_head', function() {
	if ( ! current_user_can( 'editor' ) || current_user_can( 'administrator' ) ) return;
	echo '<style>#menu-posts-product{display:none !important;}</style>';
});

add_action( 'customize_register', function( $wp_customize ) {
	if ( current_user_can( 'administrator' ) ) return;
	$wp_customize->remove_panel( 'nav_menus' );
	$wp_customize->remove_panel( 'widgets' );
}, 999 );