PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/custom/modules/Project/gantt.php

https://gitlab.com/tjaafar/SuiteCRM
PHP | 261 lines | 194 code | 36 blank | 31 comment | 63 complexity | 51f01a394cf5609e08ded7ef7108f5ef MD5 | raw file
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE as published by
  5. * the Free Software Foundation; either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  14. * along with this program; if not, see http://www.gnu.org/licenses
  15. * or write to the Free Software Foundation,Inc., 51 Franklin Street,
  16. * Fifth Floor, Boston, MA 02110-1301 USA
  17. * @Package Gantt chart
  18. * @copyright Andrew Mclaughlan 2014
  19. * @author Andrew Mclaughlan <andrew@mclaughlan.info>
  20. */
  21. class Gantt {
  22. private $start_date;
  23. private $end_date;
  24. private $tasks;
  25. public function __construct($start_date, $end_date, $tasks)
  26. {
  27. $this->start_date = $start_date;
  28. $this->end_date = $end_date;
  29. $this->tasks = $tasks;
  30. //draw the grid
  31. $this->draw($this->start_date, $this->end_date, $this->tasks);
  32. }
  33. public function draw($start_date, $end_date, $tasks){
  34. $time_span = $this->year_month($start_date, $end_date);
  35. $day_count = $this->count_days($start_date, $end_date);
  36. // $project_length = $this->time_range($start_date, $end_date);
  37. //Generate main table and the first row containing the months
  38. echo '<table class="main_table"><tr class="month_row">';
  39. foreach($time_span as $months) {
  40. foreach($months as $month => $days){
  41. echo '<td class="months">'.$month.'</td>';
  42. }
  43. }
  44. //end the month row and start the days row
  45. echo '</tr><tr class="day_row">';
  46. $month_count = 0;//start month count
  47. foreach($time_span as $months) {
  48. $m=0;
  49. foreach($months as $days){
  50. echo '<td class="inner_container">';
  51. //Generate a table containing the days in each month
  52. echo '<table class="table_inner"><tr>';
  53. foreach($days as $day => $d){
  54. echo '<td class="inner_td"><div class="cell_width">'.$day.'</div></td>';//day number shown
  55. }
  56. echo '</tr><tr>';
  57. foreach($days as $d){
  58. echo '<td class="inner_td"><div class="cell_width">'.$this->substr_unicode($d,0,1).'</div></td>';//First letter of the days name shown
  59. }
  60. echo '</tr></table></td>';//end table containing the days in each month
  61. $m++;
  62. }
  63. $month_count += $m; //total month count
  64. }
  65. //for each task generate a row of empty days
  66. $i=1;
  67. if(!is_null($tasks)){
  68. foreach($tasks as $task){
  69. echo '</tr><tr class="task_row">';
  70. echo '<td colspan="'.$month_count.'"><table id="task'.$i.'" class="table_inner"><tr>';
  71. $task_start_day = $this->count_days($start_date, $task->date_start);
  72. $task_end_day = $this->count_days($start_date, $task->date_finish);
  73. $task_duration = $this->count_days($task->date_start, $task->date_finish);
  74. $task->predecessors = $task->predecessors == '' ? 0 : $task->predecessors;
  75. for ($x=1; $x<= $day_count; $x++)
  76. {
  77. if($x==1 && $x != $task_start_day){
  78. echo '<td class="inner_td"><div class="cell_width day_block"></div></td>';
  79. }
  80. else if($x==1 && $x == $task_start_day){
  81. if($task->milestone_flag == '1' && ($task_duration == 0 || $task_duration == 1)){
  82. echo '<td class="task_td2"><div class="cell_width task_block1">
  83. <div class="task_block_inner">
  84. <div class="milestone link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  85. <img src="custom/modules/Project/images/add_milestone.png" />
  86. </div>
  87. </div>
  88. </div></td><td class="inner_td"><div class="cell_width day_block"></div></td>';
  89. }
  90. else if($task_duration == 0 || $task_duration == 1){
  91. echo '<td class="task_td2"><div class="cell_width task_block1">
  92. <div class="task_block_inner">
  93. <div class="task1 link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  94. <div class="task_percent" rel="'.$task->percent_complete.'"></div>
  95. </div>
  96. </div>
  97. </div></td><td class="inner_td"><div class="cell_width day_block"></div></td>';
  98. }
  99. else {
  100. echo '<td class="task_td" colspan="'.$task_duration.'"><div class="cell_width task_block">
  101. <div class="task_block_inner">
  102. <div class="task link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  103. <div class="task_percent" rel="'.$task->percent_complete.'">'.$task->name.'</div>
  104. </div>
  105. </div>
  106. </div></td>';
  107. }
  108. }
  109. else if($x == $task_start_day && $x == $day_count){
  110. if($task->milestone_flag == '1' && ($task_duration == 0 || $task_duration == 1)){
  111. echo '<td class="task_td2"><div class="cell_width task_block1">
  112. <div class="task_block_inner">
  113. <div class="milestone link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  114. <img src="custom/modules/Project/images/add_milestone.png" />
  115. </div>
  116. </div>
  117. </div></td>';
  118. }
  119. else if($task_duration == 0 || $task_duration == 1){
  120. echo '<td class="task_td2"><div class="cell_width task_block1">
  121. <div class="task_block_inner">
  122. <div class="task1 link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  123. <div class="task_percent" rel="'.$task->percent_complete.'"></div>
  124. </div>
  125. </div>
  126. </div></td>';
  127. }
  128. else {
  129. echo '<td class="task_td" colspan="'.$task_duration.'"><div class="cell_width task_block">
  130. <div class="task_block_inner">
  131. <div class="task link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  132. <div class="task_percent" rel="'.$task->percent_complete.'">'.$task->name.'</div>
  133. </div>
  134. </div>
  135. </div></td>';
  136. }
  137. }
  138. else if($x == $task_start_day){
  139. if($task->milestone_flag == '1' && ($task_duration == 0 || $task_duration == 1)){
  140. echo '<td class="task_td2"><div class="cell_width task_block1">
  141. <div class="task_block_inner">
  142. <div class="milestone link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  143. <img src="custom/modules/Project/images/add_milestone.png" />
  144. </div>
  145. </div>
  146. </div></td><td class="inner_td"><div class="cell_width day_block"></div></td>';
  147. }
  148. else if($task_duration == 0 || $task_duration == 1){
  149. echo '<td class="task_td2"><div class="cell_width task_block1">
  150. <div class="task_block_inner">
  151. <div class="task1 link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  152. <div class="task_percent" rel="'.$task->percent_complete.'"></div>
  153. </div>
  154. </div>
  155. </div></td><td class="inner_td"><div class="cell_width day_block"></div></td>';
  156. }
  157. else {
  158. echo '<td class="task_td" colspan="'.$task_duration.'"><div class="cell_width task_block">
  159. <div class="task_block_inner">
  160. <div class="task link" id="'.$task->project_task_id.'" pre="'.$task->predecessors.'" link="'.$task->relationship_type.'" rel="'.$task->name.'">
  161. <div class="task_percent" rel="'.$task->percent_complete.'"></div>
  162. </div>
  163. </div>
  164. </div></td>';
  165. }
  166. }
  167. else if($x == $day_count){
  168. }
  169. else if($x > $task_start_day && $x < $task_end_day){
  170. //leave blank
  171. }
  172. else {
  173. echo '<td class="inner_td"><div class="cell_width day_block"></div></td>';
  174. }
  175. }
  176. echo '</tr></table ></td></tr>';
  177. $i++;
  178. }
  179. }
  180. echo '</table>';
  181. }
  182. //Returns an array containing the years, months and days between two dates
  183. public function year_month($start_date, $end_date)
  184. {
  185. $begin = new DateTime( $start_date );
  186. $end = new DateTime( $end_date);
  187. $end->add(new DateInterval('P1D')); //Add 1 day to include the end date as a day
  188. $interval = new DateInterval('P1D'); // 1 month interval
  189. $period = new DatePeriod($begin, $interval, $end);
  190. $aResult = array();
  191. foreach ( $period as $dt )
  192. {
  193. $aResult[$dt->format('Y')][strftime("%B", $dt->getTimestamp())][$dt->format('j')] = strftime("%a", $dt->getTimestamp());
  194. }
  195. return $aResult;
  196. }
  197. //Returns the total number of days between two dates
  198. public function count_days($start_date, $end_date){
  199. $d1 = new DateTime($start_date);
  200. $d2 = new DateTime($end_date);
  201. //If the task's end date is before chart's start date return 1 to make sure task starts on first day of the chart
  202. if($d2 < $d1){
  203. return 1;
  204. }
  205. $d2->add(new DateInterval('P1D')); //Add 1 day to include the end date as a day
  206. $difference = $d1->diff($d2);
  207. return $difference->days;
  208. }
  209. //Returns the time span between two dates in years months and days
  210. public function time_range($start_date, $end_date){
  211. $datetime1 = new DateTime($start_date);
  212. $datetime2 = new DateTime($end_date);
  213. $datetime2->add(new DateInterval('P1D')); //Add 1 day to include the end date as a day
  214. $interval = $datetime1->diff($datetime2);
  215. return $interval->format('%y years %m months and %d days');
  216. }
  217. public function substr_unicode($str, $s, $l = null) {
  218. return join("", array_slice(
  219. preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY), $s, $l));
  220. }
  221. // Function for basic field validation (present and neither empty nor only white space
  222. public function IsNullOrEmptyString($question){
  223. return (!isset($question) || trim($question)==='');
  224. }
  225. }