Ver Mensaje Individual
  #1 (permalink)  
Antiguo 08/07/2013, 11:13
Avatar de repara2
repara2
 
Fecha de Ingreso: septiembre-2010
Ubicación: München
Mensajes: 2.445
Antigüedad: 10 años, 5 meses
Puntos: 331
[APORTE] Class Calendar: despliega calendario HTML con registros

Despliega un calendario en base a los parámetros mes y ańo. Muestra registros para los días en base a cualquier condición que se defina:

. Despliega calendario HTML / CSS.
. Barra de navegación opcional (adelante / atrás)
. Nombre del mes / ańo opcional.
. Posibilidad de desplegar registros.
. Para hacer el código reusable, se incluye en el ejemplo una class extendida en la cual se sobreescribe el método getHtmlContentForDay().
. getHtmlContentForDay() contiene el código que mostrará los registros para cada día, dado que cada calendario / set de datos es diferente,
es necesario implementar este método en la class base.
. Si la visibilidad de algún método está mal por favor comentar.

Implementación:

0. Un CSS (cualquier forero con paciencia puede mejorarlo).

No entra en los 10000 chars pero puedo enviarlo.

1. La class base:

Código PHP:
Ver original
  1. <?php
  2. class Calendar {
  3.  
  4. //Url para los links en la barra de navegación, por defecto apuntan a $_SERVER['PHP_SELF']
  5. private $url = '';
  6. //Mes
  7. private $month = 0;
  8. //Ańo
  9. private $year = 0;
  10. //Dias en el mes
  11. private $days_in_month = 0;
  12. //Datos a mostrar
  13. private $data = null;
  14. //Links atrás / adelante
  15. private $navigationBarPosition = false;
  16. //Mostrar ańo mes en la barra superior
  17. private $showDateHeader = false;
  18. //Encabezados
  19. public $days_headings = array (
  20. 'Domingo',
  21. 'Lunes',
  22. 'Martes',
  23. 'Miercoles',
  24. 'Jueves',
  25. 'Viernes',
  26. 'Sabado'
  27. );
  28.  
  29. //Constructor, nada para comentar
  30. public function __construct($month, $year) {
  31. // Var asignation
  32. $this->month = $month;
  33. $this->year = $year;
  34. $this->days_in_month = $this->getDaysInMonth ();
  35. $this->running_day = $this->getDayOfWeek ();
  36. }
  37.  
  38. //Output del calendario en html
  39. public function renderHTML() {
  40. //init
  41. $output = "";
  42. //Star table
  43. $output = '<table cellpadding="0" cellspacing="0" class="calendar">';
  44.  
  45. //Add the navigation bar
  46. $navBarPosition = $this->getNavigationBarPosition();
  47. if($navBarPosition == 'top' || $navBarPosition == 'both')
  48. $output .= $this->getNavigationBarHTML();
  49. //Add header
  50. if($this->showDateHeader) $output .= $this->getHeaderHTML();
  51. //First row with days names
  52. $output .= $this->getDaysHeadingsHTML ();
  53. //Empty day at the beginning of the month
  54. $output .= $this->getBlankDaysHTML ();
  55. //Rest of the days
  56. $output .= $this->getNonBlankDaysHTML ();
  57.  
  58. //Add navigation bar
  59. if($navBarPosition == 'bottom' || $navBarPosition == 'both')
  60. $output .= $this->getNavigationBarHTML();
  61. return $output;
  62.  
  63. //End
  64. $output .="</table>";
  65.  
  66. }
  67.  
  68. protected function setUrl($value)
  69. {
  70. $this->url = $value;
  71. return true;
  72. }
  73.  
  74. //Posicion de la barra de navegación
  75. public function setNavigationBarPosition($where) {
  76. //Only allowed values
  77. $allow = array('top', 'bottom', 'both');
  78. if(!in_array($where, $allow))
  79. throw new Exception ('Navigation bar position can only be top, bottom or both.');
  80. $this->navigationBarPosition = $where;
  81. return $this->navigationBarPosition;
  82. }
  83.  
  84. private function setDaysHeadings(array $names)
  85. {
  86. $this->days_headings = $names;
  87. return true;
  88. }
  89.  
  90. //Muestra ańo / mes en la barra
  91. public function setShowDateHeader($value = false)
  92. {
  93. $this->showDateHeader = $value;
  94. return $this->showDateHeader;
  95. }
  96.  
  97. public function setData($data) {
  98.  
  99. $this->data = $data;
  100. return true;
  101. }
  102.  
  103. //////Getters
  104.  
  105. protected function getUrl()
  106. {
  107. return $this->url;
  108. }
  109.  
  110. public function getData(){
  111. return $this->data;
  112. }
  113.  
  114. //Dia de la semana, se utilizará para crear el HTML
  115. protected function getDayOfWeek() {
  116. // w Numeric representation of the day of the week 0 (for Sunday)
  117. // through 6 (for Saturday)
  118. return date ( 'w', mktime ( 0, 0, 0, $this->month, 1, $this->year ) );
  119. }
  120.  
  121. protected function getDaysHeadings() {
  122. return $this->days_headings;
  123. }
  124.  
  125. //Cabezeras
  126. private function getDaysHeadingsHTML() {
  127. $output = "<tr class='calendar-row'>";
  128. foreach ( $this->days_headings as $day_name ) {
  129. $output .= "<td class='calendar-day-head'>{$day_name}</td>";
  130. }
  131. $output .= "</tr>";
  132. return $output;
  133. }
  134.  
  135. //Celdas vacias para los ultimos dias del mes anterior
  136. private function getBlankDaysHTML() {
  137. $output = "<tr>";
  138. /* print "blank" days until the first of the current week */
  139. for($x = 0; $x < $this->running_day; $x ++) {
  140. $output .= "<td class='calendar-day-np'></td>";
  141. $this->days_in_this_week ++;
  142. }
  143. return $output;
  144. }
  145.  
  146. //Mostrar los registros, este método se sobreescribe desde una classe extendida
  147. protected function getHtmlContentForDay($day_number)
  148. {
  149. }
  150.  
  151. //Dias con contenido
  152. private function getNonBlankDaysHTML() {
  153. // init
  154. $output = "";
  155. $day_counter = 1;
  156. // $list_day contains the number of the day that is being displayed
  157. for($list_day = 1; $list_day <= $this->days_in_month; $list_day ++) {
  158. $output .= "<td class='calendar-day'>";
  159. // add in the day number
  160. $output .= "<div class='day-number'>{$list_day}</div>";
  161. // The content of the day
  162. $output .= $this->getHtmlContentForDay($list_day);
  163. $output .= "</td>";
  164. // End of the week, close the row
  165. if ($this->running_day == 6) {
  166. $output .= '</tr>';
  167.  
  168. // Go on with days
  169. if (($day_counter) != $this->days_in_month) {
  170.  
  171. $output .= "<tr class='calendar-row'>";
  172. }
  173. $this->running_day = - 1;
  174. $this->days_in_this_week = 0;
  175. }
  176. //Next day
  177. $this->days_in_this_week ++;
  178. //Actual day
  179. $this->running_day ++;
  180. $day_counter ++;
  181. } // for($list_day = 1; $list_day <= $this->days_in_month; $list_day++)
  182.  
  183. //The rest of the days, after month is over, that will be printed blank
  184. if ($this->days_in_this_week < 8) {
  185. for($x = 1; $x <= (8 - $this->days_in_this_week); $x ++) {
  186. $output .= "<td class='calendar-day-np'></td>";
  187. }
  188. }
  189.  
  190. // final row
  191. $output .= '</tr>';
  192.  
  193. return $output;
  194. }
  195.  
  196. //Cabecera HTML
  197. private function getHeaderHTML()
  198. {
  199. //If no nav bar is going to be shown , then output this.
  200. if(!$this->getNavigationBarPosition())
  201. {
  202. $header = date ( 'F', mktime ( 0, 0, 0, $this->getMonth(), 1, $this->getYear() ) ) . ', ' . $this->getYear();
  203. $output = "<tr class='nav-bar'>";
  204. $output .= "<td colspan='7' align='center'>{$header}</td>";
  205. $output .= "</tr>";
  206. return $output;
  207. }
  208.  
  209. }
  210.  
  211. //Barra de navegación
  212. private function getNavigationBarHTML()
  213. {
  214. //Get nexts and previous months and years
  215. $next = $this->getNextMonth();
  216. $previous = $this->getPreviousMonth();
  217. $header = '';
  218. //If show headers is on, put it there
  219. if($this->getShowDateHeader())
  220. $header = date ( 'F', mktime ( 0, 0, 0, $this->getMonth(), 1, $this->getYear() ) ) . ', ' . $this->getYear();
  221.  
  222. $output = "<tr class='nav-bar'><td align='center'><a href='{$this->getUrl()}?calendar_year={$previous['year']}&calendar_month={$previous['month']}'>Previous</a></td>";
  223. $output .= "<td colspan='5' align='center'>{$header}</td>";
  224. $output .= "<td align='center'><a href='{$this->getUrl()}?calendar_year={$next['year']}&calendar_month={$next['month']}''>Next</a></td></tr>";
  225. return $output;
  226. }
  227.  
  228.  
  229. private function getNavigationBarPosition()
  230. {
  231. return $this->navigationBarPosition;
  232. }
  233.  
  234. private function getShowDateHeader()
  235. {
  236. return $this->showDateHeader;
  237. }
  238.  
  239. protected function getMonth() {
  240. return $this->month;
  241. }
  242.  
  243. protected function getYear()
  244. {
  245. return $this->year;
  246. }
  247.  
  248. //Ańos y meses anteriores y posteriores
  249. private function getNextMonth() {
  250. //Get next month
  251. $month = $this->getMonth() + 1;
  252. $year = $this->getYear();
  253.  
  254. if($month < 1)
  255. {
  256. $month = 12;
  257. $year--;
  258. }
  259. if($month >= 13)
  260. {
  261. $month = 1;
  262. $year++;
  263. }
  264. if($month < 10) $month = '0' . $month;
  265. return array('month' => $month, 'year' => $year);
  266. }
  267.  
  268.  
  269. private function getPreviousMonth() {
  270. //Get next month
  271. $month = $this->getMonth() - 1;
  272. $year = $this->getYear();
  273.  
  274. if($month < 1)
  275. {
  276. $month = 12;
  277. $year--;
  278. }
  279. if($month >= 13)
  280. {
  281. $month = 1;
  282. $year++;
  283. }
  284. if($month < 10) $month = '0' . $month;
  285. return array('month' => $month, 'year' => $year);
  286. }
  287.  
  288. //Dias del mes
  289. private function getDaysInMonth() {
  290. return date ( 't', mktime ( 0, 0, 0, $this->month, 1, $this->year ) );
  291. }
  292. }
  293.  
  294. ?>

2. Una clase extendida

Código PHP:
Ver original
  1. <?php
  2. class MyCalendar Extends Calendar
  3. {
  4. /**
  5. * Este es el único método que en principio debe extenderse.
  6. * La razón es que cada calendario particular mostrará registros
  7. * en base a distintos criterio.
  8. * @see Calendar::getHtmlContentForDay()
  9. */
  10. public function getHtmlContentForDay($day_number)
  11. {
  12. //En mi ejemplo, los registros tienen un campo date que uso para saber si debo mostrar el registro o no
  13. //Inicializar variables
  14. $output = '';
  15. foreach($this->getData() as $index => $values)
  16. {
  17. //Si el dia de inicio es igual a $day_number, muestro el registro con un link
  18. if($values['date'] == $this->getYear() .'-'. $this->getMonth() .'-'. $day_number)
  19. {
  20. $output .= "<a href='#'>[{$index}] ".substr($values['note'], 0, 10)."...</a><br>";
  21. }
  22. }
  23.  
  24. return $output;
  25.  
  26. }
  27. }
  28. ?>
3. Un script de ejemplo
Código PHP:
Ver original
  1. <link rel="stylesheet" media="all" href="style.css">
  2. <?php
  3. //Incluir classes
  4. include 'class.Calendar.php';
  5. include 'class.MyCalendar.php';
  6.  
  7.  
  8. //Datos de prueba
  9. $data = array(
  10. 0 => array('id' => 3434, 'date' => '2013-06-24', 'note' => 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..'),
  11. 1 => array('id' => 4532, 'date' => '2013-06-25', 'note' => 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..'),
  12. 2 => array('id' => 3355, 'date' => '2013-06-28', 'note' => 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..'),
  13. 3 => array('id' => 9876, 'date' => '2013-06-28', 'note' => 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit..');
  14.  
  15. //Mes y ańo, si no vienen por get, utilizo los actuales
  16. $month = isset ( $_GET ['calendar_month'] ) ? $_GET ['calendar_month'] : date ( 'm' );
  17. $year = isset ( $_GET ['calendar_year'] ) ? $_GET ['calendar_year'] : date ( 'Y' );
  18. //Inicializar objeto
  19. $cal = new MyCalendar ( $month, $year );
  20. //Con barra de navegación arriba
  21. $cal->setNavigationBarPosition ( 'top' );
  22. //Mostrar el mes y el ańo
  23. $cal->setShowDateHeader ( true );
  24. //Pasar los datos a mostrar
  25. $cal->setData($data);
  26. $out = $cal->renderHTML ();
  27. echo $out;
  28. ?>

Saludos y espero que a alguien le sirva, [email protected]
__________________
Fere libenter homines, id quod volunt, credunt.