action.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. <?php
  2. global $_,$conf;
  3. switch($_['action']){
  4. /** PLANNING **/
  5. //Récuperation d'une liste de planning
  6. case 'planning_search':
  7. Action::write(function(&$response){
  8. global $myUser,$_,$myFirm,$conf;
  9. User::check_access('planning','read');
  10. require_once(__DIR__.SLASH.'Planning.class.php');
  11. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  12. $rankIds = array();
  13. foreach ($myUser->ranks[$myFirm->id] as $rank) {
  14. if($rank->id==0) continue;
  15. $rankIds[] = $rank->id;
  16. }
  17. $sql = 'SELECT * FROM {{table}} p WHERE p.owner = ? OR p.id IN(SELECT s.planning FROM '.PlanningShare::tableName().' s WHERE (recipient = ? AND recipientEntity="user") ';
  18. if(count($rankIds)>0) $sql .= ' OR (recipient IN('.implode(',',$rankIds).') AND recipientEntity="rank" )';
  19. $sql .= ')';
  20. $plannings = Planning::staticQuery($sql,array($myUser->login,$myUser->login),true);
  21. $selectedPlannings = json_decode($myUser->preference('planning_selected_calendars'),true);
  22. $selectedPlannings = !is_array($selectedPlannings) ? array() : $selectedPlannings;
  23. $selectedPlannings = array_filter($selectedPlannings);
  24. if(count($plannings)==0){
  25. $item = Planning::provide();
  26. $item->label = 'Général';
  27. $item->color = '#17a2b8';
  28. $item->owner = $myUser->login;
  29. $item->type = 'local';
  30. $item->default = true;
  31. $item->slug = slugify($item->label);
  32. $item->save();
  33. $plannings[] = $item;
  34. }
  35. Plugin::callHook('planning_planning_search',array(&$plannings,&$selectedPlannings));
  36. usort($plannings, function($a,$b){
  37. global $myUser;
  38. if($a->owner == $myUser->login) return -1;
  39. return 1;
  40. });
  41. foreach($plannings as $planning){
  42. $row = $planning->toArray();
  43. if(in_array($planning->id, $selectedPlannings) || ($planning->default && count($selectedPlannings) ==0 ) )
  44. $row['selected'] = true;
  45. if((int)$conf->get('planning_show_default')!==1 && $planning->default) continue;
  46. $row['editable'] = $planning->owner != $myUser->login ? false : true;
  47. $row['shared'] = $row['owner'] != $myUser->login;
  48. $row['ownerName'] = User::byLogin($row['owner'])->fullName();
  49. $response['rows'][] = $row;
  50. }
  51. });
  52. break;
  53. case 'planning_edit':
  54. global $myUser,$_;
  55. User::check_access('planning','edit');
  56. require_once(__DIR__.SLASH.'planning.modal.php');
  57. break;
  58. //Ajout ou modification d'élément planning
  59. case 'planning_save':
  60. Action::write(function(&$response){
  61. global $myUser,$_;
  62. User::check_access('planning','edit');
  63. require_once(__DIR__.SLASH.'Planning.class.php');
  64. $item = Planning::provide();
  65. if($item->id!=0 && $item->owner != $myUser->login && !$myUser->superadmin) throw new Exception("Seul le propriétaire de ce planning peut le modifier");
  66. $item->label = $_['planning-label'];
  67. $item->color = $_['planning-color'];
  68. $item->owner = $myUser->login;
  69. $item->type = 'local';
  70. $item->save();
  71. });
  72. break;
  73. //Suppression d'élement planning
  74. case 'planning_delete':
  75. Action::write(function(&$response){
  76. global $myUser,$_;
  77. User::check_access('planning','delete');
  78. require_once(__DIR__.SLASH.'Planning.class.php');
  79. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  80. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  81. $planning = Planning::provide();
  82. if(!$planning) throw new Exception("Planning inexistant");
  83. if($planning->default) throw new Exception("Vous ne pouvez pas supprimer le planning par défaut");
  84. if($planning->owner != $myUser->login && !$myUser->superadmin) throw new Exception("Vous ne pouvez pas supprimer un planning dont vous n'êtes pas le propriétaire");
  85. Planning::deleteById($planning->id);
  86. PlanningEvent::delete(array('planning'=>$planning->id));
  87. PlanningShare::delete(array('planning'=>$planning->id));
  88. });
  89. break;
  90. case 'planning_widget_load':
  91. global $myUser;
  92. User::check_access('planning','read');
  93. require_once(__DIR__.SLASH.'..'.SLASH.'dashboard'.SLASH.'DashboardWidget.class.php');
  94. $widget = DashboardWidget::current();
  95. $widget->title = 'Mes 10 prochains rendez vous';
  96. ob_start();
  97. require_once(__DIR__.SLASH.'widget.php');
  98. $widget->content = ob_get_clean();
  99. echo json_encode($widget);
  100. break;
  101. /** PLANNINGEVENT **/
  102. //Récuperation d'une liste de planningevent
  103. case 'planning_event_search':
  104. Action::write(function(&$response){
  105. global $myUser,$_,$myFirm,$conf;
  106. User::check_access('planning','read');
  107. require_once(__DIR__.SLASH.'Planning.class.php');
  108. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  109. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  110. require_once(__DIR__.SLASH.'PlanningEventResource.class.php');
  111. if(!isset($_['plannings'])) return;
  112. $_['plannings'] = explode(',',$_['plannings']);
  113. $plannings = $_['plannings'];
  114. $start = strtotime($_['start']);
  115. $end = strtotime($_['end']);
  116. $events = array();
  117. foreach(array_merge(get_not_workable($start),get_not_workable($end)) as $time){
  118. if($time < $start || $time > $end) continue;
  119. $events[] = array(
  120. 'start' => date('Y-m-d\TH:i:s',$time),
  121. 'end' => date('Y-m-d\T23:59:59',$time),
  122. 'backgroundColor' => '#cecece',
  123. 'display' => 'background'
  124. );
  125. $events[] = array(
  126. 'start' => date('Y-m-d',$time),
  127. 'end' => date('Y-m-d',$time),
  128. 'backgroundColor' => '#cecece',
  129. 'allDay' => true,
  130. 'display' => 'background'
  131. );
  132. }
  133. $allowedPlannings = null;
  134. //en vue équipe on ne selectionne que les planning equipe des equipiers sélectionnés.
  135. if($_['view']=='teammate'){
  136. $plannings = array();
  137. foreach(Planning::loadAll(array('owner:IN'=>implode(",",$_['teammates']), 'slug'=>Planning::TEAMMATE_SLUG)) as $planning){
  138. $plannings[]= $planning->id;
  139. }
  140. $allowedPlannings = $plannings;
  141. }
  142. if(isset($_['plannings']) && count($_['plannings'])!=0){
  143. $myUser->preference('planning_selected_calendars',json_encode($_['plannings']));
  144. $myUser->loadPreferences();
  145. $_SESSION['currentUser'] = serialize($myUser);
  146. foreach(PlanningEvent::getAll($myUser->login,$myUser->ranks[$myFirm->id],$plannings,$start,$end,$allowedPlannings) as $event){
  147. if($event->startDate > $event->endDate) continue;
  148. $textColor = get_light($event->type->color) < 0.6 ? '#fefefefe': '#333333' ;
  149. $isAllDay = false;
  150. $eventLine = array(
  151. 'id' => $event->id,
  152. 'title' => html_entity_decode($event->label,ENT_QUOTES,'UTF-8'),
  153. 'type' => $event->type->id,
  154. 'planning' => $event->planning->id,
  155. 'planningOwner' => $event->planning->owner,
  156. 'planningDefault' => $event->planning->default,
  157. 'allDay' => $isAllDay,
  158. 'street' => $event->street,
  159. 'group' => $event->group,
  160. 'city' => $event->city,
  161. 'zip' => $event->zip,
  162. 'notificationNumber' => $event->notificationNumber,
  163. 'notificationUnity' => $event->notificationUnity,
  164. 'start' => date('Y-m-d\TH:i:s',$event->startDate),
  165. 'end' => date('Y-m-d\TH:i:s',$event->endDate),
  166. 'backgroundColor' => $event->type->color,
  167. 'borderColor' => $event->type->color,
  168. 'textColor' => $textColor,
  169. //'display' => 'block', a décommenter pour avoir la couleur plutot en fond et pas en point
  170. 'underlineColor' => $event->planning->color, //todo, couleur planning a reporter quelque part sur l'event
  171. 'planningLabel' => $event->planning->label,
  172. 'editable' => $conf->get('planning_allow_event_edit') == true,
  173. 'icon' => $event->type->icon,
  174. 'description' => html_entity_decode(str_replace('\n',"\n",$event->description),ENT_QUOTES,'UTF-8'),
  175. 'location' => $event->street.' '.$event->zip.' '.$event->city,
  176. 'resources' => $event->resources,
  177. 'repeatOccurence' => $event->repeatOccurence,
  178. 'repeatUntil' => $event->repeatUntil,
  179. 'repeatYearlyMonth' => $event->repeatYearlyMonth,
  180. 'repeatYearlyNumber' => $event->repeatYearlyNumber,
  181. 'repeatMonthlyDay' => $event->repeatMonthlyDay,
  182. 'repeatMonthlyNumber'=> $event->repeatMonthlyNumber,
  183. 'repeatWeeklyDay' => explode(',',$event->repeatWeeklyDay),
  184. 'repeatDailyNumber' => $event->repeatDailyNumber,
  185. 'repeatType' => $event->repeatType
  186. );
  187. //gestion de l'affichage récurrent
  188. if($event->repeatType != 'never'){
  189. switch($event->repeatType){
  190. case 'daily':
  191. $eventLine['rrule'] = array(
  192. 'dtstart' => date('Y-m-d\TH:i:s',$event->startDate),
  193. 'freq' => 'daily'
  194. );
  195. if(!empty($event->repeatDailyNumber)) $eventLine['rrule']['interval'] =(int) $event->repeatDailyNumber;
  196. break;
  197. case 'weekly':
  198. $eventLine['rrule'] = array(
  199. 'dtstart' => date('Y-m-d\TH:i:s',$event->startDate),
  200. 'freq' => 'weekly'
  201. );
  202. if(!empty($event->repeatWeeklyDay)){
  203. foreach (explode(',',$event->repeatWeeklyDay) as $key => $value) {
  204. $eventLine['rrule']['byweekday'][] = (int) $value -1;
  205. }
  206. }
  207. break;
  208. case 'monthly':
  209. $eventLine['rrule'] = array(
  210. 'dtstart' => date('Y-m-d\TH:i:s',$event->startDate),
  211. 'freq' => 'monthly'
  212. );
  213. if(!empty($event->repeatMonthlyNumber))
  214. $eventLine['rrule']['byweekday'] = array( array('n'=> (int)$event->repeatMonthlyNumber,'weekday'=> (int)$event->repeatMonthlyDay -1));
  215. break;
  216. case 'yearly':
  217. $eventLine['rrule'] = array(
  218. 'dtstart' => date('Y-m-d\TH:i:s',$event->startDate),
  219. 'freq' => 'yearly'
  220. );
  221. if(!empty($event->repeatYearlyNumber)){
  222. $eventLine['rrule']['interval'] = 1;
  223. $eventLine['rrule']['bymonth'] = [(int)$event->repeatYearlyMonth];
  224. $eventLine['rrule']['bymonthday'] = [(int)$event->repeatYearlyNumber];
  225. }
  226. break;
  227. }
  228. if(!empty($event->repeatUntil)) $eventLine['rrule']['until'] = date('Y-m-d',$event->repeatUntil);
  229. if(!empty($event->repeatOccurence)) $eventLine['rrule']['count'] = $event->repeatOccurence;
  230. $eventLine['duration'] = '02:00';
  231. }
  232. $events[] = $eventLine;
  233. }
  234. }
  235. Plugin::callHook('planning_event_search',array(&$events));
  236. $response = $events;
  237. });
  238. break;
  239. case 'planning_event_move':
  240. Action::write(function(&$response){
  241. global $myUser,$_;
  242. User::check_access('planning','edit');
  243. require_once(__DIR__.SLASH.'Planning.class.php');
  244. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  245. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  246. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  247. $item = PlanningEvent::getById($_['event']['id'],1);
  248. if(!$item) throw new Exception("Cet événement n'existe plus, merci de rafraîchir votre planning.");
  249. $planning = $item->join('planning');
  250. if($planning->owner != $myUser->login && !$myUser->can('planning','configure')){
  251. if(PlanningShare::rowCount(array('planning'=>$planning->id,'recipient'=>$myUser->login,'edit'=>1))==0)
  252. throw new Exception("Vous n'avez pas la permission d'éditer cet évenement", 403);
  253. }
  254. $start = explode('/',$_['event']['startDate']);
  255. $end = explode('/',$_['event']['endDate']);
  256. //date_default_timezone_set('Europe/Paris');
  257. $startDate = mktime($_['event']['startHour'],$_['event']['startMinut'],0,$start[1],$start[0],$start[2]);
  258. $endDate = mktime($_['event']['endHour'],$_['event']['endMinut'],0,$end[1],$end[0],$end[2]);
  259. if($_['view']=='teammate'){
  260. //Si l'évenement est bougé sur un equipier n'ayant pas de planning equipe, on le créé a la volée
  261. if($planning->owner != $_['event']['teammate']){
  262. $userPlanning = Planning::load(array('owner'=>$_['event']['teammate'],'slug'=>Planning::TEAMMATE_SLUG));
  263. if(!$userPlanning){
  264. $userPlanning = new Planning();
  265. $userPlanning->slug = Planning::TEAMMATE_SLUG;
  266. $userPlanning->owner = $_['event']['teammate'];
  267. $userPlanning->color = '#8bc34a';
  268. $userPlanning->label = 'Equipe';
  269. $userPlanning->save();
  270. }
  271. $item->planning = $userPlanning->id;
  272. }
  273. }
  274. $item->startDate = $startDate;
  275. $item->endDate = $endDate;
  276. $item->save();
  277. });
  278. break;
  279. case 'planning_event_resource_state':
  280. Action::write(function(&$response){
  281. global $myUser,$_;
  282. User::check_access('planning','read');
  283. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  284. require_once(__DIR__.SLASH.'PlanningEventResource.class.php');
  285. $start = explode('/',$_['startDate']);
  286. $end = explode('/',$_['endDate']);
  287. $startDate = mktime($_['startHour'],$_['startMinut'],0,$start[1],$start[0],$start[2]);
  288. $endDate = mktime($_['endHour'],$_['endMinut'],0,$end[1],$end[0],$end[2]);
  289. $query = 'SELECT e.*,r.resource as resource FROM '.PlanningEventResource::tableName().' r LEFT JOIN {{table}} e ON r.event=e.id WHERE
  290. (e.startDate BETWEEN ? AND ?) OR (e.endDate BETWEEN ? AND ?) OR (e.startDate < ? AND e.endDate > ?)
  291. AND r.resource IN ('.implode(',',array_fill(0, count($_['resources']), '?')).') ';
  292. $data = array(
  293. $startDate,$endDate,$startDate,$endDate,$startDate,$endDate
  294. );
  295. foreach ($_['resources'] as $resource) $data[] = $resource;
  296. if(!empty($_['event'])){
  297. $query.= ' AND e.id!=? ';
  298. $data[] = $_['event'];
  299. }
  300. $response['rows'] = array();
  301. foreach(PlanningEvent::staticQuery($query,$data,true) as $booked){
  302. if(isset($_['event']) && $booked->id == $_['event']) continue;
  303. if(!isset($response['rows'][$booked->foreign('resource')])) $response['rows'][$booked->foreign('resource')] = array();
  304. $response['rows'][$booked->foreign('resource')][] = $booked->toArray();
  305. }
  306. });
  307. break;
  308. //Ajout ou modification d'élément planningevent
  309. case 'planning_event_save':
  310. Action::write(function(&$response){
  311. global $myUser,$_;
  312. User::check_access('planning','edit');
  313. require_once(__DIR__.SLASH.'Planning.class.php');
  314. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  315. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  316. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  317. require_once(__DIR__.SLASH.'PlanningEventResource.class.php');
  318. $item = PlanningEvent::provide('id',1);
  319. if(!$item) throw new Exception("Cet événement n'existe plus, merci de rafraîchir votre planning.");
  320. $start = explode('/',$_['startDate']);
  321. $end = explode('/',$_['endDate']);
  322. $startDate = mktime($_['startHour'],$_['startMinut'],0,$start[1],$start[0],$start[2]);
  323. $endDate = mktime($_['endHour'],$_['endMinut'],0,$end[1],$end[0],$end[2]);
  324. //On ne peut pas avoir une date/heure de fin strictement similaire a la date de début (fullcalendar plante) on ajoute une minute si c'est le cas
  325. if($startDate == $endDate ) $endDate += 60;
  326. if($startDate > $endDate) throw new Exception("Dates incohérentes");
  327. $plannings = array();
  328. //Si on est en vue equipe
  329. if($_['view']=='teammate'){
  330. //on récupere les plannings d'équipe qui correspondent aux logins concernés par l'évenement
  331. $plannings = Planning::loadAll(array('owner:IN'=>$_['user'],'slug'=>Planning::TEAMMATE_SLUG));
  332. //Pour chaque login, on vérifie qu'un planning equipe existe, on le créé le cas échéant
  333. foreach (explode(',',$_['user']) as $user) {
  334. $planningExists = false;
  335. foreach ($plannings as $planning) {
  336. if($planning->owner == $user) $planningExists = true;
  337. }
  338. if(!$planningExists){
  339. $planning = new Planning();
  340. $planning->slug = Planning::TEAMMATE_SLUG;
  341. $planning->owner = $user;
  342. $planning->color = '#8bc34a';
  343. $planning->label = 'Equipe';
  344. $planning->save();
  345. $plannings[] = $planning;
  346. }
  347. }
  348. //Pour toutes les autres vues, on gère le planning de manière classique
  349. }else{
  350. $planning = $item->id==0 ? Planning::getById($_['planning']) : $item->join('planning');
  351. if($planning->owner != $myUser->login){
  352. if(PlanningShare::rowCount(array('planning'=>$planning->id,'recipient'=>$myUser->login,'edit'=>1))==0)
  353. throw new Exception("Vous n'avez pas la permission d'éditer cet évenement", 403);
  354. }
  355. }
  356. $item->label = $_['label'];
  357. if(!empty($_['planning'])) $item->planning = $_['planning'];
  358. if(isset($_['type'])) $item->type = $_['type'];
  359. $item->startDate = $startDate;
  360. $item->endDate = $endDate;
  361. $item->description = $_['description'];
  362. $item->street = $_['street'];
  363. $item->city = $_['city'];
  364. $item->zip = $_['zip'];
  365. if(isset($_['event-repeat-type'])){
  366. $item->repeatType = $_['event-repeat-type'];
  367. if($_['repeatEndType'] == 'occurence')
  368. $item->repeatOccurence = $_['event-repeat-occurences'];
  369. if($_['repeatEndType'] == 'until')
  370. $item->repeatUntil = $_['event-repeat-until'];
  371. $item->repeatYearlyMonth = $_['event-repeat-yearly-month'];
  372. $item->repeatYearlyNumber = $_['event-repeat-yearly-number'];
  373. $item->repeatMonthlyDay = $_['event-repeat-monthly-day'];
  374. $item->repeatMonthlyNumber = $_['event-repeat-monthly-number'];
  375. if(isset($_['weeklyDay']) && is_array($_['weeklyDay'])) $item->repeatWeeklyDay = implode(',',$_['weeklyDay']) ;
  376. $item->repeatDailyNumber = $_['event-repeat-daily-number'];
  377. $item->repeatUntil = !empty($_['event-repeat-until']) ? timestamp_date($_['event-repeat-until']) : '';
  378. $item->repeatOccurence = !empty($_['event-repeat-occurences']) ? $_['event-repeat-occurences'] : '';
  379. }
  380. if(isset($_['notificationNumber']) && !empty($_['notificationNumber'])){
  381. //Si les parametres de notifications ont changé on remet a zero l'etat de notification
  382. if($_['notificationNumber'] != $item->notificationNumber) $item->notificationState = '';
  383. $item->notificationNumber = $_['notificationNumber'];
  384. }
  385. if(isset($_['notificationUnity'])) $item->notificationUnity = $_['notificationUnity'];
  386. $item->save();
  387. PlanningEventResource::delete(array('event'=>$item->id));
  388. //on ajoute les reservation de ressources
  389. if(!empty($_['resources'])){
  390. foreach ($_['resources'] as $id) {
  391. $resource = new PlanningEventResource();
  392. $resource->resource = $id;
  393. $resource->event = $item->id;
  394. $resource->save();
  395. }
  396. }
  397. //on ajoute des copie de cet évenements aux autres planings equipiers concernés
  398. foreach ($plannings as $planning) {
  399. if($item->planning == $planning->id) continue;
  400. $clonedItem = clone($item);
  401. $clonedItem->id = null;
  402. $clonedItem->planning = $planning->id;
  403. $clonedItem->save();
  404. }
  405. });
  406. break;
  407. //Suppression d'élement planningevent
  408. case 'planning_event_delete':
  409. Action::write(function(&$response){
  410. global $myUser,$_;
  411. User::check_access('planning','delete');
  412. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  413. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  414. $events = PlanningEvent::removeAll($myUser->login,$_['events']);
  415. });
  416. break;
  417. case 'planning_group_events_search':
  418. Action::write(function(&$response){
  419. global $myUser,$_;
  420. User::check_access('planning','delete');
  421. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  422. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  423. $response['rows'] = PlanningEvent::loadAll(array('group'=>$_['group']));
  424. });
  425. break;
  426. case 'planning_subtype_search':
  427. Action::write(function(&$response){
  428. global $myUser,$_;
  429. User::check_access('planning','read');
  430. require_once(__DIR__.SLASH.'PlanningEvent.class.php');
  431. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  432. $response['rows'] = array();
  433. foreach (PlanningEventType::loadAll(array('parent'=>$_['type'])) as $type) {
  434. $response['rows'][] = $type->toArray();
  435. }
  436. });
  437. break;
  438. /** TEAMMATE **/
  439. case 'planning_teammate_save':
  440. Action::write(function(&$response){
  441. global $myUser,$_;
  442. User::check_access('planning','read');
  443. $myUser->preference('planning_teammate',implode(',',$_['teammates']));
  444. $myUser->loadPreferences();
  445. $response['teammates'] = array();
  446. $teammates = $myUser->preference('planning_teammate')!='' ? explode(',',$myUser->preference('planning_teammate')) : array();
  447. foreach ($teammates as $login) {
  448. $user = User::byLogin($login);
  449. $user->password = '';
  450. $row = $user->toArray();
  451. $row['avatar'] = $user->getAvatar();
  452. $response['teammates'][] = $row;
  453. }
  454. });
  455. break;
  456. case 'planning_teammate_sort':
  457. Action::write(function(&$response){
  458. global $myUser,$_;
  459. User::check_access('planning','read');
  460. $myUser->preference('planning_teammate',implode(',',$_['sort']));
  461. $myUser->loadPreferences();
  462. });
  463. break;
  464. /** EVENT TYPE **/
  465. //Récuperation d'une liste de planningeventtype
  466. case 'planning_event_type_search':
  467. Action::write(function(&$response){
  468. global $myUser,$_;
  469. User::check_access('planning','read');
  470. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  471. foreach(PlanningEventType::loadAll(array('state'=>PlanningEventType::ACTIVE),array('sort')) as $eventType){
  472. $row = $eventType->toArray();
  473. $row['textcolor'] = get_light($row['color'])> 0.5 ? '#333333':'#ffffff';
  474. $row['editable'] = !empty($row['editable']);
  475. $row['superadmin'] = $myUser->superadmin || $row['editable'];
  476. $row['editableOptions'] = $myUser->superadmin || $row['editable'];
  477. $row['class'] = !empty($eventType->parent) ? 'planning-line-child' : '';
  478. $response['rows'][] = $row;
  479. }
  480. });
  481. break;
  482. case 'planning_event_type_save':
  483. Action::write(function(&$response){
  484. global $myUser,$_,$conf;
  485. User::check_access('planning','configure');
  486. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  487. if(!isset($_['items'])) return $response;
  488. $existingTypes = array();
  489. foreach (PlanningEventType::loadAll() as $existingType) {
  490. $existingTypes[$existingType->id] = $existingType;
  491. }
  492. $o = 0;
  493. foreach ($_['items'] as $i => $item){
  494. $type = !empty($item['id']) ? $existingTypes[$item['id']] : new PlanningEventType();
  495. if($type->id!=0 && !$type->editable && !$myUser->superadmin) throw new Exception("Item non éditable");
  496. $type->sort = $o;
  497. $type->label = $item['label'];
  498. $type->icon = $item['icon'];
  499. $type->editable = $item['editable'] == '1';
  500. $type->color = $item['color'];
  501. $type->slug = slugify($item['label']);
  502. $type->save();
  503. unset($existingTypes[$item['id']]);
  504. $o++;
  505. if(isset($item['childs'])){
  506. foreach($item['childs'] as $u=>$subItem){
  507. $subtype = !empty($subItem['id']) ? $existingTypes[$subItem['id']] : new PlanningEventType();
  508. if($subtype->id!=0 && !$subtype->editable && !$myUser->superadmin) throw new Exception("Item non éditable");
  509. $subtype->label = $subItem['label'];
  510. $subtype->sort = $o;
  511. $subtype->icon = $subItem['icon'];
  512. $subtype->editable = $subItem['editable'] == '1';
  513. $subtype->parent = $type->id;
  514. $subtype->color = $subItem['color'];
  515. $subtype->slug = slugify($subItem['label']);
  516. $subtype->save();
  517. unset($existingTypes[$subItem['id']]);
  518. $o++;
  519. }
  520. }
  521. }
  522. //Suppression logique des types
  523. foreach($existingTypes as $existingType){
  524. $existingType->state = PlanningEventType::INACTIVE;
  525. $existingType->save();
  526. }
  527. });
  528. break;
  529. //Récuperation ou edition d'élément planningeventtype
  530. case 'planning_event_type_edit':
  531. Action::write(function(&$response){
  532. global $myUser,$_;
  533. User::check_access('planning','configure');
  534. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  535. $response = PlanningEventType::getById($_['id']);
  536. });
  537. break;
  538. case 'planning_event_type_sort':
  539. Action::write(function(&$response){
  540. global $myUser,$_;
  541. User::check_access('planning','configure');
  542. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  543. foreach ($_['sort'] as $i=>$id) {
  544. PlanningEventType::change(array('sort'=>$i),array('id'=>$id));
  545. }
  546. });
  547. break;
  548. //Suppression d'élement planningeventtype
  549. case 'planning_event_type_delete':
  550. Action::write(function(&$response){
  551. global $myUser,$_;
  552. User::check_access('planning','configure');
  553. require_once(__DIR__.SLASH.'PlanningEventType.class.php');
  554. $item = PlanningEventType::getById($_['id']);
  555. $item->state = PlanningEventType::INACTIVE;
  556. $item->save();
  557. });
  558. break;
  559. //Sauvegarde des configurations de planning
  560. case 'planning_setting_save':
  561. Action::write(function(&$response){
  562. global $myUser,$_,$conf;
  563. User::check_access('planning','configure');
  564. foreach(Configuration::setting('planning') as $key=>$value){
  565. if(!is_array($value)) continue;
  566. $allowed[] = $key;
  567. }
  568. foreach ($_['fields'] as $key => $value) {
  569. if(in_array($key, $allowed))
  570. $conf->put($key,$value);
  571. }
  572. });
  573. break;
  574. /** PLANNINGSHARE **/
  575. //Récuperation d'une liste de planningshare
  576. case 'planning_share_search':
  577. Action::write(function(&$response){
  578. global $myUser,$_;
  579. User::check_access('planning','read');
  580. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  581. $shares = PlanningShare::loadAll(array('planning'=>$_['planning']));
  582. foreach($shares as $planningshare){
  583. $row = $planningshare->toArray();
  584. $row['edit'] = $row['edit']==0?null:$row['edit'];
  585. if($planningshare->recipientEntity=='rank'){
  586. $rank = Rank::getById($planningshare->recipient);
  587. $row['recipient'] = $rank->label;
  588. $row['recipientType'] = "Rang";
  589. }else{
  590. $row['recipient'] = User::byLogin($planningshare->recipient)->fullName();
  591. $row['recipientType'] = "Utilisateur";
  592. }
  593. $response['rows'][] = $row;
  594. }
  595. });
  596. break;
  597. //Ajout ou modification d'élément planningshare
  598. case 'planning_share_save':
  599. Action::write(function(&$response){
  600. global $myUser,$_;
  601. User::check_access('planning','edit');
  602. require_once(__DIR__.SLASH.'Planning.class.php');
  603. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  604. if(empty($_['recipient'])) throw new Exception("Vous devez préciser le destinataire du partage");
  605. //vérifie que ce destinataire n'a pas déja un partage sur ce planning
  606. if(PlanningShare::rowCount(array('planning'=>$_['planning'],'recipient'=>$_['recipient'])) >0) throw new Exception("Ce destinataire a déja un partage sur ce planning, veuillez supprimer l'ancien partage avant d'en créer un nouveau");
  607. $planning = Planning::getById($_['planning']);
  608. if(!$planning) throw new Exception("Planning inexistant");
  609. if($planning->owner != $myUser->login) throw new Exception("Vous n'êtes pas propriétaire du planning");
  610. if(!$_['read'] && !$_['edit']) throw new Exception("Vous devez cocher au moins un droit de planning");
  611. $item = PlanningShare::provide();
  612. $item->planning = $planning->id;
  613. $item->recipient = stripslashes($_['recipient']);
  614. $item->recipientEntity = $_['recipientEntity'];
  615. $item->read = $_['read'];
  616. $item->edit = $_['edit'];
  617. $item->save();
  618. });
  619. break;
  620. //Suppression d'élement planningshare
  621. case 'planning_share_delete':
  622. Action::write(function(&$response){
  623. global $myUser,$_;
  624. User::check_access('planning','delete');
  625. require_once(__DIR__.SLASH.'Planning.class.php');
  626. require_once(__DIR__.SLASH.'PlanningShare.class.php');
  627. $item = PlanningShare::provide();
  628. $planning = Planning::getById($item->planning);
  629. if($planning->owner != $myUser->login) throw new Exception("Vous n'êtes pas propriétaire du planning");
  630. PlanningShare::deleteById($_['id']);
  631. });
  632. break;
  633. }
  634. ?>