- Revisión del código en general

- Tarea #1099 -> Mejorar la encriptación de las contraseñas
- Tarea #1104 -> Guardar en el usuario la fecha de creación y del último login
- Tarea #1125 -> Quitar la máscara en el campo 'teléfono' del usuario

git-svn-id: https://192.168.0.254/svn/Proyectos.Incam_PROFIND_Web/trunk@57 3fe1ab16-cfe0-e34b-8c9f-7d8c168d430d
This commit is contained in:
David Arranz 2012-10-09 11:44:12 +00:00
parent 51a505b4c6
commit df138cf8bb
32 changed files with 852 additions and 635 deletions

View File

@ -1,23 +1,44 @@
<?php <?php
/** /**
* Controller is the customized base controller class. * @class Controller
* All controller classes for this application should extend from this base class. * @brief Clase básica para los controladores de la aplicación.
*
* @package application.components
*/ */
class Controller extends CController class Controller extends CController {
{
/** /**
* @var string the default layout for the controller view. Defaults to '//layouts/column1', * @var string the default layout for the controller view. Defaults to '//layouts/column1',
* meaning using a single column layout. See 'protected/views/layouts/column1.php'. * meaning using a single column layout. See 'protected/views/layouts/column1.php'.
*/ */
public $layout='//layouts/main'; public $layout = '//layouts/main';
/**
* @var array context menu items. This property will be assigned to {@link CMenu::items}. /**
*/ * @var array context menu items. This property will be assigned to {@link CMenu::items}.
public $menu=array(); */
/** public $menu = array();
* @var array the breadcrumbs of the current page. The value of this property will
* be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links} /**
* for more details on how to specify this property. * @var array the breadcrumbs of the current page. The value of this property will
*/ * be assigned to {@link CBreadcrumbs::links}. Please refer to {@link CBreadcrumbs::links}
public $breadcrumbs=array(); * for more details on how to specify this property.
*/
public $breadcrumbs = array();
/**
* @brief Valida uno o más modelos y genera el resultado en formato JSON.
* @param mixed $models instancia de un modelo o un array de modelos
* @param string $ajaxId identificador AJAX que se comparará con $_POST['ajax']
*/
protected function performAjaxValidation($models, $ajaxId) {
Yii::trace('Validación AJAX de modelo', 'application.components.Controller');
if (isset($_POST['ajax']) && $_POST['ajax'] === $ajaxId) {
$result = CActiveForm::validate($models);
Yii::trace(CVarDumper::dumpAsString($result), 'application.components.Controller');
echo $result;
Yii::app()->end();
}
}
} }

View File

@ -1,8 +1,10 @@
<?php <?php
/** /**
* Sirve para comprobar si un usuario en válido en el sistema a partir * @class IdentificacionUsuario
* del email y de la contraseña. * @brief Realiza el proceso de identificación de un usuario en el sistema.
*
* @package application.components
*/ */
class IdentificacionUsuario extends CBaseUserIdentity { class IdentificacionUsuario extends CBaseUserIdentity {
@ -18,10 +20,10 @@ class IdentificacionUsuario extends CBaseUserIdentity {
const ERROR_ESTADO_NOACTIVO=3; const ERROR_ESTADO_NOACTIVO=3;
const ERROR_ESTADO_BORRADO=4; const ERROR_ESTADO_BORRADO=4;
const ERROR_ESTADO_DENEGADO=5; const ERROR_ESTADO_BLOQUEADO=5;
/** /**
* Contructor. * @brief Contructor.
* @param string $email email * @param string $email email
* @param string $password password * @param string $password password
*/ */
@ -31,8 +33,8 @@ class IdentificacionUsuario extends CBaseUserIdentity {
} }
/** /**
* Comprueba la identificación de un usuario * @brief Comprueba que la identificación de un usuario es correcta.
* @return boolean whether authentication succeeds. * @return boolean
*/ */
public function authenticate() { public function authenticate() {
$usuario = Usuario::model()->findByAttributes(array('email' => $this->email)); $usuario = Usuario::model()->findByAttributes(array('email' => $this->email));
@ -50,8 +52,8 @@ class IdentificacionUsuario extends CBaseUserIdentity {
$this->errorCode = self::ERROR_ESTADO_NOACTIVO; $this->errorCode = self::ERROR_ESTADO_NOACTIVO;
else if($usuario->estado == Usuario::ESTADO_BORRADO) else if($usuario->estado == Usuario::ESTADO_BORRADO)
$this->errorCode = self::ERROR_ESTADO_BORRADO; $this->errorCode = self::ERROR_ESTADO_BORRADO;
else if($usuario->estado == Usuario::ESTADO_DENEGADO) else if($usuario->estado == Usuario::ESTADO_BLOQUEADO)
$this->errorCode = self::ERROR_ESTADO_DENEGADO; $this->errorCode = self::ERROR_ESTADO_BLOQUEADO;
else { else {
// Si el usuario tiene cifrada la contraseña con md5() // Si el usuario tiene cifrada la contraseña con md5()
// pasarla al nuevo método. // pasarla al nuevo método.
@ -67,23 +69,18 @@ class IdentificacionUsuario extends CBaseUserIdentity {
} }
/** /**
* Returns the unique identifier for the identity. * @brief Devuelve el identificador único para la identidad del usuario
* The default implementation simply returns {@link username}. * @return string.
* This method is required by {@link IUserIdentity}.
* @return string the unique identifier for the identity.
*/ */
public function getId() { public function getId() {
return $this->_id; return $this->_id;
} }
/** /**
* Returns the display name for the identity. * @brief Devuelve el email del usuario que está en sesión.
* The default implementation simply returns {@link username}. * @return string
* This method is required by {@link IUserIdentity}.
* @return string the display name for the identity.
*/ */
public function getName() { public function getName() {
return $this->email; return $this->email;
} }
} }

View File

@ -1,9 +1,19 @@
<?php <?php
/**
* @class UsuarioWeb
* @brief Guarda los datos del usuario registrado que está en sesión
*
* @package application.components
*/
class UsuarioWeb extends CWebUser { class UsuarioWeb extends CWebUser {
private $_model; private $_model;
/**
* @brief Actualiza la fecha de la última entrada (last login) del usuario
* que ha iniciado sesión.
*/
public function afterLogin(){ public function afterLogin(){
if (($this->_model === null) && ($this->loadUser())) if (($this->_model === null) && ($this->loadUser()))
Usuario::model()->updateByPk($this->id, array( Usuario::model()->updateByPk($this->id, array(
@ -12,31 +22,62 @@ class UsuarioWeb extends CWebUser {
return true; return true;
} }
/**
* @brief ID de la empresa del usuario que está en sesión.
* @return integer
*/
public function getId_empresa() { public function getId_empresa() {
$usuario = $this->loadUser($this->id); $usuario = $this->loadUser($this->id);
return $usuario->id_empresa; return $usuario->id_empresa;
} }
/**
* @brief Comprueba si el usuario que está en sesión es coordinador o no.
* @return boolean
*/
public function getEsCoordinador() { public function getEsCoordinador() {
$usuario = $this->loadUser(); $usuario = $this->loadUser();
return ($usuario->tipo == Usuario::TIPO_USUARIO_COORDINADOR); return ($usuario->tipo == Usuario::TIPO_USUARIO_COORDINADOR);
} }
/**
* @brief Comprueba si el usuario que está en sesión tiene/puede tener
* un equipo de agentes.
* @return boolean
*/
public function getTieneEquipo() { public function getTieneEquipo() {
$subscripcion = $this->loadSubscripcion(); $subscripcion = $this->loadSubscripcion();
return ($subscripcion->producto->n_agentes > 0); Yii::log(CVarDumper::dumpAsString($subscripcion), CLogger::LEVEL_ERROR);
if ($subscripcion)
return ($subscripcion->producto->n_agentes > 0);
else
return false;
} }
/**
* @brief Devuelve la subscripción del usuario que está en sesión.
* @return Subscripcion
*/
public function getSubscripcion() { public function getSubscripcion() {
return $this->loadSubscripcion(); return $this->loadSubscripcion();
} }
/**
* @brief Devuelve el nombre del usuario que está en sesión.
* Si el usuario ha rellenado su nombre y apellidos, devuelve el nombre
* completo. Si no, devuelve la dirección e-mail del usuario.
* @return string
*/
public function getName() { public function getName() {
$usuario = $this->loadUser(); $usuario = $this->loadUser();
return ($usuario->nombre) ? $usuario->nombreCompleto : parent::getName(); return ($usuario && $usuario->nombre) ? $usuario->nombreCompleto : parent::getName();
} }
// Load user model. /**
* @brief Devuelve el usuario que ha hecho sesión.
* @return Usuario
*/
protected function loadUser() { protected function loadUser() {
if ($this->_model === null) { if ($this->_model === null) {
$this->_model = Usuario::model()->findByPk($this->id); $this->_model = Usuario::model()->findByPk($this->id);
@ -44,7 +85,10 @@ class UsuarioWeb extends CWebUser {
return $this->_model; return $this->_model;
} }
// Carga la subscripción activa /**
* @brief Devuelve la subscripción activa del usuario que ha hecho sesión.
* @return Subscripcion
*/
protected function loadSubscripcion() { protected function loadSubscripcion() {
return Subscripcion::model()->activa()->findByAttributes(array('id_usuario' => $this->id)); return Subscripcion::model()->activa()->findByAttributes(array('id_usuario' => $this->id));
} }

View File

@ -20,7 +20,14 @@ $config = array(
// autoloading model and component classes // autoloading model and component classes
'import' => array( 'import' => array(
// Modelos
'application.models.*', 'application.models.*',
'application.models.formularios.*',
// Helpers
'application.helpers.*',
// Componentes y extensiones
'application.components.*', 'application.components.*',
'application.extensions.yii-mail.YiiMailMessage', 'application.extensions.yii-mail.YiiMailMessage',
'application.extensions.PasswordHash.PasswordHash', 'application.extensions.PasswordHash.PasswordHash',

View File

@ -85,12 +85,14 @@ $configSpecific = array(
// Save log messages on file // Save log messages on file
array( array(
'class' => 'CFileLogRoute', 'class' => 'CFileLogRoute',
'levels' => 'error, warning', 'levels' => 'error, warning, trace',
//'categories' => '*',
), ),
// Show log messages on web pages // Show log messages on web pages
array( array(
'class' => 'CWebLogRoute', 'class' => 'CWebLogRoute',
'levels' => 'error, warning', 'levels' => 'error, warning, trace',
//'categories' => 'application.*',
'showInFireBug' => true, 'showInFireBug' => true,
), ),
), ),

View File

@ -56,7 +56,7 @@ class EmpresaController extends Controller {
$empresa = $this->loadModel($id); $empresa = $this->loadModel($id);
// Uncomment the following line if AJAX validation is needed // Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model); // $this->performAjaxValidation($model, 'empresa-form');
if (isset($_POST['Empresa'])) { if (isset($_POST['Empresa'])) {
$empresa->attributes = $_POST['Empresa']; $empresa->attributes = $_POST['Empresa'];
@ -128,16 +128,4 @@ class EmpresaController extends Controller {
return $empresa; return $empresa;
} }
/**
* Performs the AJAX validation.
* @param CModel the model to be validated
*/
protected function performAjaxValidation($model) {
if (isset($_POST['ajax']) && $_POST['ajax'] === 'empresa-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
} }

View File

@ -19,9 +19,9 @@ class EquipoController extends Controller {
public function accessRules() { public function accessRules() {
return array( return array(
array('allow', array('allow',
'actions' => array('index', 'delete'), 'actions' => array('index', 'deleteMember'),
'users' => array('@'), 'users' => array('@'),
'expression' => 'Yii::app()->user->esCoordinador', 'expression' => 'Yii::app()->user->esCoordinador',
), ),
array('deny', // deny all users array('deny', // deny all users
'users' => array('*'), 'users' => array('*'),
@ -33,6 +33,7 @@ class EquipoController extends Controller {
$invitacion = new FormularioInvitarAgente; $invitacion = new FormularioInvitarAgente;
if (isset($_POST['FormularioInvitarAgente'])) { if (isset($_POST['FormularioInvitarAgente'])) {
Yii::trace('Dar de alta un nuevo agente', 'application.controllers.EquipoController');
$invitacion->attributes = $_POST['FormularioInvitarAgente']; $invitacion->attributes = $_POST['FormularioInvitarAgente'];
if ($invitacion->validate()) { if ($invitacion->validate()) {
@ -46,7 +47,7 @@ class EquipoController extends Controller {
$nuevo_usuario->clave_seguridad = $nuevo_usuario->encryptSecureKey(microtime() . $nuevo_usuario->password); $nuevo_usuario->clave_seguridad = $nuevo_usuario->encryptSecureKey(microtime() . $nuevo_usuario->password);
if ($nuevo_usuario->save()) { if ($nuevo_usuario->save()) {
$this->enviarMailRegistroAgente($nuevo_usuario); EMail::enviarBienvenidaAgente($nuevo_usuario->email, $nuevo_usuario->clave_seguridad);
Yii::app()->user->setFlash('success', Yii::t('profind', 'Se ha enviado la invitación a la dirección') . ' ' . $invitacion->email); Yii::app()->user->setFlash('success', Yii::t('profind', 'Se ha enviado la invitación a la dirección') . ' ' . $invitacion->email);
$invitacion = new FormularioInvitarAgente; $invitacion = new FormularioInvitarAgente;
} else { } else {
@ -59,50 +60,38 @@ class EquipoController extends Controller {
} }
$agentes = Usuario::model()->equipo()->findAll(); $agentes = Usuario::model()->equipo()->findAll();
if (count($agentes) >= Yii::app()->user->subscripcion->producto->n_agentes) if (count($agentes) >= Yii::app()->user->subscripcion->producto->n_agentes)
$invitacion = NULL; $invitacion = NULL;
$this->render('index', array( $this->render('index', array(
'agentes' => $agentes, 'agentes' => $agentes,
'invitacion' => $invitacion, 'invitacion' => $invitacion,
)); ));
} }
public function actionDelete($id) {
$agente = $this->loadModel($id);
if ($agente) $agente->delete();
// if AJAX request (triggered by deletion via admin grid view), we should not redirect the browser
if(!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
}
/** /**
* Envía un mail de registro a un usuario * @brief Elimina a un miembro (agente) del equipo.
* con una URL de confirmación. * También envía un email al agente informándole.
* @param Usuario $usuario Usuario al que se le enviará el mail de registro
*/ */
private function enviarMailRegistroAgente($usuario) { public function actionDeleteMember($id) {
Yii::import('ext.yii-mail.YiiMailMessage'); $agente = $this->loadModel($id);
if ($agente) {
$url_activacion = Yii::app()->params['frontpage'] . '?' . 'key=' . $usuario->clave_seguridad . '&email=' . urlencode($usuario->email) . '&x=1'; try {
Yii::trace('Eliminando el agente', 'application.controllers.EquipoController');
$mensaje = new YiiMailMessage; $agente->delete();
$mensaje->from = Yii::app()->params['email_remitente']; EMail::enviarConfirmacionCancelacion($agente->email);
$mensaje->setTo($usuario->email); Yii::app()->user->setFlash('success', Yii::t('profind', 'Se ha eliminado el agente'));
$mensaje->subject = Yii::t('profind', 'Complete su registro de agente en PROFIND'); } catch (Exception $e) {
$mensaje->view = 'registro_agente'; Yii::trace($e->getMessage(), 'application.controllers.UsuarioController');
$mensaje->setBody(array( Yii::app()->user->setFlash('error', Yii::t('profind', 'Se ha producido un error al eliminar el agente'));
'url' => $url_activacion, Yii::app()->user->setFlash('error', CHtml::errorSummary($agente));
'email' => $usuario->email }
), 'text/html' }
); if (!isset($_GET['ajax']))
$this->redirect(isset($_POST['returnUrl']) ? $_POST['returnUrl'] : array('index'));
Yii::app()->mail->send($mensaje);
} }
/** /**
* Returns the data model based on the primary key given in the GET variable. * Returns the data model based on the primary key given in the GET variable.
* If the data model is not found, an HTTP exception will be raised. * If the data model is not found, an HTTP exception will be raised.
@ -115,15 +104,4 @@ class EquipoController extends Controller {
return $model; return $model;
} }
/**
* Performs the AJAX validation.
* @param CModel the model to be validated
*/
protected function performAjaxValidation($model) {
if (isset($_POST['ajax']) && $_POST['ajax'] === 'usuario-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
} }

View File

@ -1,327 +0,0 @@
<?php
/**
* Sirve para realizar el proceso de registro de un usuario nuevo.
*/
class RegistroUsuarioController extends Controller {
public $defaultAction = 'registrar';
public $layout = '//layouts/error';
public function filters() {
return array('accessControl');
}
public function accessRules() {
return array(
array('allow',
'actions' => array('registrar', 'registrarAgente', 'activar', 'cancelar'),
'users' => array('*')
),
array('deny'),
);
}
/**
* 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.
*/
public function actionRegistrar() {
$formulario = new FormularioRegistro;
$resultado = array();
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'registro-form') {
$formulario->email = $_POST['FormularioRegistro_email'];
$formulario->password = $_POST['FormularioRegistro_password'];
$formulario->password2 = $_POST['FormularioRegistro_password2'];
if (!$formulario->validate()) {
foreach ($formulario->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
$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);
if (!$nuevo_usuario->save()) {
foreach ($nuevo_usuario->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
// Crear la empresa
$nueva_empresa = new Empresa('registrar');
if (!$nueva_empresa->save()) {
foreach ($nueva_empresa->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
$nuevo_usuario->id_empresa = $nueva_empresa->id;
if (!$nuevo_usuario->save()) {
foreach ($nuevo_usuario->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
// Crear la subscripción
$nueva_subscripcion = new Subscripcion('registrar');
$nueva_subscripcion->estado = Subscripcion::ESTADO_ACTIVO;
$nueva_subscripcion->id_usuario = $nuevo_usuario->id;
$nueva_subscripcion->id_producto = 1;
if (!$nueva_subscripcion->save()) {
foreach ($nueva_subscripcion->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
if ($this->enviarMailRegistro($nuevo_usuario)) {
$resultado['status'] = '200';
$resultado['titulo'] = Yii::t('profind', 'Gracias por registrarse en PRODIND');
$resultado['texto'] = Yii::t('profind', 'Su cuenta ha sido creada. En unos momentos recibirá un email con un enlace para completar su registro.');
} else {
$resultado['status'] = '200';
$resultado['titulo'] = Yii::t('profind', 'Error en el registro');
$resultado['texto'] = Yii::t('profind', 'No se ha podido enviar el correo de registro a la dirección indicada.');
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
$this->redirect(Yii::app()->params['frontpage']);
}
public function actionRegistrarAgente() {
$formulario = new FormularioRegistroAgente;
$resultado = array();
if (isset($_POST['ajax']) && $_POST['ajax'] === 'activar-agente-form-ext') {
$formulario->key = $_POST['FormularioActivarAgente_key'];
$formulario->email = $_POST['FormularioActivarAgente_email'];
$formulario->password = $_POST['FormularioActivarAgente_password'];
$formulario->passwordRepetida = $_POST['FormularioActivarAgente_password_repetida'];
if ($formulario->validate()) {
$usuario = Usuario::model()->findByAttributes(array('email' => $formulario->email));
$usuario->estado = Usuario::ESTADO_ACTIVO;
$usuario->save();
if ($this->_cambiarPassword($usuario->id, $formulario->password)) {
$this->enviarMailConfirmacionActivacion($usuario);
$resultado['status'] = '200';
$resultado['titulo'] = Yii::t('profind', 'Cuenta de agente activada');
$resultado['texto'] = Yii::t('profind', 'Se ha activado su cuenta y se ha establecido su nueva password en PROFIND.');
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
} else {
foreach ($formulario->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
} 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']);
}
private function _cambiarPassword($id, $nueva_password) {
$usuario = Usuario::model()->findByPk($id);
if (!isset($usuario))
throw new CHttpException(404, Yii::t('profind', 'La página solicitada no existe.'));
$usuario->password = $usuario->encryptPassword($nueva_password);
$usuario->clave_seguridad = $usuario->encryptSecureKey(microtime() . $usuario->password);
if ($usuario->save()) {
return true;
} else
return false;
}
/**
* Activa la cuenta del usuario a partir de la URL de activación
* que se le ha enviado a través de un email.
*/
public function actionActivar() {
$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 activación'),
'mensaje' => Yii::t('profind', 'No se puede activar la cuenta.<br>La URL de activación es incorrecta.'),
));
} elseif ($usuario->estado == Usuario::ESTADO_ACTIVO) {
$this->render('//site/error', array(
'titulo' => Yii::t('profind', 'Cuenta ya activada'),
'mensaje' => Yii::t('profind', 'No se ha realizado ningún cambio.<br>La cuenta ya estaba activada.'),
));
} elseif ($usuario->estado == Usuario::ESTADO_DENEGADO) {
$this->render('//site/error', array(
'titulo' => Yii::t('profind', 'Cuenta bloqueada'),
'mensaje' => Yii::t('profind', 'La cuenta ha sido bloqueada.<br>Contacte con el administrador del sitio para obtener más información.'),
));
} elseif (isset($usuario->clave_seguridad) && ($usuario->clave_seguridad == $clave_seguridad)) {
// Hay que activar el usuario
$usuario->estado = Usuario::ESTADO_ACTIVO;
$usuario->clave_seguridad = $usuario->encryptSecureKey(microtime() . $usuario->password);
$usuario->save();
$this->enviarMailConfirmacionActivacion($usuario);
$this->layout = '//layouts/mensaje';
$this->render('confirmacion_usuario', array());
} else {
$this->render('//site/error', array(
'titulo' => Yii::t('profind', 'Error de activación'),
'mensaje' => Yii::t('profind', 'No se puede activar la cuenta.<br>La URL de activación es incorrecta.'),
));
}
} else {
$this->render('//site/error', array(
'titulo' => Yii::t('profind', 'Error de activación'),
'mensaje' => Yii::t('profind', 'No se puede activar la cuenta.<br>La URL de activación es incorrecta.'),
));
}
}
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.<br>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.<br>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.<br>La cuenta ya estaba cancelada.'),
));
} elseif ($usuario->estado == Usuario::ESTADO_DENEGADO) {
$this->render('//site/error', array(
'titulo' => Yii::t('profind', 'Cuenta bloqueada'),
'mensaje' => Yii::t('profind', 'La cuenta ha sido bloqueada.<br>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();
$this->enviarMailConfirmacionCancelacion($usuario);
$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.<br>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.<br>La URL de cancelación es incorrecta.'),
));
}
}
/**
* Envía un mail de registro a un usuario
* con una URL de confirmación.
* @param Usuario $usuario Usuario al que se le enviará el mail de registro
*/
private function enviarMailRegistro($usuario) {
Yii::import('ext.yii-mail.YiiMailMessage');
$url_activacion = $this->createAbsoluteUrl('registroUsuario/activar', array("key" => $usuario->clave_seguridad, "email" => $usuario->email));
$mensaje = new YiiMailMessage;
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($usuario->email);
$mensaje->subject = Yii::t('profind', 'Complete su registro en PROFIND');
$mensaje->view = 'registro_usuario';
$mensaje->setBody(array(
'url' => $url_activacion,
'email' => $usuario->email
), 'text/html'
);
return Yii::app()->mail->send($mensaje);
}
/**
* Envía un mail de confirmación de su cuenta al usuario.
* @param Usuario $usuario Usuario al que se le enviará el mail de registro
*/
private function enviarMailConfirmacionActivacion($usuario) {
Yii::import('ext.yii-mail.YiiMailMessage');
$mensaje = new YiiMailMessage;
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($usuario->email);
$mensaje->subject = Yii::t('profind', 'Gracias por registrarse en PROFIND.');
$mensaje->view = 'confirmacion_usuario';
$mensaje->setBody(array(
'email' => $usuario->email
), 'text/html'
);
return Yii::app()->mail->send($mensaje);
}
private function enviarMailConfirmacionCancelacion($usuario) {
Yii::import('ext.yii-mail.YiiMailMessage');
$mensaje = new YiiMailMessage;
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($usuario->email);
$mensaje->subject = Yii::t('profind', 'Confirmación de cancelación de su cuenta en PROFIND');
$mensaje->view = 'confirmacion_cancelacion_usuario';
$mensaje->setBody(array('email' => $usuario->email), 'text/html');
return Yii::app()->mail->send($mensaje);
}
}

View File

@ -4,42 +4,6 @@ class SeguridadUsuarioController extends Controller {
public $defaultAction = 'recuperar'; public $defaultAction = 'recuperar';
/**
* 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() {
$formulario = new FormularioRecuperarPassword;
$resultado = array();
// if it is ajax validation request
if (isset($_POST['ajax']) && $_POST['ajax'] === 'recuperar-form') {
$formulario->email = $_POST['FormularioRecuperar_email'];
if (!$formulario->validate()) {
foreach ($formulario->getErrors() as $campo => $error) {
$resultado[$campo] = $error;
}
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
$usuario = Usuario::model()->findByAttributes(array('email' => $formulario->email));
if ($usuario) {
$this->enviarMailRecuperacion($usuario);
$resultado['status'] = '200';
$resultado['titulo'] = Yii::t('profind', 'Recuperación de su cuenta en PROFIND');
$resultado['texto'] = Yii::t('profind', 'En unos momentos recibirá un un correo con los pasos necesarios para recuperar su cuenta en PROFIND.');
echo function_exists('json_encode') ? json_encode($resultado) : CJSON::encode($resultado);
Yii::app()->end();
}
}
$this->redirect(Yii::app()->params['frontpage']);
}
/** /**
* Cambiar la contraseña del usuario desde la página de entrada. * Cambiar la contraseña del usuario desde la página de entrada.
@ -135,51 +99,5 @@ class SeguridadUsuarioController extends Controller {
return false; return false;
} }
/**
* Envía un mail de recuperación de password a un usuario con una URL.
* @param Usuario $usuario Usuario al que se le enviará el mail de recuperación
*/
private function enviarMailRecuperacion($usuario) {
Yii::import('ext.yii-mail.YiiMailMessage');
$url_modificacion = Yii::app()->params['frontpage'] . '?' . 'key=' . $usuario->clave_seguridad . '&email=' . urlencode($usuario->email);
$mensaje = new YiiMailMessage;
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($usuario->email);
$mensaje->subject = Yii::t('profind', 'Recuperación de su cuenta en PROFIND');
$mensaje->view = 'recuperacion_password_usuario';
$mensaje->setBody(array(
'url' => $url_modificacion,
'email' => $usuario->email
), 'text/html'
);
Yii::app()->mail->send($mensaje);
}
/**
* Envía un mail confirmando el cambio de password a un usuario.
* También se envio una URL de recuperacion por si fuera un cambio no permitido.
* @param Usuario $usuario Usuario al que se le enviará el mail de notificación
*/
private function enviarMailNotificacionCambioPassword($usuario) {
Yii::import('ext.yii-mail.YiiMailMessage');
$url_modificacion = Yii::app()->params['frontpage'] . '?' . 'key=' . $usuario->clave_seguridad . '&email=' . urlencode($usuario->email);
$mensaje = new YiiMailMessage;
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($usuario->email);
$mensaje->subject = Yii::t('profind', 'Se ha modificado su password en PROFIND');
$mensaje->view = 'notificacion_cambio_password_usuario';
$mensaje->setBody(array(
'url' => $url_modificacion,
'email' => $usuario->email
), 'text/html'
);
Yii::app()->mail->send($mensaje);
}
} }

View File

@ -44,7 +44,7 @@ class SiteController extends Controller {
} }
/** /**
* Displays the login page * Validate login data
*/ */
public function actionLogin() { public function actionLogin() {
$formulario = new FormularioLogin; $formulario = new FormularioLogin;

View File

@ -1,5 +1,12 @@
<?php <?php
/**
* @class UsuarioController
* @brief Controlador del modelo del usuario
*
* @package application.controllers
*/
class UsuarioController extends Controller { class UsuarioController extends Controller {
public $defaultAction = 'modificar'; public $defaultAction = 'modificar';
@ -20,20 +27,432 @@ class UsuarioController extends Controller {
*/ */
public function accessRules() { public function accessRules() {
return array( return array(
array('allow', // allow admin user to perform 'admin' and 'delete' actions array('allow',
'actions' => array('modificar', 'delete'), 'actions' => array(
'activar', 'cancelar', 'establecerPassword',
'recuperar', 'registrar', 'registrarAgente',
),
'users' => array('*'),
),
array('allow',
'actions' => array(
'cambiarPassword' ,'delete', 'modificar'
),
'users' => array('@'), 'users' => array('@'),
), ),
array('deny', // deny all users array('deny',
'users' => array('*'), 'users' => array('*'),
), ),
); );
} }
/** /**
* Actualiza un usuario. * @brief Realiza el registro de un usuario.
* If update is successful, the browser will be redirected to the 'view' page. * - Coordinador => a través de la página de entrada (formulario)
* @param integer $id the ID of the model to be updated * - 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(404, Yii::t('profind', 'La página solicitada no existe.'));
$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.<br>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.<br>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.<br>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.<br>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.<br>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.<br>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.<br>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.<br>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.<br>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.<br>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.<br>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 = '') { public function actionModificar($id, $provider = '') {
if ($id != Yii::app()->user->id) if ($id != Yii::app()->user->id)
@ -60,10 +479,6 @@ class UsuarioController extends Controller {
$usuario->attributes = $_POST['Usuario']; $usuario->attributes = $_POST['Usuario'];
$ficheroFotografia = CUploadedFile::getInstance($usuario, 'ficheroFotografia'); $ficheroFotografia = CUploadedFile::getInstance($usuario, 'ficheroFotografia');
Yii::log(CVarDumper::dumpAsString($_POST['Usuario']), CLogger::LEVEL_ERROR);
Yii::log(CVarDumper::dumpAsString($usuario->attributes), CLogger::LEVEL_ERROR);
Yii::log(CVarDumper::dumpAsString($ficheroFotografia), CLogger::LEVEL_ERROR);
$quitarFotografia = Yii::app()->request->getParam('quitar_fotografia', '0'); $quitarFotografia = Yii::app()->request->getParam('quitar_fotografia', '0');
if ($usuario->save()) { if ($usuario->save()) {
@ -83,6 +498,10 @@ class UsuarioController extends Controller {
)); ));
} }
/**
* @brief Elimina un usuario.
* @param integer $id el ID del usuario a eliminar
*/
public function actionDelete($id) { public function actionDelete($id) {
if ($id != Yii::app()->user->id) if ($id != Yii::app()->user->id)
throw new CHttpException(404, Yii::t('profind', 'La página solicitada no existe.')); throw new CHttpException(404, Yii::t('profind', 'La página solicitada no existe.'));
@ -102,6 +521,12 @@ class UsuarioController extends Controller {
$this->redirect($this->createUrl('modificar', array('id' => $id))); $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) { public function loadModelwithSocialData($id, $provider) {
$usuario = $this->loadModel($id); $usuario = $this->loadModel($id);
@ -133,9 +558,9 @@ class UsuarioController extends Controller {
} }
/** /**
* Returns the data model based on the primary key given in the GET variable. * @brief Devuelve los datos del usuario.
* If the data model is not found, an HTTP exception will be raised. * Si el usuario no existe, se lanza una excepción HTTP 404
* @param integer the ID of the model to be loaded * @param integer $id el ID del usuario a recuperar
*/ */
public function loadModel($id) { public function loadModel($id) {
$model = Usuario::model()->findByPk($id); $model = Usuario::model()->findByPk($id);
@ -146,35 +571,41 @@ class UsuarioController extends Controller {
} }
/** /**
* Performs the AJAX validation. * @brief Genera un mensaje de estado en formato JSON que se utilizará
* @param CModel the model to be validated * 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 performAjaxValidation($model) { protected function performAjaxStatusMessage($status, $title, $content) {
if (isset($_POST['ajax']) && $_POST['ajax'] === 'usuario-form') { Yii::trace('Generando respuesta JSON con mensaje de estado', 'application.controllers.UsuarioController');
echo CActiveForm::validate($model); $result = array();
Yii::app()->end(); $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();
}
/** /**
* Envía un mail de registro a un usuario * @brief Genera un mensaje en formato JSON con los errores de validación de
* con una URL de confirmación. * uno o más modelos. El mensaje se mostrará al usuario en la página de entrada.
* @param Usuario $usuario Usuario al que se le enviará el mail de registro * @param mixed $models una instancia de un modelo o un array de instancias.
*/ */
private function enviarMailSolicitudBaja($usuario) { protected function performAjaxValidationMessage($models) {
Yii::import('ext.yii-mail.YiiMailMessage'); Yii::trace('Generando respuesta JSON con errores de validación', 'application.controllers.UsuarioController');
$url_cancelacion = $this->createAbsoluteUrl('registroUsuario/cancelar', array("key" => $usuario->clave_seguridad, "email" => $usuario->email)); $result = array();
$mensaje = new YiiMailMessage; if(!is_array($models))
$models=array($models);
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($usuario->email); foreach($models as $model)
$mensaje->subject = Yii::t('profind', 'Solicitud de cancelación de su cuenta en PROFIND'); foreach($model->getErrors() as $attribute => $errors)
$mensaje->view = 'solicitud_cancelacion_usuario'; $result[$attribute] = $errors;
$mensaje->setBody(array('url' => $url_cancelacion), 'text/html');
Yii::trace(CVarDumper::dumpAsString($result), 'application.controllers.UsuarioController');
return Yii::app()->mail->send($mensaje); echo function_exists('json_encode') ? json_encode($result) : CJSON::encode($result);
Yii::app()->end();
} }
} }

View File

@ -0,0 +1,141 @@
<?php
/**
* @class EMail
* @brief Clase para enviar correos electrónicos a los usuarios con mensajes
* predeterminados (bienvenida, confirmaciones, notificaciones, etc).
*
* @package application.helpers
*/
class EMail {
/**
* @brief Envía un correo electrónico.
* @param string $to destinatiario
* @param string $subject asunto
* @param string $view nombre del fichero con la vista que se utilizará
* como cuerpo del mensaje
* @param mixed $body cuerpo del mensaje. Si el parámetro es una cadena y
* se ha indicado una vista, la cadena se pasa a la vista como $body.
* Si se ha indicado una vista y el cuerpo es un array, los valores del
* array se pasan a la vista como en el método rended() de un controlador.
* @return boolean
* @see YiiMail
*/
protected static function _enviar($to, $subject, $view, $body) {
$mensaje = new YiiMailMessage;
$mensaje->from = Yii::app()->params['email_remitente'];
$mensaje->setTo($to);
$mensaje->subject = $subject;
$mensaje->view = $view;
$mensaje->setBody($body, 'text/html');
return (Yii::app()->mail->send($mensaje) > 0);
}
/**
* @brief Envía un correo de confirmación de cuenta.
* @param string $destino dirección de destino
* @return boolean
*/
public static function enviarConfirmacionActivacion($destino) {
Yii::trace('Enviando correo para confirmar activación', 'application.helpers.EMail');
return self::_enviar($destino,
Yii::t('profind', 'Gracias por registrarse en PROFIND.'),
'confirmacion_usuario',
array('email' => $destino));
}
/**
* @brief Envía un correo informando de la cancelación de cuenta
* @param string $destino dirección de destino
* @return boolean
*/
public static function enviarConfirmacionCancelacion($destino) {
Yii::trace('Enviando correo para confirmar cancelación', 'application.helpers.EMail');
return self::_enviar($destino,
Yii::t('profind', 'Confirmación de cancelación de su cuenta en PROFIND'),
'confirmacion_cancelacion_usuario',
array('email' => $destino));
}
/**
* @brief Envía un correo de recuperación de password con una URL de verificación.
* @param string $destino dirección de destino
* @param string $key clave de seguridad necesaria para construir la URL de recuperación
* @return boolean
*/
public static function enviarRecuperacion($destino, $key) {
Yii::trace('Enviando correo con URL para recuperar la contraseña', 'application.helpers.EMail');
$url_recuperacion = Yii::app()->params['frontpage'] . '?' . 'key=' . $key . '&email=' . urlencode($destino);
return self::_enviar($destino,
Yii::t('profind', 'Recuperación de su cuenta en PROFIND'),
'recuperacion_password_usuario',
array('email' => $destino, 'url' => $url_recuperacion));
}
/**
* @brief Envía un correo confirmando el cambio de password.
* También se envia una URL de recuperación por si fuera un cambio no permitido.
* @param string $destino dirección de destino
* @param string $key clave de seguridad necesaria para construir la URL de recuperación
* @return boolean
*/
public static function enviarNotificacionCambioPassword($destino, $key) {
Yii::trace('Enviando correo confirmando el cambio de contraseña', 'application.helpers.EMail');
$url_recuperacion = Yii::app()->params['frontpage'] . '?' . 'key=' . $key . '&email=' . urlencode($destino);
return self::_enviar($destino,
Yii::t('profind', 'Se ha modificado su password en PROFIND'),
'notificacion_cambio_password_usuario',
array('email' => $destino, 'url' => $url_recuperacion));
}
/**
* @brief Envía un correo de registro de agente con una URL para confirmar la cuenta.
* @param string $destino dirección de destino
* @param string $key clave de seguridad necesaria para construir la URL de confirmación
* @return boolean
*/
public static function enviarBienvenidaAgente($destino, $key) {
Yii::trace('Enviando correo de bienvenida a agente', 'application.helpers.EMail');
$url_activacion = Yii::app()->params['frontpage'] . '?' . 'key=' . $key . '&email=' . urlencode($destino) . '&x=1';
return self::_enviar($destino,
Yii::t('profind', 'Complete su registro de agente en PROFIND'),
'registro_agente',
array('email' => $destino, 'url' => $url_activacion));
}
/**
* @brief Envía un correo de registro de coordinador con una URL para confirmar la cuenta.
* @param string $destino dirección de destino
* @param string $key clave de seguridad necesaria para construir la URL de confirmación
* @return boolean
*/
public static function enviarBienvenidaCoordinador($destino, $key) {
Yii::trace('Enviando correo de bienvenida a coordinador', 'application.helpers.EMail');
$url_activacion = Yii::app()->createAbsoluteUrl('usuario/activar', array("key" => $key, "email" => $destino));
return self::_enviar($destino,
Yii::t('profind', 'Complete su registro en PROFIND'),
'registro_usuario',
array('email' => $destino, 'url' => $url_activacion));
}
/**
* @brief Envía un mail de registro a un usuario (coordinador/agente) con
* una URL de confirmación de baja.
* @param string $destino dirección de destino
* @param string $key clave de seguridad necesaria para construir la URL de confirmación
* @return boolean
*/
public static function enviarSolicitudBaja($destino, $key) {
Yii::trace('Enviando correo con URL para realizar la baja de la cuenta', 'application.helpers.EMail');
$url_cancelacion = $this->createAbsoluteUrl('usuario/cancelar', array("key" => $key, "email" => $destino));
return self::_enviar($destino,
Yii::t('profind', 'Solicitud de cancelación de su cuenta en PROFIND'),
'solicitud_cancelacion_usuario',
array('email' => $destino, 'url' => $url_cancelacion));
}
}
?>

View File

@ -0,0 +1,48 @@
<?php
/**
* @class GHelper
* @brief Clase con funciones generales de ayuda.
*
* @package application.helpers
*/
class GHelper {
/**
* @brief Borrado recursivo de un directorio y su contenido
*
* @param string directorio
* @param boolean Si es TRUE vacía el directorio pero no elimina
* @return boolean
*/
public static function recursiveRemoveDirectory($directory, $empty = FALSE) {
if (substr($directory, -1) == '/') {
$directory = substr($directory, 0, -1);
}
if (!file_exists($directory) || !is_dir($directory)) {
return FALSE;
} elseif (is_readable($directory)) {
$handle = opendir($directory);
while (FALSE !== ($item = readdir($handle))) {
if ($item != '.' && $item != '..') {
$path = $directory . '/' . $item;
if (is_dir($path)) {
recursive_remove_directory($path);
} else {
unlink($path);
}
}
}
closedir($handle);
if ($empty == FALSE) {
if (!rmdir($directory)) {
return FALSE;
}
}
}
return TRUE;
}
}
?>

View File

@ -1,46 +0,0 @@
<?php
/*
* Borrado recursivo de un directorio y su contenido
*
* @param string directorio
* @param boolean Si es TRUE vacía el directorio pero no elimina
* @return boolean
*/
function recursive_remove_directory($directory, $empty=FALSE)
{
if(substr($directory,-1) == '/')
{
$directory = substr($directory,0,-1);
}
if(!file_exists($directory) || !is_dir($directory))
{
return FALSE;
}elseif(is_readable($directory))
{
$handle = opendir($directory);
while (FALSE !== ($item = readdir($handle)))
{
if($item != '.' && $item != '..')
{
$path = $directory.'/'.$item;
if(is_dir($path))
{
recursive_remove_directory($path);
}else{
unlink($path);
}
}
}
closedir($handle);
if($empty == FALSE)
{
if(!rmdir($directory))
{
return FALSE;
}
}
}
return TRUE;
}
?>

View File

@ -13,17 +13,23 @@ class m120927_143321_tbl_productos extends CDbMigration
$this->createTable('tbl_subscripciones', array( $this->createTable('tbl_subscripciones', array(
'id' => 'pk', 'id' => 'pk',
'id_usuario' => 'integer', 'id_usuario' => 'integer NOT NULL',
'id_producto' => 'integer', 'id_producto' => 'integer NOT NULL',
'estado' => 'string', 'estado' => 'string',
'fecha_inicio' => 'datetime', 'fecha_inicio' => 'datetime',
'fecha_fin' => 'datetime', 'fecha_fin' => 'datetime',
)); ));
$this->addForeignKey('fk_subscripciones_1', 'tbl_subscripciones', 'id_usuario', 'tbl_usuarios', 'id', 'CASCADE', 'CASCADE');
$this->addForeignKey('fk_subscripciones_2', 'tbl_subscripciones', 'id_producto', 'tbl_productos', 'id', 'CASCADE', 'CASCADE');
} }
public function safeDown() public function safeDown()
{ {
$this->dropTable('tbl_productos'); $this->dropForeignKey('fk_subscripciones_2', 'tbl_subscripciones');
$this->dropForeignKey('fk_subscripciones_1', 'tbl_subscripciones');
$this->dropTable('tbl_subscripciones'); $this->dropTable('tbl_subscripciones');
$this->dropTable('tbl_productos');
} }
} }

View File

@ -173,10 +173,8 @@ class Empresa extends CActiveRecord {
private function deleteUploadDir() { private function deleteUploadDir() {
$upload = $this->getUploadPath(); $upload = $this->getUploadPath();
if(is_dir($upload)) { if(is_dir($upload))
require_once( Yii::getPathOfAlias('application.helpers') . DIRECTORY_SEPARATOR . 'recursive_remove_directory.php'); return GHelper::recursiveRemoveDirectory($upload);
return recursive_remove_directory($upload);
}
else return false; else return false;
} }

View File

@ -1,8 +0,0 @@
<?php
/**
*
*/
class FormularioRegistroAgente extends FormularioExtCambiarPassword {
}

View File

@ -45,6 +45,15 @@ class Producto extends CActiveRecord
); );
} }
public function scopes() {
return array(
'productoInicial' => array(
'condition' => 'id = 1',
'limit' => 1,
),
);
}
/** /**
* @return array relational rules. * @return array relational rules.
*/ */

View File

@ -31,7 +31,7 @@ class Usuario extends CActiveRecord {
const ESTADO_NOACTIVO = 0; const ESTADO_NOACTIVO = 0;
const ESTADO_ACTIVO = 1; const ESTADO_ACTIVO = 1;
const ESTADO_BORRADO = 2; const ESTADO_BORRADO = 2;
const ESTADO_DENEGADO = 3; const ESTADO_BLOQUEADO = 3;
const TIPO_USUARIO_COORDINADOR = 'C'; const TIPO_USUARIO_COORDINADOR = 'C';
const TIPO_USUARIO_AGENTE = 'A'; const TIPO_USUARIO_AGENTE = 'A';
@ -228,10 +228,8 @@ class Usuario extends CActiveRecord {
private function deleteUploadDir() { private function deleteUploadDir() {
$upload = $this->getUploadPath(); $upload = $this->getUploadPath();
if(is_dir($upload)) { if(is_dir($upload))
require_once( Yii::getPathOfAlias('application.helpers') . DIRECTORY_SEPARATOR . 'recursive_remove_directory.php'); return GHelper::recursiveRemoveDirectory($upload);
return recursive_remove_directory($upload);
}
else return false; else return false;
} }

View File

@ -27,7 +27,11 @@ class FormularioCambiarPassword extends CFormModel {
public function comprobarPasswordAnterior($attribute, $params) { public function comprobarPasswordAnterior($attribute, $params) {
if (!$this->hasErrors()) { if (!$this->hasErrors()) {
$usuario = Usuario::model()->findByPk(Yii::app()->user->id); $usuario = Usuario::model()->findByPk(Yii::app()->user->id);
if ($usuario->password != Usuario::model()->encryptPassword($this->passwordAnterior)) $ph = new PasswordHash(
Yii::app()->params['phpass']['iteration_count_log2'],
Yii::app()->params['phpass']['portable_hashes']
);
if (!$ph->checkPassword($this->passwordAnterior, $usuario->password))
$this->addError($this->passwordAnterior, Yii::t('profind', 'La contraseña anterior no es correcta.')); $this->addError($this->passwordAnterior, Yii::t('profind', 'La contraseña anterior no es correcta.'));
} }
} }

View File

@ -3,7 +3,7 @@
/** /**
* *
*/ */
class FormularioExtCambiarPassword extends CFormModel { class FormularioEntradaCambiarPassword extends CFormModel {
public $key; public $key;
public $email; public $email;

View File

@ -3,13 +3,10 @@
/** /**
* *
*/ */
class FormularioRecuperarPassword extends CFormModel { class FormularioEntradaRecuperarPassword extends CFormModel {
public $email; public $email;
/**
*
*/
public function rules() { public function rules() {
return array( return array(
array('email', 'required'), array('email', 'required'),
@ -18,9 +15,6 @@ class FormularioRecuperarPassword extends CFormModel {
); );
} }
/**
*
*/
public function existeEmailUsuario($attribute, $params) { public function existeEmailUsuario($attribute, $params) {
if (!$this->hasErrors()) { if (!$this->hasErrors()) {
$usuario = Usuario::model()->findByAttributes(array('email' => $this->email)); $usuario = Usuario::model()->findByAttributes(array('email' => $this->email));

View File

@ -0,0 +1,8 @@
<?php
/**
*
*/
class FormularioRegistroAgente extends FormularioEntradaCambiarPassword {
}

View File

@ -4,7 +4,7 @@
* Clase que representa los datos enviados por el usuario a través * Clase que representa los datos enviados por el usuario a través
* del formulario de registro de la página de entrada. * del formulario de registro de la página de entrada.
*/ */
class FormularioRegistro extends CFormModel { class FormularioRegistroCoordinador extends CFormModel {
public $email; public $email;
public $password; public $password;

View File

@ -12,6 +12,11 @@
", CClientScript::POS_END); ", CClientScript::POS_END);
?> ?>
<?php Yii::app()->clientScript->registerScript('tooltips', "
$('.user_list').tooltip({selector: 'a[rel=tooltip]'});
", CClientScript::POS_END);
?>
<div class="row-fluid"> <div class="row-fluid">
<div id="lista-agentes" class="span8"> <div id="lista-agentes" class="span8">
<h3 class="heading"><?php echo Yii::t('profind', 'Lista de agentes'); ?></h3> <h3 class="heading"><?php echo Yii::t('profind', 'Lista de agentes'); ?></h3>
@ -24,9 +29,9 @@
<?php foreach ($agentes as $agente) : ?> <?php foreach ($agentes as $agente) : ?>
<li> <li>
<span class="label pull-right sl_status <?php echo ($agente->estaActivo) ? 'label-success' : ''; ?>"> <a class="label pull-right sl_status <?php echo ($agente->estaActivo) ? 'label-success' : ''; ?>" rel="tooltip" href="#" data-original-title="<?php echo ($agente->estaActivo) ? Yii::t('profind', 'Cuenta confirmada') : Yii::t('profind', 'Cuenta sin confirmar por el agente'); ?>">
<?php echo ($agente->estaActivo) ? Yii::t('profind', 'activo') : Yii::t('profind', 'no activo'); ?> <?php echo ($agente->estaActivo) ? Yii::t('profind', 'activo') : Yii::t('profind', 'no activo'); ?>
</span> </a>
<div class="span1"> <div class="span1">
<?php <?php
@ -42,11 +47,12 @@
<small><?php echo $agente->titulo; ?></small><br> <small><?php echo $agente->titulo; ?></small><br>
<?php endif; ?> <?php endif; ?>
<small class="s_color sl_email"><?php echo CHtml::link($agente->email, $agente->email); ?></small><br> <small class="s_color sl_email"><?php echo CHtml::link($agente->email, $agente->email); ?></small><br>
<?php echo CHtml::link(CHtml::tag('span', array('class' => 'icon-trash')), <?php echo CHtml::link(CHtml::tag('span', array('class' => 'icon-trash')),
'#', array( '#', array(
'data-id' => $agente->id, 'data-id' => $agente->id,
'class' => 'close pull-right delete', 'class' => 'close pull-right delete',
'rel' => 'tooltip',
'data-original-title' => Yii::t('profind', 'Eliminar el agente'),
)); ));
?> ?>
<div class="clearfix">&nbsp;</div> <div class="clearfix">&nbsp;</div>
@ -97,7 +103,7 @@
<a href="#" class="btn" data-dismiss="modal" aria-hidden="true"><?php echo Yii::t('profind', 'Volver'); ?></a> <a href="#" class="btn" data-dismiss="modal" aria-hidden="true"><?php echo Yii::t('profind', 'Volver'); ?></a>
<?php echo CHtml::link( <?php echo CHtml::link(
Yii::t('profind', 'Eliminar el agente'), Yii::t('profind', 'Eliminar el agente'),
$this->createUrl('delete', array('id' => 0)), $this->createUrl('deleteMember', array('id' => 0)),
array('class' => 'btn btn-danger') array('class' => 'btn btn-danger')
);?> );?>
</div> </div>

View File

@ -85,7 +85,7 @@ Yii::app()->clientScript->registerScript(
<div class="control-group formSep"> <div class="control-group formSep">
<label class='control-label'><?php echo Yii::t('profind', 'Password'); ?></label> <label class='control-label'><?php echo Yii::t('profind', 'Password'); ?></label>
<div class="controls text_line"> <div class="controls text_line">
<?php echo CHtml::link(Yii::t('profind', 'Cambiar la password'), $this->createUrl('seguridadUsuario/cambiarPassword', array('id' => Yii::app()->user->id))); ?> <?php echo CHtml::link(Yii::t('profind', 'Cambiar la password'), $this->createUrl('cambiarPassword', array('id' => Yii::app()->user->id))); ?>
</div> </div>
</div> </div>