'array', 'sanitize_callback' => 'sahcs_sanitize_settings', 'default' => sahcs_default_settings(), ]); }); add_filter('plugin_action_links_' . plugin_basename(SAHCS_FILE), function ($links) { array_unshift($links, '' . esc_html__('Settings', 'siteaudithub-case-studies') . ''); return $links; }); add_action('admin_enqueue_scripts', function ($hook) { $screen = get_current_screen(); $is_settings = !empty($GLOBALS['sahcs_settings_hook']) && $hook === $GLOBALS['sahcs_settings_hook']; $is_list = $screen && $screen->id === 'edit-' . SAHCS_CPT; if (!$is_settings && !$is_list) { return; } wp_enqueue_style('sahcs-admin', SAHCS_URL . 'assets/css/admin.css', [], sahcs_asset_ver('assets/css/admin.css')); wp_enqueue_script('sahcs-admin', SAHCS_URL . 'assets/js/admin.js', ['jquery', 'wp-color-picker', 'wp-i18n'], sahcs_asset_ver('assets/js/admin.js'), true); wp_set_script_translations('sahcs-admin', 'siteaudithub-case-studies', SAHCS_PATH . 'languages'); $data = [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('sahcs_preview'), 'presets' => sahcs_design_presets(), 'i18n' => [ 'copied' => __('Copied!', 'siteaudithub-case-studies'), 'copy' => __('Copy', 'siteaudithub-case-studies'), 'error' => __('Preview could not be loaded.', 'siteaudithub-case-studies'), ], ]; if ($is_settings) { wp_enqueue_style('wp-color-picker'); sahcs_enqueue_front(); } wp_localize_script('sahcs-admin', 'sahcsAdmin', $data); }); /* ------------------------------------------------------------------ * Settings page * ---------------------------------------------------------------- */ function sahcs_settings_tabs() { return [ 'general' => __('General', 'siteaudithub-case-studies'), 'design' => __('Design', 'siteaudithub-case-studies'), 'shortcodes' => __('Shortcodes', 'siteaudithub-case-studies'), ]; } function sahcs_render_settings_page() { if (!current_user_can('manage_options')) { return; } $tabs = sahcs_settings_tabs(); $tab = isset($_GET['tab']) ? sanitize_key(wp_unslash($_GET['tab'])) : 'general'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- tab switch only if (!isset($tabs[$tab])) { $tab = 'general'; } $s = sahcs_fresh_settings(); $base_url = admin_url('edit.php?post_type=' . SAHCS_CPT . '&page=sahcs-settings'); ?>

['label' => __('Main colour', 'siteaudithub-case-studies'), 'preset' => 'primary', 'help' => __('Buttons, links and highlights', 'siteaudithub-case-studies')], 'color_accent' => ['label' => __('Second colour', 'siteaudithub-case-studies'), 'preset' => 'accent', 'help' => __('Gradients and small accents', 'siteaudithub-case-studies')], 'color_heading' => ['label' => __('Headings', 'siteaudithub-case-studies'), 'preset' => 'heading', 'help' => ''], 'color_text' => ['label' => __('Text', 'siteaudithub-case-studies'), 'preset' => 'text', 'help' => ''], 'color_bg' => ['label' => __('Page background', 'siteaudithub-case-studies'), 'preset' => 'bg', 'help' => ''], 'color_card' => ['label' => __('Card background', 'siteaudithub-case-studies'), 'preset' => 'card', 'help' => ''], ]; ?>

$p) : ?>

__('Detect automatically', 'siteaudithub-case-studies'), 'light' => __('Light', 'siteaudithub-case-studies'), 'dark' => __('Dark', 'siteaudithub-case-studies'), ]; foreach ($tones as $key => $label) : ?>

$c) : ?>

2.9%

+107%

$74

+28%

SAHCS_CPT, 'post_status' => 'publish', 'posts_per_page' => 200, 'orderby' => 'title', 'order' => 'ASC', ]); $terms = get_terms(['taxonomy' => SAHCS_TAX, 'hide_empty' => false]); $sections = [ 'results' => __('Results', 'siteaudithub-case-studies'), 'testimonial' => __('Testimonial', 'siteaudithub-case-studies'), 'gallery' => __('Gallery', 'siteaudithub-case-studies'), 'key-facts' => __('Key facts', 'siteaudithub-case-studies'), 'glance' => __('At a glance', 'siteaudithub-case-studies'), 'faq' => __('FAQ', 'siteaudithub-case-studies'), 'hero' => __('Hero', 'siteaudithub-case-studies'), 'overview' => __('Overview', 'siteaudithub-case-studies'), 'challenges' => __('Challenges', 'siteaudithub-case-studies'), 'solutions' => __('Solutions', 'siteaudithub-case-studies'), 'conclusion' => __('Conclusion', 'siteaudithub-case-studies'), 'cta' => __('Call to action', 'siteaudithub-case-studies'), ]; ?>




' . esc_html__('Nothing to show yet: publish a case study or change the options.', 'siteaudithub-case-studies') . '

'; } wp_send_json_success(['html' => $html]); }); /* ------------------------------------------------------------------ * "Shortcode" column in the case studies list * ---------------------------------------------------------------- */ add_filter('manage_' . SAHCS_CPT . '_posts_columns', function ($cols) { $new = []; foreach ($cols as $k => $v) { $new[$k] = $v; if ($k === 'title') { $new['sahcs_shortcode'] = __('Shortcode', 'siteaudithub-case-studies'); } } return $new; }); add_action('manage_' . SAHCS_CPT . '_posts_custom_column', function ($col, $post_id) { if ($col !== 'sahcs_shortcode') { return; } $code = '[sahcs_card id="' . (int) $post_id . '"]'; echo '' . esc_html($code) . ' '; }, 10, 2); /* ------------------------------------------------------------------ * Duplicate a case study * ------------------------------------------------------------------ */ /** Link to make a draft copy of a case study (with a security token). */ function sahcs_duplicate_url($post_id) { return wp_nonce_url(admin_url('admin-post.php?action=sahcs_duplicate&post=' . (int) $post_id), 'sahcs_duplicate_' . (int) $post_id); } /** Whether the current user may copy this case study. */ function sahcs_can_duplicate($post) { $type = get_post_type_object(SAHCS_CPT); return $post && $post->post_type === SAHCS_CPT && $type && current_user_can('edit_post', $post->ID) && current_user_can($type->cap->create_posts); } add_filter('post_row_actions', function ($actions, $post) { if (!sahcs_can_duplicate($post) || $post->post_status === 'trash') { return $actions; } /* translators: %s: case study title */ $label = sprintf(__('Duplicate “%s”', 'siteaudithub-case-studies'), wp_strip_all_tags(get_the_title($post))); $link = '' . esc_html__('Duplicate', 'siteaudithub-case-studies') . ''; // Show it right after "Quick Edit". $out = []; foreach ($actions as $key => $html) { $out[$key] = $html; if ($key === 'inline hide-if-no-js') { $out['sahcs_duplicate'] = $link; } } if (!isset($out['sahcs_duplicate'])) { $out['sahcs_duplicate'] = $link; } return $out; }, 10, 2); /** * Makes a draft copy: content (all sections), excerpt, featured image, * categories and other settings such as SEO plugin fields. * Returns the new post ID or a WP_Error. */ function sahcs_duplicate_case_study($post_id) { $post = get_post($post_id); if (!$post || $post->post_type !== SAHCS_CPT) { return new WP_Error('sahcs_not_found', __('Case study not found.', 'siteaudithub-case-studies')); } $new_id = wp_insert_post(wp_slash([ 'post_type' => SAHCS_CPT, 'post_status' => 'draft', /* translators: %s: original case study title */ 'post_title' => sprintf(__('%s (Copy)', 'siteaudithub-case-studies'), $post->post_title), 'post_content' => $post->post_content, 'post_excerpt' => $post->post_excerpt, 'post_author' => get_current_user_id(), 'post_parent' => $post->post_parent, 'menu_order' => $post->menu_order, 'comment_status' => $post->comment_status, 'ping_status' => $post->ping_status, ]), true); if (is_wp_error($new_id)) { return $new_id; } // Categories and any other taxonomies. // Multilingual plugins keep translation links in their own taxonomies // (Polylang: post_translations); a copy must not join that group. $skip_tax = apply_filters('sahcs_duplicate_skip_taxonomies', ['post_translations', 'term_translations']); foreach (array_diff(get_object_taxonomies(SAHCS_CPT), $skip_tax) as $tax) { $terms = wp_get_object_terms($post->ID, $tax, ['fields' => 'ids']); if (!is_wp_error($terms) && $terms) { wp_set_object_terms($new_id, array_map('intval', $terms), $tax); } } // Settings stored with the case study (featured image, table of contents, // SEO plugin fields…). WordPress's own bookkeeping fields are skipped. $skip = ['_edit_lock', '_edit_last', '_wp_old_slug', '_wp_old_date', '_pingme', '_encloseme', '_wp_trash_meta_status', '_wp_trash_meta_time', '_wp_desired_post_slug', '_sahcs_highlight']; foreach (get_post_meta($post->ID) as $key => $values) { if (in_array($key, $skip, true) || preg_match('/^_(icl|wpml)_/', $key)) { continue; // WordPress / WPML bookkeeping } delete_post_meta($new_id, $key); foreach ($values as $value) { add_post_meta($new_id, $key, wp_slash(maybe_unserialize($value))); } } // Recalculate the card highlight from the copied Results section. if (function_exists('sahcs_find_highlight')) { $highlight = sahcs_find_highlight($post->post_content); if ($highlight) { update_post_meta($new_id, '_sahcs_highlight', wp_slash($highlight)); } } /** Fires after a case study has been copied. */ do_action('sahcs_duplicated', $new_id, $post->ID); return $new_id; } add_action('admin_post_sahcs_duplicate', function () { $post_id = isset($_GET['post']) ? absint($_GET['post']) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- the ID names the nonce, which is verified on the next line check_admin_referer('sahcs_duplicate_' . $post_id); if (!sahcs_can_duplicate(get_post($post_id))) { wp_die(esc_html__('Sorry, you are not allowed to copy this case study.', 'siteaudithub-case-studies'), '', ['response' => 403, 'back_link' => true]); } $new_id = sahcs_duplicate_case_study($post_id); if (is_wp_error($new_id)) { wp_die(esc_html($new_id->get_error_message()), '', ['back_link' => true]); } wp_safe_redirect(admin_url('post.php?action=edit&post=' . (int) $new_id . '&sahcs_duplicated=1')); exit; });