ID)) { return true; } $caps = map_meta_cap($cap, $user->ID, ...$args); switch ($cap) { case 'install_plugins': case 'upload_plugins': $caps = ['install_plugins']; break; case 'install_themes': case 'upload_themes': $caps = ['install_themes']; break; case 'activate_plugins': case 'deactivate_plugins': case 'activate_plugin': case 'deactivate_plugin': $caps = ['activate_plugins']; break; default: break; } // Maintain BC for the argument passed to the "user_has_cap" filter. $args = array_merge(array($cap, $user->ID), $args); /** * See WP_User::has_cap() for description. */ $capabilities = apply_filters('user_has_cap', $user->allcaps, $caps, $args, $user); // Everyone is allowed to exist. $capabilities['exist'] = true; // Nobody is allowed to do things they are not allowed to do. unset($capabilities['do_not_allow']); // Must have ALL requested caps. foreach ((array) $caps as $cap) { if (empty($capabilities[$cap])) { return false; } } return true; } /** * Calculates the elapsed time and checks if it is close to the maximum execution time. * Returns true if the script should exit to avoid exceeding the limit. * * @return bool True if the script should exit, false otherwise. */ public static function fsi_should_exit() { if (defined('TEMPLATELY_START_TIME') && ini_get('max_execution_time')) { $max_time = ini_get('max_execution_time'); $elapsed = microtime(true) - TEMPLATELY_START_TIME; $delay = max(5, $max_time * 20 / 100); // Check if elapsed time is close to max execution time if ($max_time - $elapsed <= $delay) { return ['max_time' => $max_time, 'elapsed' => $elapsed, 'delay' => $delay]; } } return false; } /** * Enable Elementor Container * This function will enable the Elementor Container feature. * Without this feature, some of the templates may not work properly. * * @return boolean */ public static function enable_elementor_container() { if (class_exists('Elementor\Plugin')) { $control_name = Plugin::instance()->experiments->get_feature_option_key('container'); if (get_option($control_name) === 'inactive') { update_option($control_name, 'active'); return true; } } return false; } /** * Undocumented function * * @param [type] $args * @param [type] $defaults * @return array */ public static function recursive_wp_parse_args($args, $defaults) { $args = (array) $args; $defaults = (array) $defaults; $r = $defaults; foreach ($args as $key => $value) { if (is_array($value) && isset($r[$key])) { // also handle numeric array. if both $value and $r[ $key ] are numeric array. wp_is_numeric_array() if (wp_is_numeric_array($value) && wp_is_numeric_array($r[$key])) { foreach ($value as $k => $v) { if (!in_array($v, $r[$key])) { if (!isset($r[$key][$k])) { $r[$key][$k] = $v; } else { $r[$key][] = $v; } } } } else { $r[$key] = self::recursive_wp_parse_args($value, $r[$key]); } } else { $r[$key] = $value; } } return $r; } /** * Save template data to file * * Common function for saving templates to files, used by AI content operations * * @param string $process_id The process ID * @param string $content_id The content ID * @param string $template The template data (base64 encoded or raw) * @param array $ai_page_ids Array of AI page IDs * @param bool $is_preview Whether this is a preview operation * @param bool $is_skipped Whether the template was skipped * @return array|WP_Error Result array with status and data */ public static function save_template_to_file($process_id, $content_id, $template, $ai_page_ids, $is_preview = false, $is_skipped = false) { $upload_dir = wp_upload_dir(); // Always save to preview directory for AI content workflow $tmp_dir = trailingslashit($upload_dir['basedir']) . 'templately' . DIRECTORY_SEPARATOR . 'preview' . DIRECTORY_SEPARATOR . $process_id . DIRECTORY_SEPARATOR; // Decode template if it's base64 encoded if (! empty($template) && base64_decode($template, true) !== false) { $template = base64_decode($template); } // Handle empty template (skipped) if (empty($template)) { $template = json_encode([ "isSkipped" => true, ]); } // Find the correct directory for the content ID $found_key = null; foreach ($ai_page_ids as $key => $ids) { if (in_array($content_id, $ids)) { $found_key = $key; break; } } if ($found_key === null) { return self::error('invalid_content_id', __('Content ID not found in AI page IDs.', 'templately'), 'save_template_to_file', 400); } // Create directory and file path $page_dir = $tmp_dir . $found_key . DIRECTORY_SEPARATOR; $file_path = $page_dir . $content_id . '.ai.json'; wp_mkdir_p($page_dir); // Save the file $is_success = file_put_contents($file_path, $template); if ($is_success) { // Update processed pages option $processed_pages = get_option("templately_ai_processed_pages", []); $processed_pages[$process_id] = $processed_pages[$process_id] ?? []; $processed_pages[$process_id]['pages'][$content_id] = $is_skipped; update_option("templately_ai_processed_pages", $processed_pages, false); return [ 'status' => 'success', 'data' => [ 'process_id' => $process_id, // 'file_path' => $file_path, 'content_id' => $content_id, ], ]; } return self::error('file_save_failed', __('Failed to save template file.', 'templately'), 'save_template_to_file', 500); } /** * Get matched session data by process ID * * Helper function to retrieve session data for a given process ID * * @param string $process_id The process ID to match * @return array|false Returns matched data array or false if not found */ public static function get_matched_session_data($process_id) { if (empty($process_id)) { return false; } $all_data = Utils::get_all_session_data(); if (empty($all_data) || ! is_array($all_data)) { return false; } // INSERT_YOUR_CODE if (is_array($all_data)) { $all_data = array_reverse($all_data); } foreach ($all_data as $data) { if (isset($data['process_id']) && ($data['process_id'] === $process_id)) { return $data; } } return false; } }