repository = $repository;
$this->types = $types;
$this->categories = $categories;
$this->scanner = $scanner;
$this->replacer = $replacer;
$this->builtins = $builtins ? $builtins : new BuiltinVariables( $types );
$this->value_editor = $value_editor;
}
public function register() {
add_action( 'admin_menu', array( $this, 'menu' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'menu_icon' ) );
add_action( 'admin_post_glovario_save_variable', array( $this, 'save' ) );
add_action( 'admin_post_glovario_delete_variable', array( $this, 'delete' ) );
add_action( 'admin_post_glovario_prepare_delete_variable', array( $this, 'prepare_delete' ) );
add_action( 'admin_post_glovario_migrate_variable_key', array( $this, 'migrate_key' ) );
add_action( 'admin_post_glovario_assign_variable_category', array( $this, 'assign_category' ) );
add_action( 'admin_post_glovario_save_settings', array( $this, 'save_settings' ) );
add_action( 'admin_post_glovario_create_examples', array( $this, 'create_examples' ) );
add_filter( 'plugin_action_links_' . plugin_basename( GLOVARIO_FILE ), array( $this, 'action_links' ) );
}
public function menu() {
// The menu carries the product name, which is never translated; its first item lists the variables.
$this->hook = add_menu_page(
__( 'Site Variables', 'glovario' ),
GLOVARIO_PRODUCT_NAME,
Capabilities::EDIT_VALUES,
'glovario',
array( $this, 'page' ),
'none',
58
);
add_submenu_page( 'glovario', __( 'Site Variables', 'glovario' ), __( 'Site Variables', 'glovario' ), Capabilities::EDIT_VALUES, 'glovario', array( $this, 'page' ) );
}
/**
* The menu shows on every admin screen, so its icon style loads everywhere.
*/
public function menu_icon() {
wp_enqueue_style( 'glovario-menu-icon', GLOVARIO_URL . 'assets/menu-icon.css', array(), GLOVARIO_VERSION );
}
public function assets( $hook ) {
// Every Glovario screen: submenu hooks are named after the menu title, not the slug.
$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only routing.
if ( $hook !== $this->hook && 'glovario' !== $page && 0 !== strpos( $page, 'glovario-' ) ) {
return;
}
$css_modified = filemtime( GLOVARIO_PATH . 'assets/admin.css' );
$js_modified = filemtime( GLOVARIO_PATH . 'assets/admin.js' );
wp_enqueue_style( 'glovario-admin', GLOVARIO_URL . 'assets/admin.css', array(), GLOVARIO_VERSION . ( $css_modified ? '-' . $css_modified : '' ) );
wp_enqueue_script( 'glovario-admin', GLOVARIO_URL . 'assets/admin.js', array(), GLOVARIO_VERSION . ( $js_modified ? '-' . $js_modified : '' ), true );
// Image variables are picked from the Media Library on the edit screens.
if ( isset( $_GET['action'] ) && in_array( $_GET['action'], array( 'add', 'edit' ), true ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput -- Read-only routing compared to fixed values.
wp_enqueue_media();
}
$settings = apply_filters(
'glovario_admin_settings',
array(
'chooseImage' => __( 'Choose image', 'glovario' ),
'changeImage' => __( 'Change image', 'glovario' ),
/* translators: %s: alternative text of the chosen image. */
'altText' => __( 'Alt text: %s', 'glovario' ),
'noAlt' => __( 'No alt text.', 'glovario' ),
'useImage' => __( 'Use this image', 'glovario' ),
'copied' => __( 'Copied', 'glovario' ),
'confirmDelete' => __( 'Delete this item? Existing usages may no longer resolve.', 'glovario' ),
'confirmRestore' => __( 'Revert only the changes recorded in this entry? Later non-conflicting edits will be preserved.', 'glovario' ),
)
);
wp_localize_script(
'glovario-admin',
'glovarioAdminSettings',
$settings
);
}
public function action_links( $links ) {
array_unshift( $links, '' . esc_html__( 'Manage variables', 'glovario' ) . ' ' );
return $links;
}
/**
* Published titles that contain a Site Variable shortcode: their number and
* the first ten, for the warning shown while title integration is off.
*
* @return array{count:int,posts:\WP_Post[]}
*/
public static function titles_with_variables() {
global $wpdb;
$like = '%' . $wpdb->esc_like( '[glvr' ) . '%';
$count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type NOT IN ( 'revision', 'nav_menu_item' ) AND post_title LIKE %s", $like ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$ids = $count ? $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type NOT IN ( 'revision', 'nav_menu_item' ) AND post_title LIKE %s ORDER BY post_date DESC LIMIT 10", $like ) ) : array(); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
return array(
'count' => $count,
'posts' => array_values( array_filter( array_map( 'get_post', $ids ) ) ),
);
}
/**
* Capability check shared by the form handlers; each handler verifies its own nonce.
*/
private function guard() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( esc_html__( 'You do not have permission to manage Site Variables.', 'glovario' ), 403 );
}
}
private function keep_draft( $draft ) {
set_transient( 'glovario_form_draft_' . get_current_user_id(), $draft, 300 );
}
/**
* The values typed before a failed save of this variable, once.
*
* @param int $id Variable ID, 0 for a new variable.
* @return array|null
*/
private function take_draft( $id ) {
$name = 'glovario_form_draft_' . get_current_user_id();
$draft = get_transient( $name );
delete_transient( $name );
return is_array( $draft ) && (int) ( $draft['id'] ?? -1 ) === (int) $id ? $draft : null;
}
private function redirect( $notice, $type = 'success', $args = array() ) {
set_transient(
'glovario_notice_' . get_current_user_id(),
array(
'message' => $notice,
'type' => $type,
),
60
);
$url = add_query_arg( $args, admin_url( 'admin.php?page=glovario' ) );
wp_safe_redirect( $url );
exit;
}
private function notice() {
$key = 'glovario_notice_' . get_current_user_id();
$notice = get_transient( $key );
if ( $notice ) {
delete_transient( $key );
printf( '
', esc_attr( $notice['type'] ), esc_html( $notice['message'] ) );
}
}
public function page() {
if ( ! current_user_can( 'manage_options' ) ) {
if ( $this->value_editor && current_user_can( Capabilities::EDIT_VALUES ) ) {
echo '';
$this->notice();
$this->value_editor->page();
echo '
';
}
return;
}
$action = isset( $_GET['action'] ) ? sanitize_key( wp_unslash( $_GET['action'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
echo '';
$this->notice();
if ( 'add' === $action || 'edit' === $action ) {
$this->form();
} elseif ( 'rename' === $action ) {
$this->key_migration_confirmation();
} elseif ( 'delete' === $action ) {
$this->delete_confirmation();
} else {
$this->listing();
}
echo '
';
}
private function listing() {
$paged = isset( $_GET['glovario_page'] ) ? max( 1, absint( $_GET['glovario_page'] ) ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$category = isset( $_GET['glovario_category'] ) ? sanitize_text_field( wp_unslash( $_GET['glovario_category'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$type = isset( $_GET['glovario_type'] ) ? sanitize_key( wp_unslash( $_GET['glovario_type'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$orderby = isset( $_GET['orderby'] ) ? sanitize_key( wp_unslash( $_GET['orderby'] ) ) : 'label'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$order = isset( $_GET['order'] ) && 'desc' === strtolower( sanitize_text_field( wp_unslash( $_GET['order'] ) ) ) ? 'DESC' : 'ASC'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$query_args = compact( 'search', 'category', 'type', 'orderby', 'order' );
$per_page = 50;
$total = $this->repository->count( $query_args );
$variables = $this->repository->all(
array_merge(
$query_args,
array(
'number' => $per_page,
'offset' => ( $paged - 1 ) * $per_page,
)
)
);
$categories = $this->categories->all();
$return_args = array_merge( array( 'page' => 'glovario' ), $this->public_query_args( $query_args ) );
if ( 1 < $paged ) {
$return_args['glovario_page'] = $paged;
}
$return_url = add_query_arg( $return_args, admin_url( 'admin.php' ) );
?>
creation_prompt();
if ( 0 === $total && '' === $search && '' === $category && '' === $type ) {
$this->onboarding();
}
?>
sortable_heading( __( 'Label', 'glovario' ), 'label', $query_args ); ?>
sortable_heading( __( 'Key', 'glovario' ), 'key', $query_args ); ?>
sortable_heading( __( 'Category', 'glovario' ), 'category', $query_args ); ?>
sortable_heading( __( 'Last updated', 'glovario' ), 'updated_at', $query_args ); ?>
types->all()[ $variable['type'] ]['label'] ?? $variable['type'];
?>
$per_page ) : ?>
str_replace( '999999999', '%#%', add_query_arg( array_merge( $this->public_query_args( $query_args ), array( 'glovario_page' => '999999999' ) ), admin_url( 'admin.php?page=glovario' ) ) ),
'format' => '',
'current' => $paged,
'total' => (int) ceil( $total / $per_page ),
)
)
);
?>
builtin_listing(); ?>
guard();
check_admin_referer( 'glovario_create_examples' );
$created = $this->install_examples();
$this->redirect(
sprintf(
/* translators: %d: number of example variables created. */
_n( '%d example variable created. Edit it to match your site.', '%d example variables created. Edit them to match your site.', $created, 'glovario' ),
$created
)
);
}
/**
* Create the example variables that do not exist yet, in an "Examples" category.
*
* @return int Number of variables created.
*/
public function install_examples() {
$name = __( 'Examples', 'glovario' );
$category = null;
foreach ( $this->categories->all() as $existing ) {
if ( sanitize_title( $name ) === $existing['slug'] ) {
$category = $existing;
}
}
$category = $category ? $category : $this->categories->insert( array( 'name' => $name ) );
$created = 0;
foreach ( $this->example_variables() as $example ) {
list( $key, $label, $type, $value ) = $example;
if ( $this->repository->find_by_key( $key ) ) {
continue;
}
$result = $this->repository->insert(
array(
'variable_key' => $key,
'label' => $label,
'type' => $type,
'value' => $this->types->sanitize( $value, $type ),
'description' => __( 'Example created by the first-run guide. Edit or delete it at any time.', 'glovario' ),
'category_id' => is_wp_error( $category ) ? 0 : $category['id'],
)
);
if ( ! is_wp_error( $result ) ) {
++$created;
}
}
return $created;
}
private function creation_prompt() {
$created_id = isset( $_GET['glovario_created'] ) ? absint( $_GET['glovario_created'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$variable = $created_id ? $this->repository->find( $created_id ) : null;
if ( ! $variable || '' === (string) $variable['value'] || 'image' === $variable['type'] ) {
return;
}
$url = add_query_arg(
array(
'page' => 'glovario-content-conversion',
'variable_id' => $variable['id'],
),
admin_url( 'admin.php' )
);
?>
builtins->all();
if ( ! $variables ) {
return;
}
$types = $this->types->all();
?>
'glovario-usage',
'variable_key' => $variable['variable_key'],
),
admin_url( 'admin.php' )
);
?>
' . esc_html__( '(empty)', 'glovario' ) . '' : esc_html( wp_html_excerpt( $variable['value'], 80, '…' ) ); ?>
[glvr key="glovario_builtin_current_date" format="full"] or {{glvr:glovario_builtin_current_date|format=full}}. The block provides a Date format selector.', 'glovario' ) ); ?>
repository->find( $id ) : null;
if ( ! $variable ) {
echo '' . esc_html__( 'Variable not found.', 'glovario' ) . ' ';
return;
}
$matches = $this->scanner->matches( $variable['variable_key'] );
$total = count( $matches );
$sample = $matches ? reset( $matches ) : null;
?>
)~i';
$class = 'glovario-delete-highlight glovario-delete-highlight--reference';
} elseif ( 'keep' === $strategy ) {
$pattern = '~(\{\{glvr:\s*' . $key . '(?:\|format=[a-z]+)?\s*\}\}|\[glvr\b[^\]]*\bkey\s*=\s*"' . $key . '"[^\]]*\]|\[glvr\b[^\]]*\bkey\s*=\s*\'' . $key . '\'[^\]]*\]|)~i';
$class = 'glovario-delete-highlight glovario-delete-highlight--dead';
} elseif ( 'empty' === $strategy ) {
return esc_html( $text );
} else {
$pattern = '~(' . preg_quote( ReferenceReplacementService::PREVIEW_START, '~' ) . '.*?' . preg_quote( ReferenceReplacementService::PREVIEW_END, '~' ) . ')~u';
$class = 'glovario-delete-highlight glovario-delete-highlight--replacement';
$strip_markers = true;
}
$parts = preg_split( $pattern, (string) $text, -1, PREG_SPLIT_DELIM_CAPTURE );
if ( false === $parts ) {
return esc_html( $text );
}
$html = '';
foreach ( $parts as $index => $part ) {
if ( 1 === $index % 2 ) {
if ( $strip_markers ) {
$part = str_replace( array( ReferenceReplacementService::PREVIEW_START, ReferenceReplacementService::PREVIEW_END ), '', $part );
}
$html .= '' . esc_html( $part ) . ' ';
} else {
$html .= esc_html( $part );
}
}
return $html;
}
public function prepare_delete() {
$this->guard();
$id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0;
check_admin_referer( 'glovario_delete_variable_' . $id );
$variable = $id ? $this->repository->find( $id ) : null;
if ( ! $variable ) {
$this->redirect( __( 'Variable not found.', 'glovario' ), 'error' );
}
if ( ! $this->scanner->matches( $variable['variable_key'] ) ) {
if ( ! $this->repository->delete( $id ) ) {
$this->redirect( __( 'The variable could not be deleted.', 'glovario' ), 'error' );
}
$this->redirect( __( 'Unused variable deleted.', 'glovario' ) );
}
wp_safe_redirect(
add_query_arg(
array(
'page' => 'glovario',
'action' => 'delete',
'id' => $id,
),
admin_url( 'admin.php' )
)
);
exit;
}
private function sortable_heading( $label, $column, $query_args ) {
$current = $query_args['orderby'] === $column;
$next = $current && 'ASC' === $query_args['order'] ? 'desc' : 'asc';
$url = add_query_arg(
array_merge(
$this->public_query_args( $query_args ),
array(
'orderby' => $column,
'order' => $next,
)
),
admin_url( 'admin.php?page=glovario' )
);
$class = 'manage-column sortable ' . ( $current ? 'sorted ' . strtolower( $query_args['order'] ) : 'desc' );
echo '' . esc_html( $label ) . ' ';
}
private function public_query_args( $query_args ) {
return array_filter(
array(
's' => $query_args['search'],
'glovario_category' => $query_args['category'],
'glovario_type' => $query_args['type'],
'orderby' => $query_args['orderby'],
'order' => strtolower( $query_args['order'] ),
),
static function ( $value ) {
return '' !== $value;
}
);
}
private function form() {
$id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$variable = $id ? $this->repository->find( $id ) : null;
if ( $id && ! $variable ) {
$this->redirect( __( 'Variable not found.', 'glovario' ), 'error' );
}
$variable = $variable ? $variable : array(
'id' => 0,
'label' => '',
'variable_key' => '',
'type' => 'text',
'value' => '',
'description' => '',
'category_id' => 0,
);
$draft = $this->take_draft( $id );
if ( $draft ) {
$variable = array_merge( $variable, array_intersect_key( $draft, array_flip( array( 'label', 'variable_key', 'type', 'value', 'description', 'category_id' ) ) ) );
}
?>
guard();
check_admin_referer( 'glovario_save_variable' );
$id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0;
$existing = $id ? $this->repository->find( $id ) : null;
$raw_key = $existing ? $existing['variable_key'] : ( isset( $_POST['variable_key'] ) ? strtolower( trim( wp_unslash( $_POST['variable_key'] ) ) ) : '' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Strictly validated and passed through sanitize_key below.
$label = isset( $_POST['label'] ) ? sanitize_text_field( wp_unslash( $_POST['label'] ) ) : '';
if ( ! $existing && '' === $raw_key && '' !== $label ) {
// An empty key on a new variable is generated from the label, as in Make variable.
$raw_key = VariableKey::from_label( $label, $this->repository );
}
$key = sanitize_key( $raw_key );
$type = isset( $_POST['type'] ) ? sanitize_key( wp_unslash( $_POST['type'] ) ) : '';
$raw_value = isset( $_POST['value'] ) ? wp_unslash( $_POST['value'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated and sanitized according to selected type below.
$description = isset( $_POST['description'] ) ? sanitize_textarea_field( wp_unslash( $_POST['description'] ) ) : '';
$category_id = isset( $_POST['category_id'] ) ? absint( $_POST['category_id'] ) : 0;
if ( $category_id && ! $this->categories->find( $category_id ) ) {
$category_id = 0;
}
$back = $id ? array(
'action' => 'edit',
'id' => $id,
) : array( 'action' => 'add' );
// On an error the form comes back with what was typed.
$draft = array(
'id' => $id,
'label' => $label,
'variable_key' => $existing ? $existing['variable_key'] : ( isset( $_POST['variable_key'] ) ? sanitize_text_field( wp_unslash( $_POST['variable_key'] ) ) : '' ),
'type' => $type,
'value' => $raw_value,
'description' => $description,
'category_id' => $category_id,
);
if ( '' === $label || '' === $key || ! preg_match( '/^[a-z0-9_-]+$/', $raw_key ) || $key !== $raw_key ) {
$this->keep_draft( $draft );
$this->redirect( __( 'Enter a label and a valid key using lowercase letters, numbers, hyphens, or underscores.', 'glovario' ), 'error', $back );
}
$validation = $this->types->validate( $raw_value, $type );
if ( is_wp_error( $validation ) ) {
$this->keep_draft( $draft );
$this->redirect( $validation->get_error_message(), 'error', $back );
}
$value = $this->types->sanitize( $raw_value, $type );
$data = compact( 'label', 'type', 'value', 'description', 'category_id' );
$data['variable_key'] = $key;
$result = $id ? $this->repository->update( $id, $data ) : $this->repository->insert( $data );
if ( is_wp_error( $result ) ) {
$this->keep_draft( $draft );
$this->redirect( $result->get_error_message(), 'error', $back );
}
/**
* Filters where the administrator lands after saving a variable
* (query arguments for the Site Variables screen).
*
* @param array $args Query arguments; empty for the list.
* @param array $variable Saved variable.
* @param bool $created Whether the variable is new.
*/
$args = apply_filters( 'glovario_variable_saved_redirect_args', $id ? array() : array( 'glovario_created' => $result['id'] ), $result, ! $id );
$this->redirect(
$id ? __( 'Variable updated.', 'glovario' ) : __( 'Variable created.', 'glovario' ),
'success',
$args
);
}
private function key_migration_confirmation() {
$id = isset( $_GET['id'] ) ? absint( $_GET['id'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing; nothing is changed.
$variable = $id ? $this->repository->find( $id ) : null;
if ( ! $variable ) {
echo '' . esc_html__( 'Variable not found.', 'glovario' ) . ' ';
return;
}
$matches = $this->scanner->matches( $variable['variable_key'] );
?>
:
guard();
$id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0;
check_admin_referer( 'glovario_migrate_variable_key_' . $id );
$variable = $id ? $this->repository->find( $id ) : null;
$new_raw = isset( $_POST['new_key'] ) ? strtolower( trim( wp_unslash( $_POST['new_key'] ) ) ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Strict validation follows.
$new_key = sanitize_key( $new_raw );
$old_key = isset( $_POST['old_key'] ) ? sanitize_key( wp_unslash( $_POST['old_key'] ) ) : '';
if ( ! $variable || $variable['variable_key'] !== $old_key ) {
$this->redirect( __( 'The variable key changed after the review. Start the migration again.', 'glovario' ), 'error' );
}
if ( ! isset( $_POST['confirm_migration'] ) || '' === $new_key || $new_key !== $new_raw || ! preg_match( '/^[a-z0-9_-]+$/', $new_raw ) || $new_key === $old_key || BuiltinVariables::is_reserved_key( $new_key ) || $this->repository->find_by_key( $new_key ) ) {
$this->redirect(
__( 'Enter a different, unique key using lowercase letters, numbers, hyphens, or underscores, and confirm the reviewed migration.', 'glovario' ),
'error',
array(
'action' => 'rename',
'id' => $id,
)
);
}
$matches = $this->scanner->matches( $old_key );
$posted = isset( $_POST['reference_fingerprint'] ) ? sanitize_text_field( wp_unslash( $_POST['reference_fingerprint'] ) ) : '';
if ( ! hash_equals( $this->reference_fingerprint( $matches ), $posted ) ) {
$this->redirect(
__( 'Detected references changed after the review. Review the updated locations before migrating.', 'glovario' ),
'error',
array(
'action' => 'rename',
'id' => $id,
)
);
}
$result = $this->replacer->migrate_key(
$variable,
$new_key,
$matches,
function () use ( $id, $variable, $new_key ) {
$updated = $variable;
$updated['variable_key'] = $new_key;
return $this->repository->update( $id, $updated );
}
);
if ( is_wp_error( $result ) ) {
$this->redirect(
$result->get_error_message(),
'error',
array(
'action' => 'rename',
'id' => $id,
)
);
}
$this->redirect( __( 'Variable key and detected references migrated.', 'glovario' ) );
}
private function reference_fingerprint( $matches ) {
$locations = array();
foreach ( $matches as $match ) {
$locations[] = array(
'storage' => $match['storage'] ?? $match['kind'],
'id' => absint( $match['id'] ?? 0 ),
'rule_id' => absint( $match['rule_id'] ?? 0 ),
);
}
return hash( 'sha256', wp_json_encode( $locations ) );
}
public function delete() {
$this->guard();
$id = isset( $_POST['id'] ) ? absint( $_POST['id'] ) : 0;
check_admin_referer( 'glovario_delete_variable_' . $id );
$variable = $id ? $this->repository->find( $id ) : null;
if ( ! $variable ) {
$this->redirect( __( 'Variable not found.', 'glovario' ), 'error' );
}
$matches = $this->scanner->matches( $variable['variable_key'] );
$strategy = isset( $_POST['delete_strategy'] ) ? sanitize_key( wp_unslash( $_POST['delete_strategy'] ) ) : '';
if ( $matches && ! in_array( $strategy, array( 'keep', 'value', 'empty' ), true ) ) {
$this->redirect(
__( 'Choose how to handle detected references.', 'glovario' ),
'error',
array(
'action' => 'delete',
'id' => $id,
)
);
}
if ( $matches && in_array( $strategy, array( 'value', 'empty' ), true ) ) {
$result = $this->replacer->replace(
$variable,
$matches,
$strategy,
function () use ( $id ) {
return $this->repository->delete( $id ) ? true : new \WP_Error( 'delete_failed', __( 'The variable could not be deleted.', 'glovario' ) );
}
);
if ( is_wp_error( $result ) ) {
$this->redirect(
$result->get_error_message(),
'error',
array(
'action' => 'delete',
'id' => $id,
)
);
}
$this->redirect( __( 'Variable deleted.', 'glovario' ) );
}
if ( ! $id || ! $this->repository->delete( $id ) ) {
$this->redirect( __( 'The variable could not be deleted.', 'glovario' ), 'error' );
}
$this->redirect( __( 'Variable deleted.', 'glovario' ) );
}
public function assign_category() {
$this->guard();
$id = isset( $_POST['variable_id'] ) ? absint( $_POST['variable_id'] ) : 0;
check_admin_referer( 'glovario_assign_variable_category_' . $id );
$variable = $id ? $this->repository->find( $id ) : null;
$category_id = isset( $_POST['category_id'] ) ? absint( $_POST['category_id'] ) : 0;
$return_url = isset( $_POST['return_to'] ) ? wp_validate_redirect( esc_url_raw( wp_unslash( $_POST['return_to'] ) ), admin_url( 'admin.php?page=glovario' ) ) : admin_url( 'admin.php?page=glovario' );
if ( ! $variable ) {
$this->redirect_to( $return_url, __( 'Variable not found.', 'glovario' ), 'error' );
}
if ( $category_id && ! $this->categories->find( $category_id ) ) {
$this->redirect_to( $return_url, __( 'Select a valid variable category.', 'glovario' ), 'error' );
}
$result = $this->repository->assign_category( $id, $category_id );
if ( is_wp_error( $result ) ) {
$this->redirect_to( $return_url, $result->get_error_message(), 'error' );
}
$this->redirect_to( $return_url, __( 'Variable category updated.', 'glovario' ) );
}
public function save_settings() {
$this->guard();
check_admin_referer( 'glovario_save_settings' );
update_option( TitleShortcodes::OPTION, isset( $_POST['title_shortcodes'] ) ? '1' : '0', true ); // Read on every front-end request.
update_option( 'glovario_delete_on_uninstall', isset( $_POST['delete_on_uninstall'] ) ? '1' : '0', false );
$this->redirect( __( 'Settings saved.', 'glovario' ) );
}
private function redirect_to( $url, $notice, $type = 'success' ) {
set_transient(
'glovario_notice_' . get_current_user_id(),
array(
'message' => $notice,
'type' => $type,
),
60
);
wp_safe_redirect( $url );
exit;
}
}