ical.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. <?php
  2. /*
  3. * Recibe los perfiles y periodo por GET.
  4. */
  5. require_once("./include/nocache.php");
  6. require_once("./include/bd_pdo.php");
  7. require_once("./include/util.php");
  8. include_once("./include/iCalcreator/autoload.php");
  9. include_once("./classes/LogICal.php");
  10. use Kigkonsult\Icalcreator\Vcalendar;
  11. function getVcalDia($diaNum){
  12. switch($diaNum){
  13. case 0: return Vcalendar::SU;
  14. case 1: return Vcalendar::MO;
  15. case 2: return Vcalendar::TU;
  16. case 3: return Vcalendar::WE;
  17. case 4: return Vcalendar::TH;
  18. case 5: return Vcalendar::FR;
  19. case 6: return Vcalendar::SA;
  20. }
  21. }
  22. function getDiasArray($diasStr, $week_num = false, $freq = 0){
  23. $diasArr = explode(",", $diasStr);
  24. $final_arr = array();
  25. foreach($diasArr as $dia){
  26. if(!$week_num)
  27. $final_arr[] = array(Vcalendar::DAY => getVcalDia($dia));
  28. else
  29. $final_arr[] = array($freq, Vcalendar::DAY => getVcalDia($dia));
  30. }
  31. return $final_arr;
  32. }
  33. function fechaICal($fecha, $hora="", $tz=""){
  34. $fecha = fechaGuion($fecha);
  35. if($hora!= ""){
  36. if($tz != ""){
  37. return str_replace('-', '', $fecha).'T'.str_replace(':', '', $hora)." ".$tz;
  38. }else{
  39. return str_replace('-', '', $fecha).'T'.str_replace(':', '', $hora);
  40. }
  41. }
  42. return str_replace('-', '', $fecha);
  43. }
  44. if(!isset($_GET["per"], $_GET["valida"]) ){
  45. echo "Error! La liga proporcionada no es válida.";
  46. exit();
  47. }
  48. if(isset($_GET["perf"])){
  49. $perfiles = trim(filter_input(INPUT_GET, "perf", FILTER_SANITIZE_STRING,array('flags' => FILTER_FLAG_STRIP_LOW)));//limpia texto
  50. }else{
  51. $perfiles = "4";
  52. }
  53. $periodo = filter_input(INPUT_GET, "per", FILTER_SANITIZE_NUMBER_INT);//limpia texto
  54. if(crypt($periodo.$perfiles, "ps") != $_GET["valida"]){
  55. echo "Error! La liga proporcionada no es válida.";
  56. exit();
  57. }
  58. // Obtiene fecha máxima y min
  59. $stmt = $pdo->prepare('Select * from fs_fechaimportante(:periodo, 3)');//periodo
  60. $stmt->bindParam(":periodo", $periodo);
  61. if(!$stmt->execute()){
  62. echo "Ocurrió un error al cargar las fechas del periodo";
  63. exit();
  64. }
  65. $fecha_rs = $stmt->fetch();
  66. $fecha_min = date('d/m/Y', strtotime($fecha_rs["FechaImportante_inicial"].' - 1 month '));
  67. $fecha_max = date('d/m/Y', strtotime($fecha_rs["FechaImportante_final"].' + 1 month '));
  68. $stmt->closeCursor();
  69. $stmt = null;
  70. //Obtiene datos de periodo
  71. $stmt = $pdo->prepare('Select * from fs_periodo(:periodo, NULL, NULL, true)');
  72. $stmt->bindParam(":periodo", $periodo);
  73. if(!$stmt->execute()){
  74. //print_r($stmt->errorInfo());
  75. echo "Ocurrió un error al cargar los datos del periodo";
  76. exit();
  77. }
  78. $periodo_rs = $stmt->fetch();
  79. $stmt->closeCursor();
  80. $eventos_display = array();//todos los eventos para exportar
  81. $stmt = $pdo->prepare('Select * from fs_calendarioevento(:per, :fecha_i, :fecha_f, :perf, false)');
  82. $stmt->bindParam(":per", $periodo);
  83. $stmt->bindParam(":fecha_i", $fecha_min);
  84. $stmt->bindParam(":fecha_f", $fecha_max);
  85. $stmt->bindParam(":perf", $perfiles);
  86. unset($perfiles);
  87. if(!$stmt->execute()){
  88. echo "Ocurrió un error al obtener los eventos.";
  89. exit();
  90. }
  91. $eventos_rs = $stmt->fetchAll();
  92. $stmt->closeCursor();
  93. //-------------------------
  94. //Obtiene fechas de periodo
  95. $stmt = $pdo->prepare('Select * from fs_periodo(:periodo, NULL, NULL, true)');
  96. $stmt->bindParam(":periodo", $periodo);
  97. if(!$stmt->execute()){
  98. echo "Ocurrió un error al cargar los datos del periodo";
  99. exit();
  100. }
  101. $periodo_rs = $stmt->fetch();
  102. $stmt->closeCursor();
  103. //Configuración de calendario
  104. $tz = "America/Mexico_City";
  105. $config = [
  106. Vcalendar::UNIQUE_ID => "IngenieriaLaSalle",
  107. Vcalendar::LANGUAGE=> "es",
  108. ];
  109. $calendar = Vcalendar::factory( $config )
  110. // required of some calendar software
  111. ->setMethod( Vcalendar::PUBLISH )
  112. ->setXprop( Vcalendar::X_WR_CALNAME, "Ingeniería La Salle ".date('Y,m', strtotime($periodo_rs["Periodo_fecha_inicial"])) )
  113. ->setXprop( Vcalendar::X_WR_CALDESC, "Calendario de Ingeniería ".$periodo_rs["Periodo_desc"] )
  114. ->setXprop( Vcalendar::X_WR_RELCALID,"3E26604A-50F4-4449-8B3E-E4F4932D05B5" )
  115. ->setXprop( Vcalendar::X_WR_TIMEZONE, $tz );
  116. $calendar->VtimezonePopulate( $tz );
  117. $fecha = $periodo_rs["Periodo_fecha_inicial"];
  118. $next_day = date('Y-m-d', strtotime($fecha.' + 1 day '));
  119. //Crea evento iCal
  120. $calendar->newVevent()
  121. ->setSequence( 0 )
  122. ->setSummary("Inicio de cursos")
  123. ->setDtstart($fecha, [ Vcalendar::VALUE => Vcalendar::DATE ])
  124. ->setDtend( $next_day, [ Vcalendar::VALUE => Vcalendar::DATE ]);
  125. $fecha = $periodo_rs["Periodo_fecha_final"];
  126. $next_day = date('Y-m-d', strtotime($fecha.' + 1 day '));
  127. //Crea evento iCal
  128. $calendar->newVevent()
  129. ->setSequence( 0 )
  130. ->setSummary("Fin de cursos")
  131. ->setDtstart($fecha, [ Vcalendar::VALUE => Vcalendar::DATE ])
  132. ->setDtend( $next_day, [ Vcalendar::VALUE => Vcalendar::DATE ]);
  133. $stmt = $pdo->prepare('Select * from fs_fechaimportante(:periodo, 2)');//extras
  134. $stmt->bindParam(":periodo", $periodo);
  135. if(!$stmt->execute()){
  136. echo "Ocurrió un error al cargar las fechas del periodo";
  137. exit();
  138. }
  139. $fecha_rs = $stmt->fetch();
  140. if( is_array($fecha_rs) && count($fecha_rs) > 0){
  141. $fecha = $fecha_rs["FechaImportante_inicial"];
  142. $next_day = date('Y-m-d', strtotime($fecha.' + 1 day '));
  143. //Crea evento iCal
  144. $calendar->newVevent()
  145. ->setSequence( 0 )
  146. ->setSummary("Exámenes Extraordinarios")
  147. ->setDtstart($fecha, [ Vcalendar::VALUE => Vcalendar::DATE ])
  148. ->setDtend( $next_day, [ Vcalendar::VALUE => Vcalendar::DATE ])
  149. ->setRrule(
  150. [
  151. Vcalendar::FREQ => Vcalendar::WEEKLY,
  152. Vcalendar::BYDAY => getDiasArray("1,2,3,4,5", false),
  153. Vcalendar::UNTIL => new DateTime($fecha_rs["FechaImportante_final"] ),
  154. ]
  155. );
  156. }
  157. $stmt->closeCursor();
  158. $stmt = null;
  159. //-------------------------
  160. //Recorre eventos
  161. foreach($eventos_rs as $evento){
  162. $id_db = $evento["CalendarioEvento_id"];
  163. $fecha = fechaGuion($evento["CalendarioEvento_fecha"]);
  164. //Crea evento iCal
  165. $icalEvent = $calendar->newVevent()
  166. ->setSequence( 0 )
  167. ->setSummary($evento["CalendarioEvento_titulo"]);
  168. if(trim($evento["CalendarioEvento_desc"]) != ""){
  169. $icalEvent->setDescription(trim($evento["CalendarioEvento_desc"]));
  170. }
  171. if($evento["CalendarioEvento_todo_dia"]){//sin hora
  172. $next_day = date('Y-m-d', strtotime($fecha.' + 1 day '));
  173. $icalEvent->setDtstart($fecha, [ Vcalendar::VALUE => Vcalendar::DATE ])
  174. ->setDtend( $next_day, [ Vcalendar::VALUE => Vcalendar::DATE ]);
  175. }else{//con horas
  176. $icalEvent->setDtstart( new DateTime( $fecha.' '.$evento["CalendarioEvento_hora_inicial"], new DateTimezone( $tz )))
  177. ->setDtend( new DateTime( $fecha.' '.$evento["CalendarioEvento_hora_final"], new DateTimezone( $tz )));
  178. }
  179. //-- Calcular posibles fechas e insertar fechas en objeto --
  180. switch($evento["CalendarioRepeticion_id"]){
  181. case 1: //diario
  182. $icalEvent->setRrule(
  183. [
  184. Vcalendar::FREQ => Vcalendar::DAILY,
  185. Vcalendar::UNTIL => new DateTime($evento["CalendarioReglas_fecha_final"] ),//no incluyente
  186. ]
  187. );
  188. break;
  189. case 2: //semanal
  190. $icalEvent->setRrule(
  191. [
  192. Vcalendar::FREQ => Vcalendar::WEEKLY,
  193. Vcalendar::BYDAY => getDiasArray($evento["CalendarioReglas_dias_str"], false),
  194. /*Vcalendar::BYDAY => [
  195. [ -1, Vcalendar::DAY => Vcalendar::WE ], // last WE
  196. [ 3, Vcalendar::DAY => Vcalendar::TH ], // third TH
  197. [ 5, Vcalendar::DAY => Vcalendar::FR ], // fifth FR
  198. [ Vcalendar::DAY => Vcalendar::MO ] // every MO
  199. ],*/
  200. Vcalendar::UNTIL => new DateTime($evento["CalendarioReglas_fecha_final"] ),//no incluyente
  201. ]
  202. );
  203. break;
  204. case 3://mensual
  205. $icalEvent->setRrule(
  206. [
  207. Vcalendar::FREQ => Vcalendar::MONTHLY,
  208. Vcalendar::BYDAY => getDiasArray($evento["CalendarioReglas_dias_str"], true, $evento["CalendarioReglas_semana"]),
  209. Vcalendar::UNTIL => new DateTime($evento["CalendarioReglas_fecha_final"] ),//no incluyente
  210. ]
  211. );
  212. break;
  213. }
  214. //Obtiene eventos modificados (fechas que cambiaron)
  215. $stmt = $pdo->prepare('Select * from fs_calendarioeventoeditado(:id)');
  216. $stmt->bindParam(":id", $id_db);
  217. if(!$stmt->execute()){
  218. echo "Ocurrió un error al obtener las fechas editadas.";
  219. exit();
  220. }
  221. //--Modifica fechas
  222. $eventosEditados_rs = $stmt->fetchAll();
  223. $stmt->closeCursor();
  224. foreach($eventosEditados_rs as $modif){
  225. $eventoEdit = $calendar->newVevent()
  226. ->setUid( $icalEvent->getUid())
  227. ->setSequence( 1 )
  228. ->setSummary( $icalEvent->getSummary() )
  229. ->setDescription($icalEvent->getDescription());
  230. if($evento["CalendarioEvento_todo_dia"]){//sin hora
  231. $next_day = date('Y-m-d', strtotime($modif["CalendarioEventoEditado_fecha_nueva"].' + 1 day '));
  232. $eventoEdit->setDtstart($modif["CalendarioEventoEditado_fecha_nueva"], [ Vcalendar::VALUE => Vcalendar::DATE ])
  233. ->setDtend( $next_day, [ Vcalendar::VALUE => Vcalendar::DATE ])
  234. ->setRecurrenceid( $modif["CalendarioEventoEditado_fecha_origen"], [ Vcalendar::VALUE => Vcalendar::DATE ] );//obtiene fecha que se cambia;
  235. }else{//con horas
  236. $eventoEdit->setDtstart(
  237. new DateTime(fechaICal($modif["CalendarioEventoEditado_fecha_nueva"], $modif["CalendarioEventoEditado_hora_inicial"]), new DateTimezone( $tz ))
  238. )
  239. ->setDtend(
  240. new DateTime(fechaICal($modif["CalendarioEventoEditado_fecha_nueva"], $modif["CalendarioEventoEditado_hora_final"]), new DateTimezone( $tz ))
  241. )
  242. ->setRecurrenceid( fechaICal($modif["CalendarioEventoEditado_fecha_origen"], $evento["CalendarioEvento_hora_inicial"],$tz) );//obtiene fecha que se cambia;
  243. }
  244. }
  245. //--Quitar fechas de excepción
  246. if($evento["CalendarioEvento_excepcion_str"] != ""){
  247. foreach(explode(",", $evento["CalendarioEvento_excepcion_str"]) as $ex){
  248. $exArr = explode(" ", $ex);
  249. if($evento["CalendarioEvento_todo_dia"]){//sin hora
  250. $icalEvent->setExdate( fechaICal($exArr[0]), [ Vcalendar::VALUE => Vcalendar::DATE ] );
  251. }else{
  252. $icalEvent->setExdate( $ex, new DateTimezone( $tz ) );
  253. }
  254. }
  255. }
  256. }//foreach
  257. unset($eventos_rs);
  258. $data = "[ REMOTE_ADDR = ".$_SERVER['REMOTE_ADDR']." ]";
  259. $data .= "[ QUERY_STRING = ".$_SERVER['QUERY_STRING']." ]";
  260. $logObj = new LogICal();
  261. $logObj->appendLog($data);
  262. echo $calendar->vtimezonePopulate()->createCalendar();