Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto cleanup values of “post” field when a post is deleted #1581

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions inc/field.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static function html( $meta, $field ) {
return '';
}

protected static function begin_html( array $field ) : string {
protected static function begin_html( array $field ): string {
$id = $field['attributes']['id'] ?? $field['id'];
$required = $field['required'] || ! empty( $field['attributes']['required'] );

Expand Down Expand Up @@ -101,16 +101,16 @@ protected static function begin_html( array $field ) : string {
return $label . $input_open;
}

protected static function end_html( array $field ) : string {
protected static function end_html( array $field ): string {
return RWMB_Clone::add_clone_button( $field ) . static::input_description( $field ) . '</div>';
}

protected static function label_description( array $field ) : string {
protected static function label_description( array $field ): string {
$id = $field['id'] ? ' id="' . esc_attr( $field['id'] ) . '-label-description"' : '';
return $field['label_description'] ? "<p{$id} class='description'>{$field['label_description']}</p>" : '';
}

protected static function input_description( array $field ) : string {
protected static function input_description( array $field ): string {
$id = $field['id'] ? ' id="' . esc_attr( $field['id'] ) . '-description"' : '';
return $field['desc'] ? "<p{$id} class='description'>{$field['desc']}</p>" : '';
}
Expand Down Expand Up @@ -369,7 +369,7 @@ public static function get_attributes( $field, $value = null ) {
return $attributes;
}

public static function render_attributes( array $attributes ) : string {
public static function render_attributes( array $attributes ): string {
$output = '';

$attributes = array_filter( $attributes, 'RWMB_Helpers_Value::is_valid_for_attribute' );
Expand Down
74 changes: 73 additions & 1 deletion inc/fields/choice.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,78 @@
* The abstract choice field.
*/
abstract class RWMB_Choice_Field extends RWMB_Field {

/**
* Show field HTML
* Filters are put inside this method, not inside methods such as "meta", "html", "begin_html", etc.
* That ensures the returned value are always been applied filters.
* This method is not meant to be overwritten in specific fields.
*
* @param array $field Field parameters.
* @param bool $saved Whether the meta box is saved at least once.
* @param int $post_id Post ID.
*/
public static function show( array $field, bool $saved, $post_id = 0 ) {
$meta = self::call( $field, 'meta', $post_id, $saved );
$meta = self::filter( 'field_meta', $meta, $field, $saved );

$meta = self::remove_options_deleted( (array) $meta, $field );
$meta = RWMB_Helpers_Array::array_filter_recursive( $meta );

$begin = static::begin_html( $field );
$begin = self::filter( 'begin_html', $begin, $field, $meta );

// Separate code for cloneable and non-cloneable fields to make easy to maintain.
if ( $field['clone'] ) {
$field_html = RWMB_Clone::html( $meta, $field );
} else {
// Call separated methods for displaying each type of field.
$field_html = self::call( $field, 'html', $meta );
$field_html = self::filter( 'html', $field_html, $field, $meta );
}

$end = static::end_html( $field );
$end = self::filter( 'end_html', $end, $field, $meta );

$html = self::filter( 'wrapper_html', "$begin$field_html$end", $field, $meta );

// Display label and input in DIV and allow user-defined classes to be appended.
$classes = "rwmb-field rwmb-{$field['type']}-wrapper " . $field['class'];
if ( ! empty( $field['required'] ) ) {
$classes .= ' required';
}

$outer_html = sprintf(
$field['before'] . '<div class="%s">%s</div>' . $field['after'],
esc_attr( trim( $classes ) ),
$html
);
$outer_html = self::filter( 'outer_html', $outer_html, $field, $meta );

echo $outer_html; // phpcs:ignore WordPress.Security.EscapeOutput
}

/**
* remove_options_deleted
* @param array $meta Meta value.
* @param array $field Field parameters.
* @return array
*/
private static function remove_options_deleted( array $meta, array $field ): array {
if ( ! isset( $field['options'] ) || empty( $meta ) ) {
return $meta;
}

$options = array_keys( $field['options'] );
array_walk_recursive($meta, function ( &$value ) use ( $options ) {
if ( ! empty( $value ) && ! in_array( $value, $options ) ) {
$value = null;
}
});

return array_filter( $meta );
}

/**
* Get field HTML.
*
Expand Down Expand Up @@ -37,7 +109,7 @@ public static function normalize( $field ) {
return $field;
}

public static function transform_options( $options ) : array {
public static function transform_options( $options ): array {
$transformed = [];
$options = (array) $options;
foreach ( $options as $value => $label ) {
Expand Down
29 changes: 28 additions & 1 deletion inc/helpers/array.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,31 @@
/**
* No longer needed. Keep it here for backward compatibility.
*/
class RWMB_Helpers_Array extends Arr {}
class RWMB_Helpers_Array extends Arr {

/**
* array_filter_recursive
* @link https://gist.github.com/benjamw/1690140
* @param array
* @param string optional callback function name
* @param bool optional flag removal of empty arrays after filtering
* @return array merged array
*/
public static function array_filter_recursive( array $array, callable $callback = null, bool $remove_empty_arrays = false ): array {
foreach ( $array as $key => &$value ) { // mind the reference
if ( is_array( $value ) ) {
$value = call_user_func_array( [ 'self', 'array_filter_recursive' ], array( $value, $callback, $remove_empty_arrays ) );
if ( $remove_empty_arrays && ! (bool) $value ) {
unset( $array[ $key ] );
}
} elseif ( ! is_null( $callback ) && ! $callback( $value ) ) {
unset( $array[ $key ] );
} elseif ( ! (bool) $value ) {
unset( $array[ $key ] );
}
}
unset( $value ); // kill the reference

return array_filter( $array );
}
}