run();
}
}
// Hook into WordPress init
add_action('plugins_loaded', 'wp_notes_init', 10);
// Register activation and deactivation hooks
register_activation_hook(__FILE__, 'wp_notes_activate');
register_deactivation_hook(__FILE__, 'wp_notes_deactivate');
/**
* Plugin activation handler
*/
function wp_notes_activate() {
// Ensure PHP version is compatible
if (version_compare(PHP_VERSION, '7.2', '<')) {
deactivate_plugins(basename(__FILE__));
wp_die('This plugin requires PHP version 7.2 or higher.');
}
// Initialize plugin settings
add_option('wp_notes_version', WP_NOTES_VERSION);
// Create database tables
wp_notes_create_tables();
// Backup existing notes
$existing_notes = get_option('wp_notes', array());
$existing_done_notes = get_option('wp_done_notes', array());
if (!empty($existing_notes)) {
update_option('wp_notes_backup', $existing_notes);
}
if (!empty($existing_done_notes)) {
update_option('wp_done_notes_backup', $existing_done_notes);
}
}
/**
* Plugin deactivation handler
*/
function wp_notes_deactivate() {
delete_option('wp_notes_version');
}
/**
* Create required database tables
*/
function wp_notes_create_tables() {
global $wpdb;
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
$charset_collate = $wpdb->get_charset_collate();
$sql = array();
// Notes table
$sql[] = "CREATE TABLE IF NOT EXISTS {$wpdb->prefix}wp_notes (
id bigint(20) NOT NULL AUTO_INCREMENT,
user_id bigint(20) NOT NULL,
note_content text NOT NULL,
note_status varchar(20) NOT NULL DEFAULT 'active',
created_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY user_id (user_id),
KEY note_status (note_status)
) $charset_collate;";
foreach ($sql as $query) {
dbDelta($query);
}
}
// Initialize plugin
add_action('plugins_loaded', 'wp_notes_init');
// Set text domain for translations
function wp_notes_load_textdomain() {
load_plugin_textdomain('a-wp-notes', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
add_action('plugins_loaded', 'wp_notes_load_textdomain');
// Include required files
if (defined('WP_NOTES_PATH')) {
require_once WP_NOTES_PATH . 'inc/admin-bar.php';
require_once WP_NOTES_PATH . 'inc/wp-notes-about.php';
require_once WP_NOTES_PATH . 'inc/wp-notes-feedback.php';
require_once WP_NOTES_PATH . 'inc/wp-notes-display.php';
require_once WP_NOTES_PATH . 'inc/wp-notes-styles.php';
}
// Admin Menu
function wp_notes_admin_menu() {
add_menu_page(
'WP Notes',
'WP Notes',
'manage_options',
'wp-notes',
'wp_notes_page_callback',
'dashicons-admin-generic',
3
);
// "My Notes" — the main landing submenu. Same slug as the parent
// menu so clicking either WP Notes or My Notes lands on the same
// central dashboard (the parent's wp_notes_page_callback already
// renders form + active list + completed list).
//
// CRITICAL: callback must be empty here. WordPress registers BOTH
// the parent's and the submenu's callbacks against the same page
// hook when slugs match, and runs them in order — passing
// wp_notes_create_page as the callback caused a duplicate
// "Create a New WP Note" form to render BELOW the main page
// content. Empty callback means only the parent's renderer fires.
add_submenu_page(
'wp-notes', // Parent slug
'My Notes', // Page title (browser tab)
'My Notes', // Menu label (sidebar)
'manage_options', // Capability
'wp-notes', // Menu slug (matches parent → same page)
'' // Empty callback — see comment above
);
// Settings submenu
add_submenu_page(
'wp-notes',
'Settings',
'Settings',
'manage_options',
'wp-notes-settings',
'wp_notes_settings_page'
);
// Import/Export submenu
add_submenu_page(
'wp-notes',
'Import/Export',
'Import/Export',
'manage_options',
'wp-notes-import-export',
'wp_notes_import_export_page'
);
// About submenu — the WP Notes brand is already carried by the
// parent menu, so the submenu can be plain-spoken.
add_submenu_page(
'wp-notes',
'About', // Page title (browser tab)
'About', // Menu label (sidebar)
'manage_options',
'wp-notes-about',
'wp_notes_about_page' // Renderer in inc/wp-notes-about.php
);
// Register settings with validation callback
register_setting(
'wp_notes_settings',
'wp_notes_settings',
array(
'sanitize_callback' => 'wp_notes_validate_settings',
'default' => array(
'default_font' => 'Arial',
'default_size' => '16'
)
)
);
add_settings_section(
'wp_notes_main_section',
'General Settings',
'wp_notes_section_callback',
'wp-notes-settings'
);
add_settings_field(
'wp_notes_default_font',
'Default Font',
'wp_notes_font_callback',
'wp-notes-settings',
'wp_notes_main_section'
);
add_settings_field(
'wp_notes_default_size',
'Default Size',
'wp_notes_size_callback',
'wp-notes-settings',
'wp_notes_main_section'
);
}
// Settings validation callback
function wp_notes_validate_settings($input) {
$output = array();
// Validate font
$allowed_fonts = ['Arial', 'Helvetica', 'Times New Roman', 'Verdana'];
$output['default_font'] = in_array($input['default_font'], $allowed_fonts) ? $input['default_font'] : 'Arial';
// Validate size (8-72px)
$size = absint($input['default_size']);
$output['default_size'] = ($size >= 8 && $size <= 72) ? $size : 16;
add_settings_error(
'wp_notes_settings',
'settings_updated',
'Settings saved successfully.',
'updated'
);
return $output;
}
// Settings page callback
function wp_notes_settings_page() {
// Show any settings messages
settings_errors('wp_notes_settings');
?>
WP Notes Settings
Configure default settings for WP Notes.';
}
// Font setting callback
function wp_notes_font_callback() {
$options = get_option('wp_notes_settings');
$current = $options['default_font'] ?? 'Arial';
?>
>Arial
>Helvetica
>Times New Roman
>Verdana
Font size in pixels (8-72)
getMessage()),
'error'
);
}
}
// Get current settings for display
$options = get_option('wp_notes_settings');
?>
Import/Export Notes
Export Notes
Download your notes as JSON or CSV file.
Import Notes
Import notes from JSON or CSV file.
$notes,
'completed_notes' => $done_notes,
'export_date' => current_time('mysql')
);
if ($format === 'json') {
header('Content-Type: application/json');
header('Content-Disposition: attachment; filename=wp-notes-export-' . date('Y-m-d') . '.json');
echo wp_json_encode($data, JSON_PRETTY_PRINT);
} else {
header('Content-Type: text/csv');
header('Content-Disposition: attachment; filename=wp-notes-export-' . date('Y-m-d') . '.csv');
$output = fopen('php://output', 'w');
fputcsv($output, array('Type', 'Text', 'Created By', 'Created On', 'Status'));
foreach ($notes as $note) {
fputcsv($output, array(
'active',
$note['text'],
$note['author_name'] ?? 'Unknown',
$note['timestamp'] ?? '',
'Active'
));
}
foreach ($done_notes as $note) {
fputcsv($output, array(
'completed',
$note['text'],
$note['author_name'] ?? 'Unknown',
$note['timestamp'] ?? '',
'Completed'
));
}
fclose($output);
}
exit;
}
// Import functionality
function wp_notes_import_data() {
if (!isset($_POST['import_nonce']) || !wp_verify_nonce($_POST['import_nonce'], 'wp_notes_import')) {
wp_die('Security check failed');
}
$file = $_FILES['import_file'];
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if ($ext === 'json') {
$content = file_get_contents($file['tmp_name']);
$data = json_decode($content, true);
if (json_last_error() === JSON_ERROR_NONE) {
if (isset($data['active_notes'])) {
update_option('wp_notes', $data['active_notes']);
}
if (isset($data['completed_notes'])) {
update_option('wp_done_notes', $data['completed_notes']);
}
add_settings_error('wp_notes_import', 'import_success', 'Notes imported successfully', 'updated');
} else {
add_settings_error('wp_notes_import', 'import_error', 'Invalid JSON file');
}
} elseif ($ext === 'csv') {
$handle = fopen($file['tmp_name'], 'r');
$headers = fgetcsv($handle);
$notes = array();
$done_notes = array();
while (($data = fgetcsv($handle)) !== false) {
$note = array(
'text' => $data[1],
'author_name' => $data[2],
'timestamp' => $data[3],
'color' => '#000000',
'size' => '16',
'font' => 'Arial'
);
if ($data[0] === 'active') {
$notes[] = $note;
} else {
$done_notes[] = $note;
}
}
fclose($handle);
update_option('wp_notes', $notes);
update_option('wp_done_notes', $done_notes);
add_settings_error('wp_notes_import', 'import_success', 'Notes imported successfully', 'updated');
} else {
add_settings_error('wp_notes_import', 'import_error', 'Invalid file format. Please use JSON or CSV files.');
}
}
add_action('admin_menu', 'wp_notes_admin_menu');
// Tools → My Notes — quick-access shortcut for users who think of
// notes as a "tool" rather than navigating WP Notes from the top menu.
function wp_notes_add_tools_menu() {
add_management_page(
'My Notes', // Page title (browser tab)
'My Notes', // Menu label (Tools submenu)
'manage_options', // Capability
'wp-notes-create', // Menu slug
'wp_notes_create_page' // Renderer (same page as wp-notes)
);
}
add_action('admin_menu', 'wp_notes_add_tools_menu');
// Enqueue Scripts
function wp_notes_enqueue_scripts() {
// wp_enqueue_script('wp-notes-activity-tracker', WP_NOTES_URL . 'js/wp-notes-activity.js', ['jquery'], null, true); // Activity tracking removed 2025-05-09
wp_enqueue_script('wp-notes-feedback', WP_NOTES_URL . 'js/wp-notes-feedback.js', ['jquery'], null, true);
wp_localize_script('wp-notes-feedback', 'wp_notes_feedback_vars', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('wp_notes_feedback_nonce')
));
}
add_action('admin_enqueue_scripts', 'wp_notes_enqueue_scripts');
// Emoji picker initialization
add_action('admin_footer', 'wp_notes_emoji_picker_init');
function wp_notes_emoji_picker_init() {
?>
Create a New WP Note
jQuery(document).ready(function($) {
// Show edit form
$('.edit-note').on('click', function(e) {
e.preventDefault();
var noteId = $(this).data('note-id');
$('#edit-note-' + noteId).toggle();
});
// AJAX submit the edit form
$('.edit-note-form').on('submit', function(e) {
e.preventDefault();
var noteId = $(this).data('note-id');
var formData = $(this).serialize() + '&action=wp_notes_save_edit¬e_id=' + noteId;
$.post(ajaxurl, formData, function(response) {
if (response.success) {
alert('Note updated successfully!');
location.reload(); // Reload to display updated notes
} else {
alert('Error updating note: ' + response.data);
}
});
});
// Persist the dismissal of the empty-state notice.
// WP core's common.js attaches the X button and hides the
// notice on click; we just hook the same click and fire an
// AJAX call to set the user_meta flag so the notice does
// not reappear on the next page load.
$(document).on('click', '.wp-notes-empty .notice-dismiss', function() {
var \$notice = $(this).closest('.wp-notes-empty');
var type = \$notice.data('wp-notes-empty-type');
var nonce = \$notice.data('wp-notes-nonce');
if (!type || !nonce) { return; }
$.post(ajaxurl, {
action: 'wp_notes_dismiss_empty',
type: type,
nonce: nonce
});
});
});
";
}
// Persist a user's dismissal of the "No active/completed notes found"
// empty-state notice so it doesn't reappear on the next page load.
// Triggered by inline JS in wp_notes_add_inline_scripts() when the
// user clicks the X on a .wp-notes-empty notice.
add_action('wp_ajax_wp_notes_dismiss_empty', 'wp_notes_ajax_dismiss_empty');
function wp_notes_ajax_dismiss_empty() {
if (!current_user_can('edit_posts')) {
wp_send_json_error('Insufficient permissions.', 403);
}
check_ajax_referer('wp_notes_dismiss_empty', 'nonce');
$type = isset($_POST['type']) ? sanitize_key(wp_unslash($_POST['type'])) : '';
if (!in_array($type, ['active', 'completed'], true)) {
wp_send_json_error('Invalid list type.', 400);
}
update_user_meta(get_current_user_id(), 'wp_notes_dismissed_empty_' . $type, 1);
wp_send_json_success(['dismissed' => $type]);
}
// Handle saving edited notes
add_action('wp_ajax_wp_notes_save_edit', 'wp_notes_save_edit');
function wp_notes_save_edit() {
// Security checks
if (!current_user_can('edit_posts')) {
wp_send_json_error('Insufficient permissions.');
return;
}
// Security check using nonce
check_ajax_referer('wp_notes_nonce', '_wpnonce');
// Validate required fields
$required_fields = ['note_id', 'new_text', 'edit_color', 'edit_size', 'edit_font'];
foreach ($required_fields as $field) {
if (!isset($_POST[$field])) {
wp_send_json_error("Missing required field: $field");
return;
}
}
// Get and sanitize data
$note_id = absint($_POST['note_id']);
$new_text = sanitize_text_field($_POST['new_text']);
$new_color = sanitize_hex_color($_POST['edit_color']);
$new_size = absint($_POST['edit_size']);
// Validate font against allowed list
$allowed_fonts = ['Arial', 'Helvetica', 'Times New Roman', 'Verdana'];
$new_font = in_array($_POST['edit_font'], $allowed_fonts) ? $_POST['edit_font'] : 'Arial';
// Validate size range
if ($new_size < 8 || $new_size > 72) {
wp_send_json_error('Font size must be between 8 and 72 pixels.');
return;
}
$notes = get_option('wp_notes', array());
if (!isset($notes[$note_id])) {
wp_send_json_error('Note not found.');
return;
}
// Update note with validation
$notes[$note_id] = array_merge($notes[$note_id], [
'text' => $new_text,
'color' => $new_color ?: '#000000',
'size' => $new_size,
'font' => $new_font,
'modified_timestamp' => current_time('mysql'),
'modified_by' => get_current_user_id()
]);
if (!update_option('wp_notes', $notes)) {
wp_send_json_error('Failed to update note.');
return;
}
wp_send_json_success([
'message' => 'Note updated successfully',
'note' => $notes[$note_id]
]);
}
/**
* Main WP Notes Page - Central hub for note management
*/
function wp_notes_page_callback() {
if (!current_user_can('edit_posts')) {
wp_die(__('You do not have sufficient permissions to access this page.', 'a-wp-notes'));
}
$notes = get_option('wp_notes', array());
$done_notes = get_option('wp_done_notes', array());
$total_notes = count($notes);
$total_done = count($done_notes);
// Get user settings
$settings = get_option('wp_notes_settings', array(
'default_font' => 'Arial',
'default_size' => '16'
));
?>
' . esc_html__('No notes found.', 'a-wp-notes') . '';
return;
}
/* Dashboard widget table. No checkbox column — bulk actions are not
wired up; re-add when there is something to act on. */
echo '';
// JavaScript for form toggling and AJAX submissions
?>
' . esc_html__('No completed notes.', 'a-wp-notes') . '';
return;
}
echo ' ';
// Add JavaScript for select all functionality
?>
sanitize_text_field($_POST['wp_notes_text']),
'color' => sanitize_hex_color($_POST['wp_notes_color']) ?: '#000000',
'size' => absint($_POST['wp_notes_size']) ?: 16,
'font' => sanitize_text_field($_POST['wp_notes_font']) ?: 'Arial',
'timestamp' => current_time('mysql'),
'author' => $current_user->ID,
'author_name' => $current_user->display_name
);
$notes[] = $new_note;
update_option('wp_notes', $notes);
wp_redirect(admin_url('admin.php?page=wp-notes'));
exit;
}
// Handle "Mark as Done" submissions
if (isset($_POST['mark_done']) && isset($_POST['note_id'])) {
$notes = get_option('wp_notes', array());
$done_notes = get_option('wp_done_notes', array());
$note_id = absint($_POST['note_id']);
if (isset($notes[$note_id])) {
$note = $notes[$note_id];
$note['completed_by'] = $current_user->display_name;
$note['completed_on'] = current_time('mysql');
$done_notes[] = $note;
unset($notes[$note_id]);
update_option('wp_notes', $notes);
update_option('wp_done_notes', $done_notes);
wp_redirect(admin_url('admin.php?page=wp-notes'));
exit;
}
}
// Handle marking notes as done if 'mark_done' action is triggered
if (isset($_POST['mark_done']) && isset($_POST['note_ids'])) {
$notes = get_option('wp_notes', array());
$done_notes = get_option('wp_done_notes', array());
// Move selected notes to done list
foreach ($notes as $key => $note) {
if (in_array($key, $_POST['note_ids'])) {
$note['completed_by'] = $current_user->display_name;
$note['completed_on'] = current_time('mysql');
$done_notes[] = $note;
unset($notes[$key]); // Remove from active notes
}
}
// Update both lists in the database
update_option('wp_notes', $notes);
update_option('wp_done_notes', $done_notes);
// Redirect to avoid form resubmission
wp_redirect(admin_url('admin.php?page=wp-notes'));
exit;
}
// Handle restore note action
if (isset($_POST['restore_note']) && isset($_POST['done_ids'])) {
$notes = get_option('wp_notes', array());
$done_notes = get_option('wp_done_notes', array());
$current_user = wp_get_current_user();
$new_done_notes = array();
foreach ($done_notes as $key => $note) {
if (in_array($key, $_POST['done_ids'])) {
$note['last_modified'] = current_time('mysql');
$note['restored_by'] = $current_user->display_name;
$notes[] = $note;
} else {
$new_done_notes[] = $note;
}
}
update_option('wp_notes', $notes);
update_option('wp_done_notes', $new_done_notes);
}
// Handle edit note action
if (isset($_POST['edit_note']) && isset($_POST['note_ids'])) {
// Add edit functionality here
$notes = get_option('wp_notes', array());
$current_user = wp_get_current_user();
foreach ($_POST['note_ids'] as $key) {
if (isset($notes[$key])) {
$notes[$key]['last_modified'] = current_time('mysql');
$notes[$key]['modified_by'] = $current_user->display_name;
}
}
update_option('wp_notes', $notes);
}
}
// AJAX handler for editing a note
add_action('wp_ajax_wp_notes_edit_note', 'wp_notes_edit_note');
function wp_notes_edit_note() {
if (!isset($_POST['note_id']) || !isset($_POST['edit_text'])) {
wp_send_json_error('Invalid request');
return;
}
$note_id = absint($_POST['note_id']);
$new_text = sanitize_text_field($_POST['edit_text']);
$new_color = sanitize_hex_color($_POST['edit_color']);
$new_size = absint($_POST['edit_size']);
$new_font = sanitize_text_field($_POST['edit_font']);
$notes = get_option('wp_notes', array());
if (isset($notes[$note_id])) {
$notes[$note_id]['text'] = $new_text;
$notes[$note_id]['color'] = $new_color;
$notes[$note_id]['size'] = $new_size;
$notes[$note_id]['font'] = $new_font;
update_option('wp_notes', $notes);
wp_send_json_success();
} else {
wp_send_json_error('Note not found.');
}
}
// Optimize the restore function for performance
function wp_notes_restore($note_id) {
$done_notes = get_option('wp_done_notes', array());
$notes = get_option('wp_notes', array());
if (isset($done_notes[$note_id])) {
$notes[$note_id] = $done_notes[$note_id];
unset($done_notes[$note_id]);
update_option('wp_notes', $notes);
update_option('wp_done_notes', $done_notes);
wp_redirect(admin_url('admin.php?page=wp-notes'));
}
}
// Dashboard widget
function wp_notes_dashboard_widget() {
wp_notes_list_table();
}
function wp_notes_add_dashboard_widgets() {
wp_add_dashboard_widget(
'wp_notes_dashboard_widget',
'WP Notes',
'wp_notes_dashboard_widget'
);
}
add_action('wp_dashboard_setup', 'wp_notes_add_dashboard_widgets');
// Register Custom Post Type for notes
function wp_notes_register_cpt() {
$labels = array(
'name' => __('Notes', 'a-wp-notes'),
'singular_name' => __('Note', 'a-wp-notes'),
'menu_name' => __('WP Notes', 'a-wp-notes'),
'add_new' => __('Add New', 'a-wp-notes'),
'add_new_item' => __('Add New Note', 'a-wp-notes'),
'edit_item' => __('Edit Note', 'a-wp-notes'),
'new_item' => __('New Note', 'a-wp-notes'),
'view_item' => __('View Note', 'a-wp-notes'),
'search_items' => __('Search Notes', 'a-wp-notes'),
'not_found' => __('No notes found', 'a-wp-notes'),
'not_found_in_trash'=> __('No notes found in trash', 'a-wp-notes'),
);
$args = array(
'labels' => $labels,
'public' => false,
// show_ui=false: the live UI stores notes in wp_options, not as
// CPT posts. show_ui=true caused WordPress to auto-inject "All
// Notes" and "Add New" submenus that pointed at post-new.php and
// routed users into the standard post editor — which writes to
// the wrong storage. The CPT remains registered so the
// wp_notes_migrate_to_cpt() helper can still use wp_insert_post.
'show_ui' => false,
'show_in_menu' => false,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array('title', 'editor', 'author', 'custom-fields'),
'has_archive' => false,
'menu_position' => null,
'show_in_rest' => false,
);
register_post_type('wp_note', $args);
// Register taxonomy for note categories
$tax_labels = array(
'name' => __('Note Categories', 'a-wp-notes'),
'singular_name' => __('Note Category', 'a-wp-notes'),
'search_items' => __('Search Categories', 'a-wp-notes'),
'all_items' => __('All Categories', 'a-wp-notes'),
'parent_item' => __('Parent Category', 'a-wp-notes'),
'parent_item_colon' => __('Parent Category:', 'a-wp-notes'),
'edit_item' => __('Edit Category', 'a-wp-notes'),
'update_item' => __('Update Category', 'a-wp-notes'),
'add_new_item' => __('Add New Category', 'a-wp-notes'),
'new_item_name' => __('New Category Name', 'a-wp-notes'),
'menu_name' => __('Categories', 'a-wp-notes'),
);
register_taxonomy('wp_note_category', 'wp_note', array(
'hierarchical' => true,
'labels' => $tax_labels,
// Hidden alongside the parent CPT — live UI doesn't surface
// categories yet, and showing the taxonomy in admin with the
// parent hidden would just dead-link.
'show_ui' => false,
'show_admin_column' => false,
'query_var' => true,
'show_in_rest' => false,
));
}
add_action('init', 'wp_notes_register_cpt');
// Add custom meta box for note properties
function wp_notes_add_meta_boxes() {
add_meta_box(
'wp_notes_properties',
__('Note Properties', 'a-wp-notes'),
'wp_notes_render_properties_meta_box',
'wp_note',
'side',
'high'
);
}
add_action('add_meta_boxes', 'wp_notes_add_meta_boxes');
// Render meta box content
function wp_notes_render_properties_meta_box($post) {
// Add nonce for security
wp_nonce_field('wp_notes_meta_box', 'wp_notes_meta_box_nonce');
// Get current values
$color = get_post_meta($post->ID, '_wp_note_color', true) ?: '#000000';
$size = get_post_meta($post->ID, '_wp_note_size', true) ?: '16';
$font = get_post_meta($post->ID, '_wp_note_font', true) ?: 'Arial';
$status = get_post_meta($post->ID, '_wp_note_status', true) ?: 'active';
?>
>Arial
>Helvetica
>Times New Roman
>Verdana
>
>
'sanitize_hex_color',
'_wp_note_size' => 'absint',
'_wp_note_font' => 'sanitize_text_field',
'_wp_note_status' => 'sanitize_text_field'
);
foreach ($fields as $key => $sanitize_callback) {
if (isset($_POST[str_replace('_', '', $key)])) {
$value = call_user_func($sanitize_callback, $_POST[str_replace('_', '', $key)]);
update_post_meta($post_id, $key, $value);
}
}
}
add_action('save_post_wp_note', 'wp_notes_save_meta_box_data');
// Data Migration Tool
function wp_notes_migrate_to_cpt() {
$existing_notes = get_option('wp_notes', array());
$done_notes = get_option('wp_done_notes', array());
$migrated_count = 0;
$errors = array();
// Start migration
foreach ($existing_notes as $note) {
$post_data = array(
'post_title' => wp_trim_words($note['text'], 10, '...'),
'post_content' => $note['text'],
'post_status' => 'publish',
'post_type' => 'wp_note',
'post_author' => $note['author'] ?? get_current_user_id(),
);
// Insert the post
$post_id = wp_insert_post($post_data, true);
if (!is_wp_error($post_id)) {
// Add note meta data
update_post_meta($post_id, '_wp_note_color', $note['color'] ?? '#000000');
update_post_meta($post_id, '_wp_note_size', $note['size'] ?? '16');
update_post_meta($post_id, '_wp_note_font', $note['font'] ?? 'Arial');
update_post_meta($post_id, '_wp_note_status', 'active');
update_post_meta($post_id, '_wp_note_created', $note['timestamp'] ?? '');
update_post_meta($post_id, '_wp_note_author_name', $note['author_name'] ?? '');
$migrated_count++;
} else {
$errors[] = $post_id->get_error_message();
}
}
// Migrate completed notes
foreach ($done_notes as $note) {
$post_data = array(
'post_title' => wp_trim_words($note['text'], 10, '...'),
'post_content' => $note['text'],
'post_status' => 'publish',
'post_type' => 'wp_note',
'post_author' => $note['author'] ?? get_current_user_id(),
);
$post_id = wp_insert_post($post_data, true);
if (!is_wp_error($post_id)) {
update_post_meta($post_id, '_wp_note_color', $note['color'] ?? '#000000');
update_post_meta($post_id, '_wp_note_size', $note['size'] ?? '16');
update_post_meta($post_id, '_wp_note_font', $note['font'] ?? 'Arial');
update_post_meta($post_id, '_wp_note_status', 'completed');
update_post_meta($post_id, '_wp_note_created', $note['timestamp'] ?? '');
update_post_meta($post_id, '_wp_note_completed_by', $note['completed_by'] ?? '');
update_post_meta($post_id, '_wp_note_completed_on', $note['completed_on'] ?? '');
update_post_meta($post_id, '_wp_note_author_name', $note['author_name'] ?? '');
$migrated_count++;
} else {
$errors[] = $post_id->get_error_message();
}
}
// Create backup of old data
update_option('wp_notes_pre_migration_backup', array(
'notes' => $existing_notes,
'done_notes' => $done_notes,
'migration_date' => current_time('mysql')
));
return array(
'success' => true,
'migrated_count' => $migrated_count,
'errors' => $errors
);
}
// Add migration notice for admin
function wp_notes_migration_notice() {
if (!current_user_can('manage_options')) {
return;
}
$migrated = get_option('wp_notes_migration_completed');
if (!$migrated) {
?>