Changeset 3345168
- Timestamp:
- 08/15/2025 01:49:25 PM (8 months ago)
- Location:
- wp-todo/trunk
- Files:
-
- 10 edited
-
assets/js/wptodo-admin.js (modified) (1 diff)
-
inc/enqueue.php (modified) (1 diff)
-
list_table/custom_columns.php (modified) (3 diffs)
-
meta_boxes/wptodo_meta_boxe.php (modified) (2 diffs)
-
notification/notify.php (modified) (1 diff)
-
readme.txt (modified) (1 diff)
-
todo/count_down_timer.php (modified) (2 diffs)
-
todo/modal_view.php (modified) (4 diffs)
-
todo/wptodo_custom_post_type.php (modified) (4 diffs)
-
wp-todo.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
wp-todo/trunk/assets/js/wptodo-admin.js
r3345118 r3345168 18 18 19 19 // Fetch new content via AJAX 20 $.post(wptodo_ajax.ajax_url, { action: 'wp todo_quick_view', post_id: post_id}, function(response){20 $.post(wptodo_ajax.ajax_url, { action: 'wp-todo_quick_view', post_id: post_id, 'wp-todo_nonce': wptodo_ajax.nonce }, function(response){ 21 21 if(response.success){ 22 22 $modal.html(response.data); -
wp-todo/trunk/inc/enqueue.php
r3345118 r3345168 1 1 <?php 2 2 add_action( 'admin_enqueue_scripts', function( $hook ) { 3 if ( 'edit.php' !== $hook || get_post_type() !== 'wp todo' ) return;3 if ( 'edit.php' !== $hook || get_post_type() !== 'wp-todo' ) return; 4 4 5 5 // jQuery UI for modal 6 6 wp_enqueue_script( 'jquery-ui-dialog' ); 7 wp_enqueue_style( 'jquery-ui-css', '//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css' );7 wp_enqueue_style( 'jquery-ui-css', '//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css', array(), "1.13.2" ); 8 8 9 9 // Custom JS 10 wp_enqueue_script( 'wptodo-admin-js', PLUGIN_DIR_URL . 'assets/js/wptodo-admin.js', ['jquery', 'jquery-ui-dialog'], null, true );10 wp_enqueue_script( 'wptodo-admin-js', PLUGIN_DIR_URL . 'assets/js/wptodo-admin.js', ['jquery', 'jquery-ui-dialog'], "1.0", true ); 11 11 12 12 // Localize AJAX URL 13 13 wp_localize_script( 'wptodo-admin-js', 'wptodo_ajax', [ 14 'ajax_url' => admin_url( 'admin-ajax.php' ) 14 'ajax_url' => admin_url( 'admin-ajax.php' ), 15 'nonce' => wp_create_nonce( 'wp-todo_action' ) 15 16 ] ); 16 17 -
wp-todo/trunk/list_table/custom_columns.php
r3345118 r3345168 1 1 <?php 2 2 // 1️⃣ Add new columns to the CPT list table 3 add_filter( 'manage_wp todo_posts_columns', function( $columns ) {3 add_filter( 'manage_wp-todo_posts_columns', function( $columns ) { 4 4 // Optional: remove default Date column 5 5 // unset($columns['date']); 6 $columns['todo_assigned_by'] = __( 'Assigned By', 'wp todo' );7 $columns['todo_deadline'] = __( 'Deadline', 'wp todo' );8 $columns['todo_assignee'] = __( 'Assigned To', 'wp todo' );9 $columns['todo_priority'] = __( 'Priority', 'wp todo' );10 $columns['todo_status'] = __( 'Status', 'wp todo' );6 $columns['todo_assigned_by'] = __( 'Assigned By', 'wp-todo' ); 7 $columns['todo_deadline'] = __( 'Deadline', 'wp-todo' ); 8 $columns['todo_assignee'] = __( 'Assigned To', 'wp-todo' ); 9 $columns['todo_priority'] = __( 'Priority', 'wp-todo' ); 10 $columns['todo_status'] = __( 'Status', 'wp-todo' ); 11 11 12 12 return $columns; … … 14 14 15 15 // 2️⃣ Fill the custom columns with colored data 16 add_action( 'manage_wp todo_posts_custom_column', function( $column, $post_id ) {16 add_action( 'manage_wp-todo_posts_custom_column', function( $column, $post_id ) { 17 17 switch ( $column ) { 18 18 … … 64 64 65 65 // 3️⃣ Make columns sortable 66 add_filter( 'manage_edit-wp todo_sortable_columns', function( $columns ) {66 add_filter( 'manage_edit-wp-todo_sortable_columns', function( $columns ) { 67 67 $columns['todo_deadline'] = 'todo_deadline'; 68 68 $columns['todo_assignee'] = 'todo_assignee'; -
wp-todo/trunk/meta_boxes/wptodo_meta_boxe.php
r3345118 r3345168 5 5 */ 6 6 function wptodo_add_meta_box() { 7 8 9 add_meta_box( 10 'todo_deadline', // ID 11 'Info', // Title 12 'wptodo_meta_box_callback', // Callback function 13 'wptodo', // Post type 14 'normal', // Context 15 'default' // Priority 16 ); 17 18 add_meta_box( 19 'todo_assignee', // ID 20 '', // Title 21 'wptodo_meta_box_callback', // Callback function 22 'wptodo', // Post type 23 'normal', // Context 24 'default' // Priority 25 ); 26 27 add_meta_box( 28 'todo_status', // ID 29 '', // Title 30 'wptodo_meta_box_callback', // Callback function 31 'wptodo', // Post type 32 'normal', // Context 33 'default' // Priority 34 ); 35 36 add_meta_box( 37 'todo_priority', // ID 38 '', // Title 39 'wptodo_meta_box_callback', // Callback function 40 'wptodo', // Post type 41 'normal', // Context 42 'default' // Priority 43 ); 44 7 add_meta_box('todo_deadline', 'Deadline', 'wptodo_meta_box_callback', 'wp-todo', 'normal', 'default'); 8 add_meta_box('todo_assignee', 'Assignee', 'wptodo_meta_box_callback', 'wp-todo', 'normal', 'default'); 9 add_meta_box('todo_status', 'Status', 'wptodo_meta_box_callback', 'wp-todo', 'normal', 'default'); 10 add_meta_box('todo_priority', 'Priority', 'wptodo_meta_box_callback', 'wp-todo', 'normal', 'default'); 45 11 } 46 12 add_action('add_meta_boxes', 'wptodo_add_meta_box'); 47 13 48 function wptodo_meta_box_callback($post) { 49 // Add nonce for security 50 wp_nonce_field('wptodo_add_meta_box_nonce', 'wptodo_add_meta_box_nonce_field'); 14 function wptodo_meta_box_callback($post, $meta) { 15 wp_nonce_field('wp-todo_add_meta_box_nonce', 'wp-todo_add_meta_box_nonce_field'); 51 16 52 // Retrieve existing value53 $todo_deadline = get_post_meta($post->ID, '_todo_deadline', true);54 $todo_assignee = get_post_meta($post->ID, '_todo_assignee', true);55 $todo_status = get_post_meta($post->ID, '_todo_status', true);56 $todo_priority = get_post_meta($post->ID, '_todo_priority', true);17 switch ($meta['id']) { 18 case 'todo_deadline': 19 $value = get_post_meta($post->ID, '_todo_deadline', true) ?: gmdate('Y-m-d'); 20 echo '<input type="date" name="todo_deadline" value="'.esc_attr($value).'" style="width:100%;">'; 21 break; 57 22 23 case 'todo_assignee': 24 $users = get_users(); 25 $selected = get_post_meta($post->ID, '_todo_assignee', true) ?: get_current_user_id(); 26 echo '<select name="todo_assignee" style="width:100%">'; 27 foreach ($users as $user) { 28 echo '<option value="' . esc_attr( $user->ID ) . '" ' . selected( $selected, $user->ID, false ) . '>' . esc_html( $user->display_name ) . '</option>'; 29 } 30 echo '</select>'; 31 break; 58 32 59 ?> 60 <p> 61 <label for="deadline">Deadline:</label><br> 62 <?php 63 // Example: load deadline from DB 64 // $todo_deadline = get_post_meta( $post_id, 'todo_deadline', true ); 33 case 'todo_status': 34 $status = get_post_meta($post->ID, '_todo_status', true) ?: 'Not Started'; 35 $options = ['Not Started','In Progress','Pending','In Review','Completed','Cancelled']; 36 echo '<select name="todo_status" style="width:100%">'; 37 foreach ($options as $opt) { 38 echo '<option value="' . esc_attr( $opt ) . '" ' . selected( $status, $opt, false ) . '>' . esc_html( $opt ) . '</option>'; 39 } 40 echo '</select>'; 41 break; 65 42 66 // Default to today's date if empty 67 $todo_deadline = !empty($todo_deadline) ? $todo_deadline : date('Y-m-d'); 68 ?> 69 <input type="date" name="todo_deadline" id="todo_deadline" value="<?php echo esc_attr($todo_deadline); ?>" style="width:100%;"> 70 </p> 71 <p> 72 <label for="assignee">Assignee:</label><br> 73 <?php 74 // Get all users 75 $users = get_users(); 43 case 'todo_priority': 44 $priority = get_post_meta($post->ID, '_todo_priority', true) ?: 'Normal'; 45 $options = ['Low','Normal','High','Important']; 46 echo '<select name="todo_priority" style="width:100%">'; 47 foreach ($options as $opt) { 48 echo '<option value="' . esc_attr( $opt ) . '" ' . selected( $priority, $opt, false ) . '>' . esc_html( $opt ) . '</option>'; 49 } 50 echo '</select>'; 51 break; 52 } 53 } 76 54 77 // Get current logged-in user78 $current_user = wp_get_current_user();79 80 // Decide which user should be pre-selected81 $selected_user_id = !empty($todo_assignee) ? $todo_assignee : $current_user->ID;82 ?>83 <select name="todo_assignee" id="todo_assignee" style="width:100%;">84 <?php foreach ( $users as $user ) : ?>85 <option value="<?php echo esc_attr( $user->ID ); ?>"86 <?php selected( $selected_user_id, $user->ID ); ?>>87 <?php echo esc_html( $user->display_name ); ?>88 </option>89 <?php endforeach; ?>90 </select>91 92 </p>93 <p>94 <label for="status">Status:</label><br>95 <?php96 // Example: load status from DB (post meta, options, etc.)97 // $todo_status = get_post_meta( $post_id, 'todo_status', true );98 99 // Default value if no status is set100 $todo_status = !empty($todo_status) ? $todo_status : 'Not Started';101 ?>102 <select name="todo_status" id="todo_status" style="width:100%;">103 <option value="Not Started" <?php selected( $todo_status, 'Not Started' ); ?>>Not Started</option>104 <option value="In Progress" <?php selected( $todo_status, 'In Progress' ); ?>>In Progress</option>105 <option value="Pending" <?php selected( $todo_status, 'Pending' ); ?>>Pending</option>106 <option value="In Review" <?php selected( $todo_status, 'In Review' ); ?>>In Review</option>107 <option value="Completed" <?php selected( $todo_status, 'Completed' ); ?>>Completed</option>108 <option value="Cancelled" <?php selected( $todo_status, 'Cancelled' ); ?>>Cancelled</option>109 </select>110 </p>111 <p>112 <label for="Priority">Priority:</label><br>113 <?php114 // Example: load priority from DB115 // $todo_priority = get_post_meta( $post_id, 'todo_priority', true );116 117 // Default to "Normal" if empty118 $todo_priority = !empty($todo_priority) ? $todo_priority : 'Normal';119 ?>120 <select name="todo_priority" id="todo_priority" style="width:100%;">121 <option value="Low" <?php selected( $todo_priority, 'Low' ); ?>>Low</option>122 <option value="Normal" <?php selected( $todo_priority, 'Normal' ); ?>>Normal</option>123 <option value="High" <?php selected( $todo_priority, 'High' ); ?>>High</option>124 <option value="Important" <?php selected( $todo_priority, 'Important' ); ?>>Important</option>125 </select>126 </p>127 <?php128 }129 55 130 56 function wptodo_save_meta_box($post_id) { 131 57 // Verify nonce 132 if (!isset($_POST['wp todo_add_meta_box_nonce_field']) ||133 !wp_verify_nonce( $_POST['wptodo_add_meta_box_nonce_field'], 'wptodo_add_meta_box_nonce')) {58 if (!isset($_POST['wp-todo_add_meta_box_nonce_field']) || 59 !wp_verify_nonce(sanitize_text_field(wp_unslash( $_POST['wp-todo_add_meta_box_nonce_field'] )), 'wp-todo_add_meta_box_nonce')) { 134 60 return; 135 61 } … … 143 69 // Save field 144 70 if (isset($_POST['todo_deadline'])) { 145 update_post_meta($post_id, '_todo_deadline', sanitize_text_field( $_POST['todo_deadline']));71 update_post_meta($post_id, '_todo_deadline', sanitize_text_field(wp_unslash($_POST['todo_deadline']))); 146 72 } 147 73 if (isset($_POST['todo_assignee'])) { 148 update_post_meta($post_id, '_todo_assignee', sanitize_text_field( $_POST['todo_assignee']));74 update_post_meta($post_id, '_todo_assignee', sanitize_text_field(wp_unslash($_POST['todo_assignee']))); 149 75 } 150 76 if (isset($_POST['todo_status'])) { 151 update_post_meta($post_id, '_todo_status', sanitize_text_field( $_POST['todo_status']));77 update_post_meta($post_id, '_todo_status', sanitize_text_field(wp_unslash($_POST['todo_status']))); 152 78 } 153 79 if (isset($_POST['todo_priority'])) { 154 update_post_meta($post_id, '_todo_priority', sanitize_text_field( $_POST['todo_priority']));80 update_post_meta($post_id, '_todo_priority', sanitize_text_field(wp_unslash($_POST['todo_priority']))); 155 81 } 156 82 } -
wp-todo/trunk/notification/notify.php
r3345118 r3345168 12 12 $priority = get_post_meta( $post_id, '_todo_priority', true ) ?: 'Normal'; 13 13 $status = get_post_meta( $post_id, '_todo_status', true ) ?: 'Not Started'; 14 $deadline = get_post_meta( $post_id, '_todo_deadline', true ) ?: date( 'Y-m-d' );14 $deadline = get_post_meta( $post_id, '_todo_deadline', true ) ?: gmdate( 'Y-m-d' ); 15 15 $link = get_permalink( $post_id ); 16 16 -
wp-todo/trunk/readme.txt
r3345118 r3345168 3 3 Tags: to-do list, task management, project management, WordPress project manager, productivity 4 4 Requires at least: 6.4 or higher 5 Tested up to: 6.8 .26 Stable tag: 2.0. 15 Tested up to: 6.8 6 Stable tag: 2.0.2 7 7 Requires PHP: 7.2.24 8 8 License: GPLv2 -
wp-todo/trunk/todo/count_down_timer.php
r3345118 r3345168 1 1 <?php 2 add_filter( 'manage_wp todo_posts_columns', function( $columns ) {3 $columns['todo_deadline_countdown'] = __( 'Time Left', 'wp todo' );2 add_filter( 'manage_wp-todo_posts_columns', function( $columns ) { 3 $columns['todo_deadline_countdown'] = __( 'Time Left', 'wp-todo' ); 4 4 return $columns; 5 5 } ); 6 6 7 add_action( 'manage_wp todo_posts_custom_column', function( $column, $post_id ) {7 add_action( 'manage_wp-todo_posts_custom_column', function( $column, $post_id ) { 8 8 if ( $column === 'todo_deadline_countdown' ) { 9 9 $deadline = get_post_meta( $post_id, '_todo_deadline', true ); … … 18 18 19 19 add_action( 'admin_enqueue_scripts', function( $hook ) { 20 if ( 'edit.php' !== $hook || get_post_type() !== 'wp todo' ) return;20 if ( 'edit.php' !== $hook || get_post_type() !== 'wp-todo' ) return; 21 21 22 22 wp_add_inline_style( 'wp-admin', " -
wp-todo/trunk/todo/modal_view.php
r3345118 r3345168 1 1 <?php 2 add_action( 'wp_ajax_wptodo_quick_view', function() { 3 $post_id = intval( $_POST['post_id'] ?? 0 ); 2 add_action( 'wp_ajax_wp-todo_quick_view', function() { 3 // First, safely get and unslash the nonce 4 $nonce = isset( $_POST['wp-todo_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['wp-todo_nonce'] ) ) : ''; 5 6 // Verify the nonce 7 if ( ! wp_verify_nonce( $nonce, 'wp-todo_action' ) ) { 8 wp_send_json_error( array( 'message' => 'Security check failed' ), 400 ); 9 exit; 10 } 11 12 // Now process the post ID 13 $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0; 14 4 15 if ( ! $post_id ) wp_send_json_error('Invalid post ID'); 5 16 6 17 $post = get_post( $post_id ); 7 if ( ! $post || $post->post_type !== 'wp todo' ) wp_send_json_error('Post not found');18 if ( ! $post || $post->post_type !== 'wp-todo' ) wp_send_json_error('Post not found'); 8 19 9 20 $assignee_id = get_post_meta( $post_id, '_todo_assignee', true ); … … 16 27 17 28 if (!$deadline) { 18 $deadline = date('Y-m-d');29 $deadline = gmdate('Y-m-d'); 19 30 } 20 31 … … 62 73 add_action( 'admin_footer-edit.php', function() { 63 74 $screen = get_current_screen(); 64 if ( $screen->post_type !== 'wp todo' ) return;75 if ( $screen->post_type !== 'wp-todo' ) return; 65 76 ?> 66 77 <script> … … 85 96 // AJAX to fetch modal content 86 97 $.post(wptodo_ajax.ajax_url, { 87 action: 'wptodo_quick_view', 88 post_id: post_id 98 action: 'wp-todo_quick_view', 99 post_id: post_id, 100 'wp-todo_nonce': wptodo_ajax.nonce 89 101 }, function(response){ 90 102 if(response.success){ -
wp-todo/trunk/todo/wptodo_custom_post_type.php
r3345118 r3345168 6 6 $labels = array( 7 7 8 'name' => __( 'Todos', 'wp todo' ),9 'singular_name' => __( 'Todo', 'wp todo' ),10 'add_new' => __( 'Add New', 'wp todo' ),11 'add_new_item' => __( 'Add New Todo', 'wp todo' ),12 'edit_item' => __( 'Edit Todo', 'wp todo' ),13 'new_item' => __( 'New Todo', 'wp todo' ),14 'view_item' => __( 'View Todo', 'wp todo' ),15 'view_items' => __( 'View Todos', 'wp todo' ),16 'search_items' => __( 'Search Todos', 'wp todo' ),17 'not_found' => __( 'No Todos found.', 'wp todo' ),18 'not_found_in_trash' => __( 'No Todos found in Trash.', 'wp todo' ),19 'parent_item_colon' => __( 'Parent Todos:', 'wp todo' ),20 'all_items' => __( 'All Todos', 'wp todo' ),21 'archives' => __( 'Todo Archives', 'wp todo' ),22 'attributes' => __( 'Todo Attributes', 'wp todo' ),23 'insert_into_item' => __( 'Insert into Todo', 'wp todo' ),24 'uploaded_to_this_item' => __( 'Uploaded to this Todo', 'wp todo' ),25 'featured_image' => __( 'Featured Image', 'wp todo' ),26 'set_featured_image' => __( 'Set featured image', 'wp todo' ),27 'remove_featured_image' => __( 'Remove featured image', 'wp todo' ),28 'use_featured_image' => __( 'Use as featured image', 'wp todo' ),29 'menu_name' => __( 'WP Todo', 'wp todo' ),30 'filter_items_list' => __( 'Filter Todo list', 'wp todo' ),31 'filter_by_date' => __( 'Filter by date', 'wp todo' ),32 'items_list_navigation' => __( 'Todos list navigation', 'wp todo' ),33 'items_list' => __( 'Todos list', 'wp todo' ),34 'item_published' => __( 'Todo published.', 'wp todo' ),35 'item_published_privately' => __( 'Todo published privately.', 'wp todo' ),36 'item_reverted_to_draft' => __( 'Todo reverted to draft.', 'wp todo' ),37 'item_scheduled' => __( 'Todo scheduled.', 'wp todo' ),38 'item_updated' => __( 'Todo updated.', 'wp todo' ),39 'item_link' => __( 'Todo Link', 'wp todo' ),40 'item_link_description' => __( 'A link to an todo.', 'wp todo' ),8 'name' => __( 'Todos', 'wp-todo' ), 9 'singular_name' => __( 'Todo', 'wp-todo' ), 10 'add_new' => __( 'Add New', 'wp-todo' ), 11 'add_new_item' => __( 'Add New Todo', 'wp-todo' ), 12 'edit_item' => __( 'Edit Todo', 'wp-todo' ), 13 'new_item' => __( 'New Todo', 'wp-todo' ), 14 'view_item' => __( 'View Todo', 'wp-todo' ), 15 'view_items' => __( 'View Todos', 'wp-todo' ), 16 'search_items' => __( 'Search Todos', 'wp-todo' ), 17 'not_found' => __( 'No Todos found.', 'wp-todo' ), 18 'not_found_in_trash' => __( 'No Todos found in Trash.', 'wp-todo' ), 19 'parent_item_colon' => __( 'Parent Todos:', 'wp-todo' ), 20 'all_items' => __( 'All Todos', 'wp-todo' ), 21 'archives' => __( 'Todo Archives', 'wp-todo' ), 22 'attributes' => __( 'Todo Attributes', 'wp-todo' ), 23 'insert_into_item' => __( 'Insert into Todo', 'wp-todo' ), 24 'uploaded_to_this_item' => __( 'Uploaded to this Todo', 'wp-todo' ), 25 'featured_image' => __( 'Featured Image', 'wp-todo' ), 26 'set_featured_image' => __( 'Set featured image', 'wp-todo' ), 27 'remove_featured_image' => __( 'Remove featured image', 'wp-todo' ), 28 'use_featured_image' => __( 'Use as featured image', 'wp-todo' ), 29 'menu_name' => __( 'WP Todo', 'wp-todo' ), 30 'filter_items_list' => __( 'Filter Todo list', 'wp-todo' ), 31 'filter_by_date' => __( 'Filter by date', 'wp-todo' ), 32 'items_list_navigation' => __( 'Todos list navigation', 'wp-todo' ), 33 'items_list' => __( 'Todos list', 'wp-todo' ), 34 'item_published' => __( 'Todo published.', 'wp-todo' ), 35 'item_published_privately' => __( 'Todo published privately.', 'wp-todo' ), 36 'item_reverted_to_draft' => __( 'Todo reverted to draft.', 'wp-todo' ), 37 'item_scheduled' => __( 'Todo scheduled.', 'wp-todo' ), 38 'item_updated' => __( 'Todo updated.', 'wp-todo' ), 39 'item_link' => __( 'Todo Link', 'wp-todo' ), 40 'item_link_description' => __( 'A link to an todo.', 'wp-todo' ), 41 41 42 42 ); … … 45 45 46 46 'labels' => $labels, 47 'description' => __( 'organize and manage company Todos', 'wp todo' ),47 'description' => __( 'organize and manage company Todos', 'wp-todo' ), 48 48 'public' => false, 49 49 'hierarchical' => false, … … 62 62 'taxonomies' => array(), 63 63 'has_archive' => true, 64 'rewrite' => array( 'slug' => 'wp todo' ),64 'rewrite' => array( 'slug' => 'wp-todo' ), 65 65 'query_var' => true, 66 66 'can_export' => true, … … 71 71 ); 72 72 73 register_post_type( 'wp todo', $args );73 register_post_type( 'wp-todo', $args ); 74 74 75 75 } -
wp-todo/trunk/wp-todo.php
r3345118 r3345168 7 7 Plugin URI: https://sandalia.com.bd/apps 8 8 Description: WP-Todo: A full-featured WordPress plugin to create, manage, and track tasks with custom statuses, priorities, and deadlines from your dashboard. 9 Version:2.0. 19 Version:2.0.2 10 10 Author: Delower 11 11 Author URI: https://sandalia.com.bd/apps 12 12 License: GPLv2 or later 13 Text Domain: wp todo13 Text Domain: wp-todo 14 14 */ 15 15 /*
Note: See TracChangeset
for help on using the changeset viewer.