| Server IP : 65.108.144.40 / Your IP : 216.73.217.165 Web Server : Apache/2.4.52 (Ubuntu) System : Linux ubuntu-8gb-hel1-1 5.15.0-173-generic #183-Ubuntu SMP Fri Mar 6 13:29:34 UTC 2026 x86_64 User : dev ( 1000) PHP Version : 8.2.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /var/www/html/successkpi/wp-content/themes/successkpi/inc/ |
Upload File : |
<?php
/**
* Helper / Utility Functions
*
* General-purpose helpers used across the theme, blocks, and other inc/ files.
* Keep functions small, focused, and prefix them with sk_ to avoid conflicts.
*/
// ─────────────────────────────────────────────────────────────────────────────
// Theme Setup
// ─────────────────────────────────────────────────────────────────────────────
/**
* Enable core WordPress theme features.
*/
function sk_theme_setup()
{
add_theme_support('post-thumbnails');
add_theme_support('custom-logo');
}
add_action('after_setup_theme', 'sk_theme_setup');
// ─────────────────────────────────────────────────────────────────────────────
// Upload Permissions
// ─────────────────────────────────────────────────────────────────────────────
/**
* Allow SVG file uploads.
*/
function sk_allow_svg_upload($mimes)
{
$mimes['svg'] = 'image/svg+xml';
return $mimes;
}
add_filter('upload_mimes', 'sk_allow_svg_upload');
/**
* Allow WebP file uploads.
*/
function sk_allow_webp_uploads($mimes)
{
$mimes['webp'] = 'image/webp';
return $mimes;
}
add_filter('upload_mimes', 'sk_allow_webp_uploads');
/**
* Allow JSON file uploads.
*/
function sk_allow_json_uploads($mimes)
{
$mimes['json'] = 'application/json';
return $mimes;
}
add_filter('upload_mimes', 'sk_allow_json_uploads');
/**
* Grant unfiltered_upload capability to administrators.
*/
add_filter('user_has_cap', function ($allcaps, $cap, $args) {
if ($args[0] === 'upload_files' && current_user_can('administrator')) {
$allcaps['unfiltered_upload'] = true;
}
return $allcaps;
}, 10, 3);
// ─────────────────────────────────────────────────────────────────────────────
// Post View Tracking
// ─────────────────────────────────────────────────────────────────────────────
/**
* Track post view counts via post meta.
* Fires on wp_head for singular post/page/CPT views.
*/
function sk_track_post_views()
{
if (! is_singular()) return;
global $post;
$views = (int) get_post_meta($post->ID, 'post_views_count', true);
update_post_meta($post->ID, 'post_views_count', $views + 1);
}
add_action('wp_head', 'sk_track_post_views');
// ─────────────────────────────────────────────────────────────────────────────
// Social Share Shortcode
// ─────────────────────────────────────────────────────────────────────────────
/**
* Outputs social share buttons.
* Usage: [social_share]
*/
function sk_dynamic_social_share_shortcode()
{
$post_url = urlencode(get_permalink());
$post_title = urlencode(get_the_title());
ob_start(); ?>
<div class="custom-social-share">
<a href="https://www.facebook.com/sharer/sharer.php?u=<?php echo $post_url; ?>"
target="_blank" aria-label="Share on Facebook">
<i class="fab fa-facebook-f"></i>
</a>
<a href="https://twitter.com/intent/tweet?url=<?php echo $post_url; ?>&text=<?php echo $post_title; ?>"
target="_blank" aria-label="Share on Twitter">
<i class="fab fa-twitter"></i>
</a>
<a href="https://www.linkedin.com/sharing/share-offsite/?url=<?php echo $post_url; ?>"
target="_blank" aria-label="Share on LinkedIn">
<i class="fab fa-linkedin-in"></i>
</a>
<a href="mailto:?subject=<?php echo $post_title; ?>&body=<?php echo $post_url; ?>"
aria-label="Share via Email">
<i class="fas fa-envelope"></i>
</a>
</div>
<?php
return ob_get_clean();
}
add_shortcode('social_share', 'sk_dynamic_social_share_shortcode');
// ─────────────────────────────────────────────────────────────────────────────
// Block Preview Images
// ─────────────────────────────────────────────────────────────────────────────
/**
* Resolve preview image URL for block previews (admin only).
*/
function sk_resolve_preview_image_url($preview_image)
{
if (strpos($preview_image, 'http://') === 0 || strpos($preview_image, 'https://') === 0) {
return $preview_image;
}
return get_theme_file_uri('/' . ltrim($preview_image, '/'));
}
/**
* Render block preview image in the editor.
* Returns true if preview was rendered, false otherwise.
*/
function sk_render_block_preview_image($block, $alt_text)
{
if (! is_admin()) return false;
$preview = '';
if (! empty($block['data']['preview_image'])) {
$preview = $block['data']['preview_image'];
} elseif (! empty($block['example']['attributes']['data']['preview_image'])) {
$preview = $block['example']['attributes']['data']['preview_image'];
}
if ($preview) {
echo '<img src="' . esc_url(sk_resolve_preview_image_url($preview)) . '" style="width:100%; height:auto;" alt="' . esc_attr($alt_text) . '" />';
return true;
}
return false;
}
add_filter('styles_inline_size_limit', '__return_zero');
// ─────────────────────────────────────────────────────────────────────────────
// Greenhouse Jobs API
// ─────────────────────────────────────────────────────────────────────────────
/**
* Fetch jobs from Greenhouse API for SuccessKPI.
*/
function success_greenhouse_jobs()
{
$token = 'successkpiinc';
return file_get_contents('https://boards-api.greenhouse.io/v1/boards/' . $token . '/jobs?content=true');
}
// ─────────────────────────────────────────────────────────────────────────────
// ACF Post Type Choices (shared by acf.php and ajax.php)
// ─────────────────────────────────────────────────────────────────────────────
/**
* Returns compiled metadata for resource post types (labels and play button status).
* Avoids repeating loops in multiple blocks and AJAX handlers.
*
* @return array
*/
function sk_get_resource_metadata()
{
static $metadata = null;
if ($metadata !== null) return $metadata;
$config = sk_get_resource_cpts();
$labels = array('post' => 'Blog');
$play_buttons = array();
foreach ($config as $slug => $data) {
$labels[$slug] = $data['singular'];
if (! empty($data['has_play_btn'])) {
$play_buttons[] = $slug;
}
}
$metadata = array(
'labels' => $labels,
'play_buttons' => $play_buttons,
'all_slugs' => array_keys($labels),
);
return $metadata;
}
/**
* Returns a key => label map of all allowed post types (blog + resource CPTs).
* Used by ACF field loaders and AJAX handlers.
*
* @return array
*/
function sk_get_acf_post_type_choices()
{
$choices = array('post' => 'Blog (Posts)');
foreach (sk_get_resource_cpts() as $slug => $cpt) {
$choices[$slug] = $cpt['plural'];
}
return $choices;
}
/**
* Renders a single resource card for the all-resources-with-filters-block.
* Used by both index.php (initial load) and ajax.php (filtering).
*
* @param int $post_id The post ID.
* @param array $type_label_map Map of post_type => singular label.
* @param array $cta_map Map of post_type => default CTA text.
* @param array $play_btn_types List of post types that show a play button.
*/
function sk_render_all_resources_card($post_id, $type_label_map = array(), $cta_map = array(), $play_btn_types = array())
{
$post_type = get_post_type($post_id);
if ($post_type === 'post') {
$type_label = 'Blog';
} elseif ($post_type === 'webinars') {
$field = get_field_object('webinar_event_type', $post_id);
if (
! empty($field['value']) &&
! empty($field['choices'][$field['value']])
) {
$type_label = $field['choices'][$field['value']];
} else {
$type_label = $type_label_map['webinars'] ?? 'Unknown Webinar Type';
}
} else {
$type_label = isset($type_label_map[$post_type]) ? $type_label_map[$post_type] : ucfirst($post_type);
}
$show_play_btn = in_array($post_type, $play_btn_types, true);
//cta logic for webinars rest is same as acf approach
if ($post_type === 'webinars') {
$cta_text = get_field('card_cta', $post_id);
if (empty($cta_text)) {
$cta_text = 'Watch Now';
}
} else {
$cta_text = get_field('resource_cta_text', $post_id);
if (empty($cta_text)) {
$cta_text = isset($cta_map[$post_type])
? $cta_map[$post_type]
: 'Read More';
}
}
$ext_url = get_field('resource_external_url', $post_id);
$card_url = ! empty($ext_url) ? esc_url($ext_url) : esc_url(get_permalink($post_id));
$r_terms_raw = get_the_terms($post_id, 'resource_category');
$r_terms = (! is_wp_error($r_terms_raw) && ! empty($r_terms_raw)) ? array_values($r_terms_raw) : array();
$data_category = ! empty($r_terms) ? $r_terms[0]->slug : '';
$thumb_url = get_the_post_thumbnail_url($post_id, 'medium_large');
$thumb_alt = get_the_title($post_id);
$excerpt = get_the_excerpt($post_id);
?>
<div class="resource-card" data-type="<?php echo esc_attr($post_type); ?>" data-category="<?php echo esc_attr($data_category); ?>">
<a href="<?php echo $card_url; ?>" class="card-thumb-link">
<div class="card-thumb">
<?php if ($thumb_url) : ?>
<img src="<?php echo esc_url($thumb_url); ?>" alt="<?php echo esc_attr($thumb_alt); ?>" loading="lazy" />
<?php else : ?>
<img src="<?php echo esc_url(get_template_directory_uri() . '/assets/images/resource-placeholder.jpg'); ?>" alt="<?php echo esc_attr($thumb_alt); ?>" loading="lazy" />
<?php endif; ?>
<?php if ($show_play_btn) : ?>
<div class="card-play-btn">
<div class="card-play-btn__icon"></div>
</div>
<?php endif; ?>
</div>
</a>
<div class="card-body">
<a href="<?php echo $card_url; ?>" class="event-button resource-type-tag <?php echo esc_attr($post_type); ?>"><?php echo esc_html($type_label); ?></a>
<h3 class="card-title">
<a href="<?php echo $card_url; ?>"><?php echo get_the_title($post_id); ?></a>
</h3>
<?php if ($excerpt) : ?>
<p class="card-desc paragraph"><?php echo esc_html($excerpt); ?></p>
<?php endif; ?>
<a href="<?php echo $card_url; ?>" class="card-read-more"><?php echo esc_html($cta_text); ?></a>
</div>
</div>
<?php
}
add_action('admin_menu', function () {
global $menu;
$media = $menu[10];
unset($menu[10]);
$menu[25] = $media;
});
/**
* Remove default WP category support from posts
*/
add_action('init', function () {
unregister_taxonomy_for_object_type(
'category',
'post'
);
}, 100);
/**
* Global fallback ALT text
* Uses attachment title if ALT is missing
*/
function sk_start_output_buffer() {
! is_admin() ? ob_start( 'sk_fix_empty_image_alt' ) : null;
}
add_action( 'template_redirect', 'sk_start_output_buffer' );
/**
* Resolve attachment ID from any image URL variant.
* Handles scaled images, thumbnails, and query strings.
*/
function sk_get_attachment_id_from_url( string $url ): int {
$url = strtok( $url, '?' );
$id = attachment_url_to_postid( $url );
$clean_url = $id ? $url : preg_replace( '/-\d+x\d+(\.[a-z]{2,5})$/i', '$1', $url );
$id = ( ! $id && $clean_url !== $url ) ? attachment_url_to_postid( $clean_url ) : $id;
if ( $id ) {
return $id;
}
global $wpdb;
$filename = basename( $clean_url );
return (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attached_file' AND meta_value LIKE %s LIMIT 1",
'%' . $wpdb->esc_like( $filename )
)
);
}
/**
* Build a clean ALT string from an attachment title.
*/
function sk_build_alt_from_title( int $attachment_id ): string {
if ( ! $attachment_id ) {
return '';
}
$title = get_the_title( $attachment_id );
if ( empty( $title ) ) {
return '';
}
$alt = strtolower( $title );
$alt = preg_replace( '/\b\d+x\d+\b/i', '', $alt );
$alt = preg_replace( '/[-_]+/', ' ', $alt );
$alt = preg_replace( '/[^a-z\s]+/', '', $alt );
$alt = preg_replace( '/\b[a-z]\b/', '', $alt );
$alt = preg_replace( '/\s+/', ' ', $alt );
return trim( $alt );
}
/**
* Output-buffer callback: inject ALT text on every <img> missing one.
*/
function sk_fix_empty_image_alt( string $html ): string {
return preg_replace_callback(
'/<img\s[^>]+>/i',
function ( array $matches ): string {
$img_tag = $matches[0];
preg_match( '/\balt\s*=\s*(["\'])(?P<alt>.*?)\1/is', $img_tag, $alt_match );
$existing_alt = trim( $alt_match['alt'] ?? '' );
if ( $existing_alt !== '' ) {
return $img_tag;
}
preg_match( '/\bsrc\s*=\s*(["\'])(?P<src>.+?)\1/is', $img_tag, $src_match );
$src = trim( $src_match['src'] ?? '' );
if ( empty( $src ) ) {
return $img_tag;
}
$new_alt = sk_build_alt_from_title( sk_get_attachment_id_from_url( $src ) );
$result = preg_match( '/\balt\s*=\s*(["\'])\s*\1/i', $img_tag )
? preg_replace( '/\balt\s*=\s*(["\'])\s*\1/i', 'alt="' . esc_attr( $new_alt ) . '"', $img_tag, 1 )
: preg_replace( '/^<img\b/i', '<img alt="' . esc_attr( $new_alt ) . '"', $img_tag );
return $result ?? $img_tag;
},
$html
);
}