Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Yii

Construyendo tu Startup con PHP: Agendando la Disponibilidad y las Opciones

by
Read Time:14 minsLanguages:
This post is part of a series called Building Your Startup With PHP.
Building Your Startup With PHP: Scheduling a Meeting
Using the Mailgun Store(): A Temporary Mailbox for Your App's Incoming Email

Spanish (Español) translation by David Castrillón (you can also view the original English article)

Final product imageFinal product imageFinal product image
What You'll Be Creating

Este tutorial es parte de la serie Contruyendo tu Startup con PHP en Tuts+. En estas series, te estoy guiando a través del lanzamiento de una startup desde el concepto a la realidad usando mi aplicación Meeting Planner como un ejemplo de la vida real. A cada paso a lo largo del camino, liberaré el código del Meeting Planner como ejemplos de código abierto de los cuales puedes aprender. También direccionaré los temas relacionados a medida que surjan.

Todo el código del Meeting Planner está escrito en el Framework para PHP Yii2 . Si quisieras saber más sobre Yii2, revisa mis series paralelas Programando con Yii2 en Tuts+ También puede que quieras revisar el sitio de mi base de conocimiento para las preguntas sobre Yii2, The Yii2 Developer Exchange.

El código para la funcionalidad de la agenda de la reunión se extiende por al menos cuatro capítulos. Este es el segundo de esos cuatro episodios, los cuales se enfocan en agregar AJAX a la página de agendamiento lpara permitirle a los usuarios establecer su disponibilidad y elegir sitios, fechas y horas. Si te perdiste los tutoriales previos sobre agendar una reunión, por favor regresa y leélos antes de continuar.

En el siguiente tutorial, cubriremos la entrega de la solicitud de reunión por correo. Volveremos más tarde para optimizar y pulir la interfaz de usuario, debido a que es crítica para el éxito de este producto.

Mostrando la Disponibilidad desde la Base de Datos

The Meeting Scheduling View PageThe Meeting Scheduling View PageThe Meeting Scheduling View Page

La vista del calendario de reuniones era relativamente complejo de codificar. La presentación visual de las columnas de la tabla no se relacionan directamente con la forma en que almacenamos los datos relacionados en nuestra base de datos y el esquema. Por suerte, cada reunión no tiene un gran conjunto de datos de opciones de lugar y fecha, así que esto no presenta un problema de interpretación.

En nuestro esquema, la disponibilidad de lugar para los organizadores y participantes (es decir, si un lugar es aceptable para esta reunión) se almacena en la tabla MeetingPlaceChoice. Usando nuestro modelo relacional, cada encuentro tiene muchos MeetingPlaces los cuales tienen muchos MeetingPlaceChoices.

No se debe confundir la tabla MeetingPlaceChoice con la selección final de un lugar guardado en MeetingPlace -> status

La tabla que se muestra arriba aparecerá diferentemente cuando el organizador la vea:

  • Lugar 1 | Organizador | Participante | MeetingPlace.choice
  • Lugar 2 | Organizador | Participante | MeetingPlace.choice

Desde cuando el participante la vea:

  • Lugar 1 | Participante | Organizador | (tal vez pueda hacer MeetingPlace.choice)
  • Lugar 2 | Participante | Organizador | (tal vez puede hacer MeetingPlace.choice)

Ahora vamos a discutir cómo implementar estas tablas en las vistas.

Mostrando una Tabla con Bootstrap

Por ahora, decidí ver cada área, por ejemplo, lugar o fecha y hora, en su propio panel de Bootstrap con tablas.

En \frontend\views\meeting\view.php, verás la inclusión para el panel de lugares como este:

Aquí está una parte del archivo de vista panel meeting-place. Esto configura la cuadrícula de la tabla e incluye un widget de vista de lista para mostrar las filas:

Echemos un vistazo a la vista de lista meeting-place.

Mostrar las filas con Widgets de Interruptores de Bootstrap

La vista de lista de  Yii mostrará una fila de datos para cada lugar. El código funciona casi idénticamente para fechas.

Estoy usando el Widget Interruptor de Entrada de Krajee para Yii2 para el Interruptor de Bootstrap a cambio de las aburridas casilas de verificación y los cuadros combinados:

Examples of The Bootstrap Switch InputExamples of The Bootstrap Switch InputExamples of The Bootstrap Switch Input

Me gusta la forma en que la opción tri-estado nos permite mostrarle a los participantes un estado único antes de que ellos hagan una selección; también nos permite mostrarle al organizador que el participante aún no ha hecho una selección.

Vamos a caminar a través del código columna por columna. Aquí está el panel del Lugar y la tabla que estamos implementando:

The Place PanelThe Place PanelThe Place Panel

La Columna Lugar

En la primera columna, utilizo el enlace ayudante en Html para Yii para enlazar el nombre del lugar a su propia página de vista, observa cómo estamos utilizando el slug del lugar.

La Columna Organizador

Para encontrar selecciones del organizador, recorremos la matriz de MeetingPlaceChoices, emparejando user_id a meeting-> owner_id:

Para la selección de tu disponibilidad en un lugar específico, estamos usando el modo de casilla de verificación de la entrada, es decir, este lugar funciona para ti (on) o no (off).

La propiedad value establece el interruptor en la carga. El id correspondiente al MeetingPlaceChoice -> id es usado por AJAX abajo para identificar este interruptor en particular.

También puedes notar que estamos utilizando glyphicons para sí y no en lugar de etiquetas.

La Columna de Participantes

El código para el participante implementa interruptores de tres estados. es decir, este lugar funciona para usted (on), no (off) o usted no ha indicado todavía (indeterminado):

Cuando añadimos soporte para las reuniones que permiten a los participantes sugerir lugares y fechas, vamos a añadir widgets de tres estados a la columna del organizador también.

Mostrando Elegir Lugar y el Interruptor de Fechas

Si el organizador está viendo la reunión, lo dejamos elegir la ubicación final de la reunión y la fecha. Pronto, también vamos a añadir soporte para que los participantes también elijan las reuniones.

En este caso, el usuario realiza una selección a través de filas (eligiendo uno de los lugares mencionados). Esto requiere que utilicemos la entrada en el modo de botón de radio. Para los eventos de AJAX en los selectores, podemos escuchar sólo la propiedad name — no se necesita ningún id, porque hay solamente una selección posible para el panel.

También quería que el interruptor de selección parezca diferente a los interruptores de disponibilidad, por lo que los hice más amplios y he utilizado diferentes colores.

Ahora te guiaré a través de cómo se implementó el soporte de AJAX para todos estos selectores.

Implementando el soporte de AJAX

Obviamente, quería evitar que los usuarios tengan que guardar los cambios en estos formularios. En cambio, quería que los interruptores cambiaran de estado via AJAX sin una actualización de la página.

El código se divide entre configuración de detectores de eventos para reaccionar ante los cambios de estado y acciones de control para registrar los cambios en nuestra base de datos. También es ligeramente diferente para los interruptores de la casilla de verificación versus los casillas de radio.

Contruyendo los Detectores de Eventos

Creamos detectores de eventos para ejecutar código cuando se cambia el estado de un botón. El detector de evento es código JavaScript generado por PHP en la vista de panel (para toda la tabla de opciones).

Aquí está el código en la parte inferior de frontend\views\meeting-place\_panel.php:

Por cierto, si alguien me puede decir el nombre del atajo del bloque JS para PHP, publícalo en la sección de comentarios. Me gustaría saber. Algunas cosas son difíciles de buscar.

La función registerJs en Yii representa la secuencia de comandos para un determinado $position en la página. En este caso, es un evento preparado.

El código anterior establece los detectores de eventos para todos los botones de radio selectores de lugares, en todos los lugares, por la propiedad name. El valor objetivo del evento representará el id del lugar de reunión elegido. Hablaré más acerca de la función de AJAX en un momento.

En otras palabras, los eventos del interruptor de radio responden al organizador (generalmente) eligiendo un lugar o fecha para finalizar la reunión, transmitiendo el id del lugar de encuentro o el id de la hora de encuentro.

Aquí está el código para detectar los cambios en la disponibilidad con el interruptor de entrada de las casillas de selección.

El detector está configurado para todas los nombres de las propiedades de meeting-place-choice pero debe pasar el id para indicar exactamente cuál MeetingPlaceChoice está siendo cambiado.

Para aclarar, el detector de eventos para el interruptor de la entrada de las casillas de selección le permite a los usuarios decir que están disponibles o no para cierto lugar o fecha. Ellos envían el id meeting-place-choice o el id de meeting-place-time

Ahora, echemos un vistazo más de cerca a cómo los eventos de AJAX llaman nuestras acciones de control basadas en PHP para grabar el estado de los cambios en la base de datos.

Contruyendo las Acciones del Controlador

Aquí está de nuevo el código para el botón selector de radio del meeting-place:

La URL indica la ruta a la acción de elegir del controlador del MeetingPLace

El $id de entrada representa el meeting_id. El valor representa el id MeetingPlace elegido.El STATUS_SELECTED indica que el lugar ha sido elegido, mientras que STATUS_SUGGESTED indica sólo que ha sido sugerido (no elegido).

Este código recorre los lugares de la reunión de cada reunión y actualiza el estado del lugar seleccionado.

Veamos el código para el interruptor de entrada de casillas otra vez, que determina si alguien está disponible para un lugar específico:

Estos eventos el conjunto de acciones del controlador MeetingPlaceChoice con una cadena de texto cuyos sufijos contienen el id del MeetingPlaceChoice que necesita ser actualizado:

Asegurando las Solicitudes de AJAX

Por razones de seguridad, tenemos que verificar que la solicitud AJAX haya sido iniciada por el usuario real que puede hacer estos cambios. Este código hace eso:

y

Sin estos controles, sería fácil para un hacker escribir un script que modifique la configuración de sesión para cualquiera y quien sea.

El código de AJAX para indicar la disponibilidad de fechas y tomar decisiones es casi idéntico.

Soportando las Configuraciones de Disponibilidad

Con el fin de darle soporte a las características anteriores, también necesitamos agregar código a las tablas MeetingPlaceChoice y MeetingTimeChoice cuando los participantes, lugares y fechas sean agregadas.  Para esto, usamos Yii's afterSave events.

Cuando se agrega un participante, necesitamos agregar las filas MeetingPlaceChoice para cada MeetingPlace y nuevas filas MeetingTimeChoice para cada MeetingTime. Aquí está el código en el modelo Participar que maneja esto automáticamente por nosotros:

Cuando se agrega un nuevo lugar, se necesitan nuevos MeetingPlaceChoices para cada participante:

De manera similar cuando una nueva fecha se agrega, se necesitan nuevas entradas para MeetingTimeChoice por cada participante:

Se supone que cuando el organizador de la reunión agrega un lugar o fecha, que trabaja para ellos en primer lugar.

Elegir el Lugar Final, la fecha y la hora

Una vez que haya al menos uno de los participantes invitado, un lugar y una hora, el organizador de la reunión puede finalizar la reunión. También permitiremos en el futuro, que los participantes finalicen la reunión.

Mientras que este código cambiará un poco a futuro, hay una función en el modelo de reunión que le dice a la vista si se va a habilitar el botón Finalize:

Aquí está el código de la vista:

Una vez que se finaliza la reunión, el MeetingPlanner cambiará de modo de apoyo en la planificación a facilitar la asistencia de los participantes a través de una variedad de características interesantes que cubriremos en futuros tutoriales.

Problemas de Código que Encontré

Quería comentar algunos problemas que tuve al escribir el código para esta sección relativamente intrincada.

Tipos de AJAX

Los estados SwitchInput fueron enviados via Javascript como booleanos, es decir, verdadero o falso (true or false), pero necesité convertirlos a valores enteros para que se transmitieran exitósamente a través de AJAZ a los controladores.

Superposición de IDs

Los Id´s numéricos de los widgets MeetingPlaceChoice y MeetingTimeChoice se superpusieron. Me tomo un tiempo darme cuenta porqué los widgets del interruptor dejaban de rederizar de manera correcta cuando agregaba la capacidad de elegir. Debido a que habían ids sobrepuestos, los widgets del interruptor rederizaban sólo el primer objeto.

Fué necesario agregar prefijos tales como mpc- o mtc- a los ids y sacarlos en las acciones del controlador.

Aquí es donde sacamos esos prefijos en el controlador para cargar el modelo:

Estado de Carga del Botón del Interruptor de Radio

Me tomó un tiempo descubrir cómo establecer el estado de carga inicial y el valor para el widget de entrada del interruptor en el modo de botón de radio. No había documentación que mostrara cómo hacer esto. Finalmente escribí un manual para los demás: Configurando el Estado del Widget del Interruptor de Botón de Radio.

¿Qué sigue?

Ahora que todo lo relacionado con AJAX está en su lugar y funcionando, es momento de finalizar algunas de las áreas que permanecen de la vista de la planeación de la reunión para preparar las invitaciones que han sido enviadas y necesitan ser vistas por los participantes.

Por ejemplo, la vista de la agenda de la reunión que ven los participantes será diferente en la disposición del organizador, y variará dependiendo de los poderes que el organizador haya delegado.

Por ejemplo, las columnas tú y ellos tendrán que cambiar de su actual implementación. Se necesitará ampliar el modelo Meeting en la configuración que determina si los participantes pueden sugerir lugares y horarios y finalizar la reunión.

Más a futuro, puedo querer permitir múltiples participantes y necesitar mostrar más columnas de disponibilidad para la vista de organización, esta funcionalidad no es parte de nuestro mínimo producto viable (MVP).

También necesito terminar la implementación del MeetingLog que registrará cada cambio realizado en una reunión durante el proceso de planificación. Esto le dará una especie de historial de planificación para cada reunión. Puedo usar los eventos afterSave() para esto, también.

Atento a los próximos tutoriales en nuestra serie Construyendo tu Startup con PHP, una lista de los próximos temas ahora está publicada en nuestra Tabla de Contenidos.

Ten la libertad de agregar tus preguntas y comentarios abajo; Generalmente participo en los debates. También puedes encontrarme en Twitter @reifman o envíarme un correo electrónico directamente.

Enlaces Relacionados

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.