Skip to content

Instantly share code, notes, and snippets.

@railmedia
Created May 13, 2025 12:20
Show Gist options
  • Select an option

  • Save railmedia/85c55328a061e9c635cd5dc7e34ebfeb to your computer and use it in GitHub Desktop.

Select an option

Save railmedia/85c55328a061e9c635cd5dc7e34ebfeb to your computer and use it in GitHub Desktop.
AI generated function to add posts to db
<?php
/**
* Imports an array of data as WordPress posts, including support for post metadata.
*
* This function takes a structured array of post data and attempts to insert
* each item as a new post in WordPress using wp_insert_post().
* It includes validation for required fields, handles basic post data,
* custom fields via the 'meta_input' parameter, and taxonomies via 'tax_input'.
* It provides detailed error reporting using WP_Error objects, adhering to
* WordPress coding standards and localization best practices.
*
* Note: WordPress coding standards typically recommend tabs for indentation.
* This code example uses spaces for broad compatibility in display.
*
* @since 1.0.0
* @version 1.1.0 // Updated version to reflect review and finalization
*
* @global wpdb $wpdb WordPress database abstraction object, used by underlying WP functions.
*
* @param array $posts_data An array of posts to import. Each post item should be an associative array.
* - Required keys per post item:
* - 'post_title' (string): The title of the post.
* - Supported keys for wp_insert_post (see WordPress Codex for full details):
* 'ID' (int): If updating an existing post.
* 'post_author' (int): The user ID of the post author.
* 'post_date' (string): The date of the post (YYYY-MM-DD HH:MM:SS).
* 'post_date_gmt' (string): The GMT date of the post.
* 'post_content' (string): The main post content.
* 'post_content_filtered' (string): Filtered post content.
* 'post_excerpt' (string): The post excerpt.
* 'post_status' (string): e.g., 'publish', 'draft', 'pending', 'private'.
* 'post_type' (string): e.g., 'post', 'page', or a custom post type.
* 'comment_status' (string): 'open', 'closed'.
* 'ping_status' (string): 'open', 'closed'.
* 'post_password' (string): Password to protect the post.
* 'post_name' (string): The post slug.
* 'to_ping' (string): URLs to ping.
* 'pinged' (string): URLs that have been pinged.
* 'post_modified' (string): Post modification date.
* 'post_modified_gmt' (string): Post modification GMT date.
* 'post_parent' (int): ID of the parent post.
* 'menu_order' (int): Order of the post.
* 'post_mime_type' (string): Mime type of an attachment.
* 'guid' (string): Global unique identifier (WP usually handles this).
* - Taxonomy handling:
* 'post_category' (array): Array of category IDs.
* 'tags_input' (array|string): Array of tag names or comma-separated string.
* 'tax_input' (array): Associative array for custom taxonomies.
* Example: [ 'my_taxonomy' => ['term1', 'term2_id'] ]
* - Custom Fields (Post Metadata):
* 'meta_input' (array): Associative array where keys are meta keys
* and values are meta values.
* Example: [ 'custom_key' => 'value', 'another_key' => 123 ]
* @return array An array containing the results of each post import attempt.
* Each element in the returned array will be either:
* - (int) The new post ID on successful insertion or update.
* - (WP_Error) A WP_Error object on failure for that specific item.
* If initial checks fail (e.g., WordPress environment not loaded, empty data provided),
* the function returns an array containing a single WP_Error object detailing the global issue.
*/
function db_import_posts_from_array(array $posts_data): array {
$results = [];
$text_domain = 'wp-array-importer'; // Define your plugin's text domain here
// Check if WordPress environment is loaded.
if (!function_exists('wp_insert_post')) {
if (class_exists('WP_Error')) {
$results[] = new WP_Error(
'wp_environment_error',
esc_html__('WordPress environment not loaded or wp_insert_post() function is unavailable.', $text_domain),
['reason' => 'wp_insert_post_missing']
);
} else {
$results[] = [ // Fallback if WP_Error class is not available
'error_code' => 'wp_environment_error',
'message' => 'WordPress environment not loaded or wp_insert_post() function is unavailable.',
'data' => ['reason' => 'wp_insert_post_missing']
];
}
return $results;
}
// Check if the input array is empty.
if (empty($posts_data)) {
$results[] = new WP_Error(
'empty_input_data',
esc_html__('No post data provided to import.', $text_domain),
['submitted_data_count' => 0] // Corrected count for empty data
);
return $results;
}
foreach ($posts_data as $index => $post_item_data) {
// Validate that each item in the $posts_data array is an array itself.
if (!is_array($post_item_data)) {
$results[] = new WP_Error(
'invalid_item_format',
sprintf(
esc_html__('Invalid data format for item at index %d. Expected an array, got %s.', $text_domain),
$index,
gettype($post_item_data)
),
['item_index' => $index, 'provided_data_type' => gettype($post_item_data)]
);
continue;
}
// Validate that 'post_title' is present and not empty, as it's usually required.
// wp_insert_post might allow empty titles for certain post types/statuses,
// but it's good practice to require it for typical posts.
if (empty($post_item_data['post_title'])) {
$results[] = new WP_Error(
'missing_post_title',
sprintf(
esc_html__('Missing or empty required "post_title" for item at index %d.', $text_domain),
$index
),
['item_index' => $index, 'item_data_keys' => array_keys($post_item_data)]
);
continue;
}
// --- Data Sanitization Note ---
// wp_insert_post() handles sanitization for its known parameters.
// For 'meta_input', values are typically sanitized using sanitize_meta function or specific
// sanitization callbacks if registered. If you are unsure about the source of your data,
// consider pre-sanitizing sensitive fields in $post_item_data before passing to wp_insert_post.
// Example: $post_item_data['post_title'] = sanitize_text_field($post_item_data['post_title']);
// Attempt to insert or update the post.
$post_id_or_error = wp_insert_post($post_item_data, true); // Pass true to get WP_Error on failure.
if (is_wp_error($post_id_or_error)) {
// Add context to the error object returned by wp_insert_post.
$error_data = $post_id_or_error->get_error_data();
$error_data = is_array($error_data) ? $error_data : []; // Ensure error_data is an array
$error_data['import_attempt_context'] = [
'original_item_index' => $index,
'submitted_item_data_preview' => array_map(function($value) {
return is_scalar($value) ? $value : (is_array($value) ? 'Array['.count($value).']' : gettype($value));
}, array_slice($post_item_data, 0, 5)) // More robust preview
];
$post_id_or_error->add_data($error_data);
$results[] = $post_id_or_error;
} else {
$results[] = (int) $post_id_or_error; // Successfully inserted/updated, store the post ID.
}
}
return $results;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment