setup_globals();
if ( $this->taxonomy && $this->screen_id ) {
$this->includes();
$this->setup_hooks();
if ( isset( $_POST['action'] ) || isset( $_GET['action'] ) ) {
if ( isset( $_GET['action'] ) ) {
$action = wp_unslash( $_GET['action'] );
} else {
$action = wp_unslash( $_POST['action'] );
}
$this->handle_action( $action );
}
}
}
/**
* Register BP Types Admin.
*
* @since 7.0.0
*/
public static function register_types_admin() {
if ( ! is_admin() ) {
return;
}
$bp = buddypress();
if ( empty( $bp->core->types_admin ) ) {
$bp->core->types_admin = new self();
}
}
/**
* Set the globals.
*
* @since 7.0.0
*/
private function setup_globals() {
$current_screen = get_current_screen();
if ( isset( $current_screen->taxonomy ) && $current_screen->taxonomy ) {
$this->taxonomies = bp_get_default_taxonomies();
if ( isset( $this->taxonomies[ $current_screen->taxonomy ] ) ) {
$this->taxonomy = $current_screen->taxonomy;
$this->screen_id = $current_screen->id;
}
}
}
/**
* Include Admin functions.
*
* @since 7.0.0
*/
private function includes() {
require plugin_dir_path( __DIR__ ) . 'admin/bp-core-admin-types.php';
}
/**
* Set hooks.
*
* @since 7.0.0
*/
private function setup_hooks() {
// Actions.
add_action( 'admin_head-edit-tags.php', array( $this, 'screen_head' ) );
add_action( 'admin_head-term.php', array( $this, 'screen_head' ) );
add_action( 'bp_admin_enqueue_scripts', array( $this, 'screen_scripts' ) );
add_action( "{$this->taxonomy}_add_form_fields", array( $this, 'add_form_fields' ), 10, 1 );
add_action( "{$this->taxonomy}_edit_form_fields", array( $this, 'edit_form_fields' ), 10, 2 );
// Filters.
add_filter( 'bp_core_admin_register_scripts', array( $this, 'register_scripts' ) );
add_filter( "manage_{$this->screen_id}_columns", array( $this, 'column_headers' ), 10, 1 );
add_filter( "manage_{$this->taxonomy}_custom_column", array( $this, 'column_contents' ), 10, 3 );
add_filter( "{$this->taxonomy}_row_actions", array( $this, 'row_actions' ), 10, 2 );
add_filter( "bulk_actions-{$this->screen_id}", '__return_empty_array', 10, 1 );
/**
* Fires when a Types Admin Screen is loading.
*
* The dynamic portion of the hook name, `$this->taxonomy`, refers to the current type taxonomy.
*
* Possible hook names include:
*
* - `bp_admin_load_bp_member_type`
* - `bp_admin_load_bp_group_type`
*
* @since 14.0.0
*/
do_action( 'bp_admin_load_' . $this->taxonomy );
}
/**
* Handle BP Type actions.
*
* @since 7.0.0
*
* @param string $action Required. The action to handle ('add-tag', 'editedtag' or 'delete' ).
*/
private function handle_action( $action ) {
$referer = wp_get_referer();
if ( ! bp_current_user_can( 'bp_moderate' ) ) {
return;
}
// Adding a new type into the database.
if ( 'add-tag' === $action ) {
check_admin_referer( 'add-tag', '_wpnonce_add-tag' );
$result = bp_core_admin_insert_type( $_POST );
if ( is_wp_error( $result ) ) {
$referer = add_query_arg(
array_merge(
$result->get_error_data(),
array(
'error' => 1,
)
),
$referer
);
wp_safe_redirect( $referer );
exit;
}
wp_safe_redirect( add_query_arg( 'message', 2, $referer ) );
exit;
// Updating an existing type intot the Database.
} elseif ( 'editedtag' === $action ) {
$args = $_POST;
$args['type_term_id'] = 0;
unset( $args['tag_ID'] );
if ( isset( $_POST['tag_ID'] ) ) {
$args['type_term_id'] = $_POST['tag_ID'];
}
if ( isset( $_POST['taxonomy'] ) ) {
$args['taxonomy'] = $_POST['taxonomy'];
}
check_admin_referer( 'update-tag_' . $args['type_term_id'] );
$result = bp_core_admin_update_type( $args );
if ( is_wp_error( $result ) ) {
$referer = add_query_arg(
array_merge(
$result->get_error_data(),
array(
'error' => 1,
)
),
$referer
);
wp_safe_redirect( $referer );
exit;
}
wp_safe_redirect( add_query_arg( 'message', 4, $referer ) );
exit;
// Deletes a type.
} elseif ( 'delete' === $action ) {
$args = $_GET;
$args['type_term_id'] = 0;
unset( $args['tag_ID'] );
if ( isset( $_GET['tag_ID'] ) ) {
$args['type_term_id'] = $_GET['tag_ID'];
}
if ( isset( $_GET['taxonomy'] ) ) {
$args['taxonomy'] = $_GET['taxonomy'];
}
check_admin_referer( 'delete-tag_' . $args['type_term_id'] );
$referer = remove_query_arg( array( 'action', 'tag_ID', '_wpnonce' ), $referer );
// Delete the type.
$result = bp_core_admin_delete_type( $args );
if ( is_wp_error( $result ) ) {
$referer = add_query_arg(
array_merge(
$result->get_error_data(),
array(
'error' => 1,
)
),
$referer
);
wp_safe_redirect( $referer );
exit;
}
wp_safe_redirect( add_query_arg( 'message', 9, $referer ) );
exit;
}
}
/**
* Override the Admin parent file to highlight the right menu.
*
* @since 7.0.0
*
* @global string $parent_file The parent file of the current admin screen.
*/
public function screen_head() {
global $parent_file;
if ( 'members' === $this->taxonomies[ $this->taxonomy ]['component'] ) {
$parent_file = 'users.php';
} else {
$parent_file = 'bp-' . $this->taxonomies[ $this->taxonomy ]['component'];
}
}
/**
* Registers script.
*
* @since 7.0.0
*
* @param array $scripts Optional. The registered scripts.
*/
public function register_scripts( $scripts = array() ) {
// Neutralize WordPress Taxonomy scripts.
wp_dequeue_script( 'admin-tags' );
wp_dequeue_script( 'inline-edit-tax' );
// Adapt some styles.
wp_add_inline_style(
'common',
'.form-field:not(.bp-types-form), .term-bp_type_directory_slug-wrap:not(.bp-set-directory-slug), .edit-tag-actions #delete-link { display: none; }'
);
// Register the Types admin script.
return array_merge(
$scripts,
array(
'bp-admin-types' => array(
'file' => sprintf(
'%1$sadmin/js/types-admin%2$s.js',
plugin_dir_url( __DIR__ ),
bp_core_get_minified_asset_suffix()
),
'dependencies' => array(),
'footer' => true,
),
)
);
}
/**
* Enqueues script.
*
* @since 7.0.0
*/
public function screen_scripts() {
wp_enqueue_script( 'bp-admin-types' );
}
/**
* Outputs the BP type add form.
*
* @since 7.0.0
*
* @param string $taxonomy Optional. The type taxonomy name.
* @param null|object $type Optional. The type object, `null` if not passed to the method.
*/
public function add_form_fields( $taxonomy = '', $type = null ) {
$taxonomy_object = get_taxonomy( $taxonomy );
$labels = get_taxonomy_labels( $taxonomy_object );
// Default values for the Type ID field.
$type_id_label = __( 'Type ID', 'buddypress' );
$type_id_desc = __( 'Enter a lower-case string without spaces or special characters (used internally to identify the type).', 'buddypress' );
if ( isset( $labels->bp_type_id_label ) && $labels->bp_type_id_label ) {
$type_id_label = $labels->bp_type_id_label;
}
if ( isset( $labels->bp_type_id_description ) && $labels->bp_type_id_description ) {
$type_id_desc = $labels->bp_type_id_description;
}
// Outputs the Type ID field.
if ( isset( $type->name ) ) {
printf(
'
|
|
',
esc_html( $type_id_label ),
esc_attr( $type->name ),
esc_html( $type_id_desc )
);
} else {
printf(
'',
esc_html( $type_id_label ),
esc_html( $type_id_desc )
);
}
// Gets the Type's metadata.
$metafields = get_registered_meta_keys( 'term', $taxonomy );
foreach ( $metafields as $meta_key => $meta_schema ) {
if ( ! isset( $labels->{ $meta_key } ) || ! $labels->{ $meta_key } ) {
_doing_it_wrong(
__METHOD__,
esc_html__( 'Type metadata labels need to be set into the labels argument when registering your taxonomy using the meta key as the label’s key.', 'buddypress' )
. ' ' .
sprintf(
/* translators: %s is the name of the Type meta key */
esc_html__( 'As a result, the form elements for the "%s" meta key cannot be displayed', 'buddypress' ),
esc_html( $meta_key )
),
'7.0.0'
);
continue;
}
$type_key = str_replace( 'bp_type_', '', $meta_key );
if ( 'string' === $meta_schema['type'] ) {
if ( isset( $type->name ) ) {
$type_prop_value = null;
if ( in_array( $type_key, array( 'name', 'singular_name' ), true ) ) {
if ( isset( $type->labels[ $type_key ] ) ) {
$type_prop_value = $type->labels[ $type_key ];
}
} elseif ( isset( $type->{$type_key} ) ) {
$type_prop_value = $type->{$type_key};
}
printf(
'
|
%4$s
|
',
esc_attr( $meta_key ),
esc_html( $labels->{ $meta_key } ),
esc_attr( $type_prop_value ),
esc_html( $meta_schema['description'] )
);
} else {
printf(
'',
esc_attr( $meta_key ),
esc_html( $labels->{ $meta_key } ),
esc_html( $meta_schema['description'] )
);
}
} elseif ( isset( $type->name ) ) {
$checked = '';
if ( isset( $type->{$type_key} ) && true === (bool) $type->{$type_key} ) {
$checked = ' checked="checked"';
}
printf(
'
|
%4$s
%5$s
|
',
esc_attr( $meta_key ),
esc_html( $labels->{ $meta_key } ),
// phpcs:ignore WordPress.Security.EscapeOutput
$checked,
esc_html__( 'Yes', 'buddypress' ),
esc_html( $meta_schema['description'] )
);
} else {
printf(
'',
esc_attr( $meta_key ),
esc_html( $labels->{ $meta_key } ),
esc_html( $meta_schema['description'] )
);
}
}
}
/**
* Outputs the BP type edit form.
*
* @since 7.0.0
*
* @param WP_Term|null $term Optional. The term object for the BP Type.
* @param string $taxonomy Optional. The type taxonomy name.
*/
public function edit_form_fields( $term = null, $taxonomy = '' ) {
if ( ! isset( $term->name ) || ! $term->name || ! $taxonomy ) {
return;
}
$type = new stdClass();
$type->name = $term->name;
$type->labels = array();
$metadatas = get_metadata( 'term', $term->term_id );
foreach ( $metadatas as $meta_key => $meta_values ) {
$meta_value = reset( $meta_values );
$type_key = str_replace( 'bp_type_', '', $meta_key );
if ( in_array( $type_key, array( 'name', 'singular_name' ), true ) ) {
$type->labels[ $type_key ] = $meta_value;
} else {
$type->{$type_key} = $meta_value;
}
}
$this->add_form_fields( $taxonomy, $type );
}
/**
* Filters the terms list table column headers to customize them for BuddyPress Types.
*
* @since 7.0.0
*
* @param array $column_headers Optional. The column header labels keyed by column ID.
* @return array The column header labels keyed by column ID.
*/
public function column_headers( $column_headers = array() ) {
if ( isset( $column_headers['name'] ) ) {
$column_headers['name'] = __( 'Type ID', 'buddypress' );
}
unset( $column_headers['cb'], $column_headers['description'], $column_headers['posts'] );
$column_headers['plural_name'] = __( 'Name', 'buddypress' );
$column_headers['counts'] = _x( 'Count', 'Number/count of types', 'buddypress' );
return $column_headers;
}
/**
* Sets the content for the Plural name & Counts columns.
*
* @since 7.0.0
*
* @param string $column_content Optional. The column content.
* @param string $column_name Optional. Name of the column.
* @param int $type_id Optional. The type's term ID.
* @return string|null|int
*/
public function column_contents( $column_content = '', $column_name = '', $type_id = 0 ) {
if ( ( 'plural_name' !== $column_name && 'counts' !== $column_name ) || ! $type_id ) {
return $column_content;
}
// Set the Plural name column.
if ( 'plural_name' === $column_name ) {
$type_plural_name = get_term_meta( $type_id, 'bp_type_name', true );
// Plural name meta is not set? Let's check register by code types!
if ( ! $type_plural_name ) {
$type_name = get_term_field( 'name', $type_id, $this->taxonomy );
/**
* Filter here to set missing term meta for registered by code types.
*
* @see bp_set_registered_by_code_member_type_metadata() for an example of use.
*
* The dynamic portion of the hook name, `$this->taxonomy`, refers to the current type taxonomy.
*
* Possible hook names include:
*
* - `bp_member_type_set_registered_by_code_metada`
* - `bp_group_type_set_registered_by_code_metada`
*
* @since 7.0.0
*
* @param string $meta_data Metadata for the BP Type.
* @param string $type_name The BP Type name.
*/
$metadata = apply_filters( "{$this->taxonomy}_set_registered_by_code_metada", array(), $type_name );
if ( isset( $metadata['bp_type_name'] ) ) {
$type_plural_name = $metadata['bp_type_name'];
}
}
echo esc_html( $type_plural_name );
// Set the Totals column.
} elseif ( 'counts' === $column_name ) {
global $parent_file;
$type = bp_get_term_by( 'id', $type_id, $this->taxonomy );
if ( 0 === (int) $type->count ) {
return 0;
}
// Format the count.
$count = number_format_i18n( $type->count );
$args = array(
str_replace( '_', '-', $this->taxonomy ) => $type->slug,
);
$base_url = $parent_file;
if ( false === strpos( $parent_file, '.php' ) ) {
$base_url = add_query_arg( 'page', $parent_file, 'admin.php' );
}
printf(
'%2$s',
esc_url( add_query_arg( $args, bp_get_admin_url( $base_url ) ) ),
esc_html( $count )
);
}
}
/**
* Customizes the Types Admin list table row actions.
*
* @since 7.0.0
*
* @param array $actions Optional. The table row actions.
* @param WP_Term|null $type Optional. The current BP Type for the row.
* @return array The table row actions for the current BP type.
*/
public function row_actions( $actions = array(), $type = null ) {
if ( ! isset( $type->taxonomy ) || ! $type->taxonomy ) {
return $actions;
}
/**
* Filter here to set the types "registered by code".
*
* @see bp_get_member_types_registered_by_code() for an example of use.
*
* The dynamic portion of the hook name, `$type->taxonomy`, refers to the term's type taxonomy.
*
* Possible hook names include:
*
* - `bp_member_type_registered_by_code`
* - `bp_group_type_registered_by_code`
*
* @since 7.0.0
*
* @param array $registered_by_code_types The types registered by code.
* @param WP_Term|null $type The current BP Type for the row.
*/
$registered_by_code_types = apply_filters( "{$type->taxonomy}_registered_by_code", array(), $type );
// Types registered by code cannot be deleted as long as the custom registration code exists.
if ( isset( $registered_by_code_types[ $type->name ] ) ) {
unset( $actions['delete'] );
}
// Inline edits are disabled for all types.
unset( $actions['inline hide-if-no-js'] );
// Removes the post type query argument for the edit action.
if ( isset( $actions['edit'] ) ) {
$actions['edit'] = str_replace( '&post_type=post', '', $actions['edit'] );
}
return $actions;
}
}