{"id":228,"date":"2025-04-01T14:33:38","date_gmt":"2025-04-01T14:33:38","guid":{"rendered":"https:\/\/www.kwwd.co.uk\/blog\/?p=228"},"modified":"2025-04-01T14:33:38","modified_gmt":"2025-04-01T14:33:38","slug":"wordpress-plugin-to-download-random-posts-to-a-csv-file","status":"publish","type":"post","link":"https:\/\/www.kwwd.co.uk\/blog\/wordpress-plugin-to-download-random-posts-to-a-csv-file\/","title":{"rendered":"WordPress: Plugin To Download Random Posts To A CSV File"},"content":{"rendered":"<p>The following code will create a plugin that allows you to download random posts based on selected categories in an admin page.<\/p>\n<p>3 CVS files will be generated and downloaded as a zip file.<\/p>\n<p>The 3 files will format the post content for BlueSky (Max 300 characters), Twitter (Max 280 characters) and Facebook\/LinkedIn (500+ characters)<\/p>\n<p>Create a new folder for your plugin, e.g., random-posts-csv, and inside this folder, create a file named random-posts-csv.php.<\/p>\n<pre><code class=\"language-php line-numbers\">\r\n\r\n&lt;?php\r\n\/**\r\n * Plugin Name: Random Posts CSV Export\r\n * Description: Export random posts from selected categories to a CSV file.\r\n * Version: 1.0\r\n * Author: Your Name\r\n *\/\r\n\r\n\/\/ Exit if accessed directly.\r\nif (!defined('ABSPATH')) {\r\n    exit;\r\n}\r\n\r\n\/\/ Include the admin page.\r\ninclude(plugin_dir_path(__FILE__) . 'admin-page.php');\r\n\r\n\/\/ Include the CSV generation functionality.\r\ninclude(plugin_dir_path(__FILE__) . 'generate-csv.php');\r\n?>\r\n<\/code><\/pre>\n<p>Create a new file named admin-page.php in the same folder and add the following code:<\/p>\n<pre><code class=\"language-php line-numbers\">\r\n&lt;?php\r\n\r\n\/\/ Add the admin menu item.\r\nadd_action('admin_menu', 'rpcse_add_admin_menu');\r\nfunction rpcse_add_admin_menu() {\r\n    add_menu_page('Random Posts CSV Export', 'Random Posts CSV Export', 'manage_options', 'rpcse-admin-page', 'rpcse_admin_page');\r\n}\r\n\r\n\/\/ Display the admin page.\r\nfunction rpcse_admin_page() {\r\n    ?>\r\n    &lt;div class=\"wrap\">\r\n        &lt;h1>Random Posts CSV Export&lt;\/h1>\r\n        &lt;form method=\"post\" action=\"\">\r\n            &lt;label for=\"rpcse_num_posts\">Number of posts to select:&lt;\/label>\r\n            &lt;select name=\"rpcse_num_posts\" id=\"rpcse_num_posts\">\r\n                &lt;?php for ($i = 1; $i &lt;= 10; $i++) : ?>\r\n                    &lt;option value=\"&lt;?php echo $i; ?>\">&lt;?php echo $i; ?>&lt;\/option>\r\n                &lt;?php endfor; ?>\r\n            &lt;\/select>\r\n            &lt;br>&lt;br>\r\n            &lt;label for=\"rpcse_categories\">Select Categories:&lt;\/label>&lt;br>\r\n            &lt;?php\r\n            $categories = get_categories();\r\n            foreach ($categories as $category) : ?>\r\n                &lt;input type=\"checkbox\" name=\"rpcse_categories[]\" value=\"&lt;?php echo $category->term_id; ?>\"> &lt;?php echo $category->name; ?>&lt;br>\r\n            &lt;?php endforeach; ?>\r\n            &lt;br>\r\n            &lt;input type=\"submit\" name=\"rpcse_generate_csv\" value=\"Generate CSV\" class=\"button button-primary\">\r\n        &lt;\/form>\r\n    &lt;\/div>\r\n    &lt;?php\r\n}\r\n?>\r\n<\/code><\/pre>\n<p>Create a new file named generate-csv.php in the same folder and add the following code:<\/p>\n<pre><code class=\"language-php line-numbers\">\r\n&lt;?php\r\n\r\n\/\/ Hook into the admin_init action to handle form submission.\r\nadd_action('admin_init', 'rpcse_handle_form_submission');\r\n\r\nfunction rpcse_handle_form_submission() {\r\n    if (isset($_POST['rpcse_generate_csv'])) {\r\n        $num_posts = intval($_POST['rpcse_num_posts']);\r\n        $categories = isset($_POST['rpcse_categories']) ? $_POST['rpcse_categories'] : [];\r\n\r\n        \/\/ Fetch random posts.\r\n        $args = [\r\n            'posts_per_page' => $num_posts,\r\n            'orderby'        => 'rand',\r\n            'category__in'   => $categories,\r\n        ];\r\n        $posts = get_posts($args);\r\n\r\n        \/\/ Generate CSV content - defaults\r\n\t   $twitter_csv_content = \"\";\r\n\t   $fb_linked_csv_content = \"\";\r\n\t   $blue_mast_csv_content = \"\";\r\n\t   \r\n\t\t\/\/ Set Character Limits\r\n\t\t$FBLength = 1000;\r\n\t\t$TwitterLength = 280;\r\n\t\t$MastadonLength = 500;\r\n\t\t$BlueSkyLength = 300;\r\n\t\t\r\n\t\tglobal $wpdb;\r\n\r\n        foreach ($posts as $post) {\t\t\r\n\t\t\t\/\/ Set Defaults for error handling\r\n\t\t\t$TwitterExcerpt = '';\r\n\t\t\t$FullExcerpt = '';\r\n\t\t\t$MastadonExcerpt = '';\r\n\t\t\t$BlueSkyExcerpt = '';\r\n\r\n\t\t\t\r\n            $title = $post->post_title;\r\n            $tempexcerpt = trim($post->post_excerpt);\r\n\t\t\t\r\n\t\t\tif(($tempexcerpt=='') || (is_null($tempexcerpt)) || (empty($tempexcerpt)))\r\n\t\t\t{\r\n\t\t\t\t$tempexcerpt = trim($post->post_content);\t\t\t\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t$excerpt = wp_strip_all_tags($tempexcerpt);\r\n            $url = get_permalink($post);\r\n\t\t\t\r\n\t\t\t\r\n\t\t\t\/\/ Overwrite URL if we have a short URL\r\n\t\t\t\r\n\t\t\tif (is_plugin_active('url-shortify\/url-shortify.php')) \r\n\t\t\t{\r\n\t\t\t\t\r\n\t\t\t\t\/\/ Get the short URL slug from the custom table.\r\n\t\t\t\t$table_name = $wpdb->prefix . 'kc_us_links'; \/\/ Replace with your actual table name if different.\r\n\t\t\t\t$post_id = $post->ID;\r\n\r\n\t\t\t\t$slug = $wpdb->get_var($wpdb->prepare(\r\n\t\t\t\t\t\"SELECT slug FROM $table_name WHERE cpt_id = %d AND status = 1\",\r\n\t\t\t\t\t$post_id\r\n\t\t\t\t));\r\n\t\t\t\t\r\n\r\n\t\t\t\t\/\/ If a short URL slug is found, replace the $url variable.\r\n\t\t\t\tif (!empty($slug)) {\r\n\t\t\t\t\t$url = site_url($slug); \/\/ Assuming the slug is appended to your site URL.\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\t\t\t\r\n\t\t\t\r\n            $image = get_the_post_thumbnail_url($post, 'full');\r\n\r\n            \/\/ Adjust excerpt length if combined_info exceeds 280 characters.\r\n\t\t\t$TweetTitleLength = 19;\r\n\t\t\t$PostTitleLength = strlen($title);\r\n\t\t\t$URLLength = strlen($url);\r\n\t\t\t$excerptLength = strlen($excerpt);\r\n\t\t\r\n\t\t\t\/\/ Twitter\r\n\t\t\t$availableTwitterLength = $TwitterLength-($TweetTitleLength+$PostTitleLength+$URLLength);\r\n\t\t\t$availableTwitterLength = $availableTwitterLength - 3;\r\n\r\n\t\t\t\/\/ Grab Twitter Content\t\t\r\n\t\t\tif($excerptLength > $availableTwitterLength)\r\n\t\t\t{\r\n\t\t\t\t$TwitterExcerpt = mb_substr($excerpt, 0, $availableTwitterLength);\r\n\t\t\t\t$TwitterExcerpt = trim($TwitterExcerpt).'...';\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\t$TwitterExcerpt = $excerpt;\r\n\t\t\t}\r\n\t\t\t$combined_twitter_info = \"From The Archives: $title\\n\\n$TwitterExcerpt\\n\\n$url\";\r\n\t\t\t\r\n\t\t\t\/\/ BlueSky\r\n\t\t\t$availableBSLength = $BlueSkyLength-($TweetTitleLength+$PostTitleLength+$URLLength);\r\n\t\t\t$availableBSLength = $availableBSLength - 3;\r\n\t\r\n\t\t\t\/\/ Grab BlueSky\/Mastadon Content\t\t\r\n\t\t\tif($excerptLength > $availableBSLength)\r\n\t\t\t{\r\n\t\t\t\t$BlueSkyExcerpt = mb_substr($excerpt, 0, $availableBSLength);\r\n\t\t\t\t$BlueSkyExcerpt = trim($BlueSkyExcerpt).'...';\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\t$BlueSkyExcerpt = $excerpt;\r\n\t\t\t}\r\n\r\n\t\t\t$combined_bluesky_info = \"From The Archives: $title\\n\\n$BlueSkyExcerpt\\n\\n$url\";\r\n\t\t\t\r\n\t\t\t\/\/ Facebook\r\n\t\t\t$availableFBLength = $FBLength-($TweetTitleLength+$PostTitleLength+$URLLength);\r\n\t\t\t$availableFBLength = $availableFBLength - 3;\r\n\t\r\n\t\t\t\/\/ Grab Facebook\/LinkedIn Content\t\t\r\n\t\t\tif($excerptLength > $FBLength)\r\n\t\t\t{\r\n\t\t\t\t$FullExcerpt = mb_substr($excerpt, 0, $availableFBLength);\r\n\t\t\t\t$FullExcerpt = trim($FullExcerpt).'...';\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\t$FullExcerpt = $excerpt;\r\n\t\t\t}\r\n\r\n\t\t\t$combined_fb_info = \"From The Archives: $title\\n\\n$FullExcerpt\\n\\n$url\";\r\n\t\t\t\r\n\t\t\t\/\/ Add the data to the CSV content.\r\n\t\t\t$twitter_csv_content .= '\"' . str_replace('\"', '\"\"', $combined_twitter_info) . '\",\"' . $image . \"\\\",,,\\n\";\r\n\t\t\t$blue_mast_csv_content .= '\"' . str_replace('\"', '\"\"', $combined_bluesky_info) . '\",\"' . $image . \"\\\",,,\\n\";\r\n\t\t\t$fb_linked_csv_content .= '\"' . str_replace('\"', '\"\"', $combined_fb_info) . '\",\"' . $image . \"\\\",,,\\n\";\r\n\r\n        }\r\n\t\t\r\n\t\t$generatedTime = date(\"Y-m-d - H-i-s\");\r\n\t\t\t\t\r\n\t\t\/\/ Output Facebook\/LinkedIn CSV file for download.\r\n\t\t\r\n\t\t\/\/ Create temporary files for CSVs.\r\n        $twitter_csv_filename = tempnam(sys_get_temp_dir(), 'twitter_posts') . '.csv';\r\n        $blue_mast_csv_filename = tempnam(sys_get_temp_dir(), 'bluesky_posts') . '.csv';\r\n        $fb_linked_csv_filename = tempnam(sys_get_temp_dir(), 'facebook_posts') . '.csv';\r\n\r\n        file_put_contents($twitter_csv_filename, \"\\xEF\\xBB\\xBF\" . $twitter_csv_content);\r\n        file_put_contents($blue_mast_csv_filename, \"\\xEF\\xBB\\xBF\" . $blue_mast_csv_content);\r\n        file_put_contents($fb_linked_csv_filename, \"\\xEF\\xBB\\xBF\" . $fb_linked_csv_content);\r\n\r\n        \/\/ Create a zip file containing the CSV files.\r\n        $zip = new ZipArchive();\r\n        $zip_filename = tempnam(sys_get_temp_dir(), 'csv_files') . '.zip';\r\n        if ($zip->open($zip_filename, ZipArchive::CREATE) !== TRUE) {\r\n            exit(\"Unable to create zip file\");\r\n        }\r\n\r\n        $zip->addFile($twitter_csv_filename, 'twitter_posts-' . $generatedTime . '.csv');\r\n        $zip->addFile($blue_mast_csv_filename, 'bluesky_posts-' . $generatedTime . '.csv');\r\n        $zip->addFile($fb_linked_csv_filename, 'facebook_posts-' . $generatedTime . '.csv');\r\n        $zip->close();\r\n\r\n        \/\/ Output the zip file for download.\r\n        header('Content-Type: application\/zip');\r\n        header('Content-Disposition: attachment; filename=evergreen_posts-' . $generatedTime . '.zip');\r\n        header('Content-Length: ' . filesize($zip_filename));\r\n        readfile($zip_filename);\r\n\r\n        \/\/ Clean up the temporary files.\r\n        unlink($twitter_csv_filename);\r\n        unlink($blue_mast_csv_filename);\r\n        unlink($fb_linked_csv_filename);\r\n        unlink($zip_filename);\r\n        exit;\r\n\r\n    }\r\n}\r\n\r\n?>\r\n<\/code><\/pre>\n<p>Install and Activate the Plugin<\/p>\n<p>&#8211; Zip the random-posts-csv folder.<br \/>\n&#8211; Go to the WordPress admin dashboard.<br \/>\n&#8211; Navigate to Plugins > Add New > Upload Plugin.<br \/>\n&#8211; Upload the zipped folder and activate the plugin.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The following code will create a plugin that allows you to download random posts based on selected categories in an admin page. 3 CVS files [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[50,55,12],"class_list":["post-228","post","type-post","status-publish","format-standard","hentry","category-wordpress","tag-content","tag-plugin","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/posts\/228","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=228"}],"version-history":[{"count":0,"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/posts\/228\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=228"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=228"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.kwwd.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=228"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}