array( 'activar', 'cancelar', 'establecerPassword', 'recuperar', 'registrar', 'registrarAgente', ), 'users' => array('*'), ), array('allow', 'actions' => array( 'cambiarPassword' ,'delete', 'modificar' ), 'users' => array('@'), ), array('deny', 'users' => array('*'), ), ); } /** * @brief Realiza el registro de un usuario. * - Coordinador => a través de la página de entrada (formulario) * - Agente => a través del formulario de añadir agente en el equipo (AJAX) */ public function actionRegistrar() { // ¿Coordinador o agente? if (isset($_POST['ajax']) && $_POST['ajax'] === 'registro-coordinador-form-entrada') { $this->_registrarCoordinador(); } elseif (isset($_POST['FormularioRegistrarAgente'])) { $this->_registrarAgente(); } else $this->redirect(Yii::app()->params['frontpage']); } /** * @brief Realiza la activación de un usuario (coordinadores y agentes). * - Coordinador => a través del enlace recibido por email * - Agente => a través del formulario de la página de entrada (AJAX) */ public function actionActivar() { // ¿Coordinador o agente? if (isset($_POST['ajax']) && $_POST['ajax'] === 'activar-agente-form-entrada') { $this->_activarAgente(); } elseif (isset($_GET['email']) && isset($_GET['key'])) { $this->_activarCoordinador(); } else $this->redirect(Yii::app()->params['frontpage']); } /** * @brief Realiza la recuperación de la contraseña de un usuario. * Este método es llamado por AJAX desde la página de entrada. */ public function actionRecuperar() { Yii::trace('Recuperar la cuenta del usuario', 'application.controllers.UsuarioController'); $formulario = new FormularioEntradaRecuperarPassword; if (isset($_POST['ajax']) && $_POST['ajax'] === 'recuperar-form-entrada') { $formulario->email = $_POST['FormularioRecuperar_email']; if (!$formulario->validate()) $this->performAjaxValidationMessage($formulario); $usuario = Usuario::model()->findByAttributes(array('email' => $formulario->email)); if ($usuario) { if (EMail::enviarRecuperacion($usuario->email, $usuario->clave_seguridad)) { Yii::trace('Correo para recuperar la cuenta enviado', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Recuperación de su cuenta en PROFIND'), Yii::t('profind', 'En unos momentos recibirá un un correo con los pasos necesarios para recuperar su cuenta en PROFIND.') ); } else { Yii::trace('Error al enviar el correo para recuperar la cuenta', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Recuperación de su cuenta en PROFIND'), Yii::t('profind', 'No se ha podido enviar el correo para recuperar su cuenta a la dirección indicada.') ); } } else { Yii::trace('No se encontrado un usuario con el email indicado', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('failure', Yii::t('profind', 'Recuperación de su cuenta en PROFIND'), Yii::t('profind', 'No se encontrado un usuario con el email indicado.') ); } } $this->redirect(Yii::app()->params['frontpage']); } /** * @brief Cambia la contraseña de un usuario (coordinador / agente). * Esta acción se llama desde la ficha de un usuario. * Envia un email de notificación al usuario. * @param integer ID del usuario */ public function actionCambiarPassword($id) { Yii::trace('Cambiar la password del usuario', 'application.controllers.UsuarioController'); if ($id != Yii::app()->user->id) throw new CHttpException(401, Yii::t('profind', 'Acceso no autorizado.')); $formulario = new FormularioCambiarPassword; $this->performAjaxValidation($formulario, 'cambiar-password-form'); if (isset($_POST['FormularioCambiarPassword'])) { $formulario->attributes = $_POST['FormularioCambiarPassword']; if ($formulario->validate()) { $usuario = $this->loadModel($id); if ($this->_cambiarPassword($usuario, $formulario->password)) { Yii::trace('Se ha modificado la password', 'application.controllers.UsuarioController'); EMail::enviarNotificacionCambioPassword($usuario->email, $usuario->clave_seguridad); Yii::app()->user->setFlash('success', Yii::t('profind', 'Se ha modificado la contraseña')); $this->redirect(array('usuario/modificar', 'id' => $id)); } } Yii::app()->user->setFlash('error', Yii::t('profind', 'No se ha podido modificar la contraseña')); Yii::app()->user->setFlash('error', CHtml::errorSummary($formulario)); } $this->render('cambiar_password', array('formulario' => $formulario)); } /** * @brief Establece la contraseña del usuario desde la página de entrada. * Este método es llamado por AJAX desde la página de entrada cuando se * olvida la contraseña. * Envia un email de notificación al usuario informando del cambio. */ public function actionEstablecerPassword() { Yii::trace('Estableciendo password para el usuario', 'application.controllers.UsuarioController'); $formulario = new FormularioEntradaCambiarPassword; if (isset($_POST['ajax']) && $_POST['ajax'] === 'cambiar-password-form-entrada') { $formulario->key = $_POST['FormularioCambiarPassword_key']; $formulario->email = $_POST['FormularioCambiarPassword_email']; $formulario->password = $_POST['FormularioCambiarPassword_password']; $formulario->passwordRepetida = $_POST['FormularioCambiarPassword_password_repetida']; if (!$formulario->validate()) $this->performAjaxValidationMessage($formulario); $usuario = Usuario::model()->findByAttributes(array('email' => $formulario->email)); if ($this->_cambiarPassword($usuario, $formulario->password)) { Yii::trace('Se ha modificado la password', 'application.controllers.UsuarioController'); if (EMail::enviarNotificacionCambioPassword($usuario->email, $usuario->clave_seguridad)) { $this->performAjaxStatusMessage('success', Yii::t('profind', 'Password modificada'), Yii::t('profind', 'Se ha modificado su password en PROFIND.') ); } else { Yii::trace('Error al enviar el correo para informar del cambio', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Password modificada'), Yii::t('profind', 'Se ha modificado su password en PROFIND pero no se ha podido enviar el correo informando del cambio.') ); } } else { Yii::trace('Error al cambiar la password del usuario', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Recuperar password'), Yii::t('profind', 'No se ha podido restablecer la password de su cuenta. Inténtelo más tarde o contacto con PROFIND.') ); } } $this->redirect(Yii::app()->params['frontpage']); } /** * @brief Realiza el registro de un usuario a partir de los datos introducidos * en el formulario de la página de entrada. * También envía un email al usuario para que confirme su cuenta. */ protected function _registrarCoordinador() { Yii::trace('Registrando coordinador', 'application.controllers.UsuarioController'); $formulario = new FormularioRegistroCoordinador; $resultado = array(); $formulario->email = $_POST['FormularioRegistro_email']; $formulario->password = $_POST['FormularioRegistro_password']; $formulario->password2 = $_POST['FormularioRegistro_password2']; if (!$formulario->validate()) $this->performAjaxValidationMessage($formulario); // Crear el usuario $nuevo_usuario = new Usuario('registrar'); $nuevo_usuario->tipo = Usuario::TIPO_USUARIO_COORDINADOR; $nuevo_usuario->email = $formulario->email; $nuevo_usuario->password = $nuevo_usuario->encryptPassword($formulario->password); $nuevo_usuario->estado = Usuario::ESTADO_NOACTIVO; $nuevo_usuario->clave_seguridad = $nuevo_usuario->encryptSecureKey(microtime() . $nuevo_usuario->password); // Crear la subscripción $nueva_subscripcion = new Subscripcion('registrar'); $nueva_subscripcion->estado = Subscripcion::ESTADO_ACTIVO; $nueva_subscripcion->id_producto = $this->_darIdProductoBasico(); // Crear la empresa $nueva_empresa = new Empresa('registrar'); // Guardar los datos $transaccion = Yii::app()->db->beginTransaction(); try { Yii::trace('Guardando la nueva empresa', 'application.controllers.UsuarioController'); if (!$nueva_empresa->save()) throw new CException('Error al guardar la empresa'); Yii::trace('Guardando el nuevo usuario', 'application.controllers.UsuarioController'); $nuevo_usuario->id_empresa = $nueva_empresa->id; if (!$nuevo_usuario->save()) throw new CException('Error al guardar el usuario'); Yii::trace('Guardando la nueva subscripción', 'application.controllers.UsuarioController'); $nueva_subscripcion->id_usuario = $nuevo_usuario->id; if (!$nueva_subscripcion->save()) throw new CException('Error al guardar la subscripción'); $transaccion->commit(); Yii::trace('Nuevo coordinador dado de alta', 'application.controllers.UsuarioController'); } catch (Exception $e) { Yii::trace($e->getMessage(), 'application.controllers.UsuarioController'); $transaccion->rollBack(); $errores = array_merge($nuevo_usuario->getErrors(), $nueva_empresa->getErrors(), $nueva_subscripcion->getErrors()); foreach ($errores as $campo => $mensaje) $resultado[$campo] = $mensaje; Yii::trace(CVarDumper::dumpAsString($resultado), 'application.controllers.UsuarioController'); echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado); Yii::app()->end(); } if (EMail::enviarBienvenidaCoordinador($nuevo_usuario->email, $nuevo_usuario->clave_seguridad)) { Yii::trace('Correo para activar el coordinador enviado', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Gracias por registrarse en PRODIND'), Yii::t('profind', 'Su cuenta ha sido creada. En unos momentos recibirá un email con un enlace para completar su registro.') ); } else { Yii::trace('Error al enviar el correo para activar el coordinador', 'application.controllers.UsuarioController'); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Gracias por registrarse en PRODIND'), Yii::t('profind', 'Su cuenta ha sido creada pero no se ha podido enviar el correo de registro a la dirección indicada.') ); } } /** * @brief Activa la cuenta del coordinador a partir de la URL de activación * que se le ha enviado a través del email generado en el proceso de * registrar un coordinador. */ protected function _activarCoordinador() { Yii::trace('Activando coordinador', 'application.controllers.UsuarioController'); $email = $_GET['email']; $clave_seguridad = $_GET['key']; if ($email && $clave_seguridad) { $usuario = Usuario::model()->findByAttributes(array('email' => $email)); // Comprobamos si se ha encontrado un usuario con ese email if (!isset($usuario)) { Yii::trace('No existe el email', 'application.controllers.UsuarioController'); $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Error de activación'), 'mensaje' => Yii::t('profind', 'No se puede activar la cuenta.
La URL de activación es incorrecta.'), )); } elseif ($usuario->estado == Usuario::ESTADO_ACTIVO) { Yii::trace('El usuario ya está activo', 'application.controllers.UsuarioController'); $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Cuenta ya activada'), 'mensaje' => Yii::t('profind', 'No se ha realizado ningún cambio.
La cuenta ya estaba activada.'), )); } elseif ($usuario->estado == Usuario::ESTADO_BLOQUEADO) { Yii::trace('El usuario está bloqueado', 'application.controllers.UsuarioController'); $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Cuenta bloqueada'), 'mensaje' => Yii::t('profind', 'La cuenta ha sido bloqueada.
Contacte con el administrador del sitio para obtener más información.'), )); } elseif (isset($usuario->clave_seguridad) && ($usuario->clave_seguridad == $clave_seguridad)) { Yii::trace('Guardando el usuario', 'application.controllers.UsuarioController'); // Hay que activar el usuario $usuario->estado = Usuario::ESTADO_ACTIVO; $usuario->clave_seguridad = $usuario->encryptSecureKey(microtime() . $usuario->password); $usuario->save(); EMail::enviarConfirmacionActivacion($usuario->email); $this->layout = '//layouts/mensaje'; $this->render('confirmacion_usuario', array()); Yii::trace('Coordinador activado', 'application.controllers.UsuarioController'); } else { Yii::trace('Clave de seguridad no válida', 'application.controllers.UsuarioController'); $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Error de activación'), 'mensaje' => Yii::t('profind', 'No se puede activar la cuenta.
El enlace de activación es incorrecto.'), )); } } else { Yii::trace('URL de activación no válida', 'application.controllers.UsuarioController'); $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Error de activación'), 'mensaje' => Yii::t('profind', 'No se puede activar la cuenta.
El enlace de activación es incorrecto.'), )); } } public function actionRegistrarAgente() { $formulario = new FormularioRegistroAgente; $resultado = array(); if (isset($_POST['ajax']) && $_POST['ajax'] === 'activar-agente-form-entrada') { $formulario->key = $_POST['FormularioActivarAgente_key']; $formulario->email = $_POST['FormularioActivarAgente_email']; $formulario->password = $_POST['FormularioActivarAgente_password']; $formulario->passwordRepetida = $_POST['FormularioActivarAgente_password_repetida']; if (!$formulario->validate()) $this->performAjaxValidationMessage($formulario); $usuario = Usuario::model()->findByAttributes(array('email' => $formulario->email)); $usuario->estado = Usuario::ESTADO_ACTIVO; $usuario->save(); if ($this->_cambiarPassword($usuario, $formulario->password)) { EMail::enviarConfirmacionActivacion($usuario->email); $this->performAjaxStatusMessage('success', Yii::t('profind', 'Cuenta de agente activada'), Yii::t('profind', 'Se ha activado su cuenta y se ha establecido su nueva password en PROFIND.') ); } else { foreach ($formulario->getErrors() as $campo => $error) { $resultado[$campo] = $error; } echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado); Yii::app()->end(); } } $this->redirect(Yii::app()->params['frontpage']); } protected function _cambiarPassword($usuario, $nueva_password) { $usuario->password = $usuario->encryptPassword($nueva_password); $usuario->clave_seguridad = $usuario->encryptSecureKey(microtime() . $usuario->password); return $usuario->save(); } public function actionCancelar() { $email = $_GET['email']; $clave_seguridad = $_GET['key']; if ($email && $clave_seguridad) { $usuario = Usuario::model()->findByAttributes(array('email' => $email)); // Comprobamos si se ha encontrado un usuario con ese email if (!isset($usuario)) { $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Error de cancelación'), 'mensaje' => Yii::t('profind', 'No se puede cancelar la cuenta.
La URL de cancelación es incorrecta.'), )); } elseif ($usuario->estado == Usuario::ESTADO_NOACTIVO) { $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Cuenta no confirmada'), 'mensaje' => Yii::t('profind', 'No se ha realizado ningún cambio.
La cuenta no está confirmada.'), )); } elseif ($usuario->estado == Usuario::ESTADO_BORRADO) { $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Cuenta ya cancelada'), 'mensaje' => Yii::t('profind', 'No se ha realizado ningún cambio.
La cuenta ya estaba cancelada.'), )); } elseif ($usuario->estado == Usuario::ESTADO_BLOQUEADO) { $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Cuenta bloqueada'), 'mensaje' => Yii::t('profind', 'La cuenta ha sido bloqueada.
Contacte con el administrador del sitio para obtener más información.'), )); } elseif (isset($usuario->clave_seguridad) && ($usuario->clave_seguridad == $clave_seguridad)) { // Hay que desactivar el usuario $usuario->estado = Usuario::ESTADO_NOACTIVO; $usuario->clave_seguridad = $usuario->encryptSecureKey(microtime() . $usuario->password); $usuario->save(); EMail::enviarConfirmacionCancelacion($usuario->email); $this->layout = '//layouts/mensaje'; $this->render('confirmacion_cancelacion_usuario', array()); } else { $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Error de cancelación'), 'mensaje' => Yii::t('profind', 'No se puede cancelar la cuenta.
La URL de cancelación es incorrecta.'), )); } } else { $this->render('//site/error', array( 'titulo' => Yii::t('profind', 'Error de cancelación'), 'mensaje' => Yii::t('profind', 'No se puede cancelar la cuenta.
La URL de cancelación es incorrecta.'), )); } } /** * @brief Busca el ID del producto básico que se utilizará para la subscripción * de los coordinadores nuevos. * @return integer */ protected function _darIdProductoBasico() { $producto = Producto::model()->productoInicial()->find(); if ($producto === null) { Yii::log('No se ha encontrado un producto básico', CLogger::LEVEL_ERROR, 'application.controller.UsuarioController'); throw new CHttpException(500, Yii::t('profind', 'Error interno.')); } return $producto->id; } /** * @brief Muestra el formulario de modificación de un usuario y realiza los * cambios. * @param integer $id el ID del usuario a modificar * @param string $provider nombre de la red social a utilizar para rellenar los datos del usuario */ public function actionModificar($id, $provider = '') { if ($id != Yii::app()->user->id) throw new CHttpException(401, Yii::t('profind', 'Acceso no autorizado.')); if (($provider != '') && (!isset($_POST['Usuario']))) { switch ($provider) { case 'Twitter': case 'Facebook': case 'LinkedIn': $usuario = $this->loadModelwithSocialData($id, $provider); break; default: throw new CHttpException(404, Yii::t('profind', 'La página solicitada no existe.')); } } else $usuario = $this->loadModel($id); // Uncomment the following line if AJAX validation is needed // $this->performAjaxValidation($usuario); if (isset($_POST['Usuario'])) { $usuario->attributes = $_POST['Usuario']; $ficheroFotografia = CUploadedFile::getInstance($usuario, 'ficheroFotografia'); $quitarFotografia = Yii::app()->request->getParam('quitar_fotografia', '0'); if ($usuario->save()) { if (($quitarFotografia == '1') && ($usuario->fotografia->tieneFotografia())) $usuario->fotografia->eliminarFotografia(); if ($ficheroFotografia) $usuario->fotografia->guardarFotografia($ficheroFotografia); Yii::app()->user->setFlash('success', Yii::t('profind', 'Se ha actualizado el perfil')); $this->redirect(array('modificar', 'id' => $usuario->id)); } } $this->render('modificar', array( 'model' => $usuario, )); } /** * @brief Elimina un usuario. * @param integer $id el ID del usuario a eliminar */ public function actionDelete($id) { if ($id != Yii::app()->user->id) throw new CHttpException(401, Yii::t('profind', 'Acceso no autorizado.')); if (Yii::app()->request->isAjaxRequest) { $resultado = array(); $usuario = $this->loadModel($id); if ($this->enviarMailSolicitudBaja($usuario)) $resultado['status'] = 'success'; else $resultado['status'] = 'failure'; echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado); Yii::app()->end(); } else $this->redirect($this->createUrl('modificar', array('id' => $id))); } /** * @brief Devuelve los datos de un usuario utilizando la red social que * indique el parámetro $provider. * @param integer $id el ID del usuario a modificar * @param string $provider nombre de la red social a utilizar para rellenar los datos del usuario */ public function loadModelwithSocialData($id, $provider) { Yii::trace('Cargar el modelo con datos de redes sociales', 'application.controllers.UsuarioController'); $usuario = $this->loadModel($id); if (!Yii::app()->socialConnect->loadUserProfile($provider)) { throw new CHttpException( Yii::app()->socialConnect->errorCode, Yii::t('profind', Yii::app()->socialConnect->errorMessage) ); } $profile = Yii::app()->socialConnect->userProfile; //$usuario->email = $profile->email; <-- el email no lo cambio $usuario->nombre = $profile->firstName; $usuario->apellidos = $profile->lastName; $usuario->descripcion = $profile->description; switch ($provider) { case 'Twitter': $usuario->localidad = $profile->region; break; case 'Facebook': case 'LinkedIn': $usuario->localidad = $profile->city; break; } return $usuario; } /** * @brief Devuelve los datos del usuario. * Si el usuario no existe, se lanza una excepción HTTP 404 * @param integer $id el ID del usuario a recuperar */ public function loadModel($id) { Yii::trace('Cargar el modelo', 'application.controllers.UsuarioController'); $model = Usuario::model()->findByPk($id); if ($model === null) throw new CHttpException(404, Yii::t('profind', 'La página solicitada no existe.')); return $model; } /** * @brief Genera un mensaje de estado en formato JSON que se utilizará * para mostrar información al usuario en la página de entrada. * @param string $status 'success' o 'failure' * @param string $title título de la ventana modal con mensaje */ protected function performAjaxStatusMessage($status, $title, $content) { Yii::trace('Generando respuesta JSON con mensaje de estado', 'application.controllers.UsuarioController'); $result = array(); $result['status'] = $status; $result['titulo'] = $title; $result['texto'] = $content; Yii::trace(CVarDumper::dumpAsString($result), 'application.controllers.UsuarioController'); echo function_exists('json_encode') ? json_encode($result) : CJSON::encode($result); Yii::app()->end(); } /** * @brief Genera un mensaje en formato JSON con los errores de validación de * uno o más modelos. El mensaje se mostrará al usuario en la página de entrada. * @param mixed $models una instancia de un modelo o un array de instancias. */ protected function performAjaxValidationMessage($models) { Yii::trace('Generando respuesta JSON con errores de validación', 'application.controllers.UsuarioController'); $result = array(); if(!is_array($models)) $models=array($models); foreach($models as $model) foreach($model->getErrors() as $attribute => $errors) $result[$attribute] = $errors; Yii::trace(CVarDumper::dumpAsString($result), 'application.controllers.UsuarioController'); echo function_exists('json_encode') ? json_encode($result) : CJSON::encode($result); Yii::app()->end(); } }