Gestión de documentos de candidato

git-svn-id: https://192.168.0.254/svn/Proyectos.Incam_IntranetNueva/trunk@62 77cfc57b-8ef4-1849-9df6-4a38aa5da120
This commit is contained in:
David Arranz 2012-06-06 16:45:38 +00:00
parent 471f9f24da
commit d3abfa60af
20 changed files with 1068 additions and 27 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -4,8 +4,8 @@
$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
// Set YII_DEBUG and YII_TRACE_LEVEL flags
$debug = true;
$traceLevel = 0;
//$debug = true;
//$traceLevel = 0;
$config = array(
'basePath'=>dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
@ -23,7 +23,6 @@ $config = array(
'ext.PageSize.*',
'application.modules.auditTrail.models.AuditTrail',
),
'modules'=>array(
'auditTrail'=>array(

View File

@ -59,9 +59,12 @@ $configSpecific = array(
),
),
),
),
'params'=>array(
// Ruta de los currículums de los candidatos
'curriculumPath' => dirname(__FILE__) . '/../../documentos/',
),
);
?>

View File

@ -0,0 +1,263 @@
<?php
Yii::import('application.helpers.FileHelper');
Yii::import('application.helpers.GDownloadHelper');
class CandidatoDocumentoController extends Controller {
/**
* @var string the default layout for the views. Defaults to '//layouts/column2', meaning
* using two-column layout. See 'protected/views/layouts/column2.php'.
*/
public $layout = '//layouts/default';
/**
* @return array action filters
*/
public function filters() {
return array(
'accessControl', // perform access control for CRUD operations
);
}
/**
* Specifies the access control rules.
* This method is used by the 'accessControl' filter.
* @return array access control rules
*/
public function accessRules() {
return array(
array('allow', // allow authenticated user to perform 'create' and 'update' actions
'actions' => array('index', 'view', 'create', 'update', 'delete', 'admin', 'upload'),
'users' => array('@'),
),
array('allow', // deny all users
'users' => array('*'),
),
);
}
/**
* Displays a particular model.
* @param integer $id the ID of the model to be displayed
*/
public function actionView($id) {
$this->render('view', array(
'model' => $this->loadModel($id),
));
}
/**
* Guarda el documento en el sistema
* @param CandidatoDocumento $documento el documento
* @param CUploadedFile $file el fichero asociado al documento a guardar
* @return boolean true cuando el fichero se guarda correctamente
*/
private function guardarDocumento($documento, $file) {
if (!is_null($file)) {
$folder = $this->darRutaDocumentos() . $documento->candidato_id . '/';
if (!is_dir($folder))
mkdir($folder, 0755, true);
$file->saveAs($folder . $documento->nombre_fichero);
}
}
/**
* Genera un nombre de fichero para guardar el documento. Se comprueba
* que no exista ningún otro fichero con ese mismo nombre.
* @param CandidatoDocumento $model Documento
* @return string
*/
private function generarNombreDocumento($model) {
$cid = $model->candidato_id;
$old_filename = FileHelper::sanitizeFileName(pathinfo($model->nombre_fichero, PATHINFO_FILENAME));
$ext = pathinfo($model->nombre_fichero, PATHINFO_EXTENSION);
$folder = $this->darRutaDocumentos() . $cid . '/';
$contador = 1;
$filename = $old_filename . '.' . $ext;
// existe el directorio?
if (is_dir($folder)) {
// ya existe el fichero?
while (file_exists($folder . $filename)) {
$filename = $old_filename . '_' . $contador . '.' . $ext;
$contador++;
}
}
return $filename;
}
/**
* Da la ruta donde se guardan los documentos
* @return string ruta de los documentos
*/
private function darRutaDocumentos() {
return Yii::app()->params['curriculumPath'];
}
/**
* Borrar el documento del sistema
* @param CandidatoDocumento $documento el documento a borrar
* @return boolean true cuando el fichero se borra correctamente
*/
private function borrarDocumento($documento) {
$cid = $documento->candidato_id;
$folder = $this->darRutaDocumentos() . $cid . '/';
if (file_exists($folder . $documento->nombre_fichero))
unlink($folder . $documento->nombre_fichero);
}
/**
* Descarga el documento
* @param integer $id el ID del documento
*/
public function actionDownload($id) {
$model = $this->loadModel($id);
$cid = $model->candidato_id;
$folder = $this->darRutaDocumentos() . $model->candidato_id . '/' . $model->nombre_fichero;
GDownloadHelper::send($folder);
}
/**
* Creates a new model.
* @param integer $cid el ID del candidato
*/
public function actionCreate($cid) {
$model = new CandidatoDocumento;
$model->candidato_id = $cid;
$candidato = Candidato::model()->findByPk($cid);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['CandidatoDocumento'])) {
$model->attributes = $_POST['CandidatoDocumento'];
$documento = CUploadedFile::getInstance($model, 'file');
$model->nombre_fichero = $documento->name;
// Me aseguro que el nombre del fichero no tiene "cosas raras"
$model->nombre_fichero = $this->generarNombreDocumento($model);
if ($model->save()) {
$this->guardarDocumento($model, $documento);
Yii::app()->user->setFlash('success', Yii::t('intranet', 'Currículum guardado correctamente.'));
$url = $this->createUrl('index', array('cid' => $model->candidato_id));
$this->redirect($url);
}
}
$this->render('create', array(
'model' => $model,
'candidato' => $candidato,
));
}
/**
* Updates a particular model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id the ID of the model to be updated
*/
public function actionUpdate($id) {
$model = $this->loadModel($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if (isset($_POST['CandidatoDocumento'])) {
$model->attributes = $_POST['CandidatoDocumento'];
if ($model->save())
$this->redirect(array('view', 'id' => $model->id));
}
$this->render('update', array(
'model' => $model,
));
}
/**
* Deletes a particular model.
* If deletion is successful, the browser will be redirected to the 'admin' page.
* @param integer $id the ID of the model to be deleted
*/
public function actionDelete($id) {
if (Yii::app()->request->isPostRequest) {
// we only allow deletion via POST request
$model = $this->loadModel($id);
if ($model->delete()) {
$this->borrarDocumento($model);
}
// 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('admin'));
}
else
throw new CHttpException(400, 'Invalid request. Please do not repeat this request again.');
}
/**
* Lists all models.
*/
public function actionIndex($cid) {
$this->layout = '//layouts/candidato';
$candidato = Candidato::model()->findByPk($cid);
$dataProvider = new CActiveDataProvider('CandidatoDocumento', array(
'criteria' => array(
'condition' => 'candidato_id=' . $cid,
),
));
$this->render('index', array(
'dataProvider' => $dataProvider,
'candidato' => $candidato,
));
}
/**
* Manages all models.
*/
public function actionAdmin() {
$model = new CandidatoDocumento('search');
$model->unsetAttributes(); // clear any default values
if (isset($_GET['CandidatoDocumento']))
$model->attributes = $_GET['CandidatoDocumento'];
$this->render('admin', array(
'model' => $model,
));
}
/**
* 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.
* @param integer the ID of the model to be loaded
*/
public function loadModel($id) {
$model = CandidatoDocumento::model()->findByPk($id);
if ($model === null)
throw new CHttpException(404, 'The requested page does not exist.');
return $model;
}
/**
* Performs the AJAX validation.
* @param CModel the model to be validated
*/
protected function performAjaxValidation($model) {
if (isset($_POST['ajax']) && $_POST['ajax'] === 'candidato-documento-form') {
echo CActiveForm::validate($model);
Yii::app()->end();
}
}
}

View File

@ -0,0 +1,46 @@
<?php
/**
* FileHelper holds a collection of static methods, useful for generic purposes
*
*/
class FileHelper {
/**
* Returns a safe filename by replacing all dangerous characters
* with an underscore.
*
* @param string $filename The source filename to be "sanitized"
*
* @return Boolean string A safe version of the input filename
*/
public static function sanitizeFileName($filename) {
// replace non letter or digits by -
$filename = preg_replace('#[^\\pL\d]+#u', '-', $filename);
// trim
$filename = trim($filename, '-');
// transliterate
if (function_exists('iconv')) {
$filename = iconv('utf-8', 'us-ascii//TRANSLIT', $filename);
}
// lowercase
$filename = strtolower($filename);
// remove unwanted characters
$filename = preg_replace('#[^-\w]+#', '', $filename);
if (empty($filename)) {
return 'n-a';
}
return $filename;
}
}
// usage:
//$safe_filename = FileHelper::sanitizeFileName('#my unsaf&/file\name?"');
?>;

View File

@ -0,0 +1,200 @@
<?php
/**
* @author Rasmus Schultz
* @link http://mindplay.dk
* @copyright Copyright &copy; 2010 Rasmus Schultz
* @license http://www.gnu.org/licenses/lgpl-3.0.txt
*/
/**
* This class allows multi-threaded file downloads, and regular file downloads.
*
* You can use this class when you need to control which users are allowed to
* download a file from a protected area of the local filesystem.
*
* Note that downloading files in this way does result in some memory and processor
* overhead - you should not use this class sporadically for all downloads in your
* application, only when a regular download is not possible for some reason (usually
* because the file in question must not be made available to the general public).
*
* Avoid using this class when you need to log access to a public file - you're
* probably better off using a pre-download logging action, which then redirects to
* the actual file download.
*/
class GDownloadHelper {
/**
* Buffer size (memory requirement per download / user / thread)
*/
const BUFFER_SIZE = 32768; # = 1024*32
/**
* Time limit (time allowed to send one buffer)
*/
const TIME_LIMIT = 30;
/**
* Sends a file to the client.
*
* This is a blocking method, which means that the method-call will not return until
* the client has completed the download of the file (or segment), or until the client
* is disconnected and the connection/download is aborted.
*
* Check the return value of this method to see if the download was successful - this
* if useful, for example, if you need to count and limit the number of times a user can
* download a file; you should increase your counters only if the call returns TRUE.
*
* It is important that your action produces <strong>no other output</strong> before
* or after calling this method, as this will corrupt the downloaded binary file.
*
* Output buffers will be cleared and disabled, and any active CWebLogRoute instances
* (which might otherwise output logging information at the end of the request) will
* be detected and disabled.
*
* If your application might produce any other output after your action completes, you
* should suppress this by using the exit statement at the end of your action.
*
* This method throws a CException if the specified path does not point to a valid file.
*
* This method throws a CHttpException (416) if the requested range is invalid.
*
* @param string full path to a file on the local filesystem being sent to the client.
* @param string optional, alternative filename as the client will see it (defaults to the local filename specified in $path)
* @return boolean true if the download succeeded, false if the connection was aborted prematurely.
*/
public static function send($path, $name=null)
{
// turn off output buffering
while (ob_get_level())
ob_end_clean();
// disable any CWebLogRoutes to prevent them from outputting at the end of the request
foreach (Yii::app()->log->routes as $route)
if ($route instanceof CWebLogRoute)
$route->enabled = false;
// obtain headers:
$envs = '';
foreach ($_ENV as $item => $value)
if (substr($item, 0, 5) == 'HTTP_')
$envs .= $item.' => '.$value."\n";
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
foreach ($headers as $header => $value) {
$envs .= "apache: $header = $value\n";
}
}
// obtain filename, if needed:
if (is_null($name))
$name = basename($path);
// verify path and connection status:
if (!is_file($path) || !is_readable($path) || connection_status()!=0)
throw new CException('GDownload::send() : unable to access local file "'.$path.'"');
// obtain filesize:
$size = filesize($path);
// configure download range for multi-threaded / resumed downloads:
if (isset($_ENV['HTTP_RANGE']))
{
list($a, $range) = explode("=", $_ENV['HTTP_RANGE']);
}
else if (function_exists('apache_request_headers'))
{
$headers = apache_request_headers();
if (isset($headers['Range'])) {
list($a, $range) = explode("=", $headers['Range']);
} else {
$range = false;
}
}
else
{
$range = false;
}
// produce required headers for partial downloads:
if ($range)
{
header('HTTP/1.1 206 Partial content');
list($begin, $end) = explode("-", $range);
if ($begin == '')
{
$begin = $size-$end;
$end = $size-1;
}
else if ($end == '')
{
$end = $size-1;
}
$header = 'Content-Range: bytes '.$begin.'-'.$end.'/'.($size);
$size = $end-$begin+1;
}
else
{
$header = false;
$begin = 0;
$end = $size-1;
}
// check range:
if (($begin > $size-1) || ($end > $size-1) || ($begin > $end))
throw new CHttpException(416,'Requested range not satisfiable');
// suppress client-side caching:
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
header("Expires: ".gmdate("D, d M Y H:i:s", mktime(date("H")+2, date("i"), date("s"), date("m"), date("d"), date("Y")))." GMT");
header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
// send a generic content-type:
header("Content-Type: application/octet-stream");
// send content-range header, if present:
if ($header) header($header);
// send content-length header:
header("Content-Length: ".$size);
// send content-disposition, with special handling for IE:
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== FALSE)
{
header("Content-Disposition: inline; filename=".str_replace(' ', '%20', $name));
}
else
{
header("Content-Disposition: inline; filename=\"$name\"");
}
// set encoding:
header("Content-Transfer-Encoding: binary\n");
// stream out the binary data:
if ($file = fopen($path, 'rb'))
{
fseek($file, $begin);
$sent = 0;
while ($sent < $size)
{
set_time_limit(self::TIME_LIMIT);
$bytes = $end - ftell($file) + 1;
if ($bytes > self::BUFFER_SIZE)
$bytes = self::BUFFER_SIZE;
echo fread($file, $bytes);
$sent += $bytes;
flush();
if (connection_aborted())
break;
}
fclose($file);
}
// check connection status and return:
$status = (connection_status()==0) and !connection_aborted();
return $status;
}
}

View File

@ -0,0 +1,34 @@
<?php
class m120504_095056_tbl_candidatos_documentos extends CDbMigration
{
public function up()
{
$this->createTable('tbl_candidatos_documentos', array(
'id' => 'pk',
'candidato_id' => 'integer NOT NULL',
'fecha' => 'datetime',
'tipo' => 'string',
'nombre_fichero' => 'string',
));
$this->addForeignKey('fk_candidatos_documentos_1', 'tbl_candidatos_documentos', 'candidato_id', 'tbl_candidatos', 'id', 'CASCADE', 'CASCADE');
}
public function down()
{
$this->dropForeignKey('fk_candidatos_documentos_1', 'tbl_candidatos_documentos');
$this->dropTable('tbl_candidatos_documentos');
return false;
}
/*
// Use safeUp/safeDown to do migration with transaction
public function safeUp()
{
}
public function safeDown()
{
}
*/
}

View File

@ -35,6 +35,7 @@
* @property CandidatoCapacidad[] $capacidades
* @property CandidatoIdioma[] $idiomas
* @property CandidatoTitulacion[] $titulaciones
* @property CandidatoDocumento[] $documentos
*/
class Candidato extends CActiveRecord
{
@ -204,6 +205,8 @@ class Candidato extends CActiveRecord
'idiomasCount' => array(self::STAT, 'CandidatoIdioma', 'candidato_id'),
'titulaciones' => array(self::HAS_MANY, 'CandidatoTitulacion', 'candidato_id'),
'titulacionesCount' => array(self::STAT, 'CandidatoTitulacion', 'candidato_id'),
'documentos' => array(self::HAS_MANY, 'CandidatoDocumento', 'candidato_id'),
'documentosCount' => array(self::STAT, 'CandidatoDocumento', 'candidato_id'),
);
}

View File

@ -0,0 +1,145 @@
<?php
/**
* This is the model class for table "tbl_candidatos_documentos".
*
* The followings are the available columns in table 'tbl_candidatos_documentos':
* @property integer $id
* @property integer $candidato_id
* @property datetime $fecha
* @property string $tipo
* @property string $nombre_fichero
*
* The followings are the available model relations:
* @property Candidatos $candidato
*/
class CandidatoDocumento extends CActiveRecord
{
public $url;
const TIPO_INTERNO='Interno';
const TIPO_COMERCIAL='Comercial';
/**
* Devuelve la lista de tipos de documento.
* @return array lista de tipos
*/
public function getOpcionesTipo() {
return array(
self::TIPO_INTERNO => 'Interno',
self::TIPO_COMERCIAL => 'Comercial'
);
}
public function getReadableFileSize($retstring = null) {
// adapted from code at http://aidanlister.com/repos/v/function.size_readable.php
$sizes = array('bytes', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
if ($retstring === null) { $retstring = '%01.2f %s'; }
$lastsizestring = end($sizes);
foreach ($sizes as $sizestring) {
if ($this->size < 1024) { break; }
if ($sizestring != $lastsizestring) { $this->size /= 1024; }
}
if ($sizestring == $sizes[0]) { $retstring = '%01d %s'; } // Bytes aren't normally fractional
return sprintf($retstring, $this->size, $sizestring);
}
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return CandidatoDocumento the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'tbl_candidatos_documentos';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('candidato_id', 'required'),
array('candidato_id', 'numerical', 'integerOnly'=>true),
array('tipo, nombre_fichero', 'length', 'max'=>255),
array('fecha', 'safe'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, candidato_id, fecha, tipo, nombre_fichero', 'safe', 'on'=>'search'),
);
}
protected function afterConstruct() {
// Valores por defecto
$this->tipo = self::TIPO_INTERNO;
$this->fecha = date('Y-m-d H:i:s', time());
parent::afterConstruct();
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'candidato' => array(self::BELONGS_TO, 'Candidatos', 'candidato_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'candidato_id' => 'Candidato',
'fecha' => 'Fecha',
'tipo' => 'Tipo',
'nombre_fichero' => 'Nombre',
'file' => 'Fichero',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id);
$criteria->compare('candidato_id',$this->candidato_id);
$criteria->compare('fecha',$this->fecha,true);
$criteria->compare('tipo',$this->tipo,true);
$criteria->compare('nombre_fichero',$this->nombre_fichero,true);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}

View File

@ -0,0 +1,52 @@
<?php
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
?>
<div class="content nopadding ohidden">
<div class="padding1020">
<label><?php echo Yii::t('intranet', 'Currículums'); ?></label>
<div class="marginleft150">
<?php $this->widget('ext.multimodelform.MultiModelForm',array(
'id' => 'id_capacidad', //the unique widget id
'addItemText' => '', // no quiero mostrar el enlace de añadir
'removeText' => 'Eliminar',
'removeConfirm' => '¿Desea eliminar esta capacidad?',
'tableHtmlOptions' => array(
'class' => 'sTable2 lf',
),
'tableView' => true,
'formConfig' => $capacidadFormConfig, //the form configuration array
'model' => $capacidad, //instance of the form model
//if submitted not empty from the controller,
//the form will be rendered with validation errors
'validatedItems' => $capacidadesValidas,
//array of member instances loaded from db
'data' => $capacidad->findAll('candidato_id=:candidato_id', array(':candidato_id'=>$model->id)),
'removeHtmlOptions' => array(
'class' => 'button plain',
),
));
?>
<br clear="all" />
<div class="mmf_addlink">
<?php
echo CHtml::link('Añadir capacidad', '#', array(
'class' => 'button plain',
'rel' => '.id_capacidad_copy',
'id' => 'id_capacidad',
));
?>
</div>
<br clear="all" />
</div>
</div>
</div>

View File

@ -1,25 +1,5 @@
<?php
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . '/js/custom/elements.js');
/*Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . '/js/plugins/wysiwyg/jquery.wysiwyg.js');
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . 'js/plugins/wysiwyg/wysiwyg.image.js');
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . 'js/plugins/wysiwyg/wysiwyg.link.js');
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . 'js/plugins/wysiwyg/wysiwyg.table.js');
$script=<<<HTML
jQuery(document).ready(function() {
jQuery('#wysiwyg').wysiwyg({
initialContent: "",
controls: {
cut: { visible: true },
copy: { visible: true },
paste: { visible: true }
}
});
});
HTML;
Yii::app()->clientScript->registerScript('wysiwyg', $script, CClientScript::POS_END);*/
?>
<?php $form=$this->beginWidget('CActiveForm', array(

View File

@ -0,0 +1,52 @@
<?php
Yii::app()->clientScript->registerScriptFile(Yii::app()->baseUrl . '/js/custom/elements.js');
?>
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'candidato-documento-form',
'enableAjaxValidation'=>false,
'htmlOptions' => array('enctype' => 'multipart/form-data'),
//'clientOptions'=>array('validateOnSubmit'=>true, 'validateOnChange'=>true),
)); ?>
<div class="two_third last">
<div class="notification msginfo">
<a class="close"></a>
<p>Los campos marcados con <span class="required">*</span> son obligatorios.</p>
</div><!-- notification msginfo -->
<?php echo $form->errorSummary($model, "<a class='close'></a>", "", array('class'=>"notification msgerror")); ?>
</div>
<br clear="all" />
<div class="widgetbox two_third last form_default">
<h3>
<span>
<legend><?php echo Yii::t('intranet', 'Currículum'); ?></legend>
</span>
</h3>
<div class="content nopadding">
<div class="padding1020">
<?php echo $form->labelEx($model,'tipo', array('class'=>'nopadding')); ?>
<div class="marginleft150">
<?php echo CHtml::activeRadioButtonList($model, 'tipo', $model->OpcionesTipo, array(
'template' => '{input}{label}',
'separator' => '&nbsp;&nbsp;&nbsp;',
)); ?>
<?php echo $form->error($model,'tipo', array('class'=>'errortext')); ?>
</div>
</div>
<div class="padding1020 borderbottom">
<?php echo $form->labelEx($model,'file'); ?>
<div class="marginleft150">
<?php echo CHtml::activeFileField($model, 'file'); ?>
</div>
</div>
</div>
</div>
<br clear="all" />
<div class="form_default">
<button type="submit"><?php echo $model->isNewRecord ? 'Crear' : 'Guardar'; ?></button>
</div>
<?php $this->endWidget(); ?>

View File

@ -0,0 +1,39 @@
<div class="wide form">
<?php $form=$this->beginWidget('CActiveForm', array(
'action'=>Yii::app()->createUrl($this->route),
'method'=>'get',
)); ?>
<div class="row">
<?php echo $form->label($model,'id'); ?>
<?php echo $form->textField($model,'id'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'candidato_id'); ?>
<?php echo $form->textField($model,'candidato_id'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'fecha'); ?>
<?php echo $form->textField($model,'fecha'); ?>
</div>
<div class="row">
<?php echo $form->label($model,'tipo'); ?>
<?php echo $form->textField($model,'tipo',array('size'=>60,'maxlength'=>255)); ?>
</div>
<div class="row">
<?php echo $form->label($model,'nombre_fichero'); ?>
<?php echo $form->textField($model,'nombre_fichero',array('size'=>60,'maxlength'=>255)); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton('Search'); ?>
</div>
<?php $this->endWidget(); ?>
</div><!-- search-form -->

View File

@ -0,0 +1,24 @@
<div class="view">
<b><?php echo CHtml::encode($data->getAttributeLabel('id')); ?>:</b>
<?php echo CHtml::link(CHtml::encode($data->id), array('view', 'id'=>$data->id)); ?>
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('candidato_id')); ?>:</b>
<?php echo CHtml::encode($data->candidato_id); ?>
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('fecha')); ?>:</b>
<?php echo CHtml::encode($data->fecha); ?>
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('tipo')); ?>:</b>
<?php echo CHtml::encode($data->tipo); ?>
<br />
<b><?php echo CHtml::encode($data->getAttributeLabel('nombre_fichero')); ?>:</b>
<?php echo CHtml::encode($data->nombre_fichero); ?>
<br />
</div>

View File

@ -0,0 +1,54 @@
<?php
$this->breadcrumbs=array(
'Candidato Documentos'=>array('index'),
'Manage',
);
$this->menu=array(
array('label'=>'List CandidatoDocumento', 'url'=>array('index')),
array('label'=>'Create CandidatoDocumento', 'url'=>array('create')),
);
Yii::app()->clientScript->registerScript('search', "
$('.search-button').click(function(){
$('.search-form').toggle();
return false;
});
$('.search-form form').submit(function(){
$.fn.yiiGridView.update('candidato-documento-grid', {
data: $(this).serialize()
});
return false;
});
");
?>
<h1>Manage Candidato Documentos</h1>
<p>
You may optionally enter a comparison operator (<b>&lt;</b>, <b>&lt;=</b>, <b>&gt;</b>, <b>&gt;=</b>, <b>&lt;&gt;</b>
or <b>=</b>) at the beginning of each of your search values to specify how the comparison should be done.
</p>
<?php echo CHtml::link('Advanced Search','#',array('class'=>'search-button')); ?>
<div class="search-form" style="display:none">
<?php $this->renderPartial('_search',array(
'model'=>$model,
)); ?>
</div><!-- search-form -->
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'candidato-documento-grid',
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'id',
'candidato_id',
'fecha',
'tipo',
'nombre_fichero',
array(
'class'=>'CButtonColumn',
),
),
)); ?>

View File

@ -0,0 +1,12 @@
<?php
$this->breadcrumbs=array(
Yii::t('intranet', 'Candidatos') => array('candidato/index'),
$candidato->nombre . ' ' . $candidato->apellidos => $this->createUrl('candidato/view',array('id' => $candidato->id)),
Yii::t('intranet', 'Currículums') => $this->createUrl('candidatoDocumento/index', array('cid'=>$candidato->id)),
Yii::t('intranet', 'Añadir currículum'),
);
$this->pageTitle=Yii::t('intranet', 'Añadir currículum de candidato');
?>
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>

View File

@ -0,0 +1,90 @@
<?php
$this->breadcrumbs=array(
Yii::t('intranet', 'Candidatos') => array('candidato/index'),
$candidato->nombre . ' ' . $candidato->apellidos => array('candidato/view','id'=>$candidato->id),
Yii::t('intranet', 'Currículums'),
);
$this->pageTitle = Yii::t('intranet', 'Gestión de currículums de candidato');
?>
<?php
echo CHtml::link(
Yii::t('intranet', 'Añadir currículum'),
$this->createUrl('candidatoDocumento/create', array('cid'=>$candidato->id)),
array(
'class' => 'anchorbutton button_white',
)
);
?>
<br clear="all" />
<br clear="all" />
<div class="widgetbox">
<div class="content nopadding ohidden">
<?php
$columns = array(
array(
'name' => 'tipo',
'headerHtmlOptions'=>array(
'style' => 'width:75px;',
'class' => 'head0',
),
'cssClassExpression' => '"con1"',
),
array(
'type' => 'html',
'name' => 'nombre_fichero',
'value' => 'CHtml::link(CHtml::encode($data->nombre_fichero), array("download", "id"=>$data->id));',
'headerHtmlOptions'=>array(
'class' => 'head1',
),
'cssClassExpression' => '"con0"',
),
array(
'type' => 'raw',
'name' => 'fecha',
'value' => 'Time::timeAgoInWords($data->fecha);',
'headerHtmlOptions'=>array(
'style' => 'width:150px;',
'class' => 'head0',
),
'cssClassExpression' => '"con1"',
),
array(
'header'=>Yii::t('intranet', 'Acciones'),
'class'=>'CButtonColumn',
'headerHtmlOptions'=>array(
'style' => 'width:55px;',
'class' => 'head0',
),
'template'=>'{delete}',
'cssClassExpression' => '"con1"',
),
);
$pageSize = Yii::app()->user->getState('pageSize', Yii::app()->params['defaultPageSize']);
$dataProvider->getPagination()->setPageSize($pageSize);
$this->widget('application.extensions.SelGridView', array(
'id'=>'documentos-grid',
'dataProvider'=>$dataProvider,
'columns'=>$columns,
'cssFile' => Yii::app()->baseUrl . '/css/gridview3.css',
'itemsCssClass' => 'sTable3',
'pagerCssClass' => 'dataTables_paginate',
'template' => '{items}{pager}',
'emptyText' => Yii::t('intranet', 'Este candidato no tiene documentos'),
'selectableRows' => 1,
));
?>
</div>
</div>

View File

@ -0,0 +1,18 @@
<?php
$this->breadcrumbs=array(
'Candidato Documentos'=>array('index'),
$model->id=>array('view','id'=>$model->id),
'Update',
);
$this->menu=array(
array('label'=>'List CandidatoDocumento', 'url'=>array('index')),
array('label'=>'Create CandidatoDocumento', 'url'=>array('create')),
array('label'=>'View CandidatoDocumento', 'url'=>array('view', 'id'=>$model->id)),
array('label'=>'Manage CandidatoDocumento', 'url'=>array('admin')),
);
?>
<h1>Update CandidatoDocumento <?php echo $model->id; ?></h1>
<?php echo $this->renderPartial('_form', array('model'=>$model)); ?>

View File

@ -0,0 +1,27 @@
<?php
$this->breadcrumbs=array(
'Candidato Documentos'=>array('index'),
$model->id,
);
$this->menu=array(
array('label'=>'List CandidatoDocumento', 'url'=>array('index')),
array('label'=>'Create CandidatoDocumento', 'url'=>array('create')),
array('label'=>'Update CandidatoDocumento', 'url'=>array('update', 'id'=>$model->id)),
array('label'=>'Delete CandidatoDocumento', 'url'=>'#', 'linkOptions'=>array('submit'=>array('delete','id'=>$model->id),'confirm'=>'Are you sure you want to delete this item?')),
array('label'=>'Manage CandidatoDocumento', 'url'=>array('admin')),
);
?>
<h1>View CandidatoDocumento #<?php echo $model->id; ?></h1>
<?php $this->widget('zii.widgets.CDetailView', array(
'data'=>$model,
'attributes'=>array(
'id',
'candidato_id',
'fecha',
'tipo',
'nombre_fichero',
),
)); ?>

View File

@ -45,9 +45,9 @@ $pestañas = array(
),
array(
'label' => Yii::t('intranet', 'Currículums'),
'url' => array('/usuario'),
'url' => $this->createUrl('candidatoDocumento/index', array('cid'=>$candidatoId)),
'linkOptions' => array('class'=>'curriculum'),
'active' => ($this->id == 'curriculum')
'active' => ($this->id == 'candidatoDocumento')
),
array(
'label' => Yii::t('intranet', 'Historial'),