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( '

%2$s

', 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(); } ?>
types->all()[ $variable['type'] ]['label'] ?? $variable['type']; ?>
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 ); ?>
$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; } }