epic_header = $agilepress_options['agilepress_epic_header']; } else { $this->epic_header = 'Epics'; } if ((isset($agilepress_options['agilepress_story_header'])) && (!empty($agilepress_options['agilepress_story_header']))) { $this->story_header = $agilepress_options['agilepress_story_header']; } else { $this->story_header = 'Stories'; } if ((isset($agilepress_options['agilepress_story2sprint_header'])) && (!empty($agilepress_options['agilepress_story2sprint_header']))) { $this->send2sprint_header = $agilepress_options['agilepress_story2sprint_header']; } else { $this->send2sprint_header = 'Send to Sprint'; } if ((isset($agilepress_options['agilepress_storydone_header'])) && (!empty($agilepress_options['agilepress_storydone_header']))) { $this->completed_header = $agilepress_options['agilepress_storydone_header']; } else { $this->completed_header = 'Completed'; } if ((isset($agilepress_options['agilepress_sprintblog_header'])) && (!empty($agilepress_options['agilepress_sprintblog_header']))) { $this->sprintbacklog_header = $agilepress_options['agilepress_sprintblog_header']; } else { $this->sprintbacklog_header = 'Sprint Backlog Story'; } if ((isset($agilepress_options['agilepress_todo_header'])) && (!empty($agilepress_options['agilepress_todo_header']))) { $this->todo_header = $agilepress_options['agilepress_todo_header']; } else { $this->todo_header = 'To-Do'; } if ((isset($agilepress_options['agilepress_nprogress_header'])) && (!empty($agilepress_options['agilepress_nprogress_header']))) { $this->inprogress_header = $agilepress_options['agilepress_nprogress_header']; } else { $this->inprogress_header = 'In Progress'; } if ((isset($agilepress_options['agilepress_ntesting_header'])) && (!empty($agilepress_options['agilepress_ntesting_header']))) { $this->intesting_header = $agilepress_options['agilepress_ntesting_header']; } else { $this->intesting_header = 'In Testing/Review'; } if ((isset($agilepress_options['agilepress_done_header'])) && (!empty($agilepress_options['agilepress_done_header']))) { $this->done_header = $agilepress_options['agilepress_done_header']; } else { $this->done_header = 'Done'; } } /** * Produces product summary page * * This method creates the product summary report page. * * @param string $page_heading The display name for the top of the page * @param string $product_name The product internal name (not display name) * @return string $display A formated HTML string that displays the summary * * @global $wpdb * * @uses \wordpress\wpdb\get_results() * @uses \wordpress\get_post_meta() * @uses \wordpress\get_permalink() * * @author Ken Kitchen ken@vinlandmedia.com * @author Vinland Media, LLC. * @package AgilePress */ public function summarypage($page_heading = null, $product_name = null) { $is_story = false; $is_backlog = false; $is_sprint = false; global $wpdb; $display = ""; // summary query $product_details = $wpdb->get_results(" select 'product' as record_type, p.ID, p.post_title, p.post_name, p.post_excerpt, m.meta_key, m.meta_value from " . $wpdb->posts . " p, " . $wpdb->postmeta . " m where p.post_type = 'agilepress-products' and p.post_status = 'publish' and p.post_name = '" . $product_name . "' and m.post_id = p.ID and m.meta_key = '_agilepress_product_data' union all select 'story' as record_type, p.ID, p.post_title, p.post_name, p.post_excerpt, m.meta_key, m.meta_value from " . $wpdb->posts . " p, " . $wpdb->postmeta . " m where p.post_type = 'agilepress-stories' and p.post_status = 'publish' and m.post_id = p.ID and m.meta_key = '_agilepress_story_data' and m.meta_value like '%" . $product_name . "%' union all select 'task' as record_type, p.ID, p.post_title, p.post_name, p.post_excerpt, m.meta_key, m.meta_value from " . $wpdb->posts . " p, " . $wpdb->postmeta . " m where p.post_type = 'agilepress-tasks' and p.post_status = 'publish' and m.post_id = p.ID and m.meta_key = '_agilepress_task_data' and m.meta_value like '%" . $product_name . "%' union all select 'sprint' as record_type, p.ID, p.post_title, p.post_name, p.post_excerpt, m.meta_key, m.meta_value from " . $wpdb->posts . " p, " . $wpdb->postmeta . " m where p.post_type = 'agilepress-sprints' and p.post_status = 'publish' and m.post_id = p.ID and m.meta_key = '_agilepress_sprint_data' and m.meta_value like '%" . $product_name . "%' "); $display = ''; $display .= ''; $story_header = false; $task_header = false; $sprint_header = false; foreach ($product_details as $product_detail) { $display .= ''; switch ($product_detail->meta_key) { case '_agilepress_product_data': $agilepress_meta = get_post_meta($product_detail->ID, '_agilepress_product_data', true); $display .= ''; $display .= ''; $display .= ''; $display .= ''; break; case '_agilepress_story_data': if (!$story_header) { $display .= ''; $story_header = true; } $agilepress_meta = get_post_meta($product_detail->ID, '_agilepress_story_data', true); $display .= ''; $display .= ''; $display .= ''; $display .= ''; break; case '_agilepress_task_data': if (!$task_header) { $display .= ''; $task_header = true; } $agilepress_meta = get_post_meta($product_detail->ID, '_agilepress_task_data', true); $display .= ''; $display .= ''; $display .= ''; $display .= ''; break; case '_agilepress_sprint_data': if (!$sprint_header) { $display .= ''; $sprint_header = true; } $agilepress_meta = get_post_meta($product_detail->ID, '_agilepress_sprint_data', true); $display .= ''; $display .= ''; $display .= ''; $display .= ''; break; default: # code... break; } $display .= ''; } $display .= '
ProductVersionTargetStatus
' . esc_html($product_detail->post_title) . '' . $this->check_value($agilepress_meta['version'], 'n/a') . '' . $this->check_value($agilepress_meta['target'], 'n/a') . '' . $this->check_value($agilepress_meta['phase'], 'lookup') . '
StoriesStatusParent Epic-
' . esc_html($product_detail->post_title) . '' . $this->check_value($agilepress_meta['story_status'], 'lookup') . '' . $this->check_value($agilepress_meta['parent_epic'], 'db') . '' . $this->check_value($agilepress_meta['story_sprint'], 'db') . '
TasksSprintParent StoryStatus
' . esc_html($product_detail->post_title) . '' . $this->check_value($agilepress_meta['sprint'], 'db') . '' . $this->check_value($agilepress_meta['parent_story'], 'db') . '' . $this->check_value($agilepress_meta['task_status'], 'lookup') . '
SprintsStart DateEnd DateStatus
' . esc_html($product_detail->post_title) . '' . $this->check_value($agilepress_meta['start_date'], 'n/a') . '' . $this->check_value($agilepress_meta['end_date'], 'n/a') . '' . $this->check_value($agilepress_meta['status'], 'lookup') . '
'; return $display; } /** * Produces Kanban board * * This method creates the Kanban board. * * @param string $page_heading The display name for the top of the page * @param object $tasks The results of a query for tasks relating to product * @param array $fetch_data_atts The parameters of the shortcode * @return string $display_board A formated HTML string that displays the summary * * @uses \wordpress\get_post_meta() * @uses \vinlandmedia\agilepress\AgilePress_Boards::create_note() * @uses \vinlandmedia\agilepress\AgilePress_Modals::create_modals() * * @author Ken Kitchen ken@vinlandmedia.com * @author Vinland Media, LLC. * @package AgilePress */ public function kanbanboard($page_heading = null, $tasks = null, $fetch_data_atts = null) { $is_story = true; $is_backlog = false; $is_sprint = false; $myKanbanNotes = new AgilePress_Notes(); $display_board = '

' . $this->todo_header . '

(this is your To-Do List)

'; foreach($tasks as $task) { $agilepress_meta = get_post_meta($task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'todo') { $display_board .= $myKanbanNotes->create_note($task->id, $task->task_title, $task->task_name, $task->post_excerpt, 'todo', 'kanban'); } }; $display_board .= '

' . $this->inprogress_header . '

(the Tasks upon which you are currently working)

'; foreach($tasks as $task) { $agilepress_meta = get_post_meta($task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'inprogress') { $display_board .= $myKanbanNotes->create_note($task->id, $task->task_title, $task->task_name, $task->post_excerpt, 'inprogress', 'kanban'); } }; $display_board .= '

' . $this->intesting_header . '

(the Tasks that you feel are done but need some form of confirmation before marking as completed)

'; foreach($tasks as $task) { $agilepress_meta = get_post_meta($task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'intesting') { $display_board .= $myKanbanNotes->create_note($task->id, $task->task_title, $task->task_name, $task->post_excerpt, 'intesting', 'kanban'); } }; $display_board .= '

' . $this->done_header . '

(whew! these Tasks are in the can!)

'; foreach($tasks as $task) { $agilepress_meta = get_post_meta($task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'done') { $display_board .= $myKanbanNotes->create_note($task->id, $task->task_title, $task->task_name, $task->post_excerpt, 'done', 'kanban'); } }; $display_board .= '
'; $kanban_modal = new AgilePress_Modals(); $display_board .= $kanban_modal->create_modals('tasks', $tasks); return $display_board; } /** * Produces Sprint board * * This method creates the Sprint board. * * @param string $page_heading The display name for the top of the page * @param string $header_product_title The display name for the Product * @param object $tasks The results of a query for tasks relating to product * @param array $fetch_data_atts The parameters of the shortcode * @return string $display_board A formated HTML string that displays the summary * * @uses \wordpress\get_post_meta() * @uses \vinlandmedia\agilepress\AgilePress_Boards::create_note() * @uses \vinlandmedia\agilepress\AgilePress_Modals::create_modals() * * @author Ken Kitchen ken@vinlandmedia.com * @author Vinland Media, LLC. * @package AgilePress */ public function sprintboard($page_heading = null, $header_product_title = null, $stories = null, $tasks = null, $fetch_data_atts = null) { $is_story = false; $is_backlog = false; $is_sprint = true; $mySprintNotes = new AgilePress_Notes(); $display_board = '

' . $this->sprintbacklog_header . '

Stories (the "what") to be completed in this sprint. Items here cannot be dragged to other columns.

'; if ((isset($stories)) && (!empty($stories))) { foreach($stories as $activepbi_story) { $agilepress_meta = get_post_meta($activepbi_story->id, '_agilepress_story_data', true); $agilepress_product = (!empty($agilepress_meta['product'])) ? $agilepress_meta['product'] : ''; $agilepress_status = (!empty($agilepress_meta['story_status'])) ? $agilepress_meta['story_status'] : ''; if ($agilepress_status == 'sendtosprint') { $display_board .= $mySprintNotes->create_note($activepbi_story->id, $activepbi_story->story_title, $activepbi_story->story_name, $activepbi_story->post_excerpt, 'sendtosprint', 'sprint'); } }; $display_board .= '

' . $this->todo_header . '

Tasks (the "how") to be completed in this sprint.

'; foreach($tasks as $todo_task) { $agilepress_meta = get_post_meta($todo_task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'todo') { $display_board .= $mySprintNotes->create_note($todo_task->id, $todo_task->task_title, $todo_task->task_name, $todo_task->post_excerpt, 'todo', 'sprint'); } }; $display_board .= '

' . $this->inprogress_header . '

Tasks upon which the team is actively working.

'; foreach($tasks as $inprogress_task) { $agilepress_meta = get_post_meta($inprogress_task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'inprogress') { $display_board .= $mySprintNotes->create_note($inprogress_task->id, $inprogress_task->task_title, $inprogress_task->task_name, $inprogress_task->post_excerpt, 'inprogress', 'sprint'); } }; $display_board .= '

' . $this->done_header . '

Completed tasks.

'; foreach($tasks as $done_task) { $agilepress_meta = get_post_meta($done_task->id, '_agilepress_task_data', true); $agilepress_product = ( ! empty( $agilepress_meta['product'] ) ) ? $agilepress_meta['product'] : ''; $agilepress_sprint = ( ! empty( $agilepress_meta['sprint'] ) ) ? $agilepress_meta['sprint'] : ''; $agilepress_task_status = ( ! empty( $agilepress_meta['task_status'] ) ) ? $agilepress_meta['task_status'] : ''; $agilepress_parent_story = ( ! empty( $agilepress_meta['parent_story'] ) ) ? $agilepress_meta['parent_story'] : ''; if ($agilepress_task_status == 'done') { $display_board .= $mySprintNotes->create_note($done_task->id, $done_task->task_title, $done_task->task_name, $done_task->post_excerpt, 'done', 'sprint'); } }; $display_board .= '
'; $sprint_modal = new AgilePress_Modals(); $display_board .= $sprint_modal->create_modals('story', $stories); $display_board .= $sprint_modal->create_modals('task', $tasks); } else { $display_board = 'Nothing to display!'; } return $display_board; } /** * Produces Backlog board * * This method creates the Backlog board. * * @param string $page_heading The display name for the top of the page * @param string $header_product_title The display name for the Product * @param object $stories The results of a query for stories relating to product * @param array $fetch_data_atts The parameters of the shortcode * @return string $display_board A formated HTML string that displays the summary * * @uses \wordpress\get_post_meta() * @uses \vinlandmedia\agilepress\AgilePress_Boards::create_note() * @uses \vinlandmedia\agilepress\AgilePress_Modals::create_modals() * * @author Ken Kitchen ken@vinlandmedia.com * @author Vinland Media, LLC. * @package AgilePress */ public function backlogboard($page_heading = null, $header_product_title = null, $stories = null, $fetch_data_atts = null) { $is_story = false; $is_backlog = true; $is_sprint = false; $myStoryNotes = new AgilePress_Notes(); $display_board = '

' . esc_html($this->epic_header) . '

These are meta-stories, large enough that they should be broken into seperate PBIs.

'; foreach($stories as $epic_story) { $agilepress_meta = get_post_meta($epic_story->id, '_agilepress_story_data', true); $agilepress_product = (!empty($agilepress_meta['product'])) ? $agilepress_meta['product'] : ''; $agilepress_status = (!empty($agilepress_meta['story_status'])) ? $agilepress_meta['story_status'] : ''; if ($agilepress_status == 'isepic') { //$display_board .= $this->create_note($epic_story->id, $epic_story->story_title, $epic_story->story_name, $epic_story->post_excerpt, 'isepic'); $display_board .= $myStoryNotes->create_note($epic_story->id, $epic_story->story_title, $epic_story->story_name, $epic_story->post_excerpt, 'isepic', 'backlog'); } }; $display_board .= '

' . esc_html($this->story_header) . '

These are stories that we plan to do but have not yet added to a sprint for active work.

'; $myStoryNotes = new AgilePress_Notes(); foreach($stories as $is_story) { $agilepress_meta = get_post_meta($is_story->id, '_agilepress_story_data', true); $agilepress_product = (!empty($agilepress_meta['product'])) ? $agilepress_meta['product'] : ''; $agilepress_status = (!empty($agilepress_meta['story_status'])) ? $agilepress_meta['story_status'] : ''; if ($agilepress_status == 'isstory') { $display_board .= $myStoryNotes->create_note($is_story->id, $is_story->story_title, $is_story->story_name, $is_story->post_excerpt, 'isstory', 'backlog'); } }; $display_board .= '

' . esc_html($this->send2sprint_header) . '

Drop a story in this column to convert it to a task and send to the target/active sprint.

'; $mySprintNotes = new AgilePress_Notes(); foreach($stories as $sendtosprint_task) { $agilepress_meta = get_post_meta($sendtosprint_task->id, '_agilepress_story_data', true); $agilepress_product = (!empty($agilepress_meta['product'])) ? $agilepress_meta['product'] : ''; $agilepress_status = (!empty($agilepress_meta['story_status'])) ? $agilepress_meta['story_status'] : ''; if ($agilepress_status == 'sendtosprint') { $display_board .= $myStoryNotes->create_note($sendtosprint_task->id, $sendtosprint_task->story_title, $sendtosprint_task->story_name, $sendtosprint_task->post_excerpt, 'sendtosprint', 'backlog'); } }; $display_board .= '

' . esc_html($this->completed_header) . '

Stories and Epics that are completed, accepted, and deployed.

'; $myCompletedNotes = new AgilePress_Notes(); foreach($stories as $complete_story) { $agilepress_meta = get_post_meta($complete_story->id, '_agilepress_story_data', true); $agilepress_product = (!empty($agilepress_meta['product'])) ? $agilepress_meta['product'] : ''; $agilepress_status = (!empty($agilepress_meta['story_status'])) ? $agilepress_meta['story_status'] : ''; if ($agilepress_status == 'iscomplete') { $display_board .= $myStoryNotes->create_note($complete_story->id, $complete_story->story_title, $complete_story->story_name, $complete_story->post_excerpt, 'iscomplete', 'backlog'); } }; $display_board .= '
'; $backlog_modal = new AgilePress_Modals(); $display_board .= $backlog_modal->create_modals('story', $stories); return $display_board; } function check_value(&$value = null, $lookup_method = null) { global $wpdb; $display_value = ""; if (isset($value)) { switch ($lookup_method) { case 'lookup': $lookup_value_table_name = $wpdb->prefix . "agilepress_lookup_values"; $lookup_value = $wpdb->get_var( "select lookup_value " . "from " . $lookup_value_table_name . " " . "where lookup_key = '" . $value . "' " ); if ((isset($lookup_value)) && (!empty($lookup_value))) { $display_value = $lookup_value; } break; case 'db': $lookup_value = $wpdb->get_var( "select post_title " . "from " . $wpdb->posts . " " . "where post_type like 'agilepress-%' " . "and post_name = '" . $value . "'" ); if ((isset($lookup_value)) && (!empty($lookup_value))) { $display_value = $lookup_value; } break; default: $display_value = ""; break; } } else { $display_value = ""; } return $display_value; } }