_field || !in_array($ref_field['type'], ['reference'], true)) { continue; } $ref_post_parent = $ref_field['ref_collection']; $nested_matched_ids = self::get_matched_post_ids_recursive($ref_post_parent, $query, $depth + 1, $max_depth); if (!empty($nested_matched_ids)) { $meta_key = ContentManagerHelper::get_child_post_meta_key_using_field_id( $post_parent, $ref_field['id'] ); $ids = implode( ',', array_map( 'intval', $nested_matched_ids ) ); $ref_post_ids = $wpdb->get_col( $wpdb->prepare( "SELECT post_id FROM {$wpdb->prefix}kirki_cm_reference WHERE field_meta_key = %s AND ref_post_id IN ($ids)", $meta_key ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared $matched_post_ids = array_merge($matched_post_ids, $ref_post_ids); } } return array_unique(array_map('intval', $matched_post_ids)); } public static function get_referenced_post_ids($post_parent, $post) { global $wpdb; $allData = ContentManagerHelper::get_post_type_custom_field_keys($post_parent); $post_ids = []; foreach ($allData as $data) { if ($data && in_array($data['type'], ['reference', 'multi-reference'], true)) { $meta_key = 'kirki_cm_field_' . $post_parent . '_' . $data['id']; $results = $wpdb->get_results( $wpdb->prepare( "SELECT ref_post_id FROM {$wpdb->prefix}kirki_cm_reference WHERE field_meta_key = %s AND post_id = %d", $meta_key, $post->ID ), ARRAY_A ); foreach ($results as $id) { $related_posts = $wpdb->get_results( $wpdb->prepare( "SELECT post_id FROM {$wpdb->prefix}kirki_cm_reference WHERE field_meta_key = %s AND ref_post_id = %d", $meta_key, (int) $id['ref_post_id'] ), ARRAY_A ); foreach ($related_posts as $related) { $related_id = (int) $related['post_id']; if ($related_id !== (int) $post->ID) { $post_ids[] = $related_id; } } } } } $post_ids = array_values(array_unique($post_ids)); return !empty($post_ids) ? $post_ids : [0]; } public static function get_terms($params) { $terms_array = []; $current_page = isset($params['current_page']) ? (int)$params['current_page'] : 1; $item_per_page = isset($params['item_per_page']) ? (int)$params['item_per_page'] : 3; $offset = isset($params['offset']) ? (int)$params['offset'] : 0; if (!empty($params['inherit'])) { $terms_array = get_the_terms($params['post_parent'], $params['taxonomy']); if (is_array($terms_array)) { // Convert WP_Term objects to arrays only if needed $terms_array = array_map(function($term) { return is_object($term) && method_exists($term, 'to_array') ? $term->to_array() : (array)$term; }, $terms_array); $calculated_offset = (($current_page - 1) * $item_per_page) + $offset; $terms_array = array_slice($terms_array, $calculated_offset, $item_per_page); } else { $terms_array = []; } } else { $params['offset'] = (($current_page - 1) * $item_per_page) + $offset; $params['number'] = $item_per_page; $terms_array = get_terms($params); if (is_array($terms_array)) { foreach ($terms_array as &$item) { if (is_object($item) && method_exists($item, 'to_array')) { $item = $item->to_array(); } elseif (is_object($item)) { $item = (array)$item; } } } else { $terms_array = []; } } // Count total terms $total_terms = 0; if (!empty($params['inherit'])) { $t = get_the_terms($params['post_parent'], $params['taxonomy']); if (is_array($t)) { $total_terms = count($t); } else { $total_terms = wp_count_terms($params['taxonomy'], array_merge($params, ['offset' => 0, 'number' => 0])); } } else { $total_terms = wp_count_terms($params['taxonomy'], array_merge($params, ['offset' => 0, 'number' => 0])); } $total_pages = ($item_per_page > 0) ? ceil($total_terms / $item_per_page) : 1; $prev_page = ($current_page > 1) ? $current_page - 1 : null; $next_page = ($current_page < $total_pages) ? $current_page + 1 : null; return [ 'data' => $terms_array, 'pagination' => [ 'per_page' => $item_per_page, 'current_page' => $current_page, 'total_pages' => $total_pages, 'total_count' => $total_terms, 'previous' => $prev_page, 'next' => $next_page, ], ]; } public static function buildTaxonomyForRelatedPosts(\WP_Post $post) { $taxonomies = get_object_taxonomies( $post->post_type ); $taxQuery = [ 'relation' => 'OR', ]; foreach ($taxonomies as $taxonomy) { $taxQuery[] = [ 'taxonomy' => $taxonomy, 'field' => 'slug', 'terms' => array_filter(wp_get_object_terms($post->ID, $taxonomy, ['fields' => 'slugs']), function ($termSlug) { return strtolower($termSlug) !== 'uncategorized'; }), ]; } return $taxQuery; } /** * Get dynamic collectiond data * * @param object $params query object. * * @return array post array */ public static function get_comments( $params ) { $parent = (int)($params['parent'] ?? 0); $post_id = (int)($params['post_id'] ?? 0); $type = ($params['type'] ?? 'comment'); $sorting = isset( $params['sorting'] ) ? $params['sorting'] : null; $filters = isset( $params['filters'] ) ? $params['filters'] : null; // add new $current_page = isset( $params['current_page'] ) ? $params['current_page'] : 1; $item_per_page = isset( $params['item_per_page'] ) ? $params['item_per_page'] : 3; $offset = isset( $params['offset'] ) ? $params['offset'] : 0; // Calculate the offset $offset_cal = ($current_page - 1) * $item_per_page + $offset; $args = array( 'parent' => $parent, 'post_id' => $post_id, 'type' => $type, 'number' => $item_per_page, 'paged' => $current_page, 'offset' => $offset_cal, 'count' => false ); if ( isset( $filters ) && is_array( $filters ) ) { foreach ( $filters as $filter_item ) { $field_name = isset( $filter_item['id'] ) ? $filter_item['id'] : ''; if(!$field_name){ continue; } switch($field_name) { case 'comment_date': case 'comment_date_gmt':{ /** * $filter_item['items'] max contain one array. * in array may contain start-date, end-date * Like: [{"start-date": "2020-01-01","end-date": "2020-01-02"}] */ if(isset($filter_item['items'], $filter_item['items'][0])) { $items = $filter_item['items']; $item = $items[0]; // Get first item in array. $date_query = array('column' => $field_name); $date_query['inclusive'] = true; if (!empty($item['start-date'])) { $date_query['after'] = $item['start-date']; } if (!empty($item['end-date'])) { $date_query['before'] = $item['end-date']; } $args['date_query'] = $date_query; } break; } case 'comment_author': { $items = $filter_item['items']; // $items['items'] max contain one array. foreach($items as $item) { if ( isset( $item['condition'], $item['values'] ) && is_array( $item['values'] ) ) { if ( $item['condition'] === 'in' ) { $args['author__in'] = $item['values']; } if ( $item['condition'] === 'not-in' ) { $args['author__not_in'] = $item['values']; } } } break; } case 'comment_approved': { $items = $filter_item['items']; // $items['items'] max contain one array. foreach($items as $item) { if ( isset( $item['condition'], $item['values'] ) && is_array( $item['values'] ) ) { if ( $item['condition'] === 'in' ) { $args['status'] = $item['values']; } } } } } } } if(isset($sorting)){ // Set the sort order (ASC/DESC) if ( isset( $sorting['order'] ) ) { $args['order'] = $sorting['order']; } if ( isset( $sorting['orderby'] ) && !empty($sorting['orderby']) ) { $args['orderby'] = $sorting['orderby']; } } $comments = get_comments($args); unset($args['number']); unset($args['paged']); if (is_array($comments)) { foreach($comments as &$comment) { $comment = (object)(array)$comment; $author_posts_page_link = $comment->comment_author_url; if (!$author_posts_page_link) { $author_posts_page_link = \get_author_posts_url($comment->user_id); } $comment->author_profile_picture = array( 'src' => get_avatar_url( $comment->user_id ) ); $comment->author_posts_page_link = $author_posts_page_link; } } // Get total comments count $total_comments = get_comments( array_merge( $args, array( 'count' => true ) ) ) ; $total_comments = $total_comments - $offset; // Calculate total pages $total_pages = ceil( $total_comments / $item_per_page ); // Calculate previous and next pages $prev_page = ( $current_page > 1 ) ? $current_page - 1 : null; $next_page = ( $current_page < $total_pages ) ? $current_page + 1 : null; // return $comments; return array( 'data' => $comments, // Raw comments data 'pagination' => array( 'per_page' => $item_per_page, 'current_page' => $current_page, 'total_pages' => $total_pages, 'total_count' => $total_comments, 'previous' => $prev_page, 'next' => $next_page, ), ); } /** * Remove all default assets * * @return void */ public static function remove_wp_assets() { /* // Remove all WordPress actions // remove_all_actions('wp_head'); // remove_all_actions('wp_print_styles'); // remove_all_actions('wp_print_head_scripts'); // remove_all_actions('wp_footer'); // // Handle `wp_head` // add_action('wp_head', 'wp_enqueue_scripts', 1); // add_action('wp_head', 'wp_print_styles', 8); // add_action('wp_head', 'wp_print_head_scripts', 9); // add_action('wp_head', 'wp_site_icon'); // // Handle `wp_footer` // add_action('wp_footer', 'wp_print_footer_scripts', 20); // // Handle `wp_enqueue_scripts` // remove_all_actions('wp_enqueue_scripts'); // // Also remove all scripts hooked into after_wp_tiny_mce. // remove_all_actions('after_wp_tiny_mce'); */ // remove admin-bar. add_filter( 'show_admin_bar', '__return_false', PHP_INT_MAX ); } /** * Get server protocol * currently not in use * * @return string protocol name. */ public static function get_protocol() { $protocol = isset( $_SERVER['HTTPS'] ) ? 'https' : 'http'; return $protocol; } /** * Check if the current user has specific role ($role) * * @param string $role The role to check. * @return boolean */ public static function user_is( $role ) { $user = wp_get_current_user(); $roles = $user->roles; return is_array( $roles ) && count( $roles ) && in_array( $role, $roles, true ) ? true : false; } /** * Check if the user has access to edit/create specific/all post * * @param int $post_id post id. * @return boolean */ public static function user_has_post_edit_access() { return self::has_access( array( KIRKI_ACCESS_LEVELS['FULL_ACCESS'], KIRKI_ACCESS_LEVELS['CONTENT_ACCESS'], ) ); } /** * Check if the user has access to editor * * @return boolean */ public static function user_has_editor_access() { if(isset($_GET['editor-preview-token'])){ //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $editor_preview_token = self::sanitize_text( isset( $_GET['editor-preview-token'] ) ? $_GET['editor-preview-token'] : '' ); return self::is_post_editor_preview_token_valid($editor_preview_token); } return self::has_access( array( KIRKI_ACCESS_LEVELS['FULL_ACCESS'], KIRKI_ACCESS_LEVELS['CONTENT_ACCESS'], KIRKI_ACCESS_LEVELS['VIEW_ACCESS'], ) ); } public static function getallheaders() { $headers = []; foreach ($_SERVER as $name => $value) { if (strpos($name, 'HTTP_') === 0) { $key = substr($name, 5); } elseif (in_array($name, ['CONTENT_TYPE', 'CONTENT_LENGTH', 'CONTENT_MD5'])) { $key = $name; } else { continue; } // Convert HEADER_NAME → Header-Name $key = str_replace('_', ' ', strtolower($key)); $key = ucwords($key); $key = str_replace(' ', '-', $key); $headers[$key] = $value; } return $headers; } public static function is_api_call_from_editor_preview(){ // Check the Editor-Preview-Token header $headers = self::getallheaders(); $editor_preview_token = isset($headers['Editor-Preview-Token']) ? $headers['Editor-Preview-Token'] : null; if($editor_preview_token){ return true; } return false; } public static function is_api_header_post_editor_preview_token_valid(){ // Check the Editor-Preview-Token header $headers = self::getallheaders(); $editor_preview_token = isset($headers['Editor-Preview-Token']) ? $headers['Editor-Preview-Token'] : null; if(HelperFunctions::is_post_editor_preview_token_valid( $editor_preview_token)){ return true; } return false; } public static function is_post_editor_preview_token_valid($token){ $status = HelperFunctions::get_global_data_using_key('kirki_editor_read_only_access_status'); if($status){ $kirki_editor_read_only_access_token = HelperFunctions::get_global_data_using_key('kirki_editor_read_only_access_token'); if($kirki_editor_read_only_access_token && $kirki_editor_read_only_access_token === $token){ return true; } } return false; } /** * Check if the current user has specific access * * @param string|string[] $access_level The access level to check access. */ public static function has_access( $access_level ) { $user = wp_get_current_user(); $roles = $user->roles; $has_access = false; if ( is_array( $access_level ) ) { foreach ( $roles as $role ) { $access = get_option('kirki_' . $role ); if ( ! empty( $access ) && in_array( $access, $access_level, true ) ) { $has_access = true; break; } } } elseif ( is_string( $access_level ) ) { foreach ( $roles as $role ) { $access = get_option('kirki_' . $role ); if ( ! empty( $access ) && $access === $access_level ) { $has_access = true; break; } } } return $has_access; } /** * This method will collect license info from kirki.com * * @param string $license_key user license key. * @return array license info. */ public static function get_my_license_info( $license_key ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $info = self::http_get( KIRKI_CORE_PLUGIN_URL . '/?license_key=' . $license_key . '&host=' . rawurlencode( self::sanitize_text( isset( $_SERVER['HTTP_HOST'] ) ? $_SERVER['HTTP_HOST'] : null ) ) ); $info = json_decode( $info, true ); if ( $info && isset( $info['success'] ) ) { return $info['data']; } else { return array( 'key' => $license_key ); } } /** * HTTP get * * @param string $url api endpoint url. * @return string|bool response. */ public static function http_get( $url, $args = array() ) { try { $response = wp_remote_get( $url, $args ); if ( ( !is_wp_error($response)) && (200 === wp_remote_retrieve_response_code( $response ) ) ) { $responseBody = $response['body']; return $responseBody; } return false; } catch( \Exception $ex ) { return false; } } /** * HTTP post * * @param string $url api endpoint url. * @param array $options options. * @return array|WP_Error response. */ public static function http_post( $url, $options ) { $res = wp_remote_post( $url, $options ); return $res; } /** * Text domain load hooks * * @param string $handle kirki handle. * @return void */ public static function load_script_text_domain( $handle ) { wp_set_script_translations( $handle, 'kirki', KIRKI_ROOT_PATH . 'languages/' ); } /** * Delete kirki related meta if a post is deleted. * * @param int $post_id post id. * @return void */ public static function delete_post_with_meta_key( $post_id ) { delete_post_meta( $post_id, KIRKI_META_NAME_FOR_USED_STYLE_BLOCK_IDS ); delete_post_meta( $post_id, KIRKI_META_NAME_FOR_USED_STYLE_BLOCK_IDS . '_random' ); delete_post_meta( $post_id, 'kirki' ); delete_post_meta( $post_id, KIRKI_META_NAME_FOR_POST_EDITOR_MODE ); delete_post_meta( $post_id, KIRKI_GLOBAL_STYLE_BLOCK_META_KEY ); delete_post_meta( $post_id, KIRKI_GLOBAL_STYLE_BLOCK_META_KEY . '_random' ); } /** * Get the query string for the media type * * @param string $type media type. * @return string The query string. * @example HelperFunctions::get_media_type_query_string('image') => 'image/jpeg, image/png, image/gif' */ public static function get_media_type_query_string( $type ) { return implode( ', ', array_map( function ( $v ) { return "'" . $v . "'"; }, KIRKI_SUPPORTED_MEDIA_TYPES[ $type ] ) ); } /** * This is for component configuration/object javascript variable. * * @return string script tag */ public static function get_empty_variables() { $s = "'; return $s; } /** * Check kirki and kirki pro is active or not * * @param string $plugin_main_file plugin main PHP file name. * @return boolean */ public static function is_plugin_activate( $plugin_main_file ) { if ( in_array( $plugin_main_file, apply_filters( 'active_plugins', get_option( 'active_plugins' ) ), true ) ) { // plugin is activated. return true; } return false; } /** * This function will verify nonce * ACT like API calls auth middleware * * @param string $action ajax action name. * * @return void */ public static function verify_nonce( $action = -1 ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.NonceVerification.Recommended,WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $nonce = self::sanitize_text( isset( $_SERVER['HTTP_X_WP_NONCE'] ) ? $_SERVER['HTTP_X_WP_NONCE'] : null ); if ( ! wp_verify_nonce( $nonce, $action ) ) { wp_send_json_error( 'Not authorized' ); exit; } } /** * Unslash and sanitize text * * @param string $v text. * @return string sanitized text. */ public static function sanitize_text( $v ) { return sanitize_text_field( wp_unslash( $v ) ); } /** * Get current WordPress session ID. * This method generates a unique session ID if none exists. * * @return string Session ID. */ public static function get_session_id() { // First, check if a session ID is already stored in the static variable. if (self::$global_session_id) { return self::$global_session_id; } // Check if a session ID exists in a cookie. if (isset($_COOKIE['kirki_session_id'])) { self::$global_session_id = sanitize_text_field($_COOKIE['kirki_session_id']); return self::$global_session_id; } // Generate a new session ID. self::$global_session_id = wp_generate_uuid4(); // Set the session ID in a cookie. setcookie('kirki_session_id', self::$global_session_id, time() + (DAY_IN_SECONDS * 7), COOKIEPATH, COOKIE_DOMAIN, is_ssl(), true); return self::$global_session_id; } /** * Get session data by key using WordPress transients. * * @param string $key The key of the session data to retrieve. * @return mixed|null The session data if found, null otherwise. */ public static function get_session_data($key) { // Get the current session ID. $session_id = self::get_session_id(); // Retrieve the session data. $session_data = get_transient('kirki_session_' . $session_id); if (isset($session_data[$key])) { return $session_data[$key]; } return null; } /** * Add or update session data using WordPress transients. * * @param string $key The key of the session data. * @param mixed $value The value of the session data. * @return void */ public static function set_session_data($key, $value) { // Get the current session ID. $session_id = self::get_session_id(); // Retrieve existing session data. $session_data = get_transient('kirki_session_' . $session_id) ?: array(); // Update the session data. $session_data[$key] = $value; // Save the updated session data with a 24-hour expiration time. set_transient('kirki_session_' . $session_id, $session_data, DAY_IN_SECONDS); } /** * Delete session data by key using WordPress transients. * * @param string $key The key of the session data to delete. * @return void */ public static function delete_session_data($key) { // Get the current session ID. $session_id = self::get_session_id(); // Retrieve existing session data. $session_data = get_transient('kirki_session_' . $session_id); if (isset($session_data[$key])) { unset($session_data[$key]); // Save the updated session data or delete the transient if empty. if (!empty($session_data)) { set_transient('kirki_session_' . $session_id, $session_data, DAY_IN_SECONDS); } else { delete_transient('kirki_session_' . $session_id); } } } /** * Is Pro user checking function. * * @return bool */ public static function is_pro_user() { $common_data = WpAdmin::get_common_data( true ); $bool= isset( $common_data['license_key']['valid'] ) && boolval( $common_data['license_key']['valid'] ) === true; return $bool; } /** * Store Error log to kirki server * * @param string $error_text the error text created in PHP. * * @return void */ public static function store_error_log( $error_text ) { $kirki_version = KIRKI_VERSION; self::http_get( KIRKI_CORE_PLUGIN_URL . "?log_data=error&version=$kirki_version&error_type=php&error_text=$error_text" ); } /** * Get all view port lists * * @return string viewports list variable in script markup. */ public static function get_view_port_lists() { $s = ''; $list = UserData::get_view_port_list(); if ( $list ) { $s .= "'; } return $s; } /** * Get all css variables * * @return string variables in script markup. */ public static function get_kirki_css_variables_data() { $s = ''; $variableData = UserData::get_kirki_variable_data(); if ( $variableData ) { $s .= "'; } return $s; } /** * Get smooth scroll script * * @return string script markup. */ public static function get_smooth_scroll_script() { $common_data = WpAdmin::get_common_data(true); $smooth_scroll_enabled = isset($common_data['smooth_scroll'], $common_data['smooth_scroll']['enabled']) ? $common_data['smooth_scroll']['enabled'] : false; $smooth_scroll_value = isset($common_data['smooth_scroll'], $common_data['smooth_scroll']['value']) ? $common_data['smooth_scroll']['value'] : 1; /** * User value 1 to 200 * * Min duration 1s * Max duration 12s * */ $duration = ceil(($smooth_scroll_value / 200) * 12); $s = ''; if ($smooth_scroll_enabled) { $s .= "'; } return $s; } /** * Format the date with date format * * @return string */ public static function format_date($date, $format) { if ($date && $format) { $date_formats_arr = [ 'DD/MM/YYYY' => 'd/m/Y', 'DD-MM-YYYY' => 'd-m-Y', 'DD.MM.YYYY' => 'd.m.Y', 'MM/DD/YYYY' => 'm/d/Y', 'MM-DD-YYYY' => 'm-d-Y', 'MM.DD.YYYY' => 'm.d.Y', 'MMMM DD, YYYY' => 'F j, Y', 'MMM DD, YYYY' => 'M j, Y', 'YYYY-MM-DD' => 'Y-m-d', 'YYYY/MM/DD' => 'Y/m/d', 'YY.MM.DD' => 'y.m.d', 'YY/MM/DD' => 'y/m/d', 'YY-MM-DD' => 'y-m-d', ]; $timestamp = strtotime($date); if ($timestamp === false) { return $date; // fallback (avoid fatal) } $datetime = (new \DateTime())->setTimestamp($timestamp); return $datetime->format($date_formats_arr[$format] ?? $format); } return $date; } /** * Format the time with time format * * @return string */ public static function convert_time_format($timeString, $format = 'h:i a') { $dateTime = null; try { $dateTime = new \DateTime($timeString); if ($dateTime && $timeString) { return $dateTime->format($format); } } catch (\Exception $e) { // if timeString is an invalid time format $parts = explode(' ', $timeString); if (count($parts) > 1) { // Remove the last part (am/pm) $time_value = $parts[0]; try { $dateTime = new \DateTime($time_value); if ($dateTime && $timeString) { return $dateTime->format($format); } } catch (\Exception $e2) { return $timeString; } } return $timeString; } return $timeString; } /** * Get single post if has a kirki type post * * @return object|bool */ public static function get_last_edited_kirki_editor_type_page(){ $args = array( 'post_type' => 'page', // Change to 'post' if you want to search for posts 'post_status' => ['publish', 'draft'], 'numberposts' => 1, // Number of results to retrieve (change as needed) 'meta_key' => 'kirki_editor_mode', 'meta_value' => 'kirki', 'orderby' => 'modified', // Order by post date 'order' => 'DESC', // Sort in descending order ); $pages = get_posts($args); if(count($pages) > 0){ return $pages[0]; } return false; } public static function get_kirki_version_from_db() { $version = wp_cache_get('kirki_version', 'kirki'); if (false === $version) { $version = get_option('kirki_version', ''); if ( !empty($version) ) { wp_cache_set('kirki_version', $version, 'kirki'); } } return $version; } public static function set_kirki_version_in_db() { $version = self::get_kirki_version_from_db(); if($version && version_compare($version, KIRKI_VERSION, '==')) { // No need to update the version if it's already equal to the current version. return; } update_option('kirki_version', KIRKI_VERSION, false); wp_cache_set('kirki_version', KIRKI_VERSION, 'kirki'); } public static function accepted_file_types_by_plugin($accepted_media_types = KIRKI_SUPPORTED_MEDIA_TYPES) { $result = array(); foreach ($accepted_media_types as $value) { if (is_array($value)) { $result = array_merge($result, self::accepted_file_types_by_plugin($value)); } else { $result[] = $value; } } return $result; } public static function content_manager_link_filter($dynamic_content = array(), $href="#") { $current_post = get_post(self::get_post_id_if_possible_from_url()); if ($current_post->post_type === KIRKI_CONTENT_MANAGER_PREFIX) { $fields = ContentManagerHelper::get_post_type_custom_field_keys($current_post->post_parent); if (isset($fields[$dynamic_content['value']]) && is_array($fields[$dynamic_content['value']])) { if ('email' === $fields[$dynamic_content['value']]['type']) { $href = "mailto:$href"; } else if ('phone' === $fields[$dynamic_content['value']]['type']) { $href = "tel:$href"; } } } return $href; } public static function check_string_has_this_tags($string, $tag) { // Check if the string contains either a

tag or an

tag return preg_match("/<".$tag."[^>]*>/i", $string) === 1; } private static function get_global_data_post_id(){ $post_id = get_option('KIRKI_GLOBAL_DATA_POST_TYPE_ID', get_option('DROIP_GLOBAL_DATA_POST_TYPE_ID', false)); if($post_id){ return $post_id; }else{ //this block will run only once $posts = get_posts(array( 'post_type' => KIRKI_GLOBAL_DATA_POST_TYPE_NAME, 'numberposts' => 1, )); if($posts){ $post_id = $posts[0]->ID; }else{ //create new post $post = array( 'post_title' => KIRKI_GLOBAL_DATA_POST_TYPE_NAME, 'post_type' => KIRKI_GLOBAL_DATA_POST_TYPE_NAME, 'post_status' => 'draft' ); $post_id = wp_insert_post($post); } update_option('KIRKI_GLOBAL_DATA_POST_TYPE_ID', $post_id, true); } return $post_id; } /** * Get global data using key * */ public static function get_global_data_using_key($key){ //first get post using KIRKI_GLOBAL_DATA_POST_TYPE_NAME post_type name. if not found then create new one. $post_id = self::get_global_data_post_id(); if ( metadata_exists( 'post', $post_id, $key ) ) { return get_post_meta( $post_id, $key, true ); } // this block will run only once for a legacy option key. $value = get_option( $key, null ); if ( null !== $value ) { update_post_meta( $post_id, $key, $value ); delete_option( $key ); } return $value; } /** * Get global data using key * */ public static function update_global_data_using_key($key, $value){ $post_id = self::get_global_data_post_id(); update_post_meta($post_id, $key, $value); } public static function get_template_data_if_current_page_is_kirki_template(){ $custom_data = get_query_var('kirki_custom_data'); $data = false; $builder_div = ''; if ($custom_data && isset($custom_data['kirki_template_content'])) { $action = HelperFunctions::sanitize_text(isset($_GET['action']) ? $_GET['action'] : null); $load_for = HelperFunctions::sanitize_text( isset( $_GET['load_for'] ) ? $_GET['load_for'] : '' ); if ($action === KIRKI_EDITOR_ACTION && $load_for ==='kirki-iframe' && !str_contains($custom_data['kirki_template_content'],'kirki-builder')){ $template_edit_url = HelperFunctions::get_post_url_arr_from_post_id( $custom_data['kirki_template_id'], ['editor_url' => true] )['editor_url']; $builder_div = '
'; } $data = array( 'content' => $custom_data['kirki_template_content'] . $builder_div, 'template_id' => $custom_data['kirki_template_id'] ); } return $data; } public static function get_custom_data_if_current_page_is_kirki_custom_post(){ $custom_data = get_query_var('kirki_custom_data'); $data = false; $builder_div = ''; if ($custom_data && isset($custom_data['kirki_custom_post_content'])) { $action = HelperFunctions::sanitize_text(isset($_GET['action']) ? $_GET['action'] : null); $load_for = HelperFunctions::sanitize_text( isset( $_GET['load_for'] ) ? $_GET['load_for'] : '' ); if ($action === KIRKI_EDITOR_ACTION && $load_for ==='kirki-iframe' && !str_contains($custom_data['kirki_custom_post_content'],'kirki-builder')){ $template_edit_url = HelperFunctions::get_post_url_arr_from_post_id( $custom_data['kirki_custom_post_id'], ['editor_url' => true] )['editor_url']; $builder_div = '
'; } $data = array( 'content' => $custom_data['kirki_custom_post_content'] . $builder_div, 'post_id' => $custom_data['kirki_custom_post_id'] ); } return $data; } public static function validate_slug($post_id, $post_type, $post_name){ global $wpdb; // Execute the query $result = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d", $post_name, $post_type, $post_id ? $post_id : 0 ) ); // If a post with the same slug exists, return false if ($result) { return false; } // If no post with the same slug exists, return true return true; } /** * Summary of find_utility_page_for_this_context * @param mixed $type * @param mixed $get_by id | type. * @return mixed */ public static function find_utility_page_for_this_context( $value = '404', $get_by = 'type' ) { $utility_pages = Page::fetch_list('kirki_utility', true, array('publish')); if(count($utility_pages) > 0) { foreach ($utility_pages as $key => $page) { if($get_by === 'type'){ if($page['utility_page_type'] === $value){ return $page; } }else if($get_by === 'id'){ if($page['id'] === (int) $value){ return $page; } } } } return false; } public static function get_current_page_context(){ $context = array(); // {id, type} $obj = get_queried_object(); if(is_404()){ $context['type'] = '404'; } else if ($obj instanceof WP_Post) { $context['id'] = $obj->ID; $context['type'] = 'post'; } else if ($obj instanceof WP_User) { $context['id'] = $obj->ID; $context['type'] = 'user'; } elseif ($obj instanceof WP_Term) { $context['id'] = $obj->term_id; $context['type'] = 'term'; } // elseif ($obj instanceof WP_Post_Type) { // echo 'This is a WP_Post_Type object'; // } elseif (is_null($obj)) { // echo 'No queried object (null)'; // } else { $kirki_utility_page_type = get_query_var('kirki_utility_page_type'); $kirki_utility_page_id = get_query_var('kirki_utility_page_id'); if(!empty($kirki_utility_page_type)){ if(!self::check_utility_page_visibility_condition($kirki_utility_page_type)){ $context['type'] = '404'; }else{ $context['type'] = 'kirki_utility'; $context['kirki_utility_page_type'] = $kirki_utility_page_type; $context['kirki_utility_page_id'] = $kirki_utility_page_id; } } } return $context; } /** * Get utility page slug using type. * { type: 'login', title: 'Login' }, * { type: 'sign_up', title: 'Registration' }, * { type: 'forgot_password', title: 'Forgot Password' }, * { type: 'reset_password', title: 'Reset Password' }, * { type: 'retrive_username', title: 'Retrive Username' }, * { type: '404', title: '404' }, * * @param string $type //utility page type. * @return string||bool //string or false. */ public static function get_utility_page_url($type){ $utility_pages = Page::fetch_list('kirki_utility', true, array('publish')); foreach ($utility_pages as $key => $page) { $utility_page_type = $page['utility_page_type']; $slug = $page['slug']; if( $utility_page_type === $type ){ return home_url('/'.$slug); } } return false; } public static function check_utility_page_visibility_condition($type){ if ($type === 'login' || $type === 'sign_up' || $type === 'forgot_password'|| $type === 'reset_password'|| $type === 'retrive_username') { // Check if the user is already logged in if (is_user_logged_in()) { return false; // User is logged in, so the page should not be visible } // Add other conditions based on the type if needed if ($type === 'signup') { // Example: Check if registrations are enabled in WordPress if (!get_option('users_can_register')) { return false; // Registration is disabled } } // If the user is not logged in and other conditions pass, allow the page to be visible return true; } // If the type is not 'login' or 'signup', return false by default return true; } public static function delete_directory($dirname) { global $wp_filesystem; if ( empty( $wp_filesystem ) ) { require_once ABSPATH . 'wp-admin/includes/file.php'; WP_Filesystem(); } if ( $wp_filesystem->exists( $dirname ) ) { return $wp_filesystem->delete( $dirname, true ); } return false; } public static function get_temp_folder_path(){ $upload_dir = wp_upload_dir(); $temp_folder = 'kirki_temp'; $temp_folder_path = $upload_dir['basedir'] . '/' . $temp_folder; return $temp_folder_path; } public static function get_initial_view_ports(){ return json_decode('{ "active":"md", "scale":1, "zoom":1, "width":1200, "mdWidth":"", "defaults":[ "md", "tablet", "mobileLandscape", "mobile" ], "list":{ "md":{ "value":1200, "scale":1, "minWidth":1200, "maxWidth":1200, "title":"Desktop", "icon":"desktop", "activeIcon":"desktop-hover" }, "tablet":{ "value":991, "scale":1, "minWidth":991, "maxWidth":991, "title":"Tablet", "icon":"tablet-default", "activeIcon":"tablet-hover" }, "mobileLandscape":{ "value":767, "scale":1, "minWidth":767, "maxWidth":767, "title":"Landscape", "icon":"phone-hr-default", "activeIcon":"phone-hr-hover" }, "mobile":{ "value":575, "scale":1, "minWidth":575, "maxWidth":575, "title":"Mobile", "icon":"phone-vr-default", "activeIcon":"phone-vr-hover" } } }', true); } public static function download_zip_from_remote($remote_file, $new_name) { $file_ext = explode('.', $remote_file); // ['file', 'ext'] $file_ext = strtolower(end($file_ext)); // 'ext' $allowed = ['zip']; if (!in_array($file_ext, $allowed)) { return false; } try { // error_reporting(E_ALL); // ini_set('display_errors', 1); // Download the file from the remote server. // Create a stream context to disable SSL verification $options = [ "http" => [ "method" => "GET", "header" => "User-Agent: WordPress\r\n" ], "ssl" => [ "verify_peer" => false, // Disable verification of the peer's certificate "verify_peer_name" => false // Disable verification of the peer's name ] ]; $context = stream_context_create($options); $file_contents = file_get_contents($remote_file, false, $context); // Save the file locally. if ($file_contents !== false) { // Local path to save the downloaded file. $local_file = wp_upload_dir()['basedir'] . '/' . $new_name; file_put_contents($local_file, $file_contents); return $local_file; } } catch (\Throwable $th) { // throw $th; } return false; } public static function filterZipFile($zip, $zip_file_path) { // Temporary filtered ZIP path $filtered_zip_path = sys_get_temp_dir() . '/filtered.zip'; $filtered_zip = new \ZipArchive; if ($filtered_zip->open($filtered_zip_path, \ZipArchive::CREATE | \ZipArchive::OVERWRITE) === TRUE) { // Loop through all files in the archive for ($i = 0; $i < $zip->numFiles; $i++) { $filename = $zip->getNameIndex($i); $file_path = 'zip://' . $zip_file_path . '#' . $filename; // Get MIME type based on file extensioncm_f $file_mime = self::getMimeTypeByExtension($filename); // Additional JSON validation if ($file_mime === 'application/json' && !self::isJsonFile($file_path)) { $file_mime = 'text/plain'; // Fallback if not valid JSON } // Check if the file MIME type matches supported types $is_supported = false; foreach (KIRKI_SUPPORTED_MEDIA_TYPES as $types) { if (in_array($file_mime, $types)) { $is_supported = true; break; } } // Add the file to the filtered archive if supported if ($is_supported) { $file_contents = $zip->getFromIndex($i); $filtered_zip->addFromString($filename, $file_contents); } } $filtered_zip->close(); return $filtered_zip_path; } else { return false; } } // Helper function to get MIME type by file extension private static function getMimeTypeByExtension($filename) { $extension_to_mime = [ 'json' => 'application/json', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'png' => 'image/png', 'gif' => 'image/gif', 'webp' => 'image/webp', 'svg' => 'image/svg+xml', 'pdf' => 'application/pdf', 'mp4' => 'video/mp4', 'ogg' => 'audio/ogg', 'lottie' => 'text/plain', 'mov' => 'video/quicktime', 'mp3' => 'audio/mpeg', 'wav' => 'audio/wav', // Add more extensions as needed ]; $ext = pathinfo($filename, PATHINFO_EXTENSION); return $extension_to_mime[strtolower($ext)] ?? 'application/octet-stream'; } // Helper function to validate JSON file content private static function isJsonFile($file_path) { $file_contents = @file_get_contents($file_path); $trimmed = trim($file_contents); return $trimmed[0] === '{' || $trimmed[0] === '['; } public static function is_remote_url($url) { // Parse the URL to get components $parsed_url = wp_parse_url($url); return isset($parsed_url['scheme']); } public static function is_element_accessible($access) { switch ($access) { case 'all': return true; // Accessible to everyone case 'guest': return !is_user_logged_in(); case 'logged-in': return is_user_logged_in(); // Accessible to logged-in users case 'admin': return current_user_can('administrator'); // Accessible to administrators case 'editor': return current_user_can('editor'); // Accessible to editors case 'author': return current_user_can('author'); // Accessible to authors case 'subscriber': return current_user_can('subscriber'); // Accessible to subscribers default: return false; // Default to not accessible if the value is unrecognized } } /** * Find symbol for post id using condition * it will find and return selected symbols html and css; * * @param string $type : symbol type. * @param string $post : post object. * @return symbol || bool(false) */ public static function find_symbol_for_this_page( $type ) { $all_symbols = Symbol::fetch_list( true, false ); foreach ( $all_symbols as $key => $symbol ) { if(isset($symbol['setAs']) && $symbol['setAs'] === $type){ return $symbol; } } return false; } /** * Get Custom Header * it will find and return selected symbols html and css; * * @param string $type stymbol type header|footer. * @param string $html if true the function will return html otherwise return symbol object. * @return string|object custom section html or stymbol object. */ public static function get_page_custom_section( $type, $html = true ) { $show = apply_filters('kirki_show_custom_section_' . $type, true); if(!$show){ return ''; } $symbol = self::find_symbol_for_this_page( $type ); if ( ! $html ) { return $symbol; } if(isset(self::$custom_sections[$type])){ return self::$custom_sections[$type]; } $s = self::isShowWPThemeHeaderFooter() ? '':' '; // this is for disableing theme header footer forcefully if is_show_wp_theme_header_footer is false if ( $symbol ) { $action = HelperFunctions::sanitize_text( isset( $_GET['action'] ) ? $_GET['action'] : '' ); $symbol_data = $symbol['symbolData']; $set_as = isset($symbol['setAs']) ? $symbol['setAs'] : ''; $post_id = self::get_post_id_if_possible_from_url(); $template_data = self::get_template_data_if_current_page_is_kirki_template(); if($template_data) $post_id = $template_data['template_id']; $custom_page_data = self::get_custom_data_if_current_page_is_kirki_custom_post(); if($custom_page_data) $post_id = $custom_page_data['post_id']; $is_page_symbol_disabled = get_post_meta($post_id, KIRKI_META_NAME_FOR_PAGE_HF_SYMBOL_DISABLE_STATUS, true); if (isset($is_page_symbol_disabled) && is_array($is_page_symbol_disabled) && isset($is_page_symbol_disabled[$type])) { $is_page_symbol_disabled = $is_page_symbol_disabled[$type]; } else { $is_page_symbol_disabled = false; } $params = array( 'blocks' => $symbol_data['data'], 'style_blocks' => $symbol_data['styleBlocks'], 'root' => $symbol_data['root'], 'post_id' => $symbol['id'], 'options' => [], 'get_style' => true, 'get_variable' => false, 'should_take_app_script' => false, 'prefix' => 'kirki-s' . $symbol['id'] ); if($action === KIRKI_EDITOR_ACTION){ $extra_attr_for_hf_symbol = ''; if($is_page_symbol_disabled) $extra_attr_for_hf_symbol = ' style="display:none;"'; $s = '<' . $type . $extra_attr_for_hf_symbol . ' data-kirki-symbol_set_as="' . $set_as . '" data-kirki-symbol="' . $symbol['id'] . '" data-kirki="' . $type . '">' . self::get_html_using_preview_script( $params ) . ''; //added data-kirki="$type" => We removed theme header and footer using preg_replace in TheFrontendHooks.php file }else if(!$is_page_symbol_disabled){ $params['should_take_app_script'] = true; $params['get_variable'] = true; $s = self::get_html_using_preview_script( $params ); }else if($is_page_symbol_disabled){ $s = ''; } } $s = do_shortcode($s); self::$custom_sections[$type] = $s; return $s; } public static function isShowWPThemeHeaderFooter(){ $common_data = WpAdmin::get_common_data( true ); return $common_data['is_show_wp_theme_header_footer']; } /** * Check if a value is considered true or false. * * @param mixed $value The value to check. * @return bool Returns true if the value is considered "truthy", otherwise false. */ public static function isTruthy($value): bool { return filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false; } /** * Get the upload directory path has upload or write permission. */ public static function get_upload_dir_has_write_permission() { if (! function_exists('request_filesystem_credentials')) { require_once ABSPATH . 'wp-admin/includes/file.php'; } if (WP_Filesystem()) { global $wp_filesystem; $upload_dir = wp_upload_dir(); return $wp_filesystem->is_writable($upload_dir['basedir']); } return false; } /** * $name = [] or string */ public static function add_prefix_to_class_name($prefix, $name) { if (is_array($name)) { foreach ($name as $key => $c) { $c = strtolower($c); if (in_array($c, KIRKI_PRESERVED_CLASS_LIST)) { $name[$key] = $c; } else { $name[$key] = $prefix ? strtolower($prefix) . '-' . $c : $c; } } } else { $name = strtolower($name); if (!in_array($name, KIRKI_PRESERVED_CLASS_LIST)) { $name = $prefix ? strtolower($prefix) . '-' . $name : $name; } } return $name; } public static function checkVisibilityConditions($element, $options) { $conditions = $element['properties']['visibilityConditions'] ?? []; if ( !count($conditions) ) return true; foreach ($conditions as $and_group) { $and_result = true; foreach ($and_group as $condition) { $source = (string) ($condition['source'] ?? 'kirki'); $condition_result = apply_filters('kirki_visibility_condition_check_' . $source, false, $condition, $options); if (!$condition_result) { $and_result = false; break; // If any condition fails in AND group } } if ($and_result) { return true; // If any OR group passes } } return false; // No group passed } private static function update_slider_style_blocks($blocks, $styles) { $slider_mask_styleIds = []; $slider_item_styleIds = []; // slider_item foreach ($blocks as $id => $block) { // Check if the block has a 'name' key if (isset($block['name'])) { if (isset($block['name']) && $block['name'] === 'slider_mask') { // Loop through each item in $block['styleIds'] foreach ($block['styleIds'] as $styleId) { // Check if the styleId is NOT already in the $slider_mask_styleIds array if (!in_array($styleId, $slider_mask_styleIds)) { // If not present, push it into the array $slider_mask_styleIds[] = $styleId; } } } if (isset($block['name']) && $block['name'] === 'slider_item') { // Loop through each item in $block['styleIds'] foreach ($block['styleIds'] as $styleId) { // Check if the styleId is NOT already in the $slider_item_styleIds array if (!in_array($styleId, $slider_item_styleIds)) { // If not present, push it into the array $slider_item_styleIds[] = $styleId; } } } } } if (count($slider_mask_styleIds) > 0) { foreach ($slider_mask_styleIds as $styleId) { if($styles[$styleId]){ $style = $styles[$styleId]; $style_variants = $style['variant']; $styleVariants = []; if ($style_variants && count($style_variants) > 0) { foreach ($style_variants as $key => $css) { $css = preg_replace('/overflow\s*:\s*hidden;?/', '', $css); $css = preg_replace('/pointer-events\s*:\s*none;?/', '', $css); $css = trim($css); $styleVariants[$key] = $css; } } $styles[$styleId]['variant'] = $styleVariants; } } } if (count($slider_item_styleIds) > 0) { foreach ($slider_item_styleIds as $styleId) { $style = $styles[$styleId]; $style_variants = $style['variant']; $styleVariants = []; if ($style_variants && count($style_variants) > 0) { foreach ($style_variants as $key => $css) { $css = preg_replace('/position\s*:\s*absolute;?/', '', $css); $css = preg_replace('/display\s*:\s*none;?/', '', $css); $css = trim($css); $styleVariants[$key] = $css; } $styles[$styleId]['variant'] = $styleVariants; } } } return $styles; } public static function handle_legacy_slider_class() { $data = Page::get_all_data_by_kirki_meta_key(); foreach ($data as $key => $value) { $post_id = $value['post_id']; // ID of the post $meta_key = $value['meta_key']; // Meta key name $meta_value = $value['meta_value']; // Serialized meta value $meta_value = unserialize($meta_value); // Convert serialized data to array // If the meta value has a 'blocks' key, handle it as a full page data if (isset($meta_value['blocks'])) { $blocks = $meta_value['blocks']; // Get the blocks array $styles = self::get_page_styleblocks($post_id); $updated_styles = self::update_slider_style_blocks($blocks, $styles); // Update block names self::update_page_styleblocks($post_id, $updated_styles); } else { // If no 'blocks' key, treat entire value as blocks array $blocks = $meta_value; $post = get_post($post_id); if (isset($post->post_type) && $post->post_type === 'kirki_symbol') { $styles = $blocks['styleBlocks']; $updated_styles = self::update_slider_style_blocks($blocks['data'], $styles); $blocks['styleBlocks'] = $updated_styles; update_post_meta($post_id, $meta_key, $blocks); } } } } public static function handle_legacy_slider_default_class(){ $styles = self::get_global_data_using_key(KIRKI_GLOBAL_STYLE_BLOCK_META_KEY); if(!$styles){ $styles = array(); } if(count($styles) > 0){ if(isset($styles['kirki_slider_slide'])){ // Handle kirki_slider_mask if(isset($styles['kirki_slider_mask'])){ $variants = $styles['kirki_slider_mask']['variant']; if(count($variants) > 0){ $styleVariants = []; foreach ($variants as $key => $css) { $css = preg_replace('/overflow\s*:\s*hidden;?/', '', $css); $css = preg_replace('/pointer-events\s*:\s*none;?/', '', $css); $css = trim($css); $styleVariants[$key] = $css; } $styles['kirki_slider_mask']['variant'] = $styleVariants; } } // Handle kirki_slider_slide if(isset($styles['kirki_slider_slide'])){ $variants = $styles['kirki_slider_slide']['variant']; if(count($variants) > 0){ $styleVariants = []; foreach ($variants as $key => $css) { $css = preg_replace('/position\s*:\s*absolute;?/', '', $css); $css = preg_replace('/display\s*:\s*none;?/', '', $css); $css = trim($css); $styleVariants[$key] = $css; } $styles['kirki_slider_slide']['variant'] = $styleVariants; } } } } } public static function get_current_item_index($index, $options) { $pagination = isset($options['pagination']) ? $options['pagination'] : false; $items_per_page = isset($options['items_per_page']) ? $options['items_per_page'] : 3; $page_no = isset($options['page_no']) ? $options['page_no'] : 1; if ($pagination && $items_per_page > 0 && $page_no > 0) { // Calculate the start index based on the current page and items per page $index = (($page_no - 1) * $items_per_page) + $index; } return $index; } public static function convertToBytes($val) { $val = trim($val); $last = strtolower($val[strlen($val) - 1]); $val = (int)$val; switch ($last) { case 'g': $val *= 1024; case 'm': $val *= 1024; case 'k': $val *= 1024; } return $val; } public static function get_kirki_full_canvas_template_path(){ return self::normalize_kirki_full_canvas_template_path(KIRKI_FULL_CANVAS_TEMPLATE_PATH); } public static function normalize_kirki_full_canvas_template_path($path){ // replace if has kirki-pro => kirki if (strpos($path, 'kirki-pro') !== false) { $path = str_replace('kirki-pro', 'kirki', $path); } return $path; } }