PageRenderTime 67ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/class.xmodcalendar.inc

https://github.com/jcplat/console-seolan
PHP | 2827 lines | 2613 code | 117 blank | 97 comment | 227 complexity | a97078b6b85fa0f0cbf8d4064248fd95 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /// Module de gestion des Agenda
  3. class XModCalendar extends XModule {
  4. public $prefs; /* Preferences du module */
  5. public $day;
  6. public $month;
  7. public $year;
  8. public $week;
  9. public $date;
  10. public $paques;
  11. public $ascencion;
  12. public $pentecote;
  13. public $request; /* tableau avec les elements de base pour les requetes sur les evenements */
  14. public $diary; /* resulset de l'agenda selectionne */
  15. public $group_of_diary;
  16. public $tcolors='#a3d0f2,#ef6464,#77c26d,#eb815d,#a794f0,#d5c128,#b4aeb0,#83d9ff,#e8879e,#98e057,#f68f3d,#c5a3e4,#e8da3f,#c9c1cd,#9fdbf3,#f19999,#c1ec4b,#efaf6a,#b3b8ef,#f4f078,#bac9cd';
  17. public $synchro=false; /* Indique si on est sur une synchronisation ou non (par defaut non) */
  18. public $sendToUser=false; /* Indique si les mails doivent etre envoyes a  l'utilisateur loge */
  19. public $defcal='';
  20. public $categories;
  21. public $display_begin;
  22. public $display_end;
  23. public $cal_content;
  24. public $tagenda; /* liste des agendas connus */
  25. public $tevt; /* evenements */
  26. public $tlinks; /* liens entre agendas et evenements */
  27. public $tcatevt; /* categories d'evenements */
  28. public $tcatagenda; /* categories d'agendas */
  29. public $tplan; /* liste des planifications en cours de traitement */
  30. public $tplaninv; /* liste des invités pour les planification */
  31. public $tplandates; /* liste des dates pour les planification */
  32. public $xsetevt; /* xset sur la table de evenement */
  33. public $catperso; /* oid de la categorie d'agenda perso */
  34. /* ensemble des variables a passer aux templates (_fieldlist : liste des champs de base de l'agenda) */
  35. public $bloc=array('_fieldlist'=>array('text','begin','end','allday','cat','place','descr','visib','repet','end_rep','except','recall',
  36. 'isrecal','attext','rrule','UIDI','KOIDD','KOIDS','KOIDIT'));
  37. function __construct($ar=NULL) {
  38. parent::__construct($ar);
  39. XLabels::loadLabels('xmodcalendar');
  40. $this->colors=explode(',',$this->tcolors);
  41. $p=new XParam($ar,array());
  42. $oid=$p->get('oid');
  43. $now=$p->get('now');
  44. // Dans la cas du traitement d'une planification, on ne construit pas les infos de l'agenda
  45. if(Kernel::getTable($oid)==$this->tplaninv) return;
  46. // Recupere la date a visualiser
  47. if(isset($_REQUEST['now']) || !empty($now)){
  48. $this->day=date('j');
  49. $this->month=date('n');
  50. $this->year=date('Y');
  51. }else{
  52. $this->day=$p->get('day');
  53. $this->month=ltrim($p->get('month'),'0');
  54. $this->year=ltrim($p->get('year'),'0');
  55. }
  56. $this->date=$this->year.'-'.str_pad($this->month,2,'0',STR_PAD_LEFT).'-'.str_pad($this->day,2,'0',STR_PAD_LEFT);
  57. $this->bloc['day']=$this->day;
  58. $this->bloc['month']=$this->month;
  59. $this->bloc['year']=$this->year;
  60. // S'authentifie a la connexion pour une synchro par PUT
  61. if(!empty($_REQUEST['_function'])) $f=$_REQUEST['_function'];
  62. elseif(!empty($_REQUEST['function'])) $f=$_REQUEST['function'];
  63. if($f=='synchro'){
  64. if(empty($_REQUEST['oid'])){
  65. die('nok');
  66. }
  67. if(!XUser::authentified()){
  68. $sess=new XSession();
  69. $ret=$sess->procTmpAuth();
  70. if(!$ret){
  71. header("HTTP/1.0 401 Authorization Required");
  72. die('Authorization Required');
  73. }
  74. }
  75. }
  76. $this->xsetevt=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tevt);
  77. $this->xsetevt->desc['begin']->display_format=$this->xsetevt->desc['end']->display_format='H:M';
  78. // Si pas d'utilisateur, ca ne sert à rien de continuer car on est dans un upgrade
  79. if(empty($GLOBALS['XUSER'])) return;
  80. // Recupere les preferences, l'agenda courant
  81. $this->getPrefs();
  82. if(empty($this->defcal) && !empty($this->prefs['defaultcal'])) $this->defcal=$this->prefs['defaultcal'];
  83. if(empty($oid)){
  84. if(!empty($this->prefs['defaultcal'])) $oid=$this->prefs['defaultcal'];
  85. else $oid=$this->defcal;
  86. }
  87. // Dans le cas ou il n'y a ni oid ni agenda par defaut on prend le premier des agendas autorises
  88. if(empty($oid)) {
  89. $oids=$this->getAuthorizedDiaries();
  90. if(!empty($oids)) {
  91. reset($oids);
  92. $oid=current($oids);
  93. }
  94. }
  95. // Vue par défaut
  96. if(!empty($this->prefs['defview'])) $this->defview=$this->prefs['defview'];
  97. // Verifications de securite
  98. $params_to_check=array('day','week','year','month');
  99. foreach($params_to_check as $t) {
  100. $t1=$p->get($t);
  101. if(!empty($t1) && !is_numeric($t1)) {
  102. $this->$t=$t1;
  103. }
  104. }
  105. if($oid!='') {
  106. if(!strpos($oid,' ')) {
  107. }
  108. }
  109. if($p->get('koid')!='') {
  110. if(!strpos($p->get('koid'),' ')) {
  111. }
  112. }
  113. // Recupere les renseignements sur les categories d'evenement
  114. $rs=selectQuery('SELECT * FROM '.$this->tcatevt.' WHERE commun=1 OR OWN="'.XUser::get_current_user_uid().'" ORDER BY name');
  115. while($rs && $cat=$rs->fetch()) $this->categories[$cat['KOID']]=array('name'=>$cat['name'],'color'=>@$cat['color']);
  116. $this->bloc['categories']=$this->categories;
  117. $this->initialize($oid);
  118. date_default_timezone_set($this->diary['tz']);
  119. }
  120. /// Initialise le module pour un agenda donné : Recupere les données de l'agenda et prepare les composants de base pour les requetes SQL
  121. function initialize($oid){
  122. $rs=selectQuery('SELECT * FROM '.$this->tagenda.' where KOID="'.$oid.'"');
  123. if($this->diary=$rs->fetch()){
  124. if(empty($this->diary['defvisi']) || !in_array($this->diary['defvisi'],array('PU','OC','PR'))) $this->diary['defvisi']='PR';
  125. $this->bloc['diary']=&$this->diary;
  126. $ar=explode(':',$this->diary['begin']);
  127. $this->diary['beginnum']=$ar[0]+$ar[1]/60;
  128. $ar=explode(':',$this->diary['end']);
  129. $this->diary['endnum']=$ar[0]+$ar[1]/60;
  130. if($this->diary['cons']==1) {
  131. $ar=explode('||',$this->diary['agcons']);
  132. $br=array($this->diary['KOID']);
  133. foreach($ar as $i=>$oid){
  134. if(!empty($oid)){
  135. $br[]=$oid;
  136. $this->bloc['diariesprop'][$oid]['color']=$this->colors[$i];
  137. }
  138. }
  139. $this->bloc['group_of_diary']=$this->group_of_diary=true;
  140. } else {
  141. $this->diary['rwsecure']=$this->secure($this->diary['KOID'],'saveEvt');
  142. $this->bloc['diariesprop'][$this->diary['KOID']]['rwsecure']=$this->diary['rwsecure'];
  143. $this->bloc['group_of_diary']=$this->group_of_diary=false;
  144. $this->bloc['diariesprop'][$this->diary['KOID']]['color']=$this->colors[0];
  145. $br=array($this->diary['KOID']);
  146. }
  147. $all=$br;
  148. // Ajoute les consolidations
  149. $cons=$this->getDiariesForConsolidation();
  150. if(!empty($cons['active'])){
  151. $list=array_keys($cons['active']);
  152. $br=array_merge($br,$list);
  153. }
  154. if(!empty($cons['list'])){
  155. $all=array_merge($all,array_keys($cons['list']));
  156. }
  157. // Récupère les noms des differentes consolidations
  158. $rs=selectQuery('select KOID,name from '.$this->tagenda.' where KOID in ("'.implode('","',$all).'")');
  159. while($rs && ($ors=$rs->fetch())){
  160. $this->bloc['diariesprop'][$ors['KOID']]['name']=$ors['name'];
  161. }
  162. foreach($cons['list'] as $oid=>$foo){
  163. $this->bloc['diariesprop'][$oid]['color']=$foo['color'];
  164. if(is_numeric($oid)){
  165. $mod=&XModule::objectfactory(array('moid'=>$oid,'tplentry'=>TZR_RETURN_DATA));
  166. if(!is_object($mod)) continue;
  167. $this->bloc['diariesprop'][$oid]['name']=$mod->modulename;
  168. $this->bloc['diariesprop'][$oid]['url']=$mod->XCalGetUrl('display');
  169. $this->bloc['diariesprop'][$oid]['generalurl']=$mod->XCalGetUrl('browse');
  170. }
  171. }
  172. // Supprime les consolidations erronées (qui n'ont pas de nom) et met à jour le cache
  173. foreach($cons['list'] as $oid=>&$foo){
  174. if(empty($this->bloc['diariesprop'][$oid]['name'])){
  175. unset($cons['list'][$oid]);
  176. unset($cons['active'][$oid]);
  177. }
  178. }
  179. $this->bloc['consolidation']=$this->cache['consolidations']=$cons;
  180. $rw=$this->getAuthorizedDiaries('rw');
  181. $this->bloc['privatediaries']=$rw;
  182. // Champs dans les request (+ KOID et LANG qui ne sont pas dans le tableau) (ordre important dans un union en sql)
  183. $this->request['selectedfields']=array('begin','end','allday','visib','DOWNER','DNAME','DKOID','cat');
  184. // Requete
  185. $this->request['select']='select '.$this->tevt.'.KOID,'.$this->tevt.'.LANG,'.$this->tevt.'.begin,'.$this->tevt.'.end,'.
  186. $this->tevt.'.allday,'.$this->tevt.'.visib,'.$this->tagenda.'.OWN as DOWNER,'.$this->tagenda.'.name as DNAME,'.
  187. $this->tagenda.'.KOID as DKOID,'.$this->tevt.'.cat,"'.$this->_moid.'" as MOID';
  188. $this->request['from']='from '.$this->tevt.','.$this->tlinks.','.$this->tagenda;
  189. $this->request['where']='where '.$this->tagenda.'.KOID in ("'.implode('","',$br).'") AND '.
  190. $this->tagenda.'.KOID='.$this->tlinks.'.KOIDD AND '.$this->tevt.'.KOID='.$this->tlinks.'.KOIDE AND '.
  191. '('.$this->tagenda.'.KOID in ("'.implode('","',$rw).'") OR '.$this->tevt.'.visib!="PR")';
  192. }
  193. }
  194. /// Recupere les evenements en rappel et envoie un mail de rappel
  195. function _daemon($period) {
  196. $rs=selectQuery('select '.$this->tevt.'.*, '.$this->tagenda.'.tz, USERS.email '.
  197. 'from '.$this->tevt.','.$this->tlinks.','.$this->tagenda.',USERS '.
  198. 'where '.$this->tagenda.'.KOID='.$this->tlinks.'.KOIDD AND '.$this->tlinks.'.KOIDE='.$this->tevt.'.KOID AND '.
  199. 'USERS.KOID='.$this->tagenda.'.OWN AND '.
  200. 'UNIX_TIMESTAMP('.$this->tevt.'.begin)<=UNIX_TIMESTAMP("'.gmdate('Y-m-d H:i:s',time()).'")+'.$this->tevt.'.recall*60'.
  201. ' AND recall!=0');
  202. while($rs && $ev=$rs->fetch()) {
  203. date_default_timezone_set($ev['tz']);
  204. $rs2=&updateQuery('update '.$this->tevt.' set recall=0 where KOID="'.$ev['KOID'].'"');
  205. $mail=new XMail();
  206. $mail->_moid=$this->_moid;
  207. $mail->FromName='';
  208. $mail->From='noreply@xsalto.com';
  209. $mail->Subject='Rappel évènement';
  210. $mail->IsHTML(true);
  211. $mail->Body = 'Du '.date('d/m/Y H:i',strtotime($ev['begin'].' GMT')).' au '.
  212. date('d/m/Y H:i',strtotime($ev['end'].' GMT')).' : '.$ev['text'];
  213. $mail->AddAddress($ev['email']);
  214. $mail->Send();
  215. }
  216. return true;
  217. }
  218. /// suppression du module
  219. function delete($ar=NULL) {
  220. parent::delete($ar);
  221. }
  222. /// initialisation des proprietes
  223. public function initOptions() {
  224. parent::initOptions();
  225. $this->_options->setOpt('Vue par defaut', 'defview', 'list',
  226. array('values'=>array('displayDay', 'displayWeek', 'displayMonth', 'displayYear'),
  227. 'labels'=>array('Jour', 'Semaine','Mois', 'Annee')));
  228. $this->_options->setOpt('Alerte mail a la personne connectee','sendToUser', 'boolean', NULL ,false);
  229. $this->_options->setOpt('Agenda : table des agendas', 'tagenda', 'table');
  230. $this->_options->setOpt('Agenda : table des évènements', 'tevt', 'table');
  231. $this->_options->setOpt('Agenda : table des liens', 'tlinks', 'table');
  232. $this->_options->setOpt('Agenda : table des catégories d\'evenements', 'tcatevt', 'table');
  233. $this->_options->setOpt('Agenda : table des catégories d\'agendas', 'tcatagenda', 'table');
  234. $this->_options->setOpt('Planification : table des planifications', 'tplan', 'table');
  235. $this->_options->setOpt('Planification : table des paticipants', 'tplaninv', 'table');
  236. $this->_options->setOpt('Planification : table des dates', 'tplandates', 'table');
  237. $p1=XModule::findParam($this->_moid);
  238. $this->_options->setOpt('Categorie "agenda personnel"', 'catperso', 'object', array('table'=>$p1['MPARAM']['tcatagenda']));
  239. $this->_options->setOpt('Couleurs des agendas', 'tcolors', 'text',array('rows'=>5,'cols'=>50));
  240. }
  241. /// securite des fonctions accessibles par le web
  242. function secGroups($function, $group=NULL) {
  243. $g=array('index' =>array('ro','rw','rwv','admin'),
  244. 'displayDay' =>array('ro','rw','rwv','admin'),
  245. 'displayWeek' =>array('ro','rw','rwv','admin'),
  246. 'displayMonth' =>array('ro','rw','rwv','admin'),
  247. 'displayYear' =>array('ro','rw','rwv','admin'),
  248. 'addEvt' =>array('ro','rw','rwv','admin'),
  249. 'insertPlanif' =>array('rwv','admin'),
  250. 'procInsertPlanif' =>array('rwv','admin'),
  251. 'confirmPlanif' =>array('none','ro','rw','rwv','admin'),
  252. 'procConfirmPlanif' =>array('none','ro','rw','rwv','admin'),
  253. 'browsePlanif' =>array('rwv','admin'),
  254. 'displayPlanif' =>array('rwv','admin'),
  255. 'editPlanif' =>array('rwv','admin'),
  256. 'procEditPlanif' =>array('rwv','admin'),
  257. 'delPlanif' =>array('rwv','admin'),
  258. 'getEmails' =>array('ro','rw','rwv','admin'),
  259. 'saveEvt' =>array('rwv','admin'),
  260. 'saveFastEvt' =>array('rwv','admin'),
  261. 'editDiary' =>array('ro','rw','rwv','admin'),
  262. 'saveDiary' =>array('rwv','admin'),
  263. 'delEvt' =>array('rwv','admin'),
  264. 'exportEvt' =>array('ro','rw','rwv','admin'),
  265. 'saveExport' =>array('ro','rw','rwv','admin'),
  266. 'importEvt' =>array('rwv','admin'),
  267. 'saveImportTable' =>array('rwv','admin'),
  268. 'synchro' =>array('ro','rw','rwv','admin'),
  269. 'setDefault' =>array('ro','rw','rwv','admin'),
  270. 'addConsolidation' =>array('ro','rw','rwv','admin'),
  271. 'updateConsolidation' =>array('ro','rw','rwv','admin'),
  272. 'paramsConsolidation' =>array('ro','rw','rwv','admin'),
  273. 'ajaxEdit' =>array('rwv','admin'),
  274. 'ajaxDel' =>array('rwv','admin')
  275. );
  276. if(isset($g[$function])) {
  277. if(!empty($group)) return in_array($group, $g[$function]);
  278. return $g[$function];
  279. }
  280. return parent::secGroups($function,$group);
  281. }
  282. function ajaxEdit($ar=NULL){
  283. $p=new XParam($ar,NULL);
  284. $oid=$p->get('koid');
  285. $ar['oid']=$oid;
  286. $daybegin=$p->get('daybegin');
  287. $dayend=$p->get('dayend');
  288. $allday=$p->get('allday');
  289. if(!$allday) $ar['options']['begin']['togmt']=$ar['options']['end']['togmt']=true;
  290. if(!empty($oid)){
  291. $ors=selectQueryGetOne('select begin,KOIDS from '.$this->tevt.' where KOID="'.$oid.'" LIMIT 1');
  292. // L'evenement fait parti d"une repetition et n'est pas l'evenement de base : on ajoute une exception à l'evenement de base et on le rend independant
  293. if(!empty($ors['KOIDS'])){
  294. $ar['KOIDS']='';
  295. $date=substr($ors['begin'],0,10);
  296. $ors2=selectQueryGetOne('select except from '.$this->tevt.' where KOID="'.$ors['KOIDS'].'" LIMIT 1');
  297. if(empty($ors2['except'])) $except=$date;
  298. else $except=$ors2['except'].';'.$date;
  299. updateQuery('update '.$this->tevt.' set UPD=UPD, except="'.$except.'" where KOID="'.$ors['KOIDS'].'"');
  300. }else{
  301. $ors2=selectQueryGetOne('select KOID from '.$this->tevt.' where KOIDS="'.$oid.'" order by begin limit 1');
  302. // L'evenement fait parti d"une repetition et est pas l'evenement de base : la premiere repet devient l'evenement de base
  303. if(!empty($ors2)){
  304. updateQuery('update '.$this->tevt.' set KOIDS="'.$ors2['KOID'].'" where KOIDS="'.$oid.'"');
  305. updateQuery('update '.$this->tevt.' set KOIDS=NULL where KOID="'.$ors2['KOID'].'"');
  306. }
  307. }
  308. $ret=$this->xsetevt->procEdit($ar);
  309. }else{
  310. $text=$p->get('text');
  311. $begin=$p->get('begin');
  312. $end=$p->get('end');
  313. $ar1=array('text'=>$text,
  314. 'begindate'=>$begin['date'],
  315. 'beginhour'=>$begin['hour'],
  316. 'enddate'=>$end['date'],
  317. 'endhour'=>$end['hour'],
  318. 'visib'=>'PU',
  319. 'repet'=>'NO',
  320. 'recalltime'=>'',
  321. 'recalltype'=>'1',
  322. 'tplentry'=>TZR_RETURN_DATA);
  323. if($allday) $ar1['allday']=$ar1['allday_HID']=1;
  324. $ret=$this->saveEvt($ar1);
  325. $oid=$ret['oid'];
  326. }
  327. $ors=selectQueryGetAll($this->request['select'].' '.$this->request['from'].' where '.$this->tagenda.'.KOID='.$this->tlinks.'.KOIDD AND '.
  328. $this->tevt.'.KOID='.$this->tlinks.'.KOIDE AND '.$this->tevt.'.KOID="'.$oid.'" LIMIT 1');
  329. $this->convertEventTime($ors[0]);
  330. $this->cutEvents($ors,$daybegin,$dayend);
  331. $ors=$ors[0];
  332. die(json_encode(array('_isod'=>substr($ors['begin'],0,10),'_bd'=>$ors['_begindate'],'_bh'=>$ors['_beginhour'],
  333. '_ed'=>$ors['_enddate'],'_eh'=>$ors['_endhour'],
  334. '_obd'=>$ors['_cbegindate'],'_obh'=>$ors['_cbeginhour'],
  335. '_oed'=>$ors['_cenddate'],'_oeh'=>$ors['_cendhour'],
  336. 'oid'=>$ors['oid'],'text'=>$ors['otext']->html,'descr'=>$ors['odescr']->html,'place'=>$ors['oplace']->html,
  337. 'allday'=>($ors['allday']==1?'1':'0'),'color'=>$this->bloc['diariesprop'][$this->diary['KOID']]['color'],
  338. 'rw'=>1,'cat'=>$this->bloc['categories'][$ors['cat']]['color'],'url'=>$ors['_url'],'dname'=>$ors['DNAME']
  339. )));
  340. }
  341. function ajaxDel($ar=NULL){
  342. $ret=$this->delEvt($ar);
  343. if($ret) die(json_encode("ok"));
  344. else die(json_encode("nok"));
  345. }
  346. /// Action principale du menu
  347. public function getMainAction(){
  348. return $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'moid='.$this->_moid.'&function='.$this->defview.'&oid='.$this->diary['KOID'].
  349. '&tplentry=br&template=xmodcalendar/'.$this->defview.'.html&now=1';
  350. }
  351. function secure($oid,$func,$user=NULL,$lang=TZR_DEFAULT_LANG){
  352. $evoid=@$_REQUEST['koid'];
  353. if($func=='addEvt' && empty($evoid) && !parent::secure($oid,'saveEvt',$user,$lang)){
  354. return false;
  355. }
  356. if($func=='saveEvt' && !empty($evoid)){
  357. $cnt=countSelectQuery('select COUNT(KOID) from '.$this->tevt.' where KOID="'.$evoid.'" and KOIDD="'.$this->diary['KOID'].'"');
  358. if($cnt==0) return false;
  359. }
  360. $table=Kernel::getTable($oid);
  361. if($table==$this->tplaninv){
  362. $ors=selectQueryGetOne('select who from '.$this->tplaninv.' where KOID="'.$oid.'" LIMIT 1');
  363. $who=$ors['who'];
  364. if(Kernel::getTable($who)==$this->tagenda){
  365. $ors=selectQueryGetOne('select OWN from '.$this->tagenda.' where KOID="'.$who.'" LIMIT 1');
  366. $who=$ors['OWN'];
  367. }
  368. if($who==XUser::get_current_user_uid()) return true;
  369. else return false;
  370. }
  371. return parent::secure($oid,$func,$user,$lang);
  372. }
  373. /// Recupere tous les notes et evenements du jour
  374. function &getTasklet(){
  375. $txt='';
  376. $date=date('Y-m-d');
  377. $display_begin_gmt=gmdate('Y-m-d H:i:s',strtotime($date.' 00:00:00'));
  378. $display_end_gmt=gmdate('Y-m-d H:i:s',strtotime($date.' 23:59:00'));
  379. $rs=$this->getAlls($display_begin_gmt,$display_end_gmt,$date.' 00:00:00',$date.' 23:59:59',
  380. 'where '.$this->tagenda.'.KOID='.$this->tlinks.'.KOIDD AND '.$this->tlinks.'.KOIDE='.$this->tevt.'.KOID AND '.
  381. '('.$this->tagenda.'.OWN="'.XUser::get_current_user_uid().'" OR '.$this->tagenda.'.KOID="'.$this->defcal.'")');
  382. while($rs && ($ors=$rs->fetch())){
  383. $this->getCompleteEvent($ors);
  384. $date=explode('-',$ors['begin']);
  385. $url=$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&oid='.$ors['DKOID'].'&moid='.$this->_moid.'&_function=displayDay&'.
  386. 'template=xmodcalendar/displayDay.html&tplentry=br&day='.substr($date[2],0,2).'&month='.$date[1].'&year='.$date[0];
  387. $txt.='<p><a href="'.$url.'">'.$ors['text'].'</a> se d&eacute;roule aujourd\'hui';
  388. if($ors['allday']!=1){
  389. $txt.=' (de '.date('H\hi',strtotime($ors['begin']. 'GMT')).' &agrave; '.date('H\hi',strtotime($ors['end'].' GMT')).')';
  390. }
  391. $txt.='.</p>';
  392. }
  393. return $txt;
  394. }
  395. function getShortTasklet(){
  396. return $this->getTasklet();
  397. }
  398. /// synchronisation des agendas
  399. function synchro($ar=NULL){
  400. $p=new XParam($ar,array());
  401. $this->synchro=true;
  402. $rw=$this->secure($p->get('oid'), 'importEvt');
  403. if($_SERVER["REQUEST_METHOD"]=='PROPFIND'){
  404. die();
  405. }
  406. if(!empty($_REQUEST['phpputdata'])) {
  407. if($rw){
  408. $_FILES['filetoimp']['tmp_name']=$_REQUEST['phpputdata'];
  409. $_FILES['filetoimp']['size']=filesize($filename);
  410. $_FILES['filetoimp']['name']='Importics.ics';
  411. $this->importEvt($ar);
  412. }else{
  413. header("HTTP/1.0 404 Not Found");
  414. }
  415. }else{
  416. $ar['period']='all';
  417. $this->saveExport($ar);
  418. }
  419. $id=session_id();
  420. session_destroy();
  421. die();
  422. }
  423. function index($ar=NULL) {
  424. $p=new XParam($ar,array());
  425. $tplentry=$p->get('tplentry');
  426. $r=array();
  427. if($tplentry=='*return*') {
  428. return $r;
  429. } else {
  430. $this->setTplCommons();
  431. XShell::toScreen1($tplentry,$r);
  432. }
  433. }
  434. /// cette fonction est appliquee pour afficher l'ensemble des methodes de ce module
  435. protected function _actionlist(&$my=NULL) {
  436. if(!$this->day) $date='now';
  437. else $date='day='.$this->day.'&month='.$this->month.'&year='.$this->year;
  438. $uniqid=XShell::uniqid();
  439. $moid=$this->_moid;
  440. $dir='xmodcalendar';
  441. $oidcal=@$this->diary['KOID'];
  442. parent::_actionlist($my);
  443. if($this->interactive) {
  444. $o1=new XModuleAction($this,'def',$this->modulename,
  445. '&moid='.$moid.'&_function='.$this->defview.'&tplentry=br&template='.$dir.'/'.$this->defview.'.html&now','display');
  446. $my['stack'][]=$o1;
  447. if(!empty($oidcal)){
  448. $o1=new XModuleAction($this,'diary',$this->diary['name'],
  449. '&moid='.$moid.'&oid='.$oidcal.'&_function='.$this->defview.'&tplentry=br&template='.$dir.'/'.$this->defview.'.html&now',
  450. 'display');
  451. $my['stack'][]=$o1;
  452. }
  453. }
  454. if(empty($oidcal)) return;
  455. // Liste des agendas
  456. if(!empty($this->bloc['diary_list']['lines_oid']) && count($this->bloc['diary_list']['lines_oid'])>1){
  457. $o1=new XModuleAction($this,'chooseag', XLabels::getSysLabel('xmodcalendar','diary','text'),'#');
  458. $o1->newgroup='chooseag';
  459. $o1->menuable=true;
  460. $my['chooseag']=$o1;
  461. foreach($this->bloc['diary_list']['lines_oid'] as $i=>$oid){
  462. $o1=new XModuleAction($this,'chooseag', $this->bloc['diary_list']['lines_oname'][$i]->html,
  463. '&moid='.$this->_moid.'&oid='.$oid.'&function='.$this->defview.'&tplentry=br&template=xmodcalendar/'.$this->defview.'.html&now','chooseag');
  464. $o1->menuable=true;
  465. $my['chooseag'.$i]=$o1;
  466. }
  467. }
  468. // Assigner agenda par defaut
  469. $o1=new XModuleAction($this, 'setDefault', XLabels::getSysLabel('xmodcalendar','default','text'),
  470. '&moid='.$moid.'&oid='.$oidcal.'&display='.XShell::_function().'&_function=setDefault','edit');
  471. $o1->menuable=true;
  472. $my['setDefault']=$o1;
  473. // Aujourd'hui
  474. $o1=new XModuleAction($this, 'displayToday', XLabels::getSysLabel('xmodcalendar','today','text'),
  475. '&moid='.$moid.'&oid='.$oidcal.
  476. '&_function='.$this->defview.'&tplentry=br&template='.$dir.'/'.$this->defview.'.html&now','display');
  477. $o1->setToolbar('xmodcalendar','today');
  478. $my['displaytoday']=$o1;
  479. // Affichage quotidien
  480. $o1=new XModuleAction($this, 'displayDay', XLabels::getSysLabel('xmodcalendar','displayday','text'),
  481. '&moid='.$moid.'&oid='.$oidcal.
  482. '&_function=displayDay&tplentry=br&template='.$dir.'/displayDay.html&'.$date,'display');
  483. $o1->setToolbar('xmodcalendar','displayday');
  484. $my['displayday']=$o1;
  485. // Affichage hebdo
  486. $o1=new XModuleAction($this, 'displayWeek', XLabels::getSysLabel('xmodcalendar','displayweek','text'),
  487. '&moid='.$moid.'&oid='.$oidcal.
  488. '&_function=displayWeek&tplentry=br&template='.$dir.'/displayWeek.html&'.$date,'display');
  489. $o1->setToolbar('xmodcalendar','displayweek');
  490. $my['displayweek']=$o1;
  491. // Affichage mensuel
  492. $o1=new XModuleAction($this, 'displayMonth', XLabels::getSysLabel('xmodcalendar','displaymonth','text'),
  493. '&moid='.$moid.'&oid='.$oidcal.
  494. '&_function=displayMonth&tplentry=br&template='.$dir.'/displayMonth.html&'.$date,'display');
  495. $o1->setToolbar('xmodcalendar','displaymonth');
  496. $my['displaymonth']=$o1;
  497. // Affichage annuel
  498. $o1=new XModuleAction($this, 'displayYear', XLabels::getSysLabel('xmodcalendar','displayyear','text'),
  499. '&moid='.$moid.'&oid='.$oidcal.
  500. '&_function=displayYear&tplentry=br&template='.$dir.'/displayYear.html&'.$date,'display');
  501. $o1->setToolbar('xmodcalendar','displayyear');
  502. $my['displayyear']=$o1;
  503. // Parcourir planification en cours
  504. if($this->secure($this->diary['KOID'],'browsePlanif')){
  505. $o1=new XModuleAction($this, 'browsePlanif', XLabels::getSysLabel('xmodcalendar','browseplanif','text'),
  506. '&moid='.$moid.'&oid='.$oidcal.'&_function=browsePlanif&template=xmodcalendar/browsePlanif.html&tplentry=br',
  507. 'edit');
  508. $o1->menuable=true;
  509. $o1->separator=true;
  510. $my['browsePlanif']=$o1;
  511. }
  512. // Ajouter planification
  513. if($this->secure($this->diary['KOID'],'insertPlanif')){
  514. $o1=new XModuleAction($this, 'insertPlanif', XLabels::getSysLabel('xmodcalendar','insertplanif','text'),
  515. '&moid='.$moid.'&oid='.$oidcal.'&_function=insertPlanif&template=xmodcalendar/newPlanif.html&tplentry=br',
  516. 'edit');
  517. $o1->menuable=true;
  518. $my['insertPlanif']=$o1;
  519. }
  520. // Next et prev dans la toolbar
  521. $tb=XShell::from_screen('br','toolbar');
  522. if(!empty($tb['prev'])) {
  523. $o1=new XModuleAction($this, 'next', XLabels::getSysLabel('general','previous','text'),
  524. '&moid='.$moid.'&oid='.$oidcal.
  525. '&_function='.XShell::_function().'&tplentry=br&template='.$_REQUEST['template'].'&'.$tb['prev'],'display');
  526. $o1->setToolbar('general','previous');
  527. $my['previous']=$o1;
  528. }
  529. if(!empty($tb['next'])) {
  530. $o1=new XModuleAction($this, 'next', XLabels::getSysLabel('general','next','text'),
  531. '&moid='.$moid.'&oid='.$oidcal.
  532. '&_function='.XShell::_function().'&tplentry=br&template='.$_REQUEST['template'].'&'.$tb['next'],'display');
  533. $o1->setToolbar('general','next');
  534. $my['next']=$o1;
  535. }
  536. // Edition de l'agenda courant
  537. if(!empty($oidcal)){
  538. $o1=new XModuleAction($this,'edit',XLabels::getSysLabel('xmodcalendar','editdiary','text'),
  539. '&moid='.$moid.'&oid='.$oidcal.'&_function=editDiary&tplentry=br&'.
  540. 'template=xmodcalendar/editDiary.html&day='.$this->day.'&month='.$this->month.'&year='.$this->year,'edit');
  541. $o1->order=2;
  542. $o1->setToolbar('general','edit');
  543. $my['edit']=$o1;
  544. }
  545. // Abonnement
  546. $modsubmoid=XModule::getMoid(XMODSUB_TOID);
  547. if(!empty($modsubmoid)){
  548. $o1=new XModuleAction($this, 'subscribe', XLabels::getSysLabel('xmodsub','subadd','text'),
  549. 'javascript:v'.$uniqid.'.addSub("'.$modsubmoid.'","'.$oidcal.'");','more');
  550. $o1->menuable=true;
  551. $my['subscribe']=$o1;
  552. }
  553. }
  554. protected function _lasttimestamp() {
  555. $rs=selectQueryByNum('select MAX(UPD) from '.$this->tlinks);
  556. if($ors=$rs->fetch()) {
  557. $rs->closeCursor();
  558. return $ors[0];
  559. }
  560. return 0;
  561. }
  562. function _whatsNew($ts,$user,$group=NULL,$specs=NULL,$timestamp) {
  563. list($oid)=explode(';',$specs);
  564. if($oid){
  565. $lvl=XUser::secure8maxlevel($this,$oid);
  566. if(in_array($lvl,array('rw','rwv','admin'))){
  567. $rs=selectQuery('select '.$this->tlinks.'.* from '.$this->tlinks.' left outer join '.$this->tevt.' on '.
  568. $this->tevt.'.KOID='.$this->tlinks.'.KOIDE where '.$this->tlinks.'.UPD>="'.$ts.'" and '.
  569. $this->tlinks.'.KOIDD="'.$oid.'"');
  570. }elseif($lvl=='ro'){
  571. $rs=selectQuery('select '.$this->tlinks.'.* from '.$this->tlinks.' left outer join '.$this->tevt.' on '.
  572. $this->tevt.'.KOID='.$this->tlinks.'.KOIDE where '.$this->tlinks.'.UPD>="'.$ts.'" and '.
  573. $this->tlinks.'.KOIDD="'.$oid.'" and '.$this->tevt.'.visib="PU"');
  574. }
  575. }else{
  576. $prcals=$this->getAuthorizedDiaries('ro','array',true);
  577. $pucals=$this->getAuthorizedDiaries('rw','array',true);
  578. $prcals=implode('","',array_diff($prcals,$pucals));
  579. $pucals=implode('","',$pucals);
  580. $rs=selectQuery('select '.$this->tlinks.'.* from '.$this->tlinks.' left outer join '.$this->tevt.' on '.
  581. $this->tevt.'.KOID='.$this->tlinks.'.KOIDE where '.$this->tlinks.'.UPD>="'.$ts.'" and '.
  582. '((visib="PU" and '.$this->tlinks.'.KOIDD in ("'.$prcals.'")) or ('.$this->tlinks.'.KOIDD in ("'.$pucals.'"))) '.
  583. 'order by '.$this->tlinks.'.KOIDE');
  584. }
  585. $txt='';
  586. $prevoid='';
  587. $rs2=selectQuery('select KOID,name from '.$this->tagenda);
  588. $diaries=array();
  589. while($rs2 && ($ors2=$rs2->fetch())){
  590. $diaries[$ors2['KOID']]=$ors2['name'];
  591. }
  592. while($rs && ($ors=$rs->fetch())){
  593. if($prevoid!=$ors['KOIDE']){
  594. $d=$this->xsetevt->display(array('oid'=>$ors['KOIDE'],'tplentry'=>TZR_RETURN_DATA));
  595. $when=$d['oUPD']->html;
  596. $who=$d['lst_upd']['usernam'];
  597. $prevoid=$ors['KOIDE'];
  598. }
  599. $txt.='<li><a href="'.$GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,false).'moid='.$this->_moid.'&function=addEvt&mode=view&oid='.$ors['KOIDD'].
  600. '&koid='.$d['oid'].'&tplentry=br&template=xmodcalendar/addEvt.html&_direct=1">"'.$d['otext']->html.'"</a> sur "'.$diaries[$ors['KOIDD']].'" '.
  601. '('.$when.', '.$who.')</li>';
  602. }
  603. return $txt;
  604. }
  605. function actionListAdd(&$my,$f){
  606. if(!$this->group_of_diary && $this->diary['rwsecure']){
  607. $o1=new XModuleAction($this,'addevt',XLabels::getSysLabel('xmodcalendar','addevt','text'),
  608. '&moid='.$this->_moid.'&_function=addEvt&tplentry=br&template=xmodcalendar/addEvt.html&oid='.$this->diary['KOID'].
  609. '&day='.$this->day.'&month='.$this->month.'&year='.$this->year.'&display='.$f,'edit');
  610. $o1->setToolbar('xmodcalendar','addevt');
  611. $my['addevt']=$o1;
  612. $o1=new XModuleAction($this,'import',XLabels::getSysLabel('xmodcalendar','importevt','text'),
  613. '&moid='.$this->_moid.'&_function=importEvt&tplentry=br&template=xmodcalendar/importEvt.html&oid='.$this->diary['KOID'].
  614. '&day='.$this->day.'&month='.$this->month.'&year='.$this->year.'&display='.$f,'edit');
  615. $o1->menuable=true;
  616. $my['importevt']=$o1;
  617. }
  618. $o1=new XModuleAction($this,'export',XLabels::getSysLabel('xmodcalendar','exportevt','text'),
  619. '&moid='.$this->_moid.'&_function=exportEvt&tplentry=br&template=xmodcalendar/exportEvt.html&oid='.$this->diary['KOID'].
  620. '&day='.$this->day.'&month='.$this->month.'&year='.$this->year.'&display='.$f,'edit');
  621. $o1->menuable=true;
  622. $my['exportevt']=$o1;
  623. }
  624. function al_displayDay(&$my){
  625. // Si pas d'utilisateur, ca ne sert à rien de continuer car on est dans un upgrade
  626. if(empty($GLOBALS['XUSER']) || XUser::isNobody()) return;
  627. $uniqid=XShell::uniqid();
  628. $moid=$this->_moid;
  629. $oidcal=@$this->diary['KOID'];
  630. $cons=$this->getDiariesForConsolidation();
  631. $f=XShell::_function();
  632. $this->actionListAdd($my,$f);
  633. $o1=new XModuleAction($this, 'cons', XLabels::getSysLabel('xmodcalendar','consolidation','text'),'#','edit');
  634. $o1->newgroup='cons_index';
  635. $o1->menuable=true;
  636. $my['cons']=$o1;
  637. $auths=$this->getAuthorizedDiaries();
  638. foreach($auths as $oid){
  639. if($oid==$this->diary['KOID'] || !empty($cons['list'][$oid])) continue;
  640. if(empty($my['consag'])){
  641. $o1=new XModuleAction($this, 'consag', XLabels::getSysLabel('xmodcalendar','diary','text'),'#');
  642. $o1->group='cons_index';
  643. $o1->newgroup='consag_index';
  644. $o1->menuable=true;
  645. $my['consag']=$o1;
  646. }
  647. $ors=selectQueryGetAll('select name from '.$this->tagenda.' where KOID="'.$oid.'"');
  648. $o1=new XModuleAction($this, 'consag', $ors[0]['name'],'javascript:v'.$uniqid.'.addConsolidation("'.$oid.'");');
  649. $o1->group='consag_index';
  650. $o1->menuable=true;
  651. $my['consag'.$oid]=$o1;
  652. }
  653. $o1=new XModuleAction($this, 'consmod', XLabels::getSysLabel('general','module','text'),'#');
  654. $o1->group='cons_index';
  655. $o1->newgroup='consmod_index';
  656. $o1->menuable=true;
  657. $my['consmod']=$o1;
  658. $mods=XModule::authorizedModules();
  659. $rs=&cacheSelectQuery('select MOID,MODULE from MODULES where TOID in("'.XMODTABLE_TOID.'") order by MODULE');
  660. while($rs && ($ors=$rs->fetch())){
  661. $moid=$ors['MOID'];
  662. if(!in_array($moid,$mods) || !empty($cons['list'][$moid])) continue;
  663. $o1=new XModuleAction($this, 'consag', $ors['MODULE'],'javascript:v'.$uniqid.'.addConsolidation("'.$moid.'");');
  664. $o1->group='consmod_index';
  665. $o1->menuable=true;
  666. $my['consmod'.$ors['MODULE']]=$o1;
  667. }
  668. }
  669. function al_displayWeek(&$my){
  670. $this->al_displayDay($my);
  671. }
  672. function al_displayMonth(&$my){
  673. $this->al_displayDay($my);
  674. }
  675. function al_displayYear(&$my){
  676. $this->al_displayDay($my);
  677. }
  678. function al_addEvt(&$my){
  679. $this->actionListAdd($my,$_REQUEST['display']);
  680. }
  681. function al_editDiary(&$my){
  682. $this->actionListAdd($my,$_REQUEST['display']);
  683. }
  684. function al_exportEvt(&$my){
  685. $this->actionListAdd($my,$_REQUEST['display']);
  686. }
  687. function al_importEvt(&$my){
  688. }
  689. function al_browsePlanif(&$my){
  690. $uniqid=XShell::uniqid();
  691. $o1=new XModuleAction($this,'delPlan',XLabels::getSysLabel('general','delete','text'),'javascript:v'.$uniqid.'.deleteselected();','edit');
  692. $o1->order=3;
  693. $o1->setToolbar('general','delete');
  694. $my['delPlan']=$o1;
  695. }
  696. function al_displayPlanif(&$my){
  697. $o1=new XModuleAction($this,'editPlan',XLabels::getSysLabel('general','edit','text'),str_replace('function=displayPlanif','function=editPlanif',$_SERVER['REQUEST_URI']),'edit');
  698. $o1->menuable=true;
  699. $my['editPlan']=$o1;
  700. }
  701. /// Afficher les infos sur une journee
  702. function displayDay($ar=NULL) {
  703. $p=new XParam($ar,array());
  704. $this->bloc['calendar_mode']='';
  705. $this->createCalendar($p);
  706. $display_begin_gmt=gmdate('Y-m-d H:i:s',strtotime($this->date.' 00:00:00'));
  707. $display_end_gmt=gmdate('Y-m-d H:i:s',strtotime($this->date.' 23:59:00'));
  708. $this->display_begin=date('Y-m-d H:i:s',strtotime($this->date.' 00:00:00'));
  709. $this->display_end=date('Y-m-d H:i:s',strtotime($this->date.' 23:59:00'));
  710. $day_begin=$this->diary['beginnum'];
  711. $day_end=$this->diary['endnum'];
  712. // Recupere les notes et evenements
  713. $notes=$this->getNotes($this->display_begin,$this->display_end,false,true);
  714. $events=$this->getEvents($display_begin_gmt,$display_end_gmt,false,true);
  715. $this->getDisplayHours($events,$day_begin,$day_end);
  716. $this->cutNotes($notes);
  717. $this->cutEvents($events,$day_begin,$day_end);
  718. // Construit les infos a envoyer au template
  719. $this->bloc['daybegin']=$day_begin;
  720. $this->bloc['dayend']=$day_end;
  721. $this->bloc['dates']=array($this->date);
  722. $this->bloc['events']=$events;
  723. $this->bloc['notes']=$notes;
  724. $this->bloc['toolbar']=array('prev'=>date('\d\a\y=j&\m\o\n\t\h=n&\y\e\a\r=Y',strtotime($this->date.' -1 day')),
  725. 'next'=>date('\d\a\y=j&\m\o\n\t\h=n&\y\e\a\r=Y',strtotime($this->date.' +1 day')));
  726. return XShell::toScreen1('br',$this->bloc);
  727. }
  728. /// Afficher les infos sur une semaine
  729. function displayWeek($ar=NULL) {
  730. $p=new XParam($ar,array());
  731. $first_day_week=$this->calculateWeekDetails($p);
  732. $this->createCalendar($p);
  733. $display_begin_gmt=gmdate('Y-m-d H:i:s',$first_day_week);
  734. $display_end_gmt=gmdate('Y-m-d H:i:s',strtotime('+7 day -1 minute',$first_day_week));
  735. $this->display_begin=date('Y-m-d H:i:s',$first_day_week);
  736. $this->display_end=date('Y-m-d H:i:s',strtotime('+7 day -1 minute',$first_day_week));
  737. $day_begin=$this->diary['beginnum'];
  738. $day_end=$this->diary['endnum'];
  739. // Recupere les notes et evenements
  740. $notes=$this->getNotes($this->display_begin,$this->display_end,false,true);
  741. $events=$this->getEvents($display_begin_gmt,$display_end_gmt,false,true);
  742. $this->getDisplayHours($events,$day_begin,$day_end);
  743. $this->cutNotes($notes);
  744. $this->cutEvents($events,$day_begin,$day_end);
  745. // Construit les infos a envoyer au template
  746. $this->bloc['daybegin']=$day_begin;
  747. $this->bloc['dayend']=$day_end;
  748. $this->bloc['dates']=array();
  749. for($i=0;$i<7;$i++) $this->bloc['dates'][]=date('Y-m-d',strtotime('+'.$i.' day',$first_day_week));
  750. $this->bloc['events']=$events;
  751. $this->bloc['notes']=$notes;
  752. $this->bloc['toolbar']=array('prev'=>date('\w\e\e\k=W&\y\e\a\r=o',strtotime('-1 week '.$this->date)),
  753. 'next'=>date('\w\e\e\k=W&\y\e\a\r=o',strtotime('+1 week '.$this->date))
  754. );
  755. return XShell::toScreen1('br',$this->bloc);
  756. }
  757. /// Afficher les infos sur un mois
  758. function displayMonth($ar=NULL) {
  759. $p=new XParam($ar,array());
  760. $events=$table=array();
  761. $this->day=1;
  762. $this->createCalendar($p);
  763. $month_list_label=XLabels::getSysLabel('xmodcalendar','monthlist','text');
  764. $this->bloc['header']=$month_list_label[$this->month-1].' '.$this->year;
  765. // Les infos a afficher sont deja calculer pour le mini calendrier du bas. On les recupere donc pour les afficher en entier
  766. $this->bloc['body']=$this->cal_content;
  767. $this->bloc['toolbar']=array('prev'=>date('\d\a\y=1&\m\o\n\t\h=n&\y\e\a\r=Y',strtotime($this->date.' -1 month')),
  768. 'next'=>date('\d\a\y=1&\m\o\n\t\h=n&\y\e\a\r=Y',strtotime($this->date.' +1 month'))
  769. );
  770. return XShell::toScreen1('br',$this->bloc);
  771. }
  772. /// Afficher les infos sur une annee
  773. function displayYear($ar=NULL) {
  774. $p=new XParam($ar,array());
  775. $month_list_label=XLabels::getSysLabel('xmodcalendar','monthlist','text');
  776. $this->createCalendar($p);
  777. $display_begin_gmt=gmdate('Y-m-d H:i:s',strtotime($this->year.'-01-01 00:00:00'));
  778. $display_end_gmt=gmdate('Y-m-t H:i:s',strtotime($this->year.'-12-31 23:59:00'));
  779. $this->display_begin=date('Y-m-d H:i:s',strtotime($this->year.'-01-01 00:00:00'));
  780. $this->display_end=date('Y-m-t H:i:s',strtotime($this->year.'-12-31 23:59:00'));
  781. // Recupere les notes et les evenements
  782. $rs=$this->getAlls($display_begin_gmt,$display_end_gmt,$this->display_begin,$this->display_end);
  783. while($rs && ($event=$rs->fetch())) {
  784. $this->convertEventTime($event);
  785. $begin=date('z',strtotime($event['begin']));
  786. $end=date('z',strtotime($event['end']));
  787. for($i=$begin;$i<=$end;$i++) $events[$i]=1;
  788. }
  789. for($j=1;$j<13;$j++) {
  790. $nb_day_prev_month=date('t', mktime(12,0,0,$j-1,1,$this->year));
  791. $nb_day_month=date('t', mktime(12,0,0,$j,1,$this->year));
  792. $first_day=date('N',mktime(12,00,00,$j,1,$this->year));
  793. $last_day=date('N',mktime(12,00,00,$j+1,0,$this->year));
  794. $day_of_year=date('z',mktime(12,00,00,$j,1,$this->year));
  795. $prev_month=date('n',mktime(12,00,00,$j-1,1,$this->year));
  796. $next_month=date('n',mktime(12,00,00,$j+1,1,$this->year));
  797. $prev_year=date('Y',mktime(12,00,00,$j-1,1,$this->year));
  798. $next_year=date('Y',mktime(12,00,00,$j+1,1,$this->year));
  799. $month_content=array();
  800. for($i=$first_day-2;$i>-1;$i--) {
  801. $month_content[]=array('day'=>$nb_day_prev_month-$i,'month'=>$prev_month,'year'=>$prev_year,'event'=>false,'style'=>'out');
  802. }
  803. for($i=1;$i<=$nb_day_month;$i++) {
  804. $month_content[]=array('day'=>$i,'month'=>$j,'year'=>$this->year,'event'=>(isset($events[$day_of_year+$i-1]))?true:false,
  805. 'style'=>'in');
  806. }
  807. for($i=1;$i<8-$last_day;$i++) {
  808. $month_content[]=array('day'=>$i,'month'=>$next_month,'year'=>$next_year,'event'=>false,'style'=>'out');
  809. }
  810. $content[$j]=array('header'=>$month_list_label[$j-1].' '.$this->year,'content'=>$month_content);
  811. }
  812. $this->bloc['body']=$content;
  813. $this->bloc['toolbar']=array('prev'=>'day=1&month1=n&year='.($this->year-1),'next'=>'day=1&month1=n&year='.($this->year+1));
  814. return XShell::toScreen1('br',$this->bloc);
  815. }
  816. /// Retourne une liste d'evenements/notes/tous sur une periode
  817. function browsePeriod($ar=NULL){
  818. $p=new XParam($ar,array('type'=>'all','begin'=>'1970-01-01','end'=>'2037-12-31'));
  819. $type=$p->get('type');
  820. $begin=$p->get('begin');
  821. $end=$p->get('end');
  822. $tplentry=$p->get('tplentry');
  823. $getrsonly=$p->get('getrsonly');
  824. if($type=='all') $rs=$this->getAlls(gmdate('Y-m-d H:i:s',strtotime($begin.' 00:00:00')),
  825. gmdate('Y-m-d H:i:s',strtotime($end.' 23:59:00')),
  826. $begin.' 00:00:00',$end.' 23:59:59');
  827. if($getrsonly) return $rs;
  828. $result=array();
  829. while($rs && ($ors=$rs->fetch())){
  830. $this->getCompleteEvent($ors);
  831. $ors['_begindate']=date('d/m/Y',strtotime($ors['begin'].' GMT'));
  832. $ors['_beginhour']=date('H:i',strtotime($ors['begin'].' GMT'));
  833. $ors['_enddate']=date('d/m/Y',strtotime($ors['end'].' GMT'));
  834. $ors['_endhour']=date('H:i',strtotime($ors['end'].' GMT'));
  835. $result[]=$ors;
  836. }
  837. return XShell::toScreen2($tplentry,'list',$result);
  838. }
  839. /// rend les emails d'un user ou des users d'un groupe
  840. function getEmails($ar=NULL) {
  841. $p=new XParam($ar, array());
  842. $doid=$p->get("doid");
  843. if(Kernel::getTable($doid)=='GRP') {
  844. $users = XModGroup::users(array($doid));
  845. } else {
  846. $users=array($doid);
  847. }
  848. $emails=array();
  849. foreach($users as $oid) {
  850. $xuser=new XUser(array("UID"=>$oid));
  851. $emails[]=$xuser->email();
  852. unset($xuser);
  853. }
  854. echo json_encode($emails);
  855. exit(0);
  856. }
  857. /// Ajout/edition/consultation d'un evenement
  858. function addEvt($ar=NULL) {
  859. $p=new XParam($ar,array('getintattendees'=>true,'hour'=>'08:00:00'));
  860. $mode=$p->get('mode');
  861. $oid=$p->get('oid');
  862. $koid=$p->get('koid');
  863. $hour=$p->get('hour');
  864. $allday=$p->get('allday');
  865. $getintattendees=$p->get('getintattendees');
  866. // Definit la fonction a executer
  867. if($mode=='view'){
  868. $function='display';
  869. $secure=false;
  870. }else{
  871. $secure=$this->secure($oid,'saveEvt');
  872. if(empty($koid) && $secure) $function="input";
  873. elseif($secure) $function="edit";
  874. else $function="display";
  875. }
  876. if(!empty($koid)){
  877. $ors=selectQueryGetOne('select * from '.$this->tevt.' where KOID="'.$koid.'" LIMIT 1');
  878. if(!empty($ors['KOIDS'])) $ar['oid']=$ors['KOIDS'];
  879. else $ar['oid']=$koid;
  880. if($ors['allday']!=1){
  881. $ar['options']['begin']['tz']='GMT';
  882. $ar['options']['end']['tz']='GMT';
  883. }
  884. }else{
  885. $ar['options']['begin']['value']=$this->date.' '.$hour;
  886. $ar['options']['end']['value']=date('Y-m-d H:i:s',strtotime($this->date.' '.$hour.' +1 hour'));
  887. }
  888. $ar['tplentry']=TZR_RETURN_DATA;
  889. $this->xsetevt->desc['end_rep']->compulsory=true;
  890. $ev=$this->xsetevt->$function($ar);
  891. $ev['secure']=$secure;
  892. // Formate les donnees dans le cas d'une edition
  893. if(!empty($koid)) {
  894. if(!empty($ev['oexcept']->raw)) {
  895. $datedef=new XDateDef();
  896. $tab_except=explode(';',$ev['oexcept']->raw);
  897. foreach($tab_except as $tmp) $this->bloc['except'][$tmp]=$datedef->dateFormat($tmp);
  898. }
  899. $rs=selectQuery('SELECT KOIDD from '.$this->tlinks.' where KOIDE="'.$koid.'" and KOIDD!="'.$this->diary['KOID'].'"');
  900. while($rs && ($attendee=$rs->fetch())) $all_attendees[$attendee['KOIDD']]='';
  901. }
  902. // Liste des differents mode de repetition et champ date except
  903. $this->bloc['repetition']=array('NO'=>XLabels::getSysLabel('xmodcalendar','repetition','text'),
  904. 'DAILY'=>XLabels::getSysLabel('xmodcalendar','daily','text'),
  905. 'WEEKLY'=>XLabels::getSysLabel('xmodcalendar','weekly','text'),
  906. 'MONTHLY'=>XLabels::getSysLabel('xmodcalendar','monthly','text'),
  907. 'YEARLY'=>XLabels::getSysLabel('xmodcalendar','annual','text'));
  908. $xdatedef=clone($this->xsetevt->desc['end_rep']);
  909. $xdatedef->compulsory=false;
  910. $ev['oexcepttmp']=$xdatedef->edit($v='',$opt=array('fieldname'=>'excepttmp'));
  911. // Prepare la liste des invites possible (par defaut, liste des agendas non consolides)
  912. if($getintattendees){
  913. if(!defined('TZR_ALTERNATIVE_SENDTO_DIRECTORY') && !defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')){
  914. if($this->object_sec){
  915. if($function=='display') $cplt=' AND KOID IN ('.$this->getAuthorizedDiaries('ro','sql').')';
  916. else $cplt=' AND KOID IN ('.$this->getAuthorizedDiaries('rwv','sql').')';
  917. }else{
  918. $cplt='';
  919. }
  920. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tagenda);
  921. $vals=implode('||',array_keys($all_attendees));
  922. $opts=array('filter'=>'(cons IS NULL OR cons!=1) and KOID!="'.$this->diary['KOID'].'"'.$cplt);
  923. if($function=='display') $ev['oattendees']=&$xset->desc['agcons']->display($vals,$opts);
  924. else $ev['oattendees']=&$xset->desc['agcons']->edit($vals,$opts);
  925. }else{
  926. if(defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')) $altmoid=TZR_ALTERNATIVE_CALINTERNE_DIRECTORY;
  927. else $altmoid=TZR_ALTERNATIVE_SENDTO_DIRECTORY;
  928. $mod=XModule::objectFactory($altmoid);
  929. $list=&$mod->browse(array('tplentry'=>TZR_RETURN_DATA,'pagesize'=>999,'_options'=>array('local'=>true),'tlink'=>true));
  930. foreach($list['lines_oid'] as $i=>$oid){
  931. if(isset($all_attendees[$oid])) {
  932. $attendees[$oid]=$list['lines_tlink'][$i];
  933. } else {
  934. $users_unselected[$oid]=$list['lines_tlink'][$i];
  935. }
  936. }
  937. $this->bloc['attendees']=$attendees;
  938. $this->bloc['users_unselected']=$users_unselected;
  939. }
  940. $ev['oattendees']->sys=false;
  941. }else{
  942. $ev['oattendees']->sys=true;
  943. }
  944. if(!empty($ev['oattext'])){
  945. list($acl_user, $acl_grp)=XUser::getUsersAndGroups();
  946. XShell::toScreen1('users',$acl_user);
  947. XShell::toScreen1('grps',$acl_grp);
  948. }
  949. XShell::toScreen1('ev',$ev);
  950. return XShell::toScreen1('br',$this->bloc);
  951. }
  952. /// Sauvegarde un evenement
  953. public function saveEvt($ar=NULL) {
  954. $p=new XParam($ar,array());
  955. $koid=$p->get('koid');
  956. $text=$p->get('text');
  957. $cat=$p->get('cat');
  958. $place=$p->get('place');
  959. $descr=$p->get('descr');
  960. $visib=$p->get('visib');
  961. if(empty($visib)) $visib='PU';
  962. $repet=$p->get('repetition');
  963. $recalltime=$p->get('recalltime');
  964. $recalltype=$p->get('recalltype');
  965. $allday=$p->get('allday');
  966. $allday_HID=$p->get('allday_HID');
  967. $attext=$p->get('attext');
  968. $excepttab=$p->get('except');
  969. $xset_link=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tlinks);
  970. $allday=$this->xsetevt->desc['allday']->post_edit($allday,array('allday_HID'=>$allday_HID));
  971. $allday=$allday->raw;
  972. $datedef=new XDateDef();
  973. $ar1=array();
  974. $except=$except_mail=null;
  975. $list_mail_text='';
  976. $attselected=$p->get('selected');
  977. // Recupere l'agenda de l'evenement (si modifiation sur un agenda consolide, recupere l'agenda de l'evenement, sinon agenda courant)
  978. if($this->group_of_diary && !empty($koid)) {
  979. $rs=selectQuery('SELECT KOIDD FROM '.$this->tevt.' where KOID="'.$koid.'"');
  980. $tmp=$rs->fetch();
  981. $diary=$tmp['KOIDD'];
  982. } else {
  983. $diary=$this->diary['KOID'];
  984. }
  985. // Formatage des dates/heures
  986. $foo=$p->get('begin');
  987. if(!empty($foo) && is_array($foo)){
  988. $begindate=$foo['date'];
  989. $beginhour=$foo['hour'];
  990. }else{
  991. $begindate=$p->get('begindate');
  992. $beginhour=$p->get('beginhour');
  993. }
  994. $foo=$p->get('end');
  995. if(!empty($foo) && is_array($foo)){
  996. $enddate=$foo['date'];
  997. $endhour=$foo['hour'];
  998. }else{
  999. $enddate=$p->get('enddate');
  1000. $endhour=$p->get('endhour');
  1001. }
  1002. if($allday=='1') {
  1003. $beginhour='00:00:00';
  1004. $endhour='23:59:00';
  1005. } else {
  1006. $beginhour=$beginhour.':00';
  1007. $endhour=$endhour.':00';
  1008. }
  1009. $begin=$this->xsetevt->desc['begin']->post_edit(array('date'=>$begindate,'hour'=>$beginhour));
  1010. $end=$this->xsetevt->desc['end']->post_edit(array('date'=>$enddate,'hour'=>$endhour));
  1011. if($begin->raw>$end->raw) return array();
  1012. $dbegin=$this->xsetevt->desc['begin']->display($begin->raw);
  1013. $dend=$this->xsetevt->desc['end']->display($end->raw);
  1014. $date_begin_tsp=strtotime($begin->raw);
  1015. $date_end_tsp=strtotime($end->raw);
  1016. // Preparation de la repetition
  1017. if($repet=='NO') {
  1018. $until=null;
  1019. $until_tsp=0;
  1020. } else {
  1021. if($repet=='DAILY') $add_repetition='DAY';
  1022. elseif($repet=='WEEKLY') $add_repetition='WEEK';
  1023. elseif($repet=='MONTHLY') $add_repetition='MONTH';
  1024. else $add_repetition='YEAR';
  1025. $tmp=$datedef->post_edit($p->get('end_rep'));
  1026. $until=$tmp->raw;
  1027. $until_tsp=strtotime($until.' 23:59:00');
  1028. // Preparation des exceptions
  1029. if(!empty($excepttab)) {
  1030. foreach($excepttab as $tmp) {
  1031. $tmp2=$datedef->post_edit($tmp);
  1032. $except.=$tmp2->raw.';';
  1033. $except_mail.=$tmp.';';
  1034. }
  1035. $except=substr($except,0,(strlen($except)-1));
  1036. $except_mail=substr($except_mail,0,(strlen($except_mail)-1));
  1037. }
  1038. }
  1039. // Preparation du tableau de donnees
  1040. $ar1=$ar;
  1041. $ar1['repet']=$repet;
  1042. $ar1['end_rep']=$until;
  1043. $ar1['except']=$except;
  1044. $ar1['recall']=($recalltime*$recalltype);
  1045. $ar1['KOIDD']=$diary;
  1046. $ar1['UIDI']=null;
  1047. $ar1['tplentry']=TZR_RETURN_DATA;
  1048. $ar1['visib']=$visib;
  1049. $ar1['rrule']='';
  1050. // Si on est dans une modification, on efface les evenements lies a la source mais on garde l'evenement d'origine pour le modifier
  1051. if(!empty($koid)) {
  1052. $this->delEvt(array('koid'=>$koid,'noalert'=>true,'nodelsource'=>true));
  1053. $ar1['oid']=$koid;
  1054. $function='procEdit';
  1055. }else{
  1056. $function='procInput';
  1057. }
  1058. // Tant que l'on est dans l'intervale de repetition, on insere des entrees
  1059. $repet=false;
  1060. $koids=NULL;
  1061. do {
  1062. $date_begin=date('Y-m-d',$date_begin_tsp);
  1063. // Si la date n'est pas dans les exceptions
  1064. if(strpos($except,$date_begin)===FALSE) {
  1065. $ar1['begin']=($allday!='1') ? gmdate('Y-m-d H:i:s',$date_begin_tsp) : date('Y-m-d H:i:s',$date_begin_tsp);
  1066. $ar1['end']=($allday!='1') ? gmdate('Y-m-d H:i:s',$date_end_tsp) : date('Y-m-d H:i:s',$date_end_tsp);
  1067. $ar1['KOIDS']=$koids;
  1068. $ret=$this->xsetevt->$function($ar1);
  1069. if($function=='procEdit') $ret['oid']=$koid;
  1070. $xset_link->procInput(array('KOIDE'=>$ret['oid'],'KOIDD'=>$diary));
  1071. foreach($attselected as $att) {
  1072. // On ne copie pas l'événement dans l'agenda à l'origine de cet événement
  1073. if ($att == $diary) continue;
  1074. $ar2=array('KOIDD'=>$att,'KOIDE'=>$ret['oid']);
  1075. $xset_link->procInput($ar2);
  1076. }
  1077. if(!$repet) $koids=$ret['oid'];
  1078. }
  1079. $repet=true;
  1080. $function='procInput';
  1081. $date_begin_tsp=strtotime('+1 '.$add_repetition,$date_begin_tsp);
  1082. $date_end_tsp=strtotime('+1 '.$add_repetition,$date_end_tsp);
  1083. } while($date_begin_tsp<$until_tsp+1);
  1084. // Envoie des invitations
  1085. if(!$noalert){
  1086. $diaryowner=$this->getMailSender($ar);
  1087. $mail=new XMail();
  1088. $mail->_moid=$this->_moid;
  1089. $mail->From=$diaryowner['email'];
  1090. $mail->FromName='';
  1091. $mail->setTZRSubject(sprintf(XLabels::getSysLabel('xmodcalendar','attendeesmail_sub',null),$diaryowner['fullnam'],$text));
  1092. $mail->Body='<html><head><base href="'.$GLOBALS['HOME_ROOT_URL'].'"></head><body>';
  1093. $mail->Body.=XLabels::getSysLabel('xmodcalendar','attendeesmail_header',null).'<br>';
  1094. $mail->Body.=XLabels::getSysLabel('xmodcalendar','diary',null).' : '.$this->diary['name'].'<br>';
  1095. $mail->Body.=XLabels::getSysLabel('xmodcalendar','text',null).' : '.$text.'<br>';
  1096. $ldate=XLabels::getSysLabel('xmodcalendar','date',null);
  1097. $lthe=XLabels::getSysLabel('xmodcalendar','the',null);
  1098. $lat=XLabels::getSysLabel('xmodcalendar','at1',null);
  1099. $lto=XLabels::getSysLabel('xmodcalendar','to1',null);
  1100. if($allday=='1'){
  1101. if($dbegin->date->raw==$dend->date->raw) $mail->Body.=$ldate.' : '.$lthe.' '.$dbegin->date->html.'<br>';
  1102. else $mail->Body.=$ldate.' : '.$lat.' '.$dbegin->date->html.' '.$lto.' '.$dend->date->html.'<br>';
  1103. }else{
  1104. $mail->Body.=$ldate.' : '.$lat.' '.$dbegin->html.' '.$lto.' '.$dend->html.'<br>';
  1105. }
  1106. $mail->Body.=XLabels::getSysLabel('xmodcalendar','place',null).' : '.$place.'<br>';
  1107. $mail->Body.=XLabels::getSysLabel('xmodcalendar','description',null).' : '.$descr.'<br>';
  1108. if($until){
  1109. $mail->Body.=XLabels::getSysLabel('xmodcalendar','repetition',null).' : '.
  1110. XLabels::getSysLabel('xmodcalendar',$p->get('repetition'),null).' '.
  1111. XLabels::getSysLabel('xmodcalendar','until',null).' '.$p->get('until').' '.
  1112. XLabels::getSysLabel('xmodcalendar','except',null).' '.$except_mail.'<br><br>';
  1113. }
  1114. // Recupere la liste d'envoi
  1115. $list=$this->getSendList($ar);
  1116. $mailatt='';
  1117. foreach($list as $email){
  1118. if(!empty($email['fullnam']) && $email['fullnam']!="NOTATT") $mailatt.=$email['fullnam'].", ";
  1119. elseif($email['fullnam']!="NOTATT") $mailatt.=$email['email'].", ";
  1120. }
  1121. if(!empty($mailatt)){
  1122. $mailatt=substr($mailatt,0,-2);
  1123. $mail->Body.=XLabels::getSysLabel('xmodcalendar','attendees',null)." : ".$mailatt.'<br>';
  1124. }
  1125. // Ajout de champs supplementaires au mail
  1126. if(defined('XMODCALENDAR_MAILFIELDS')){
  1127. $addfields=explode(',',XMODCALENDAR_MAILFIELDS);
  1128. if(!empty($addfields)){
  1129. $ev=$this->xsetevt->display(array('oid'=>$koids,'tplentry'=>TZR_RETURN_DATA));
  1130. foreach($addfields as $f){
  1131. $mail->Body.=$ev['o'.$f]->fielddef->label.' : '.$ev[$f].'<br>';
  1132. }
  1133. }
  1134. }
  1135. $mail->Body.='<br>'.XLabels::getSysLabel('xmodcalendar','attendeesmail_msg',null).'<br>';
  1136. $mail->Body.='</body></html>';
  1137. foreach($list as $email){
  1138. if(!empty($email['email'])) $mail->AddAddress($email['email']);
  1139. }
  1140. // Ajout du fichier iCal UTF8
  1141. $file=TZR_TMP_DIR.uniqid('ical-').'.ics';
  1142. $fd=fopen($file,'a');
  1143. fwrite($fd,$this->saveExport(array('expoid'=>$koids,'intcall'=>true)));
  1144. fclose($fd);
  1145. $mail->AddAttachment($file);
  1146. // Ajout du fichier iCal latin1 pour outlook
  1147. $file2=TZR_TMP_DIR.uniqid('outlook-').'.ics';
  1148. $fd=fopen($file2,'a');
  1149. fwrite($fd,$this->saveExport(array('expoid'=>$koids,'intcall'=>true,'charset'=>'latin1')));
  1150. fclose($fd);
  1151. $mail->AddAttachment($file2);
  1152. $mail->Send();
  1153. unlink($file);
  1154. unlink($file2);
  1155. }
  1156. $_REQUEST['_next']=str_replace('adddate',date('\d\a\y=j&\m\o\n\t\h=n&\y\e\a\r=Y',strtotime($begin->raw)),$_REQUEST['_next']);
  1157. return array('oid'=>$koids);
  1158. }
  1159. /// Renvoie la liste des emails pour les invitations
  1160. public function getSendList($ar=NULL){
  1161. $p=new XParam($ar,NULL);
  1162. $curuid=XUser::get_current_user_uid();
  1163. $maillist=array();
  1164. // Ajout du possesseur de l'agenda a la liste d'envoi
  1165. if(!empty($this->diary['mail']) && $this->diary['mail']==1){
  1166. $rs=selectQuery('SELECT email,"NOTATT" as fullnam FROM USERS WHERE KOID="'.$this->diary['OWN'].'"');
  1167. $diaryowner=$rs->fetch();
  1168. $maillist[$diaryowner['email']]=$diaryowner;
  1169. }
  1170. // Ajout du user loge a la liste d'envoi
  1171. if($this->sendToUser){
  1172. $rs=selectQuery('SELECT email,"NOTATT" as fullnam FROM USERS WHERE KOID="'.$curuid.'"');
  1173. while($rs && $email=$rs->fetch())
  1174. $maillist[$email['email']]=$email;
  1175. }
  1176. // Ajoute les mails externes a la liste d'envoi
  1177. $att_ext=$p->get('attext');
  1178. if($att_ext!='') {
  1179. $tab_attendees_ext=explode(';',str_replace("\n",';',str_replace("\r\n",';',$att_ext)));
  1180. foreach($tab_attendees_ext as $tmp){
  1181. if($tmp) $maillist[$tmp]=array('email'=>trim($tmp),'fullnam'=>trim($tmp));
  1182. }
  1183. }
  1184. // Ajoute les mails internes et l'utilisateur de l'agenda courant a la liste d'envoi
  1185. $att_selected=$p->get('selected');
  1186. if(!defined('TZR_ALTERNATIVE_SENDTO_DIRECTORY') && !defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')){
  1187. if(!empty($att_selected)) {
  1188. $attendees_mysql=array();
  1189. foreach($att_selected as $att) $attendees_mysql[]=$this->tagenda.'.KOID="'.$att.'"';
  1190. $attendees_mysql='(USERS.KOID='.$this->tagenda.'.OWN AND ('.implode(' OR ',$attendees_mysql).'))';
  1191. $rs=&selectQuery('SELECT DISTINCT USERS.email,CONCAT(USERS.fullnam," (",'.$this->tagenda.'.name,")") as fullnam '.
  1192. 'from USERS,'.$this->tagenda.' where '.$attendees_mysql);
  1193. while($rs && $email=$rs->fetch()) $maillist[$email['email']]=$email;
  1194. }
  1195. }else{
  1196. if(defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')) $altmoid=TZR_ALTERNATIVE_CALINTERNE_DIRECTORY;
  1197. else $altmoid=TZR_ALTERNATIVE_SENDTO_DIRECTORY;
  1198. if(!empty($att_selected)) {
  1199. $mod=XModule::objectFactory($altmoid);
  1200. foreach($att_selected as $att) {
  1201. if(Kernel::getTable($att)==$mod->table){
  1202. $r1=$mod->display(array('oid'=>$att,'tplentry'=>TZR_RETURN_DATA));
  1203. $email=$mod->xset->emailsFromDisplay($r1);
  1204. $maillist[$email[0]]=array('email'=>$email[0],'fullnam'=>$r1['tlink']);
  1205. }
  1206. }
  1207. }
  1208. }
  1209. return $maillist;
  1210. }
  1211. /// Fixe l'expediteur du mail : manuellement (tableau avec email et fullnam) ou automatique a partir du user loge ou du possesseur
  1212. private function getMailSender($ar=NULL){
  1213. $p=new XParam($ar,array('mailSender'=>'user'));
  1214. $mailSender=$p->get('mailSender');
  1215. if(is_array($mailSender))
  1216. $diaryowner=&$mailSender;
  1217. else{
  1218. if($mailSender=='user') $rs=selectQuery('SELECT * FROM USERS WHERE KOID="'.XUser::get_current_user_uid().'"');
  1219. elseif($mailSender=='owner') $rs=selectQuery('SELECT * FROM USERS WHERE KOID="'.$this->diary['OWN'].'"');
  1220. $diaryowner=$rs->fetch();
  1221. }
  1222. return $diaryowner;
  1223. }
  1224. /// Sauvegarde d'un evenement via le formulaire rapide
  1225. function saveFastEvt($ar=NULL) {
  1226. $p=new XParam($ar,array());
  1227. $visib=$p->get('visib');
  1228. if(empty($visib)) $visib='PU';
  1229. $datedef=new XDateDef();
  1230. $rs=selectQuery('select * from '.$this->tcatevt.' where KOID="'.$p->get('cat').'"');
  1231. $cat=$rs->fetch();
  1232. $date=$datedef->post_edit($p->get('date'));
  1233. if($cat['allday']==1) {
  1234. $begindate=$date->raw;
  1235. $beginhour='00:00';
  1236. $enddate=$date->raw;
  1237. $endhour='23:59';
  1238. } else {
  1239. $begin_tsp=strtotime($date->raw.' '.$p->get('begin').':00');
  1240. $begindate=date('Y-m-d',$begin_tsp);
  1241. $beginhour=date('H:i',$begin_tsp);
  1242. $during=strtotime('+'.$cat['time'].' minute',$begin_tsp);
  1243. $enddate=date('Y-m-d',$during);
  1244. $endhour=date('H:i',$during);
  1245. }
  1246. $ar1=array('begindate'=>$begindate,
  1247. 'beginhour'=>$beginhour,
  1248. 'enddate'=>$enddate,
  1249. 'endhour'=>$endhour,
  1250. 'visib'=>$visib,
  1251. 'repet'=>'NO',
  1252. 'allday'=>$cat['allday'],
  1253. 'recalltime'=>$cat['recall'],
  1254. 'recalltype'=>'1',
  1255. 'tplentry'=>TZR_RETURN_DATA);
  1256. $this->saveEvt($ar1);
  1257. }
  1258. /// Suppression d'un evenement
  1259. function delEvt($ar) {
  1260. $p=new XParam($ar,array('noalert'=>false,'nodelsource'=>false));
  1261. $oid=$p->get('koid');
  1262. $noalert=$p->get('noalert');
  1263. $nodelsource=$p->get('nodelsource');
  1264. $curuid=XUser::get_current_user_uid();
  1265. // Verifie si on supprime depuis l'agenda propriétaire ou non
  1266. $rs=selectQuery('select KOID from '.$this->tevt.' where KOID="'.$oid.'" and KOIDD="'.$this->diary['KOID'].'"');
  1267. if($rs->rowCount()==1) $fromown=true;
  1268. else $fromown=false;
  1269. // Si on ne specifie pas qu'on ne veut pas d'alert
  1270. if(!$noalert){
  1271. $diaryowner=$this->getMailSender($ar);
  1272. $rs=selectQuery('select * from '.$this->tevt.' where KOID="'.$oid.'"');
  1273. $orsevt=$rs->fetch();
  1274. $mail=new XMail();
  1275. $mail->_moid=$this->_moid;
  1276. $mail->FromName='';
  1277. $mail->From=$diaryowner['email'];
  1278. $mail->setTZRSubject(sprintf(XLabels::getSysLabel('xmodcalendar','delmail_sub','text'),$diaryowner['fullnam'],$orsevt['text']));
  1279. if($orsevt['allday']==1){
  1280. if(substr($orsevt['begin'],0,10)==substr($orsevt['end'],0,10)){
  1281. $datetext=strtolower(XLabels::getSysLabel('xmodcalendar','the','text').' '.date('d/m/Y',strtotime($orsevt['begin'])));
  1282. }else{
  1283. $datetext=XLabels::getSysLabel('xmodcalendar','at1','text').' '.date('d/m/Y',strtotime($orsevt['begin'])).' '.
  1284. XLabels::getSysLabel('xmodcalendar','to1','text').' '.date('d/m/Y',strtotime($orsevt['end']));
  1285. }
  1286. }else{
  1287. $datetext=XLabels::getSysLabel('xmodcalendar','at1','text').' '.date('d/m/Y H\hi',strtotime($orsevt['begin'].' GMT')).' '.
  1288. XLabels::getSysLabel('xmodcalendar','to1','text').' '.date('d/m/Y H\hi',strtotime($orsevt['end'].' GMT'));
  1289. }
  1290. $mail->Body=sprintf(XLabels::getSysLabel('xmodcalendar','delmail_msg','text'),$orsevt['text'],$datetext);
  1291. if($fromown){
  1292. $rs=selectQuery('SELECT * FROM '.$this->tlinks.' WHERE KOIDE="'.$oid.'"');
  1293. while($rs && ($ors=$rs->fetch())) $ar2['selected'][]=$ors['KOIDD'];
  1294. $ar2['attext']=$orsevt['attext'];
  1295. }else{
  1296. $ar2['selected'][]=$this->diary['KOID'];
  1297. }
  1298. $list=$this->getSendList($ar2);
  1299. foreach($list as $email){
  1300. if(!empty($email['email'])) $mail->AddAddress($email['email']);
  1301. }
  1302. $mail->Send();
  1303. }
  1304. // Recuperation de l'objet source si necessaire
  1305. $rs=selectQuery('select KOIDS from '.$this->tevt.' where KOID="'.$oid.'"');
  1306. $tmp=$rs->fetch();
  1307. if(!empty($tmp['KOIDS'])) $oid=$tmp['KOIDS'];
  1308. // Suppression de tous les object non source et de leur lien
  1309. $rs=selectQuery('select * from '.$this->tevt.' where KOIDS="'.$oid.'"');
  1310. while($rs && ($tmp=$rs->fetch())) {
  1311. if($fromown){
  1312. $this->xsetevt->del(array('oid'=>$tmp['KOID']));
  1313. updateQuery('DELETE FROM '.$this->tlinks.' where KOIDE="'.$tmp['KOID'].'"');
  1314. }else{
  1315. updateQuery('DELETE FROM '.$this->tlinks.' where KOIDE="'.$tmp['KOID'].'" and KOIDD="'.$this->diary['KOID'].'"');
  1316. }
  1317. }
  1318. // Suppression du lien de l'objet source
  1319. if($fromown) updateQuery('DELETE FROM '.$this->tlinks.' where KOIDE="'.$oid.'"');
  1320. else updateQuery('DELETE FROM '.$this->tlinks.' where KOIDE="'.$oid.'" and KOIDD="'.$this->diary['KOID'].'"');
  1321. // Suppression de l'evenement source si pas de demande contraire et depuis agenda proprietaire
  1322. if(!$nodelsource && $fromown) $this->xsetevt->del(array('oid'=>$oid));
  1323. return true;
  1324. }
  1325. /// Prepare l'ajout/modifiaction d'un agenda
  1326. function editDiary($ar=NULL) {
  1327. $uid=XUser::get_current_user_uid();
  1328. $p=new XParam($ar,array());
  1329. $ar['tplentry']=TZR_RETURN_DATA;
  1330. $ar['selectedfields']=array('name','begin','end');
  1331. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tagenda);
  1332. if($uid==$this->diary['OWN']) $ins=$xset->edit($ar);
  1333. else $ins=$xset->display($ar);
  1334. // Recupere l'alias et le mot de passe pour le lien de synchro
  1335. $ors=selectQueryGetOne('select alias,MD5(passwd) as passwd from USERS where KOID="'.XUser::get_current_user_uid().'" LIMIT 1');
  1336. $ins['user']=$ors;
  1337. XShell::toScreen1('ins',$ins);
  1338. XShell::toScreen1('br',$this->bloc);
  1339. }
  1340. /// Sauvegarde un agenda
  1341. function saveDiary($ar=NULL) {
  1342. $p=new XParam($ar,array());
  1343. $oid=$p->get('oid');
  1344. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tagenda);
  1345. $xset->procEdit($ar);
  1346. }
  1347. /// Prepare l'export de l'agenda
  1348. function exportEvt($ar=NULL) {
  1349. $p=new XParam($ar,array());
  1350. $display=$p->get('display');
  1351. if($display=='displayDay') {
  1352. $filter_begin=$filter_end=$this->date;
  1353. } elseif($display=='displayWeek') {
  1354. $first_day_week=$this->calculateWeekDetails($p);
  1355. $filter_begin=date('Y-m-d',$first_day_week);
  1356. $filter_end=date('Y-m-d',strtotime('+6 day',$first_day_week));
  1357. } elseif($display=='displayMonth') {
  1358. $filter_begin=date('Y-m-01',strtotime($this->date));
  1359. $filter_end=date('Y-m-t',strtotime($this->date));
  1360. } else {
  1361. $filter_begin=$this->year.'-01-01';
  1362. $filter_end=$this->year.'-12-31';
  1363. }
  1364. $xdatedef=new XDateDef();
  1365. $xdatedef->compulsory=true;
  1366. $this->bloc['begindate']=$xdatedef->edit($v=$filter_begin,$opt=array('fieldname'=>'begindate'));
  1367. $this->bloc['enddate']=$xdatedef->edit($v=$filter_end,$opt=array('fieldname'=>'enddate'));
  1368. return XShell::toScreen1('br',$this->bloc);
  1369. }
  1370. /// Exporte des evenements
  1371. function saveExport($ar=NULL) {
  1372. $p=new XParam($ar,array());
  1373. $uid=XUser::get_current_user_uid();
  1374. $export=array();
  1375. $expoid=$p->get('expoid');
  1376. $intcall=$p->get('intcall');
  1377. $charset=$p->get('charset');
  1378. $period=$p->get('period');
  1379. $begindate=$p->get('begindate');
  1380. $enddate=$p->get('enddate');
  1381. if(empty($charset)) $charset='UTF-8';
  1382. if($expoid){
  1383. $rs=selectQuery('select '.$this->tevt.'.* from '.$this->tevt.','.$this->tlinks.' '.
  1384. 'where '.$this->tevt.'.KOID='.$this->tlinks.'.KOIDE and '.$this->tlinks.'.KOIDD="'.$this->diary['KOID'].'" and '.
  1385. $this->tevt.'.KOID="'.$expoid.'"');
  1386. }elseif($period=='all') {
  1387. $rs=selectQuery('select '.$this->tevt.'.* from '.$this->tevt.','.$this->tlinks.' '.
  1388. 'where '.$this->tevt.'.KOID='.$this->tlinks.'.KOIDE and '.$this->tlinks.'.KOIDD="'.$this->diary['KOID'].'" and '.
  1389. '('.$this->tevt.'.KOIDS IS NULL or '.$this->tevt.'.KOIDS="")');
  1390. } else {
  1391. $tab_date_1=explode('/',$begindate);
  1392. $tab_date_2=explode('/',$enddate);
  1393. $date_begin_tsp=strtotime($tab_date_1[2].$tab_date_1[1].$tab_date_1[0].' 00:00:00');
  1394. $date_end_tsp=strtotime($tab_date_2[2].$tab_date_2[1].$tab_date_2[0].' 23:59:00');
  1395. $rs=selectQuery('select '.$this->tevt.'.* from '.$this->tevt.','.$this->tlinks.' '.
  1396. 'where '.$this->tevt.'.KOID='.$this->tlinks.'.KOIDE and '.$this->tlinks.'.KOIDD="'.$this->diary['KOID'].'" and '.
  1397. 'UNIX_TIMESTAMP('.$this->tevt.'.begin) BETWEEN '.$date_begin_tsp.' AND '.$date_end_tsp);
  1398. }
  1399. $content="BEGIN:VCALENDAR\r\n";
  1400. if($charset=="UTF-8") $content.="VERSION:2.0\r\n"; // Declaration normale de la version d'iCal
  1401. else $content.="VERSION:2\r\n"; // Si pas en utf8, c'est qu'on exporte pour outlook et outlook n'aime pas le .0 alors en le met pas
  1402. $content.="PRODID:-//Agenda Seolan\r\n";
  1403. while($rs && $event=$rs->fetch()) {
  1404. if(!in_array($event['KOID'],$export) && !in_array($event['KOIDS'],$export)) {
  1405. if(!empty($event['KOIDS'])) {
  1406. $rs2=selectQuery('select * from '.$this->tevt.' where '.$this->tevt.'.KOID="'.$event['KOIDS'].'"');
  1407. $event=$rs2->fetch();
  1408. }
  1409. // Visibilite
  1410. if($event['visib']=='PU') $visibility='PUBLIC';
  1411. elseif($event['visib']=='PR'){
  1412. if(!in_array($this->diary['KOID'],$this->getAuthorizedDiaries('rw'))) continue;
  1413. $visibility='PRIVATE';
  1414. }else{
  1415. $visibility='CONFIDENTIAL';
  1416. if(!in_array($this->diary['KOID'],$this->getAuthorizedDiaries('rw')))
  1417. $event['text']=XLabels::getSysLabel('xmodcalendar','occupy','text');
  1418. }
  1419. // Heure
  1420. $this->convertEventTime($event);
  1421. if($event['allday']==1) {
  1422. $begin=';VALUE=DATE:'.date('Ymd',strtotime($event['begin']));
  1423. $end=';VALUE=DATE:'.date('Ymd',strtotime($event['end'].' +1 day'));
  1424. } else {
  1425. $begin=':'.gmdate('Ymd\THis\Z',strtotime($event['begin']));
  1426. $end=':'.gmdate('Ymd\THis\Z',strtotime($event['end']));
  1427. $beginhour=gmdate('\THis\Z',strtotime($event['begin']));
  1428. }
  1429. // Debut evenement
  1430. $content.="BEGIN:VEVENT\r\n";
  1431. $content.="UID:".$event['KOID']."\r\n";
  1432. $content.="LAST-MODIFIED:".gmdate('Ymd\THis\Z',strtotime($event['UPD']))."\r\n";
  1433. $content.="DTSTART$begin\r\n";
  1434. $content.="DTEND$end\r\n";
  1435. // Repetition
  1436. if(!empty($event['rrule'])){
  1437. $content.='RRULE:'.$event['rrule']."\r\n";
  1438. }elseif(!empty($event['repet']) && $event['repet']!='NO'){
  1439. $content.="RRULE:FREQ=".$event['repet'].";UNTIL=".str_replace('-','',$event['end_rep'])."\r\n";
  1440. }
  1441. if(!empty($event['except'])) {
  1442. $except=explode(';',$event['except']);
  1443. if($event['allday']==1) {
  1444. foreach($except as $tmp) {
  1445. $content.="EXDATE;VALUE=DATE:".str_replace('-','',$tmp)."\r\n";
  1446. }
  1447. }else{
  1448. foreach($except as $tmp) {
  1449. $content.="EXDATE:".str_replace('-','',$tmp)."$beginhour\r\n";
  1450. }
  1451. }
  1452. }
  1453. $content.="CLASS:$visibility\r\n";
  1454. $content.="SUMMARY:".$this->escapeICSText($event['text'])."\r\n";
  1455. $content.="CATEGORIES:".$this->escapeICSText(@$this->categories[$event['cat']]['name'])."\r\n";
  1456. if($visibility=='PUBLIC' || in_array($this->diary['KOID'],$this->getAuthorizedDiaries('rw'))){
  1457. if(!empty($event['place'])) $content.="LOCATION:".$this->escapeICSText($event['place'])."\r\n";
  1458. if(!empty($event['descr'])) $content.="DESCRIPTION:".$this->escapeICSText($event['descr'])."\r\n";
  1459. // Invites
  1460. if(!empty($event['attext'])) {
  1461. $attendees_ext=explode("\r\n",$event['attext']);
  1462. foreach($attendees_ext as $att) {
  1463. $content.="ATTENDEE:MAILTO:".$att."\r\n";
  1464. }
  1465. }
  1466. $rs2=selectQuery('select USERS.fullnam, USERS.email, '.$this->tagenda.'.name from '.$this->tlinks.','.$this->tagenda.',USERS '.
  1467. 'where '.$this->tlinks.'.KOIDD='.$this->tagenda.'.KOID and '.$this->tagenda.'.OWN=USERS.KOID '.
  1468. 'and '.$this->tlinks.'.KOIDE="'.$event['KOID'].'" and '.$this->tlinks.'.KOIDD!="'.$event['KOIDD'].'"');
  1469. while($rs2 && $att=$rs2->fetch()) {
  1470. $content.='ATTENDEE;CN=[CS] '.trim(str_replace(':','-',$att['fullnam'])).
  1471. ' ('.trim(str_replace(':','-',$att['name'])).'):MAILTO:'.$att['email']."\r\n";
  1472. }
  1473. // Rappel
  1474. if(!empty($event['recall'])){
  1475. $content.="BEGIN:VALARM\r\n";
  1476. $content.="TRIGGER;VALUE=DURATION:-PT".$event['recall']."M\r\n";
  1477. $content.="END:VALARM\r\n";
  1478. }
  1479. }
  1480. $content.="END:VEVENT\r\n";
  1481. $export[]=$event['KOID'];
  1482. }
  1483. }
  1484. $content.="END:VCALENDAR\r\n";
  1485. convert_charset($content,'UTF-8',$charset);
  1486. if($intcall)
  1487. return $content;
  1488. else{
  1489. header('Content-Type: text/calendar; charset='.$charset);
  1490. header('Content-Transfer-Encoding:'.$charset);
  1491. header('Content-disposition: attachment; filename=export_seolan.ics');
  1492. header('Content-Length: '.strlen($content));
  1493. header('Pragma: private');
  1494. header('Cache-Control: no-cache, must-revalidate');
  1495. header('Expires: 0');
  1496. echo $content;
  1497. }
  1498. }
  1499. function escapeICSText($text){
  1500. $text=str_replace(array('&','\\','"',';',',',"\n","\r","\t"),array('et','\\\\','\"','\;','\,','\n','\r','\t'),$text);
  1501. return $text;
  1502. }
  1503. function unescapeICSText($text){
  1504. $text=str_replace(array('&','\\\\','\"','\;','\,','\n','\r','\t'),array('et','\\','"',';',',',"\n","\r","\t"),$text);
  1505. return $text;
  1506. }
  1507. /// Importe un ICS dans l'agenda
  1508. function importEvt($ar=NULL) {
  1509. $p=new XParam($ar,array());
  1510. $error=false;
  1511. if(isset($_FILES['filetoimp'])) {
  1512. $filename=$_FILES['filetoimp']['tmp_name'];
  1513. //copy($filename,TZR_WWW_DIR.date('Ymd_His').'.ics');
  1514. require_once('add-ons/ical/functions/ical_parser.php');
  1515. if(!$this->synchro) {
  1516. if(!$error) return 0;
  1517. }
  1518. }
  1519. $this->bloc['error']=$error;
  1520. return XShell::toScreen1('br',$this->bloc);
  1521. }
  1522. /// Positionne l'agenda par defaut de l'utilisateur sur l'agenda courant
  1523. function setDefault($ar=NULL){
  1524. global $XSHELL;
  1525. $p=new XParam($ar,NULL);
  1526. $uid=$p->get('uid','local');
  1527. $display=$p->get('display');
  1528. $_nonext=$p->get('_nonext');
  1529. if(empty($uid)) $uid=XUser::get_current_user_uid();
  1530. $oid=$this->diary['KOID'];
  1531. updateQuery('update '.$this->tagenda.' set def=2 where OWN="'.$uid.'" AND KOID!="'.$oid.'"');
  1532. if($uid==$this->diary['OWN']) updateQuery('update '.$this->tagenda.' set def=1 where KOID="'.$oid.'"');
  1533. $prefs=array('defaultcal'=>$oid);
  1534. // Définie aussi la vue par défaut si l'action est appelé depuis un affichage du calendrier
  1535. if(strpos($display,'display')===0) $prefs['defview']=$display;
  1536. $this->savePrefs($uid,$prefs);
  1537. if(empty($_nonext)){
  1538. $back=$XSHELL->get_back_url();
  1539. XShell::setNext($back);
  1540. }
  1541. return;
  1542. }
  1543. /// Ajout une entrée dans les consolidations de l'agenda courant
  1544. function addConsolidation($ar=NULL){
  1545. $p=new XParam($ar,NULL);
  1546. $save=$p->get('save');
  1547. $color=$p->get('color');
  1548. $target=$p->get('target');
  1549. $text=$p->get('text');
  1550. $begin=$p->get('begin');
  1551. $end=$p->get('end');
  1552. $descr=$p->get('descr');
  1553. $place=$p->get('place');
  1554. $params=array('color'=>$color,'text'=>$text,'begin'=>$begin,'end'=>$end,'descr'=>$descr,'place'=>$place);
  1555. if($save){
  1556. $cons=$this->prefs['consolidations'];
  1557. $cons['list'][$target]=$params;
  1558. $cons['active'][$this->diary['KOID']][$target]=1;
  1559. $this->setPref(array('prop'=>'consolidations','propv'=>$cons));
  1560. }else{
  1561. $sess=getSessionVar('xmodcalendar'.$this->_moid.':consolidations');
  1562. $sess['list'][$target]=$params;
  1563. $sess['active'][$this->diary['KOID']][$target]=1;
  1564. setSessionVar('xmodcalendar'.$this->_moid.':consolidations',$sess);
  1565. }
  1566. }
  1567. /// Actualise la partie consolidation
  1568. function updateConsolidation($ar=NULL){
  1569. $p=new XParam($ar,NULL);
  1570. $active=$p->get('active');
  1571. $activehid=$p->get('active_HID');
  1572. $del=$p->get('del');
  1573. $sess=getSessionVar('xmodcalendar'.$this->_moid.':consolidations');
  1574. foreach($activehid as $oid=>$foo){
  1575. if(isset($this->prefs['consolidations']['list'][$oid])){
  1576. if(isset($active[$oid])) $this->prefs['consolidations']['active'][$this->diary['KOID']][$oid]=1;
  1577. else unset($this->prefs['consolidations']['active'][$this->diary['KOID']][$oid]);
  1578. }
  1579. if(isset($sess['list'][$oid])){
  1580. if(isset($active[$oid])) $sess['active'][$this->diary['KOID']][$oid]=1;
  1581. else unset($sess['active'][$this->diary['KOID']][$oid]);
  1582. }
  1583. }
  1584. foreach($del as $oid=>$v){
  1585. if(!$v) continue;
  1586. unset($this->prefs['consolidations']['list'][$oid],$sess['list'][$oid]);
  1587. foreach($this->prefs['consolidations']['active'] as $d=>&$foo) unset($foo[$oid]);
  1588. foreach($sess['active'] as $d=>&$foo) unset($foo[$oid]);
  1589. }
  1590. $this->setPref(array('prop'=>'consolidations','propv'=>$this->prefs['consolidations']));
  1591. setSessionVar('xmodcalendar'.$this->_moid.':consolidations',$sess);
  1592. }
  1593. /// Recupere la liste des parametres pour l'importation d'evenements a partir d'une table
  1594. function paramsConsolidation($ar=NULL) {
  1595. $p=new XParam($ar,NULL);
  1596. $tplentry=$p->get('tplentry');
  1597. XShell::toScreen1($tplentry,$this->bloc);
  1598. $moid=$p->get('cmoid');
  1599. if(is_numeric($moid)){
  1600. $mod=XModule::objectFactory($moid);
  1601. $mod->XCalParamsConsolidation($ar);
  1602. }
  1603. }
  1604. /// Prepare les donnees pour la partie basse de l'agenda (navigation rapide)
  1605. function createCalendar($p) {
  1606. $nb_day_prev_month=date('t', mktime(12,0,0,$this->month-1,1,$this->year));
  1607. $first_day=date('N',mktime(12,00,00,$this->month,1,$this->year));
  1608. $last_day=date('N',mktime(12,00,00,$this->month+1,0,$this->year));
  1609. $prev_month=date('n',mktime(12,00,00,$this->month-1,1,$this->year));
  1610. $next_month=date('n',mktime(12,00,00,$this->month+1,1,$this->year));
  1611. $prev_year=date('Y',mktime(12,00,00,$this->month-1,1,$this->year));
  1612. $next_year=date('Y',mktime(12,00,00,$this->month+1,1,$this->year));
  1613. $month_list_label_min=XLabels::getSysLabel('xmodcalendar','monthlistmin','text');
  1614. $month_list_label=XLabels::getSysLabel('xmodcalendar','monthlist','text');
  1615. $day_max_list=XLabels::getSysLabel('xmodcalendar','daymax','text');
  1616. $day_inter_list=XLabels::getSysLabel('xmodcalendar','dayinter','text');
  1617. $this->calculateFreeDay();
  1618. // Creation de la liste des semaines du mois selctionne pour le calendrier
  1619. $first_cal_week=intval(date('W',mktime(00,00,00,$this->month,1,$this->year)));
  1620. $last_cal_week=date('W',mktime(00,00,00,$this->month+1,0,$this->year));
  1621. if($first_cal_week>51) {
  1622. $week_cal_list[]=array('week'=>$first_cal_week,'year'=>($this->year-1));
  1623. $first_cal_week=1;
  1624. }
  1625. if($last_cal_week==1) {
  1626. $last_cal_week=52;
  1627. $tmp_week=$last_cal_week;
  1628. }
  1629. for($i=$first_cal_week;$i<=$last_cal_week;$i++) {
  1630. $week_cal_list[]=array('week'=>$i,'year'=>$this->year);
  1631. }
  1632. if(isset($tmp_week)) {
  1633. $week_cal_list[]=array('week'=>1,'year'=>($this->year+1));
  1634. }
  1635. // Creation du calendrier
  1636. for($i=1;$i<32;$i++) {
  1637. $table[$i]=null;
  1638. }
  1639. // Mois precedent
  1640. $events=$notes=$table;
  1641. $events_tmp=$notes_tmp=array();
  1642. $display_begin_gmt=gmdate('Y-m-20 H:i:s',strtotime($prev_year.'-'.$prev_month.'-20 00:00:00'));
  1643. $display_end_gmt=gmdate('Y-m-t H:i:s',strtotime($this->year.'-'.$this->month.'-00 23:59:00'));
  1644. $this->display_begin=date('Y-m-20 H:i:s',strtotime($prev_year.'-'.$prev_month.'-20 00:00:00'));
  1645. $this->display_end=date('Y-m-t H:i:s',strtotime($this->year.'-'.$this->month.'-00 23:59:00'));
  1646. $rs=$this->getAlls($display_begin_gmt,$display_end_gmt,$this->display_begin,$this->display_end);
  1647. while($rs && ($event=$rs->fetch())) {
  1648. $this->convertEventTime($event);
  1649. $start=strtotime($event['begin']);
  1650. $start_date = date('Y-m-d', $start);
  1651. $end_date = date('Y-m-d', strtotime($event['end']));
  1652. if($start_date<substr($this->display_begin,0,10)) {
  1653. $event['begin']=substr($this->display_begin,0,10).' 00:00:00';
  1654. }
  1655. if($end_date>substr($this->display_end,0,10)) {
  1656. $event['end']=substr($this->display_end,0,10).' 23:59:00';
  1657. }
  1658. if($event['allday']==1) {
  1659. $notes_tmp[]=$event;
  1660. } else {
  1661. $events_tmp[]=$event;
  1662. }
  1663. }
  1664. $this->cutNotes($notes_tmp);
  1665. $this->cutEvents($events_tmp,null,null);
  1666. foreach($notes_tmp as $note) {
  1667. $notes[date('j',strtotime($note['begin']))][]=$note;
  1668. }
  1669. foreach($events_tmp as $event) {
  1670. $events[date('j',strtotime($event['begin']))][]=$event;
  1671. }
  1672. for($i=$first_day-2;$i>-1;$i--) {
  1673. $this->cal_content[]=array('day'=>$nb_day_prev_month-$i,
  1674. 'month'=>$prev_month,
  1675. 'year'=>$prev_year,
  1676. 'day_cal_type'=>'out',
  1677. 'day_display_type'=>'out',
  1678. 'notes'=>$notes[$nb_day_prev_month-$i],
  1679. 'events'=>$events[$nb_day_prev_month-$i]);
  1680. }
  1681. // Mois actuel
  1682. $events=$notes=$table;
  1683. $events_tmp=$notes_tmp=array();
  1684. $display_begin_gmt=gmdate('Y-m-d H:i:s',strtotime($this->year.'-'.$this->month.'-01 00:00:00'));
  1685. $display_end_gmt=gmdate('Y-m-t H:i:s',strtotime($next_year.'-'.$next_month.'-00 23:59:00'));
  1686. $this->display_begin=date('Y-m-d H:i:s',strtotime($this->year.'-'.$this->month.'-01 00:00:00'));
  1687. $this->display_end=date('Y-m-t H:i:s',strtotime($next_year.'-'.$next_month.'-00 23:59:00'));
  1688. $rs=$this->getAlls($display_begin_gmt,$display_end_gmt,$this->display_begin,$this->display_end);
  1689. while($rs && ($event=$rs->fetch())) {
  1690. $this->convertEventTime($event);
  1691. $start=strtotime($event['begin']);
  1692. $start_date = date('Y-m-d', $start);
  1693. $end_date = date('Y-m-d', strtotime($event['end']));
  1694. if($start_date<substr($this->display_begin,0,10)) {
  1695. $event['begin']=substr($this->display_begin,0,10).' 00:00:00';
  1696. }
  1697. if($end_date>substr($this->display_end,0,10)) {
  1698. $event['end']=substr($this->display_end,0,10).' 23:59:00';
  1699. }
  1700. if($event['allday']==1) {
  1701. $notes_tmp[]=$event;
  1702. } else {
  1703. $events_tmp[]=$event;
  1704. }
  1705. }
  1706. $this->cutNotes($notes_tmp);
  1707. $this->cutEvents($events_tmp,null,null);
  1708. foreach($notes_tmp as $note) {
  1709. $notes[date('j',strtotime($note['begin']))][]=$note;
  1710. }
  1711. foreach($events_tmp as $event) {
  1712. $events[date('j',strtotime($event['begin']))][]=$event;
  1713. }
  1714. for($i=1;$i<date('t',mktime(12,00,00,$this->month,$this->day,$this->year))+1;$i++) {
  1715. $this->cal_content[]=array('day'=>$i,
  1716. 'month'=>$this->month,
  1717. 'year'=>$this->year,
  1718. 'day_cal_type'=>$this->dayType($i,$this->month),
  1719. 'day_display_type'=>'in',
  1720. 'notes'=>$notes[$i],
  1721. 'events'=>$events[$i]);
  1722. }
  1723. // Mois suivant
  1724. $events=$notes=$table;
  1725. $events_tmp=$notes_tmp=array();
  1726. $display_begin_gmt=gmdate('Y-m-d H:i:s',strtotime($next_year.'-'.$next_month.'-01 00:00:00'));
  1727. $display_end_gmt=gmdate('Y-m-d H:i:s',strtotime($next_year.'-'.$next_month.'-10 23:59:00'));
  1728. $this->display_begin=date('Y-m-d H:i:s',strtotime($next_year.'-'.$next_month.'-01 00:00:00'));
  1729. $this->display_end=date('Y-m-d H:i:s',strtotime($next_year.'-'.$next_month.'-10 23:59:00'));
  1730. $rs=$this->getAlls($display_begin_gmt,$display_end_gmt,$this->display_begin,$this->display_end);
  1731. while($rs && ($event=$rs->fetch())) {
  1732. $this->convertEventTime($event);
  1733. $start=strtotime($event['begin']);
  1734. $start_date = date('Y-m-d', $start);
  1735. $end_date = date('Y-m-d', strtotime($event['end']));
  1736. if($start_date<substr($this->display_begin,0,10)) {
  1737. $event['begin']=substr($this->display_begin,0,10).' 00:00:00';
  1738. }
  1739. if($end_date>substr($this->display_end,0,10)) {
  1740. $event['end']=substr($this->display_end,0,10).' 23:59:00';
  1741. }
  1742. if($event['allday']==1) {
  1743. $notes_tmp[]=$event;
  1744. } else {
  1745. $events_tmp[]=$event;
  1746. }
  1747. }
  1748. $this->cutNotes($notes_tmp);
  1749. $this->cutEvents($events_tmp,null,null);
  1750. foreach($notes_tmp as $note) {
  1751. $notes[date('j',strtotime($note['begin']))][]=$note;
  1752. }
  1753. foreach($events_tmp as $event) {
  1754. $events[date('j',strtotime($event['begin']))][]=$event;
  1755. }
  1756. for($i=1;$i<8-$last_day;$i++) {
  1757. $this->cal_content[]=array('day'=>$i,
  1758. 'month'=>$next_month,
  1759. 'year'=>$next_year,
  1760. 'day_cal_type'=>'out',
  1761. 'day_display_type'=>'out',
  1762. 'notes'=>$notes[$i],
  1763. 'events'=>$events[$i]);
  1764. }
  1765. // Creation de la liste des semaines de l'annee en cours
  1766. $first_week=date('W',mktime(00,00,00,1,1,$this->year));
  1767. $last_week=date('W',mktime(00,00,00,12,31,$this->year));
  1768. $first_monday=strtotime('Monday',mktime(00,00,00,12,29,$this->year-1));
  1769. if($last_week==1) {
  1770. $last_week=52;
  1771. }
  1772. if($first_week!=1) {
  1773. $week_begin_tsp=strtotime('-1 week',$first_monday);
  1774. $tmp_1=strptime(strftime('%d/%m/%Y',$week_begin_tsp),'%d/%m/%Y');
  1775. $tmp_2=strptime(strftime('%d/%m/%Y',strtotime('+6 day',$week_begin_tsp)),'%d/%m/%Y');
  1776. $week_list[$first_week.'-'.($this->year-1)]=$tmp_1['tm_mday'].' '.$month_list_label_min[$tmp_1['tm_mon']].' - '.$tmp_2['tm_mday'].
  1777. ' '.$month_list_label_min[$tmp_2['tm_mon']];
  1778. }
  1779. for($i=1;$i<=$last_week;$i++) {
  1780. $week_begin_tsp=strtotime('+'.($i-1).' week',$first_monday);
  1781. $tmp_1=strptime(strftime('%d/%m/%Y',$week_begin_tsp),'%d/%m/%Y');
  1782. $tmp_2=strptime(strftime('%d/%m/%Y',strtotime('+6 day',$week_begin_tsp)),'%d/%m/%Y');
  1783. $week_list[$i.'-'.$this->year]=$tmp_1['tm_mday'].' '.$month_list_label_min[$tmp_1['tm_mon']].' - '.$tmp_2['tm_mday'].' '.
  1784. $month_list_label_min[$tmp_2['tm_mon']];
  1785. }
  1786. if(date('W',mktime(00,00,00,12,31,$this->year))==1) {
  1787. $week_begin_tsp=strtotime('+52 week',$first_monday);
  1788. $tmp_1=strptime(strftime('%d/%m/%Y',$week_begin_tsp),'%d/%m/%Y');
  1789. $tmp_2=strptime(strftime('%d/%m/%Y',strtotime('+6 day',$week_begin_tsp)),'%d/%m/%Y');
  1790. $week_list['1-'.($this->year+1)]=$tmp_1['tm_mday'].' '.$month_list_label_min[$tmp_1['tm_mon']].' - '.$tmp_2['tm_mday'].' '.
  1791. $month_list_label_min[$tmp_2['tm_mon']];
  1792. }
  1793. // Creation de la liste des mois
  1794. for($i=1;$i<13;$i++) {
  1795. $month_list[$i]=$month_list_label[$i-1].' '.$this->year;
  1796. }
  1797. // Creation de la liste des agenda
  1798. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tagenda);
  1799. $xset->order='name';
  1800. if($this->object_sec){
  1801. $oids=$this->getAuthorizedDiaries();
  1802. $select=$xset->select_query(array('order'=>'name','cond'=>array('KOID'=>array('=',$oids))));
  1803. }else{
  1804. $select='select '.$this->tagenda.'.* from '.$this->tagenda.' order by name';
  1805. }
  1806. $diary_list=$xset->browse(array('selectedfields'=>array('name'),'select'=>$select,'_options'=>array('local'=>true)));
  1807. // Formate la semaine en cours
  1808. $this->week=intval(date('W',mktime(12,00,00,$this->month,$this->day,$this->year)));
  1809. if($this->week>50 && $this->month==1) {
  1810. $this->bloc['week']=$this->week.'-'.($this->year-1);
  1811. } elseif($this->week==1 && $this->month==12) {
  1812. $this->bloc['week']=$this->week.'-'.($this->year+1);
  1813. } else {
  1814. $this->bloc['week']=$this->week.'-'.$this->year;
  1815. }
  1816. $this->bloc['month_list']=$month_list;
  1817. $this->bloc['week_list']=$week_list;
  1818. $this->bloc['week_cal_list']=$week_cal_list;
  1819. $this->bloc['prev_month']=$prev_month;
  1820. $this->bloc['next_month']=$next_month;
  1821. $this->bloc['prev_year']=$prev_year;
  1822. $this->bloc['next_year']=$next_year;
  1823. $this->bloc['cal_contents']=$this->cal_content;
  1824. $this->bloc['diary_list']=$diary_list;
  1825. }
  1826. /// Calcul les jours feries
  1827. function calculateFreeDay() {
  1828. $tmp=24*3600;
  1829. $this->paques=date('j-n', easter_date($this->year)+$tmp);
  1830. $this->ascension=date('j-n', easter_date($this->year)+39*$tmp);
  1831. $this->pentecote=date('j-n', easter_date($this->year)+50*$tmp);
  1832. }
  1833. /// Renvoie le type du jour : aujourd'hui, jour selectionne, ferie, weekend, normal
  1834. function dayType($day,$month) {
  1835. if(date('j-n-Y')==$day.'-'.$month.'-'.$this->year) return('today');
  1836. if($this->day.'-'.$this->month.'-'.$this->year==$day.'-'.$month.'-'.$this->year) return('select');
  1837. switch ($day.'-'.$month) {
  1838. case $this->paques:
  1839. case $this->ascension:
  1840. case $this->pentecote:
  1841. case '1-1':
  1842. case '1-5':
  1843. case '8-5':
  1844. case '14-7':
  1845. case '15-8':
  1846. case '1-11':
  1847. case '11-11':
  1848. case '25-12':
  1849. return('free');
  1850. break;
  1851. }
  1852. switch (date('N', mktime(12,00,00,$month,$day,$this->year))) {
  1853. case 6:
  1854. case 7:
  1855. return('weekend');
  1856. break;
  1857. default:
  1858. return('work');
  1859. break;
  1860. }
  1861. }
  1862. function decimal($num) {
  1863. return $num-floor($num);
  1864. }
  1865. /// Calcul les heures de debut et de fin d'affichage
  1866. function getDisplayHours(&$events,&$day_begin,&$day_end) {
  1867. foreach($events as &$event){
  1868. $this->convertEventTime($event);
  1869. $begin_hour=date('H',strtotime($event['begin']));
  1870. $begin_minute=date('i',strtotime($event['begin']));
  1871. $end_hour=date('H',strtotime($event['end']));
  1872. $end_minute=date('i',strtotime($event['end']));
  1873. $bagin['hour'];
  1874. if(strtotime($event['begin'])>=strtotime($this->display_begin) && $begin_hour<$day_begin) $day_begin=$begin_hour;
  1875. if(strtotime($event['end'])<=strtotime($this->display_end) && $end_hour>$day_end) $day_end=$end_hour;
  1876. }
  1877. return;
  1878. }
  1879. /// Calcul les elements de la date pour un affichage hebdo
  1880. function calculateWeekDetails($p) {
  1881. $this->week=$p->get('week');
  1882. if(empty($this->week)) {
  1883. $this->week=date('W',mktime(00,00,00,$this->month,$this->day,$this->year));
  1884. if($this->day<4 && $this->month==1 && $this->week!=1){
  1885. $first_monday=strtotime('Monday',mktime(00,00,00,12,29,$this->year-2));
  1886. }elseif($this->day>28 && $this->month==12 && $this->week==1) {
  1887. $first_monday=strtotime('Monday',mktime(00,00,00,12,29,$this->year));
  1888. } else {
  1889. $first_monday=strtotime('Monday',mktime(00,00,00,12,29,$this->year-1));
  1890. }
  1891. $first_day_week=strtotime('+'.($this->week-1).' week',$first_monday);
  1892. } else {
  1893. $first_monday=strtotime('Monday',mktime(00,00,00,12,29,$this->year-1));
  1894. $first_day_week=strtotime('+'.($this->week-1).' week',$first_monday);
  1895. if($this->week==1) {
  1896. $this->day=4;
  1897. $this->month=1;
  1898. } else {
  1899. $this->day=date('j',$first_day_week);
  1900. $this->month=date('n',$first_day_week);
  1901. }
  1902. }
  1903. $this->bloc['day']=$this->day;
  1904. $this->bloc['month']=$this->month;
  1905. $this->date=$this->year.'-'.str_pad($this->month,2,'0',STR_PAD_LEFT).'-'.str_pad($this->day,2,'0',STR_PAD_LEFT);
  1906. return $first_day_week;
  1907. }
  1908. /// Arrondi le debut et la fin de l'evenement en fonction de l'interval d'affichage
  1909. function calculateRound(&$actual_event,&$round_begin,&$round_end,$interval_minute,$day_begin,$day_end) {
  1910. if($actual_event['allday']==1) {
  1911. $actual_event['begin']=$round_begin=strtotime(date('H:i:00',mktime(00,($day_begin*60),00,01,01,2006)),
  1912. strtotime($actual_event['begin']));
  1913. $actual_event['end']=$round_end=strtotime(date('H:i:00',mktime(00,($day_end*60),00,01,01,2006)),strtotime($actual_event['end']));
  1914. } else {
  1915. $event_begin=strtotime($actual_event['begin']);
  1916. $event_end=strtotime($actual_event['end']);
  1917. $round_begin=$event_begin-$this->decimal(date('i',$event_begin)/$interval_minute)*$interval_minute*60;
  1918. $tmp=$this->decimal(date('i',$event_end)/$interval_minute)*$interval_minute;
  1919. if($tmp==0) {
  1920. $round_end=$event_end;
  1921. } else {
  1922. $round_end=$event_end+($interval_minute-$tmp)*60;
  1923. }
  1924. }
  1925. }
  1926. /// Convertit la date GMT vers le fuseau de l'agenda
  1927. function convertEventTime(&$event) {
  1928. if(!empty($event['_timeconvert'])) return;
  1929. if(!empty($event['oallday'])) {
  1930. if($event['oallday']->raw!=1){
  1931. $event['obegin']->raw=date('Y-m-d H:i:s',strtotime($event['obegin']->raw.' GMT'));
  1932. $event['oend']->raw=date('Y-m-d H:i:s',strtotime($event['oend']->raw.' GMT'));
  1933. $opt=array();
  1934. $event['obegin']=$this->xsetevt->desc['begin']->edit($event['obegin']->raw,$opt);
  1935. $event['oend']=$this->xsetevt->desc['end']->edit($event['oend']->raw,$opt);
  1936. $event['begin']=$event['obegin']->raw;
  1937. $event['end']=$event['oend']->raw;
  1938. }
  1939. }elseif($event['allday']!=1) {
  1940. $event['begin']=date('Y-m-d H:i:s',strtotime($event['begin'].' GMT'));
  1941. $event['end']=date('Y-m-d H:i:s',strtotime($event['end'].' GMT'));
  1942. }
  1943. $event['_timeconvert']=true;
  1944. }
  1945. /// Recupere les notes brutes dans un interval (gmt)
  1946. function &getNotes($begin,$end,$where=false,$all=false){
  1947. $rq=$this->request['select'].' '.$this->request['from'].' ';
  1948. if($where) $rq.=$where;
  1949. else $rq.=$this->request['where'];
  1950. $rq.=' AND '.$this->tevt.'.allday=1 AND ('.$this->tevt.'.begin BETWEEN "'.$begin.'" AND "'.$end.'" OR '.
  1951. '"'.$begin.'" BETWEEN '.$this->tevt.'.begin AND '.$this->tevt.'.end)';
  1952. $rq=array($rq);
  1953. $cons=$this->getDiariesForConsolidation();
  1954. foreach($cons['active'] as $oid=>$foo){
  1955. if(is_numeric($oid)){
  1956. $mod=XModule::objectFactory($oid);
  1957. if(!is_object($mod)) continue;
  1958. $req=$mod->XCalGetConsolidationQuery($this->diary,$cons['list'][$oid],$this->request['selectedfields'],$begin,$end,'note');
  1959. if(!empty($req)) $rq[]=$req;
  1960. }
  1961. }
  1962. $rq='('.implode(') UNION (',$rq).') order by begin,end desc';
  1963. if($all) return selectQueryGetAll($rq);
  1964. else return selectQuery($rq);
  1965. }
  1966. /// Recupere les evenements bruts dans un interval (gmt)
  1967. function &getEvents($begin,$end,$where=false,$all=false){
  1968. $rq=$this->request['select'].' '.$this->request['from'].' ';
  1969. if($where) $rq.=$where;
  1970. else $rq.=$this->request['where'];
  1971. $rq.=' AND ('.$this->tevt.'.allday!=1 or '.$this->tevt.'.allday is null) AND '.
  1972. '('.$this->tevt.'.begin BETWEEN "'.$begin.'" AND "'.$end.'" OR '.
  1973. '"'.$begin.'" BETWEEN '.$this->tevt.'.begin AND '.$this->tevt.'.end)';
  1974. $rq=array($rq);
  1975. $cons=$this->getDiariesForConsolidation();
  1976. foreach($cons['active'] as $oid=>$foo){
  1977. if(is_numeric($oid)){
  1978. $mod=XModule::objectFactory($oid);
  1979. if(!is_object($mod)) continue;
  1980. $req=$mod->XCalGetConsolidationQuery($this->diary,$cons['list'][$oid],$this->request['selectedfields'],$begin,$end,'event');
  1981. if(!empty($req)) $rq[]=$req;
  1982. }
  1983. }
  1984. $rq='('.implode(') UNION (',$rq).') order by begin,end desc';
  1985. if($all) return selectQueryGetAll($rq);
  1986. else return selectQuery($rq);
  1987. }
  1988. /// Recupere les notes et les evenements dans un interval (gmt)
  1989. function &getAlls($evbegin,$evend,$nobegin,$noend,$where=false){
  1990. $rq=$this->request['select'].' '.$this->request['from'].' ';
  1991. if($where) $rq.=$where.' ';
  1992. else $rq.=$this->request['where'].' ';
  1993. $rq.=' AND ((('.$this->tevt.'.allday!=1 or '.$this->tevt.'.allday is null) AND '.
  1994. '('.$this->tevt.'.begin BETWEEN "'.$evbegin.'" AND "'.$evend.'" OR '.
  1995. '"'.$evbegin.'" BETWEEN '.$this->tevt.'.begin AND '.$this->tevt.'.end)) OR '.
  1996. '('.$this->tevt.'.allday=1 AND '.
  1997. '('.$this->tevt.'.begin BETWEEN "'.$nobegin.'" AND "'.$noend.'"'.
  1998. 'OR "'.$nobegin.'" BETWEEN '.$this->tevt.'.begin AND '.$this->tevt.'.end)))';
  1999. $rq=array($rq);
  2000. $cons=$this->getDiariesForConsolidation();
  2001. foreach($cons['active'] as $oid=>$foo){
  2002. if(is_numeric($oid)){
  2003. $mod=XModule::objectFactory($oid);
  2004. if(!is_object($mod)) continue;
  2005. $req=$mod->XCalGetConsolidationQuery($this->diary,$cons['list'][$oid],$this->request['selectedfields'],$nobegin,$noend);
  2006. if(!empty($req)) $rq[]=$req;
  2007. }
  2008. }
  2009. $rq='('.implode(') UNION (',$rq).') order by begin,end desc';
  2010. $rs=selectQuery($rq);
  2011. return $rs;
  2012. }
  2013. /// Coupe les evenements sur plusieurs jours
  2014. function cutEvents(&$events, $day_begin, $day_end) {
  2015. $events_tmp=array();
  2016. if(is_null($day_begin)) {
  2017. $day_begin='00:00:00';
  2018. $day_end='23:59:00';
  2019. } else {
  2020. $day_begin=date('H:i:s',strtotime('2010-10-10 '.floor($day_begin).':'.($this->decimal($day_begin)*60).':00'));
  2021. if($day_end==24) {
  2022. $day_end='23:59:00';
  2023. } else {
  2024. $day_end=date('H:i:s',strtotime('2010-10-10 '.floor($day_end).':'.($this->decimal($day_end)*60).':00'));
  2025. }
  2026. }
  2027. foreach($events as $event) {
  2028. $this->getCompleteEvent($event);
  2029. $start = strtotime($event['begin']);
  2030. $end = strtotime($event['end']);
  2031. $start_date = date('Y-m-d', $start);
  2032. $end_date = date('Y-m-d', $end);
  2033. $start_hour = date('H:i:00', $start);
  2034. $end_hour = date('H:i:00', $end);
  2035. $event_tmp=array();
  2036. $event['_cbegin']=$event['begin'];
  2037. $event['_cend']=$event['end'];
  2038. if($start_date == $end_date) {
  2039. $events_tmp[]=$event;
  2040. } else {
  2041. $start2=$start;
  2042. if($start_date.' 12:00:00'>=$this->display_begin) {
  2043. $event['end']=$start_date.' '.$day_end;
  2044. $events_tmp[]=$event;
  2045. }
  2046. $start = strtotime('+1 day', $start);
  2047. $start_date = date('Y-m-d', $start);
  2048. while ($start_date < $end_date) {
  2049. if($start_date.' 12:00:00'>$this->display_begin && $start_date.' 12:00:00'<$this->display_end) {
  2050. $event['begin']=$start_date.' '.$day_begin;
  2051. $event['end']=$start_date.' '.$day_end;
  2052. $events_tmp[]=$event;
  2053. }
  2054. $start = strtotime('+1 day', $start);
  2055. $start_date = date('Y-m-d', $start);
  2056. }
  2057. if($start_date.' 12:00:00'>$this->display_begin && $start_date.' 12:00:00'<$this->display_end) {
  2058. $event['begin']=$start_date.' '.$day_begin;
  2059. $event['end']=date('Y-m-d H:i:s',$end);
  2060. $events_tmp[]=$event;
  2061. }
  2062. }
  2063. }
  2064. uasort($events_tmp, create_function('$a,$b','if ($a["begin"] == $b["begin"] && $a["_cbegin"] == $b["_cbegin"]) return 0;
  2065. if($a["begin"] < $b["begin"]) return -1;
  2066. return ($a["begin"] == $b["begin"] && $a["_cbegin"] < $b["_cbegin"]) ? -1 : 1;'));
  2067. foreach($events_tmp as $i=>&$event){
  2068. $event['_begindate']=date('d/m/Y',strtotime($event['begin']));
  2069. $event['_beginhour']=date('H:i',strtotime($event['begin']));
  2070. $event['_cbegindate']=date('d/m/Y',strtotime($event['_cbegin']));
  2071. $event['_cbeginhour']=date('H:i',strtotime($event['_cbegin']));
  2072. $event['_enddate']=date('d/m/Y',strtotime($event['end']));
  2073. $event['_endhour']=date('H:i',strtotime($event['end']));
  2074. $event['_cenddate']=date('d/m/Y',strtotime($event['_cend']));
  2075. $event['_cendhour']=date('H:i',strtotime($event['_cend']));
  2076. }
  2077. $events=$events_tmp;
  2078. }
  2079. /// Coupe les notes sur plusieurs jours
  2080. function cutNotes(&$notes) {
  2081. $notes_tmp=array();
  2082. foreach($notes as $note) {
  2083. $this->getCompleteEvent($note);
  2084. $start = strtotime($note['begin']);
  2085. $end = strtotime($note['end']);
  2086. $start_date = date('Y-m-d', $start);
  2087. $end_date = date('Y-m-d', $end);
  2088. $note['_cbegin']=$note['begin'];
  2089. $note['_cend']=$note['end'];
  2090. while ($start_date <= $end_date) {
  2091. if($start_date.' 12:00:00'>$this->display_begin && $start_date.' 12:00:00'<$this->display_end) {
  2092. $note['begin']=$start_date.' 00:00:00';
  2093. $note['end']=$start_date.' 23:59:00';
  2094. $notes_tmp[]=$note;
  2095. }
  2096. $start = strtotime('+1 day', $start);
  2097. $start_date = date('Y-m-d', $start);
  2098. }
  2099. }
  2100. foreach($notes_tmp as $i=>&$note){
  2101. $note['_begindate']=date('d/m/Y',strtotime($note['begin']));
  2102. $note['_cbegindate']=date('d/m/Y',strtotime($note['_cbegin']));
  2103. $note['_enddate']=date('d/m/Y',strtotime($note['end']));
  2104. $note['_cenddate']=date('d/m/Y',strtotime($note['_cend']));
  2105. }
  2106. $notes=$notes_tmp;
  2107. }
  2108. /// Complete les données d'un evenement via un rdisplay (au depart, $event ne contient que certains champs (voir fin du construct))
  2109. function getCompleteEvent(&$event){
  2110. // Si l'evenement à déjà été traité
  2111. if($event['_url']) return;
  2112. $this->convertEventTime($event);
  2113. if($event['MOID']!=$this->_moid){
  2114. $mod=XModule::objectFactory($event['MOID']);
  2115. $cons=$this->getDiariesForConsolidation();
  2116. $params=$cons['list'][$event['MOID']];
  2117. $tmp=$mod->XCalRDisplay($event['KOID'],array('text'=>$params['text'],'place'=>$params['place'],'descr'=>$params['descr']));
  2118. if(!empty($tmp)) $event=array_merge($event,$tmp);
  2119. $event['_url']=str_replace('%s',$event['KOID'],$this->bloc['diariesprop'][$event['DKOID']]['url']);
  2120. }else{
  2121. $tmp=$this->xsetevt->rDisplay($event['KOID'],array(), false,'','',array('selectedfields'=>array('text','place','descr')));
  2122. if(!empty($tmp)) $event=array_merge($event,$tmp);
  2123. $event['_url']=$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'oid='.$this->diary['KOID'].'&moid='.$this->_moid.'&function=addEvt&tplentry=br&'.
  2124. 'template=xmodcalendar/addEvt.html&day='.$this->day.'&month='.$this->month.'&year='.$this->year.'&koid='.$event['KOID'];
  2125. }
  2126. }
  2127. // Supprime les lignes inutiles entre deux heures pleines
  2128. // Attention : dans les tableaux, decalage de +1 entre le tableau des evenements et des heures (du aux notes)
  2129. function delEmptyPeriod(&$table,$tablefordel,&$hours,$interval){
  2130. if($interval==1) return;
  2131. $nbrow=count($tablefordel);
  2132. for($l=0;$l<$nbrow;$l++){
  2133. $row=$tablefordel[$l];
  2134. $del=0;
  2135. $min=substr($hours[$l+1],-3);
  2136. if($interval==0.5 && $min==':00' && $row==$tablefordel[$l+1]) $del=1;
  2137. elseif($interval==0.25 && $min==':00' && $row==$tablefordel[$l+1] && $tablefordel[$l+2]==$tablefordel[$l+3]){
  2138. if($row==$tablefordel[$l+2]) $del=3;
  2139. else $del=1;
  2140. }elseif($interval==0.25 && $min=':30' && $row==$tablefordel[$l+1] && !isset($table[$l-1])) $del=1;
  2141. if($del>0){
  2142. foreach($row as $col=>$tmp){
  2143. if($tmp!=='empty') $table[$tmp][$col]['nb_interval']-=$del;
  2144. }
  2145. if($del===1) unset($table[$l+1],$hours[$l+2]);
  2146. elseif($del===3) unset($table[$l+1],$hours[$l+2],$table[$l+2],$hours[$l+3],$table[$l+3],$hours[$l+4]);
  2147. $l+=$del;
  2148. }
  2149. }
  2150. $table=array_values($table);
  2151. $hours=array_values($hours);
  2152. }
  2153. public function usedTables() {
  2154. return array($this->tagenda,$this->tevt,$this->tlinks,$this->tcatevt,$this->tcatagenda,$this->tplan,$this->tplaninv,$this->tplandates);
  2155. }
  2156. public function usedMainTables() {
  2157. return array($this->tagenda);
  2158. }
  2159. public function usedBoids(){
  2160. return array($this->xsetevt->getBoid());
  2161. }
  2162. /// rend la liste des agendas authorises
  2163. public function getAuthorizedDiaries($level='ro',$mode='array',$forcecache=false){
  2164. if($forcecache || !array_key_exists('authdiaries-'.$level,$this->cache)){
  2165. $this->cache['authdiaries-ro']=array();
  2166. $this->cache['authdiaries-rw']=array();
  2167. $this->cache['authdiaries-rwv']=array();
  2168. $xsetag=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tagenda);
  2169. $oids=$xsetag->browseOids();
  2170. $lang_data=XShell::getLangData();
  2171. if($this->object_sec){
  2172. $oidsrights=$GLOBALS['XUSER']->getObjectsAccess($this, $lang_data, $oids);
  2173. list($access,$l)=$GLOBALS['XUSER']->getObjectAccess($this, $lang_data);
  2174. foreach($oidsrights as $i => $rights) {
  2175. if(array_key_exists('ro',$rights) || in_array('ro',$access)) $this->cache['authdiaries-ro'][]=$oids[$i];
  2176. if(array_key_exists('rw',$rights) || in_array('rw',$access)) $this->cache['authdiaries-rw'][]=$oids[$i];
  2177. if(array_key_exists('rwv',$rights) || in_array('rwv',$access)) $this->cache['authdiaries-rwv'][]=$oids[$i];
  2178. }
  2179. }else{
  2180. $this->cache['authdiaries-ro']=$oids;
  2181. $this->cache['authdiaries-rw']=$oids;
  2182. $this->cache['authdiaries-rwv']=$oids;
  2183. }
  2184. }
  2185. $oids=$this->cache['authdiaries-'.$level];
  2186. if($mode=='array') return $oids;
  2187. else return '"'.implode('","',$oids).'"';
  2188. }
  2189. /// Renvoie la liste des consolidations
  2190. public function getDiariesForConsolidation(){
  2191. if(empty($this->cache['consolidations'])){
  2192. $oid=$this->diary['KOID'];
  2193. $ret=array('active'=>array(),'list'=>array());
  2194. $sess=getSessionVar('xmodcalendar'.$this->_moid.':consolidations');
  2195. if(!empty($this->prefs['consolidations']['active'][$oid])) $ret['active']=$this->prefs['consolidations']['active'][$oid];
  2196. if(!empty($this->prefs['consolidations']['list'])) $ret['list']=$this->prefs['consolidations']['list'];
  2197. if(!empty($sess['active'][$oid])){
  2198. foreach($sess['active'][$oid] as $foid=>&$foo){
  2199. $ret['active'][$foid]=$foo;
  2200. }
  2201. }
  2202. if(!empty($sess['list'])){
  2203. foreach($sess['list'] as $foid=>&$foo){
  2204. $ret['list'][$foid]=$foo;
  2205. }
  2206. }
  2207. unset($ret['active'][$oid]);
  2208. unset($ret['list'][$oid]);
  2209. $this->cache['consolidations']=$ret;
  2210. }
  2211. return $this->cache['consolidations'];
  2212. }
  2213. /// verification qu'un module est bien installé + nettoyage des preferences
  2214. public function chk($ar=NULL) {
  2215. $rs=selectQuery('select * from OPTS where dtype="pref" and modid="'.$this->_moid.'"');
  2216. while($rs && ($ors=$rs->fetch())){
  2217. if(!empty($ors['specs'])) $prefs=unserialize($ors['specs']);
  2218. else $prefs=array();
  2219. // Supprime l'agenda par defaut s'il n'existe plus
  2220. $def=@$prefs['defaultcal'];
  2221. if(!empty($def)){
  2222. $rs=&cacheSelectQuery('select KOID from '.$this->tagenda.' where KOID="'.$def.'"',5);
  2223. if($rs->rowCount()==0) unset($prefs['defaultcal']);
  2224. }
  2225. // Supprime les consolidation (list + active) qui n'existe plus
  2226. $cons=@$prefs['consolidations'];
  2227. if(!empty($cons['list'])){
  2228. foreach($cons['list'] as $oid=>&$foo){
  2229. if(is_numeric($oid)) $rs=&cacheSelectQuery('select MOID from MODULES where MOID="'.$oid.'"',5);
  2230. else $rs=&cacheSelectQuery('select KOID from '.$this->tagenda.' where KOID="'.$oid.'"',5);
  2231. if($rs->rowCount()==0) unset($prefs['consolidations']['list'][$oid]);
  2232. }
  2233. }
  2234. if(!empty($cons['active'])){
  2235. foreach($cons['active'] as $oid=>&$foo){
  2236. $rs=&cacheSelectQuery('select KOID from '.$this->tagenda.' where KOID="'.$oid.'"',5);
  2237. if($rs->rowCount()==0) unset($prefs['consolidations']['active'][$oid]);
  2238. else{
  2239. foreach($cons['active'][$oid] as $oid2=>&$foo){
  2240. if(is_numeric($oid2)) $rs=&cacheSelectQuery('select MOID from MODULES where MOID="'.$oid2.'"',5);
  2241. else $rs=&cacheSelectQuery('select KOID from '.$this->tagenda.' where KOID="'.$oid2.'"',5);
  2242. if($rs->rowCount()==0) unset($prefs['consolidations']['active'][$oid][$oid2]);
  2243. }
  2244. }
  2245. }
  2246. }
  2247. updateQuery('update OPTS set specs="'.addslashes(serialize($prefs)).'" where KOID="'.$ors['KOID'].'"');
  2248. }
  2249. return parent::chk($ar);
  2250. }
  2251. /// Preparation d'une planification
  2252. function insertPlanif($ar=NULL){
  2253. $p=new XParam($ar,NULL);
  2254. $tplentry=$p->get('tplentry');
  2255. // Input planif
  2256. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2257. $xset->desc['begin']->sys=true;
  2258. $xset->desc['end']->sys=true;
  2259. $xset->desc['rem']->sys=true;
  2260. $xset->desc['cancel']->sys=true;
  2261. $xset->desc['close']->sys=true;
  2262. $ar['options']['ag']['value']=$this->diary['KOID'];
  2263. $xset->input($ar);
  2264. // Liste groupes/users
  2265. $users = XModule::singletonFactory(XMODUSER2_TOID);
  2266. if(defined('TZR_ALTERNATIVE_SENDTO_DIRECTORY') || defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')) {
  2267. if(defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')) $altmoid=TZR_ALTERNATIVE_CALINTERNE_DIRECTORY;
  2268. else $altmoid=TZR_ALTERNATIVE_SENDTO_DIRECTORY;
  2269. $ausers = XModule::objectFactory($altmoid);
  2270. $userlist=&$ausers->browse(array('pagesize'=>1000,'tplentry'=>TZR_RETURN_DATA,'tlink'=>true,'_options'=>array('local'=>true)));
  2271. XShell::toScreen1($tplentry.'l',$userlist);
  2272. } else {
  2273. $list=XUser::getUsersAndGroups(true);
  2274. XShell::toScreen1($tplentry.'g',$list[1]);
  2275. }
  2276. // Liste agenda
  2277. $xsetag=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tagenda);
  2278. if($this->object_sec) $cplt=' AND KOID IN ('.$this->getAuthorizedDiaries('ro','sql').')';
  2279. else $cplt='';
  2280. $opts=array('filter'=>'(cons IS NULL OR cons!=1) and KOID!="'.$this->diary['KOID'].'"'.$cplt);
  2281. XShell::toScreen2($tplentry,'oattendees',$xsetag->desc['agcons']->edit($foo='',$opts));
  2282. XShell::toScreen1($tplentry.'ag',$this->diary);
  2283. }
  2284. /// Valide l'ajout d'une planification
  2285. function procInsertPlanif($ar=NULL){
  2286. $p=new XParam($ar,array('attendees'=>array(),'uattendees_groups'=>array(),'uattendees'=>array()));
  2287. $dates=$p->get('date');
  2288. $begins=$p->get('begin');
  2289. $ends=$p->get('end');
  2290. $alldays=$p->get('allday');
  2291. $invitt=stripslashes($p->get('invitt'));
  2292. $title=stripslashes($p->get('title'));
  2293. $datelim=$p->get('datelim');
  2294. $atts=$p->get('attendees');
  2295. $grps=$p->get('uattendees_groups');
  2296. $users=$p->get('uattendees');
  2297. if($users[0]=='') unset($users[0]);
  2298. if(empty($users)) $users=array();
  2299. // Ajout de la planification
  2300. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2301. $ret=$xset->procInput($ar);
  2302. // Création des dates
  2303. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplandates);
  2304. foreach($dates as $date){
  2305. $dbegins=$begins[$date];
  2306. $dends=$ends[$date];
  2307. $allday=$alldays[$date];
  2308. foreach($dbegins as $i=>$begin){
  2309. if(empty($begin) || empty($dends[$i])) continue;
  2310. $end=$dends[$i];
  2311. $xset->procInput(array('planif'=>$ret['oid'],'begin'=>$date.' '.$begin,'end'=>$date.' '.$end,'confirm'=>'',
  2312. '_options'=>array('local'=>true)));
  2313. }
  2314. if(!empty($allday)){
  2315. $xset->procInput(array('planif'=>$ret['oid'],'begin'=>$date.' 00:00','end'=>$date.' 00:00','confirm'=>'',
  2316. '_options'=>array('local'=>true)));
  2317. }
  2318. }
  2319. // Creation des sous fiches invités
  2320. $invoids=$emails=array();
  2321. $xsetinv=&XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplaninv);
  2322. $modgroups=XModule::singletonFactory(XMODGROUP_TOID);
  2323. $modusers=XModule::singletonFactory(XMODUSER2_TOID);
  2324. $usersfromgroups=$modgroups->users($grps);
  2325. $users=array_merge($usersfromgroups,$users);
  2326. $users=array_unique($users);
  2327. $oids=array_merge($users,$atts);
  2328. foreach($oids as $oid){
  2329. $ret2=$xsetinv->procInput(array('planif'=>$ret['oid'],'who'=>$oid,'part'=>1,'_options'=>array('local'=>1)));
  2330. $invoids[]=$ret2['oid'];
  2331. }
  2332. $emails=$this->getMailsForPlanif($oids);
  2333. $user=$modusers->display(array('oid'=>XUser::get_current_user_uid(),'tplentry'=>TZR_RETURN_DATA,
  2334. 'selectedfields'=>array('fullnam','email')));
  2335. $sub=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','planinvitmail_subject','mail'),$title);
  2336. $body=$GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','planinvitmail_body','mail');
  2337. $cplt='';
  2338. if($invitt){
  2339. $cplt=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','planmail_bodycomm','mail'),
  2340. $user['ofullnam']->raw,$invitt);
  2341. }
  2342. $url=$GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,false).'&moid='.$this->_moid.'&function=confirmPlanif&template=xmodcalendar/confirmPlanif.html'.
  2343. '&tplentry=br&_direct=1&oid=';
  2344. $text=XLabels::getSysLabel('xmodcalendar','procinsertplanifconfirm');
  2345. foreach($emails as $i=>$mail){
  2346. $this->sendMail2User($sub,sprintf($body,$title,$url.$invoids[$i],$datelim,$cplt),$mail,array($user['oemail']->raw,$user['ofullnam']->raw),true,NULL,NULL,NULL,NULL,array('sign'=>true));
  2347. $text.='&nbsp;- '.$mail['name'].' ('.$mail['mail'].')<br>';
  2348. }
  2349. setSessionVar('message',$text);
  2350. }
  2351. /// Confirmer une planification
  2352. function confirmPlanif($ar=NULL){
  2353. $p=new XParam($ar,NULL);
  2354. $oid=$p->get('oid');
  2355. $tplentry=$p->get('tplentry');
  2356. // Edition de sa fiche (remarque + autres champs eventuels)
  2357. $xsetinv=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplaninv);
  2358. $ret=&$xsetinv->edit();
  2359. // Display de la planification
  2360. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2361. $xset->desc['begin']->sys=true;
  2362. $xset->desc['end']->sys=true;
  2363. $xset->desc['rem']->sys=true;
  2364. $xset->desc['cancel']->sys=true;
  2365. $xset->desc['close']->sys=true;
  2366. $d=&$xset->display(array('tplentry'=>$tplentry.'p','oid'=>$ret['oplanif']->raw,'_options'=>array('local'=>true)));
  2367. // Si la date limite est apssé, on remplace l'edit par un display
  2368. if($d['odatelim']->raw<date('Y-m-d') || $d['ocancel']->raw==1 || $d['oclose']->raw==1){
  2369. $ret=&$xsetinv->display();
  2370. XShell::toScreen2($tplentry,'_mode','display');
  2371. }
  2372. // Browse des dates
  2373. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplandates);
  2374. $xset->browse(array('tplentry'=>$tplentry.'d','select'=>'select * from '.$this->tplandates.' where planif="'.$ret['oplanif']->raw.'"',
  2375. 'selectedfields'=>array('begin','end','confirm'),'order'=>'begin,end','_options'=>array('local'=>true)));
  2376. }
  2377. /// Enregistre une confirmation
  2378. function procConfirmPlanif($ar=NULL){
  2379. $p=new XParam($ar=NULL);
  2380. $oid=$p->get('oid');
  2381. $confirm=$p->get('confirm');
  2382. $confirmhid=$p->get('confirm_HID');
  2383. $nopart=$p->get('nopart');
  2384. // Verifie la date limite de réponse
  2385. $rs=selectQuery('select '.$this->tplan.'.KOID from '.$this->tplan.' '.
  2386. 'left outer join '.$this->tplaninv.' on '.$this->tplaninv.'.planif='.$this->tplan.'.KOID '.
  2387. 'where '.$this->tplaninv.'.KOID="'.$oid.'" and (datelim<"'.date('Y-m-d').'" or cancel=1 or close=1)');
  2388. if($rs->rowCount()>0) securityWarning('XModCalendar::procConfirmPlanif: Trying to edit '.$oid.' with datelim expired/close/cancel');
  2389. // Enregistre remarque + autres champs eventuels
  2390. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplaninv);
  2391. if(!empty($nopart)) $ar['part']=2;
  2392. else $ar['part']=1;
  2393. $ret=&$xset->procEdit($ar);
  2394. // Enregistre les dates
  2395. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplandates);
  2396. foreach($confirmhid as $doid=>$foo){
  2397. $ors=selectQueryGetOne('select confirm from '.$this->tplandates.' where KOID="'.$doid.'"');
  2398. $act=explode('||',$ors['confirm']);
  2399. if(!empty($confirm[$doid]) && !in_array($oid,$act)){
  2400. $act[]=$oid;
  2401. $xset->procEdit(array('oid'=>$doid,'confirm'=>$act,'_options'=>array('local'=>true)));
  2402. }elseif(empty($confirm[$doid]) && in_array($oid,$act)){
  2403. $k=array_search($oid,$act);
  2404. unset($act[$k]);
  2405. $xset->procEdit(array('oid'=>$doid,'confirm'=>$act,'_options'=>array('local'=>true)));
  2406. }
  2407. }
  2408. $text=XLabels::getSysLabel('xmodcalendar','procconfirmplanifconfirm');
  2409. setSessionVar('message',$text);
  2410. }
  2411. /// Parcourir les planifications
  2412. function browsePlanif($ar=NULL){
  2413. XLabels::loadLabels('xmodtable');
  2414. $p=new XParam($ar=NULL);
  2415. $tplentry=$p->get('tplentry');
  2416. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2417. if(!XShell::isRoot()) $q=$xset->select_query(array('cond'=>array('OWN'=>array('=',XUser::get_current_user_uid()))));
  2418. $r=&$xset->browse(array('tplentry'=>TZR_RETURN_DATA,'select'=>$q,'pagesize'=>20));
  2419. $this->browsePlanif_actions($r,$assubmodule);
  2420. $r['function']='browsePlanif';
  2421. $r['_noselectionlink']=1;
  2422. return XShell::toScreen1($tplentry,$r);
  2423. }
  2424. /// Droits sur les fiches losr d'un browse
  2425. function browsePlanif_actions(&$r,$assubmodule=false){
  2426. $uniqid=XShell::uniqid();
  2427. $self1=$GLOBALS['TZR_SESSION_MANAGER']::complete_self();
  2428. $self1.='&moid='.$this->_moid.'&oid='.$this->diary['KOID'].'&tplentry=br&function=';
  2429. if(!is_array($r['lines_oid'])) return;
  2430. $viewico = XLabels::getSysLabel('general','view');
  2431. $viewtxt = XLabels::getSysLabel('general','view','text');
  2432. $editico = XLabels::getSysLabel('general','edit');
  2433. $edittxt = XLabels::getSysLabel('general','edit','text');
  2434. $delico = XLabels::getSysLabel('general','delete');
  2435. $deltxt = XLabels::getSysLabel('general','delete','text');
  2436. foreach($r['lines_oid'] as $i =>$oid) {
  2437. $rs=selectQuery('select KOID from '.$this->tplan.' where KOID="'.$oid.'" and (cancel=1 or close=1)');
  2438. $count=$rs->rowCount();
  2439. $url=$self1.'displayPlanif&koid='.$oid.'&template=xmodcalendar/viewPlanif.html';
  2440. $r['actions'][$i][0]='<a class="cv8-ajaxlink" href="'.$url.'" title="'.$viewtxt.'">'.$viewico.'</a>';
  2441. $r['actions_url'][$i][0]=$url;
  2442. $r['actions_label'][$i][0]=$viewico;
  2443. // edition
  2444. if($count==0){
  2445. $url=$self1.'editPlanif&koid='.$oid.'&template=xmodcalendar/viewPlanif.html';
  2446. $r['actions'][$i][1]='<a class="cv8-ajaxlink" href="'.$url.'" title="'.$edittxt.'">'.$editico.'</a>';
  2447. $r['actions_url'][$i][1]=$url;
  2448. $r['actions_label'][$i][1]=$editico;
  2449. }
  2450. // Suppression
  2451. $url=$self1.'delPlanif&koid='.$oid.'&template=message.html';
  2452. $r['actions'][$i][2]='<a href="'.$url.'" class="cv8-delaction" title="'.$deltxt.'">'.$delico.'</a>';
  2453. $r['actions_url'][$i][2]=$url;
  2454. $r['actions_label'][$i][2]=$deltxt;
  2455. }
  2456. }
  2457. /// Affichage d'une planification
  2458. function displayPlanif($ar=NULL){
  2459. $p=new XParam($ar=NULL);
  2460. $oid=$p->get('koid');
  2461. $tplentry=$p->get('tplentry');
  2462. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2463. $xset->desc['begin']->sys=true;
  2464. $xset->desc['end']->sys=true;
  2465. $xset->desc['rem']->sys=true;
  2466. $xset->desc['cancel']->sys=true;
  2467. $xset->desc['close']->sys=true;
  2468. $xset->desc['datelim']->sys=true;
  2469. $xset->desc['invitt']->sys=true;
  2470. $xset->display(array('oid'=>$oid,'tplentry'=>$tplentry));
  2471. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplandates);
  2472. $q=$xset->select_query(array('cond'=>array('planif'=>array('=',$oid))));
  2473. $xset->browse(array('tplentry'=>$tplentry.'d','order'=>'begin','selectedfields'=>array('begin','end','confirm'),'select'=>$q));
  2474. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplaninv);
  2475. $q=$xset->select_query(array('cond'=>array('planif'=>array('=',$oid))));
  2476. $xset->browse(array('tplentry'=>$tplentry.'i','order'=>'who','selectedfields'=>array('who','part','remark'),'select'=>$q));
  2477. XShell::toScreen2($tplentry,'_mode','display');
  2478. }
  2479. /// Edition d'une planification
  2480. function editPlanif($ar=NULL){
  2481. $p=new XParam($ar=NULL);
  2482. $oid=$p->get('koid');
  2483. $tplentry=$p->get('tplentry');
  2484. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2485. $xset->desc['begin']->sys=true;
  2486. $xset->desc['end']->sys=true;
  2487. $xset->desc['rem']->sys=true;
  2488. $xset->desc['cancel']->sys=true;
  2489. $xset->desc['close']->sys=true;
  2490. $xset->desc['datelim']->sys=true;
  2491. $xset->desc['invitt']->sys=true;
  2492. $xset->desc['begin']->compulsory=true;
  2493. $xset->desc['end']->compulsory=true;
  2494. $xset->edit(array('oid'=>$oid,'tplentry'=>$tplentry));
  2495. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplandates);
  2496. $q=$xset->select_query(array('cond'=>array('planif'=>array('=',$oid))));
  2497. $xset->browse(array('tplentry'=>$tplentry.'d','order'=>'begin','selectedfields'=>array('begin','end','confirm'),'select'=>$q));
  2498. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplaninv);
  2499. $q=$xset->select_query(array('cond'=>array('planif'=>array('=',$oid))));
  2500. $xset->browse(array('tplentry'=>$tplentry.'i','order'=>'who','selectedfields'=>array('who','part','remark'),'select'=>$q));
  2501. }
  2502. /// Enregistrer une modification sur une planification
  2503. function procEditPlanif($ar=NULL){
  2504. $p=new XParam($ar=NULL);
  2505. $oid=$p->get('koid');
  2506. $close=$p->get('close');
  2507. $cancel=$p->get('cancel');
  2508. $begin=$p->get('begin');
  2509. $end=$p->get('end');
  2510. $allday=$p->get('allday');
  2511. $rem=$p->get('rem');
  2512. $tplentry=$p->get('tplentry');
  2513. $ar['oid']=$oid;
  2514. $ar['end']['date']=$end['date']=$begin['date'];
  2515. $ar['end']['hour']=$end['hour'];
  2516. // Verifie la date limite de réponse
  2517. $rs=selectQuery('select KOID from '.$this->tplan.' where KOID="'.$oid.'" and (cancel=1 or close=1)');
  2518. if($rs->rowCount()>0) securityWarning('XModCalendar::procEditPlanif: Trying to edit '.$oid.' with close/cancel=1');
  2519. $modusers=XModule::singletonFactory(XMODUSER2_TOID);
  2520. $user=$modusers->display(array('oid'=>XUser::get_current_user_uid(),'tplentry'=>TZR_RETURN_DATA,
  2521. 'selectedfields'=>array('fullnam','email')));
  2522. $xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2523. $ret=$xset->procEdit($ar);
  2524. $d=$xset->display(array('oid'=>$oid,'tplentry'=>TZR_RETURN_DATA));
  2525. $cplt='';
  2526. if($rem){
  2527. $cplt=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','planmail_bodycomm','mail'),
  2528. $user['ofullnam']->raw,$rem);
  2529. }
  2530. if($cancel==1){
  2531. $sub=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','plancancelmail_subject','mail'),$d['otitle']->html);
  2532. $body=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','plancancelmail_body','mail'),$d['otitle']->html,$cplt);
  2533. }elseif($close==1){
  2534. $sub=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','planclosemail_subject','mail'),$d['otitle']->html);
  2535. if($allday){
  2536. $datetext=$begin['date'].' ('.XLabels::getSysLabel('xmodcalendar','allday','text').')';
  2537. }else{
  2538. $datetext=$begin['date'].' '.XLabels::getSysLabel('xmodcalendar','at2','text').' '.$begin['hour'].' '.
  2539. XLabels::getSysLabel('xmodcalendar','to2','text').' '.$end['hour'];
  2540. }
  2541. $body=sprintf($GLOBALS['XSHELL']->labels->getCustomSysLabel('xmodcalendar','planclosemail_body','mail'),$d['otitle']->html,$datetext,$cplt);
  2542. }
  2543. $oids=array();
  2544. $rs=selectQuery('select who from '.$this->tplaninv.' where planif="'.$oid.'"');
  2545. while($rs && ($ors=$rs->fetch())) $oids[]=$ors['who'];
  2546. $emails=$this->getMailsForPlanif($oids);
  2547. // Création des evenements dans les agendas
  2548. if($close==1){
  2549. $agatts=array();
  2550. $otheratts=array();
  2551. foreach($emails as $mail){
  2552. if($mail['type']=='agenda') $agatts[]=$mail['oid'];
  2553. else $otheratts[]=$mail['mail'];
  2554. }
  2555. $ret2=$this->saveEvt(array('text'=>addslashes($d['otitle']->raw),'descr'=>addslashes($d['odescr']->raw),'cat'=>$d['ocat']->raw,
  2556. 'allday'=>$allday,'begindate'=>$begin['date'],'enddate'=>$end['date'],'beginhour'=>$begin['hour'],
  2557. 'endhour'=>$end['hour'],'attext'=>implode(';',$otheratts),'selected'=>$agatts,'noalert'=>true,
  2558. '_options'=>array('local'=>true)));
  2559. // Ajout du fichier iCal UTF8
  2560. $file=TZR_TMP_DIR.uniqid('ical-').'.ics';
  2561. $fd=fopen($file,'a');
  2562. fwrite($fd,$this->saveExport(array('expoid'=>$ret2['oid'],'intcall'=>true)));
  2563. fclose($fd);
  2564. // Ajout du fichier iCal latin1 pour outlook
  2565. $file2=TZR_TMP_DIR.uniqid('outlook-').'.ics';
  2566. $fd=fopen($file2,'a');
  2567. fwrite($fd,$this->saveExport(array('expoid'=>$ret2['oid'],'intcall'=>true,'charset'=>'latin1')));
  2568. fclose($fd);
  2569. $filesname=array($file,$file2);
  2570. $filestitle=array(rewriteToAscii($d['otitle']->html).'.ics',rewriteToAscii($d['otitle']->html).'_Outlook.ics');
  2571. }
  2572. $this->sendMail2User($sub,$body,$emails,array($user['oemail']->raw,$user['ofullnam']->raw),true,$filesname,$filestitle,NULL,NULL,
  2573. array('sign'=>true));
  2574. if($close==1){
  2575. unlink($file);
  2576. unlink($file2);
  2577. }
  2578. return $ret;
  2579. }
  2580. /// Supression d'une planification
  2581. function delPlanif($ar=NULL){
  2582. $p = new XParam($ar,array());
  2583. $parentoid=$p->get('_selected');
  2584. $selectedok=$p->get('_selectedok');
  2585. $parentoid=array_keys($parentoid);
  2586. if(($selectedok!='ok') || empty($parentoid)) $parentoid=$p->get('koid');
  2587. if(!is_array($parentoid)) $parentoid=array($parentoid);
  2588. $xsetplan=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplan);
  2589. $xsetdate=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplandates);
  2590. $xsetinv=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->tplaninv);
  2591. foreach($parentoid as $oid){
  2592. $xsetplan->del(array('oid'=>$oid,'_options'=>array('local'=>true)));
  2593. $rs=selectQuery('select KOID from '.$this->tplandates.' where planif="'.$oid.'"');
  2594. while($rs && ($ors=$rs->fetch())) $xsetdate->del(array('oid'=>$ors['KOID'],'_options'=>array('local'=>true)));
  2595. $rs=selectQuery('select KOID from '.$this->tplaninv.' where planif="'.$oid.'"');
  2596. while($rs && ($ors=$rs->fetch())) $xsetinv->del(array('oid'=>$ors['KOID'],'_options'=>array('local'=>true)));
  2597. }
  2598. }
  2599. /// Recupere la liste des mails des invité d'une planification
  2600. function getMailsForPlanif($oids,$filter=''){
  2601. if(defined('TZR_ALTERNATIVE_SENDTO_DIRECTORY') || defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')) {
  2602. if(defined('TZR_ALTERNATIVE_CALINTERNE_DIRECTORY')) $altmoid=TZR_ALTERNATIVE_CALINTERNE_DIRECTORY;
  2603. else $altmoid=TZR_ALTERNATIVE_SENDTO_DIRECTORY;
  2604. $modusers=XModule::objectFactory($altmoid);
  2605. }else{
  2606. $modusers=XModule::singletonFactory(XMODUSER2_TOID);
  2607. }
  2608. $emails=array();
  2609. foreach($oids as $oid){
  2610. if(Kernel::getTable($oid)!=$this->tagenda && $filter!='agenda'){
  2611. $r1=$modusers->display(array('oid'=>$oid,'tplentry'=>TZR_RETURN_DATA));
  2612. if(empty($altmoid)) $emails[]=array('mail'=>$r1['oemail']->raw,'name'=>$r1['ofullnam']->raw,'type'=>'user','oid'=>$oid);
  2613. else{
  2614. $tmp=$modusers->xset->emailsFromDisplay($r1);
  2615. foreach($tmp as $mail){
  2616. $emails[]=array('mail'=>$mail,'name'=>$r1['tlink'],'type'=>'user','oid'=>$oid);
  2617. }
  2618. }
  2619. }elseif($filter!='user'){
  2620. $ors=selectQueryGetOne('select OWN from '.$this->tagenda.' where KOID="'.$oid.'" LIMIT 1');
  2621. $r1=$modusers->display(array('oid'=>$ors['OWN'],'tplentry'=>TZR_RETURN_DATA,'selectedfields'=>array('fullnam','email')));
  2622. $emails[]=array('mail'=>$r1['oemail']->raw,'name'=>$r1['ofullnam']->raw,'type'=>'agenda','oid'=>$oid);
  2623. }
  2624. }
  2625. return $emails;
  2626. }
  2627. /// Recupere les preferences du module pour une édition
  2628. function &getParamPrefs($uid){
  2629. $desc['defaultcal']=XFieldDef::objectFactory((object)array('FIELD'=>'defaultcal','FTYPE'=>'XLinkDef','MULTIVALUED'=>0,
  2630. 'COMPULSORY'=>false,'LABEL'=>'Calendrier par défaut',
  2631. 'TARGET'=>$this->tagenda));
  2632. $desc['defaultcal']->checkbox=false;
  2633. $desc['defview']=XFieldDef::objectFactory((object)array('FIELD'=>'defview','FTYPE'=>'XShortTextDef','MULTIVALUED'=>0,
  2634. 'COMPULSORY'=>false,'LABEL'=>'Vue par defaut'));
  2635. $options['defview']['selectBoxValues']=array('displayDay', 'displayWeek', 'displayMonth', 'displayYear');
  2636. // consolidations ??
  2637. return array('desc'=>$desc,'options'=>$options);
  2638. }
  2639. }
  2640. ?>