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

/inc/calendar.class.php

https://github.com/ardowz/Thesis-SideB
PHP | 417 lines | 383 code | 2 blank | 32 comment | 1 complexity | 964f35ec8d73000638dccb48b5a0d7a5 MD5 | raw file
  1. <?php
  2. /*
  3. * @version $Id: calendar.class.php 14684 2011-06-11 06:32:40Z remi $
  4. -------------------------------------------------------------------------
  5. GLPI - Gestionnaire Libre de Parc Informatique
  6. Copyright (C) 2003-2011 by the INDEPNET Development Team.
  7. http://indepnet.net/ http://glpi-project.org
  8. -------------------------------------------------------------------------
  9. LICENSE
  10. This file is part of GLPI.
  11. GLPI is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15. GLPI is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. GNU General Public License for more details.
  19. You should have received a copy of the GNU General Public License
  20. along with GLPI; if not, write to the Free Software Foundation, Inc.,
  21. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  22. --------------------------------------------------------------------------
  23. */
  24. // ----------------------------------------------------------------------
  25. // Original Author of file: Remi Collet
  26. // Purpose of file:
  27. // ----------------------------------------------------------------------
  28. if (!defined('GLPI_ROOT')) {
  29. die("Sorry. You can't access directly to this file");
  30. }
  31. /// Class Calendar
  32. class Calendar extends CommonDropdown {
  33. // From CommonDBTM
  34. var $dohistory = true;
  35. protected $forward_entity_to = array('CalendarSegment');
  36. static function getTypeName() {
  37. global $LANG;
  38. return $LANG['buttons'][15];
  39. }
  40. function canCreate() {
  41. return haveRight('calendar', 'w');
  42. }
  43. function canView() {
  44. return haveRight('calendar', 'r');
  45. }
  46. function defineTabs($options=array()) {
  47. global $LANG;
  48. $ong = array();
  49. if ($this->fields['id'] > 0) {
  50. $ong[1] = $LANG['calendar'][10];
  51. $ong[2] = $LANG['calendar'][11];
  52. } else { // New item
  53. $ong[1] = $LANG['title'][26];
  54. }
  55. return $ong;
  56. }
  57. /** Clone a calendar to another entity : name is updated
  58. * @param $options array of new values to set
  59. **/
  60. function duplicate ($options=array()) {
  61. if (is_array($options) && count($options)) {
  62. foreach ($options as $key => $val) {
  63. if (isset($this->fields[$key])) {
  64. $this->fields[$key] = $val;
  65. }
  66. }
  67. }
  68. $input = $this->fields;
  69. $oldID = $input['id'];
  70. unset($input['id']);
  71. $newID = $this->add($input);
  72. $calhol = new Calendar_Holiday();
  73. $calhol->cloneCalendar($oldID, $newID);
  74. $calseg = new CalendarSegment();
  75. $calseg->cloneCalendar($oldID, $newID);
  76. $this->updateDurationCache($newID);
  77. }
  78. /**
  79. * Display content of Tab
  80. *
  81. * @param $ID of the item
  82. * @param $tab number of the tab
  83. *
  84. * @return true if handled (for class stack)
  85. **/
  86. function showTabContent ($ID, $tab) {
  87. if ($ID>0 && !parent::showTabContent ($ID, $tab)) {
  88. switch ($tab) {
  89. case 1 :
  90. CalendarSegment::showForCalendar($this);
  91. return true;
  92. case 2 :
  93. Calendar_Holiday::showForCalendar($this);
  94. return true;
  95. case -1 :
  96. CalendarSegment::showForCalendar($this);
  97. Calendar_Holiday::showForCalendar($this);
  98. return false;
  99. }
  100. }
  101. return false;
  102. }
  103. function cleanDBonPurge() {
  104. global $DB;
  105. $query2 = "DELETE
  106. FROM `glpi_calendars_holidays`
  107. WHERE `calendar_id` = '".$this->fields['id']."'";
  108. $DB->query($query2);
  109. $query2 = "DELETE
  110. FROM `glpi_calendarsegments`
  111. WHERE `calendar_id` = '".$this->fields['id']."'";
  112. $DB->query($query2);
  113. }
  114. // TODO : override it : only check link item (SLA / entity) but not calendars_holidays and calendarsegments
  115. // function isUsed() {
  116. // }
  117. /**
  118. * is an holiday day ?
  119. *
  120. * @param $date date of the day to check
  121. *
  122. * @return boolean
  123. **/
  124. function isHoliday($date) {
  125. global $DB;
  126. $query = "SELECT COUNT(*) AS CPT
  127. FROM `glpi_calendars_holidays`
  128. INNER JOIN `glpi_holidays`
  129. ON (`glpi_calendars_holidays`.`holidays_id` = `glpi_holidays`.`id`)
  130. WHERE `glpi_calendars_holidays`.`calendars_id` = '".$this->fields['id']."'
  131. AND (('$date' <= `glpi_holidays`.`end_date`
  132. AND '$date' >= `glpi_holidays`.`begin_date`)
  133. OR (`glpi_holidays`.`is_perpetual` = 1
  134. AND MONTH(`end_date`)*100 + DAY(`end_date`)
  135. >= ".date('nd',strtotime($date))."
  136. AND MONTH(`begin_date`)*100 + DAY(`begin_date`)
  137. <= ".date('nd',strtotime($date))."
  138. )
  139. )";
  140. if ($result=$DB->query($query)) {
  141. return $DB->result($result, 0, 'CPT');
  142. }
  143. return false;
  144. }
  145. /**
  146. * Get active time between to date time for the active calendar
  147. *
  148. * @param $start datetime begin
  149. * @param $end datetime end
  150. * @param $force_work_in_days boolean force working in days
  151. *
  152. * @return timestamp of delay
  153. **/
  154. function getActiveTimeBetween($start, $end, $force_work_in_days=false) {
  155. if (!isset($this->fields['id'])) {
  156. return false;
  157. }
  158. if ($end<$start) {
  159. return 0;
  160. }
  161. $timestart = strtotime($start);
  162. $timeend = strtotime($end);
  163. $datestart = date('Y-m-d',$timestart);
  164. $dateend = date('Y-m-d',$timeend);
  165. $activetime = 0;
  166. if ($force_work_in_days) {
  167. $activetime = $timeend-$timestart;
  168. } else {
  169. $cache_duration = importArrayFromDB($this->fields['cache_duration']);
  170. for ($actualtime=$timestart ; $actualtime<=$timeend ; $actualtime+=DAY_TIMESTAMP) {
  171. $actualdate = date('Y-m-d',$actualtime);
  172. if (!$this->isHoliday($actualdate)) {
  173. $beginhour = '00:00:00';
  174. $endhour = '24:00:00';
  175. $dayofweek = self::getDayNumberInWeek($actualtime);
  176. $timeoftheday = 0;
  177. if ($actualdate==$datestart) { // First day : cannot use cache
  178. $beginhour = date('H:i:s',$timestart);
  179. }
  180. if ($actualdate==$dateend) { // Last day : cannot use cache
  181. $endhour = date('H:i:s',$timeend);
  182. }
  183. if (($actualdate==$datestart || $actualdate==$dateend)
  184. && $cache_duration[$dayofweek]>0) {
  185. $timeoftheday = CalendarSegment::getActiveTimeBetween($this->fields['id'],
  186. $dayofweek, $beginhour,
  187. $endhour);
  188. } else {
  189. $timeoftheday = $cache_duration[$dayofweek];
  190. }
  191. // echo "time of the day = $timeoftheday ".timestampToString($timeoftheday).'<br>';
  192. $activetime+=$timeoftheday;
  193. // echo "cumulate time = $activetime ".timestampToString($activetime).'<br>';
  194. } else {
  195. // echo "$actualdate is an holiday<br>";
  196. }
  197. }
  198. }
  199. return $activetime;
  200. }
  201. /**
  202. * Add a delay to a date using the active calendar
  203. *
  204. * if delay >= DAY_TIMESTAMP : work in days
  205. * else work in minutes
  206. *
  207. * @param $start datetime begin
  208. * @param $delay timestamp delay to add
  209. * @param $force_work_in_days boolean force working in days
  210. *
  211. * @return end date
  212. **/
  213. function computeEndDate($start, $delay, $force_work_in_days=false) {
  214. if (!isset($this->fields['id'])) {
  215. return false;
  216. }
  217. $actualtime = strtotime($start);
  218. $timestart = strtotime($start);
  219. $datestart = date('Y-m-d',$timestart);
  220. if ($delay >= DAY_TIMESTAMP || $force_work_in_days) { // only based on days
  221. $cache_duration = importArrayFromDB($this->fields['cache_duration']);
  222. // Compute Real starting time
  223. // If day is an holiday must start on the begin of next working day
  224. $actualdate = date('Y-m-d',$actualtime);
  225. $dayofweek = self::getDayNumberInWeek($actualtime);
  226. if ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
  227. while ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
  228. $actualtime += DAY_TIMESTAMP;
  229. $actualdate = date('Y-m-d',$actualtime);
  230. $dayofweek = self::getDayNumberInWeek($actualtime);
  231. }
  232. $firstworkhour = CalendarSegment::getFirstWorkingHour($this->fields['id'],
  233. $dayofweek);
  234. $actualtime = strtotime($actualdate.' '.$firstworkhour);
  235. }
  236. while ($delay>0) {
  237. // Begin next day : do not take into account first day : must finish to a working day
  238. $actualtime += DAY_TIMESTAMP;
  239. $actualdate = date('Y-m-d',$actualtime);
  240. $dayofweek = self::getDayNumberInWeek($actualtime);
  241. if (!$this->isHoliday($actualdate) && $cache_duration[$dayofweek]>0 ) {
  242. $delay -= DAY_TIMESTAMP;
  243. }
  244. if ($delay<0) { // delay done : if < 0 delete hours
  245. $actualtime += $delay;
  246. }
  247. }
  248. // If > last working hour set last working hour
  249. $dayofweek = self::getDayNumberInWeek($actualtime);
  250. $lastworkinghour = CalendarSegment::getLastWorkingHour($this->fields['id'], $dayofweek);
  251. if ($lastworkinghour< date('H:i:s', $actualtime)) {
  252. $actualtime = strtotime(date('Y-m-d',$actualtime).' '.$lastworkinghour);
  253. }
  254. return date('Y-m-d H:i:s', $actualtime);
  255. }
  256. // else // based on working hours
  257. $cache_duration = importArrayFromDB($this->fields['cache_duration']);
  258. // Only if segments exists
  259. if (countElementsInTable('glpi_calendarsegments',
  260. "`calendars_id` = '".$this->fields['id']."'")) {
  261. while ($delay>=0) {
  262. $actualdate = date('Y-m-d',$actualtime);
  263. if (!$this->isHoliday($actualdate)) {
  264. $dayofweek = self::getDayNumberInWeek($actualtime);
  265. $beginhour = '00:00:00';
  266. $endhour = '24:00:00';
  267. if ($actualdate==$datestart) { // First day cannot use cache
  268. $beginhour = date('H:i:s',$timestart);
  269. $timeoftheday = CalendarSegment::getActiveTimeBetween($this->fields['id'],
  270. $dayofweek, $beginhour,
  271. $endhour);
  272. } else {
  273. $timeoftheday = $cache_duration[$dayofweek];
  274. }
  275. // Day do not complete the delay : pass to next day
  276. if ($timeoftheday<$delay) {
  277. $actualtime += DAY_TIMESTAMP;
  278. $delay -= $timeoftheday;
  279. } else { // End of the delay in the day : get hours with this delay
  280. $beginhour = '00:00:00';
  281. $endhour = '24:00:00';
  282. if ($actualdate==$datestart) {
  283. $beginhour = date('H:i:s',$timestart);
  284. }
  285. $endhour = CalendarSegment::addDelayInDay($this->fields['id'], $dayofweek,
  286. $beginhour, $delay);
  287. return $actualdate.' '.$endhour;
  288. }
  289. } else { // Holiday : pass to next day
  290. $actualtime += DAY_TIMESTAMP;
  291. }
  292. }
  293. }
  294. return false;
  295. }
  296. /**
  297. * Get days durations including all segments of the current calendar
  298. *
  299. * @return end date
  300. **/
  301. function getDaysDurations() {
  302. if (!isset($this->fields['id'])) {
  303. return false;
  304. }
  305. $results = array();
  306. for ($i=0 ; $i<7 ; $i++) {
  307. $results[$i] = CalendarSegment::getActiveTimeBetween($this->fields['id'], $i, '00:00:00',
  308. '24:00:00');
  309. }
  310. return $results;
  311. }
  312. /**
  313. * Update the calendar cache
  314. **/
  315. function updateDurationCache($calendars_id) {
  316. if ($this->getFromDB($calendars_id)) {
  317. $input['id'] = $calendars_id;
  318. $input['cache_duration'] = exportArrayToDB($this->getDaysDurations());
  319. return $this->update($input);
  320. }
  321. return false;
  322. }
  323. /**
  324. * Get day number (in week) for a date
  325. *
  326. * @param $date date
  327. **/
  328. static function getDayNumberInWeek($date) {
  329. return date('w', $date);
  330. }
  331. }
  332. ?>