Documentos (CV) de los candidatos (a falta de repaso)
git-svn-id: https://192.168.0.254/svn/Proyectos.Incam_PROFIND_Web/trunk@74 3fe1ab16-cfe0-e34b-8c9f-7d8c168d430d
This commit is contained in:
parent
40dc4031b5
commit
b4eedbc7ee
@ -180,6 +180,7 @@ class CandidatoController extends Controller {
|
||||
throw new CHttpException(405, Yii::t('profind', 'Método no permitido.'));
|
||||
}
|
||||
Yii::trace(CVarDumper::dumpAsString($_POST));
|
||||
Yii::trace(CVarDumper::dumpAsString($_FILES));
|
||||
|
||||
// Candidato
|
||||
$candidato->attributes = $_POST['Candidato'];
|
||||
@ -239,6 +240,29 @@ class CandidatoController extends Controller {
|
||||
$candidato->idiomas = $listaIdiomas;
|
||||
}
|
||||
|
||||
// Documentos del candidato
|
||||
$listaDocumentosBorrar = array();
|
||||
if (isset($_POST['CandidatoDocumento'])) {
|
||||
$listaDocumentos = array();
|
||||
foreach ($_POST['CandidatoDocumento'] as $key => $documento) {
|
||||
if ($documento['id'])
|
||||
$candidatoDocumento = CandidatoDocumento::model()->findByPk($documento['id']);
|
||||
else {
|
||||
$candidatoDocumento = new CandidatoDocumento();
|
||||
$candidatoDocumento->ficheroDocumento = CUploadedFile::getInstance($candidatoDocumento, "[$key]nombre_fichero");
|
||||
Yii::trace(CVarDumper::dumpAsString($candidatoDocumento->ficheroDocumento));
|
||||
}
|
||||
$candidatoDocumento->attributes = $documento;
|
||||
$candidatoDocumento->id_candidato = $candidato->id;
|
||||
|
||||
if ($documento['_borrar'])
|
||||
$listaDocumentosBorrar[] = $candidatoDocumento;
|
||||
else
|
||||
$listaDocumentos[] = $candidatoDocumento;
|
||||
}
|
||||
$candidato->documentos = $listaDocumentos;
|
||||
}
|
||||
|
||||
// Guardar los datos
|
||||
$errores = array();
|
||||
$transaccion = Yii::app()->db->beginTransaction();
|
||||
@ -326,6 +350,30 @@ class CandidatoController extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
// Documentos
|
||||
if (!empty($listaDocumentosBorrar)) {
|
||||
Yii::trace('Eliminando documentos marcados para borrar', 'application.controllers.CandidatoController');
|
||||
foreach ($listaDocumentosBorrar as $candidatoDocumento) {
|
||||
Yii::trace('Eliminando documento... ', 'application.controllers.CandidatoController');
|
||||
Yii::trace(CVarDumper::dumpAsString($candidatoDocumento->attributes), 'application.controllers.CandidatoController');
|
||||
if (!$candidatoDocumento->delete()) {
|
||||
$errores = array_merge($errores, $candidatoDocumento->getErrors());
|
||||
throw new CException('Error al eliminar un documento del candidato');
|
||||
}
|
||||
}
|
||||
$listaDocumentosBorrar = NULL;
|
||||
}
|
||||
if (!empty($candidato->documentos)) {
|
||||
Yii::trace('Guardando la lista de documentos', 'application.controllers.CandidatoController');
|
||||
foreach ($candidato->documentos as $candidatoDocumento) {
|
||||
Yii::trace(CVarDumper::dumpAsString($candidatoDocumento->attributes), 'application.controllers.CandidatoController');
|
||||
if (!$candidatoDocumento->save()) {
|
||||
$errores = array_merge($errores, $candidatoDocumento->getErrors());
|
||||
throw new CException('Error al guardar un documento del candidato');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$transaccion->commit();
|
||||
Yii::trace('Candidato guardado', 'application.controllers.CandidatoController');
|
||||
Yii::app()->user->setFlash('success', Yii::t('profind', 'Se ha actualizado el candidato'));
|
||||
|
||||
46
www/protected/helpers/FileHelper.php
Normal file
46
www/protected/helpers/FileHelper.php
Normal 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?"');
|
||||
?>;
|
||||
200
www/protected/helpers/GDownloadHelper.php
Normal file
200
www/protected/helpers/GDownloadHelper.php
Normal file
@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* @author Rasmus Schultz
|
||||
* @link http://mindplay.dk
|
||||
* @copyright Copyright © 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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @class m121114_120630_tbl_candidatos_documentos
|
||||
* @var $this CDbMigration
|
||||
* @package application.migrations
|
||||
*/
|
||||
|
||||
class m121114_120630_tbl_candidatos_documentos extends CDbMigration {
|
||||
|
||||
public function safeUp() {
|
||||
$this->createTable('tbl_candidatos_documentos', array(
|
||||
'id' => 'pk',
|
||||
'id_candidato' => 'integer NOT NULL',
|
||||
'fecha' => 'datetime',
|
||||
'titulo' => 'string',
|
||||
'nombre_fichero' => 'string',
|
||||
), 'ENGINE=InnoDB CHARSET=utf8');
|
||||
$this->addForeignKey('fk_candidatos_documentos_1', 'tbl_candidatos_documentos', 'id_candidato', 'tbl_candidatos', 'id', 'CASCADE', 'CASCADE');
|
||||
}
|
||||
|
||||
public function safeDown() {
|
||||
$this->dropForeignKey('fk_candidatos_documentos_1', 'tbl_candidatos_documentos');
|
||||
$this->dropTable('tbl_candidatos_documentos');
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@ -38,6 +38,7 @@
|
||||
* @property CandidatoTitulacion[] $titulaciones
|
||||
* @property CandidatoAreaFuncional[] $areasFuncionales
|
||||
* @property CandidatoCapacidadProfesional[] $capacidadesProfesionales
|
||||
* @property CandidatoDocumento[] $documentos
|
||||
*
|
||||
* @package application.models
|
||||
*
|
||||
@ -134,7 +135,7 @@ class Candidato extends CActiveRecord {
|
||||
|
||||
|
||||
array('fecha_nacimiento, observaciones', 'safe'),
|
||||
array('fecha_nacimiento', 'date', 'format' => 'dd/MM/yyyy'),
|
||||
array('fecha_nacimiento', 'date', 'format' => 'dd/mm/yyyy'),
|
||||
|
||||
// The following rule is used by search().
|
||||
// Please remove those attributes that should not be searched.
|
||||
@ -167,7 +168,10 @@ class Candidato extends CActiveRecord {
|
||||
'areasFuncionalesCount' => array(self::STAT, 'CandidatoAreaFuncional', 'id_candidato'),
|
||||
|
||||
'capacidadesProfesionales' => array(self::HAS_MANY, 'CandidatoCapacidadProfesional', 'id_candidato'),
|
||||
'capacidadesProfesionalesCount' => array(self::STAT, 'CandidatoTitulacion', 'id_candidato'),
|
||||
'capacidadesProfesionalesCount' => array(self::STAT, 'CandidatoCapacidadProfesional', 'id_candidato'),
|
||||
|
||||
'documentos' => array(self::HAS_MANY, 'CandidatoDocumento', 'id_candidato'),
|
||||
'documentosCount' => array(self::STAT, 'CandidatoDocumento', 'id_candidato'),
|
||||
);
|
||||
}
|
||||
|
||||
@ -316,7 +320,7 @@ class Candidato extends CActiveRecord {
|
||||
|
||||
return parent::beforeSave();
|
||||
}
|
||||
|
||||
|
||||
protected function afterFind() {
|
||||
$this->fotografia = new FotografiaPerfil();
|
||||
$this->fotografia->modelo = $this;
|
||||
@ -330,8 +334,13 @@ class Candidato extends CActiveRecord {
|
||||
$this->fotografia->modelo = $this;
|
||||
}
|
||||
|
||||
protected function afterValidate() {
|
||||
parent::afterValidate();
|
||||
}
|
||||
|
||||
protected function afterSave() {
|
||||
parent::afterSave();
|
||||
$this->fecha_nacimiento = Yii::app()->dateFormatter->formatDateTime(CDateTimeParser::parse($this->fecha_nacimiento, 'yyyy-MM-dd'), 'medium', null);
|
||||
if ($this->isNewRecord)
|
||||
$this->createUploadDir();
|
||||
}
|
||||
|
||||
218
www/protected/models/CandidatoDocumento.php
Normal file
218
www/protected/models/CandidatoDocumento.php
Normal file
@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @class CandidatoDocumento
|
||||
* @brief Modelo de la tabla "tbl_candidatos_documentos".
|
||||
*
|
||||
* The followings are the available columns in table 'tbl_candidatos_documentos':
|
||||
* @property integer $id
|
||||
* @property integer $id_candidato
|
||||
* @property datetime $fecha
|
||||
* @property string $titulo
|
||||
* @property string $nombre_fichero
|
||||
*
|
||||
* @property CUploadedFile $ficheroDocumento
|
||||
*
|
||||
* The followings are the available model relations:
|
||||
* @property Candidatos $candidato
|
||||
*/
|
||||
class CandidatoDocumento extends CActiveRecord {
|
||||
|
||||
public $ficheroDocumento;
|
||||
|
||||
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('id_candidato, titulo, fecha', 'required'),
|
||||
array('nombre_fichero', 'required', 'on' => 'insert'),
|
||||
array('id_candidato', 'numerical', 'integerOnly' => true),
|
||||
array('titulo, nombre_fichero', 'length', 'max' => 255),
|
||||
array('titulo, nombre_fichero, fecha', 'safe'),
|
||||
|
||||
array('ficheroDocumento', 'file',
|
||||
//'types' => 'pdf, doc, docx, txt, odt',
|
||||
'maxSize' => 1024 * 1024 * 5, // 5MB como máximo
|
||||
'tooLarge' => Yii::t('profind', 'El documento es demasiado pesado.'),
|
||||
//'wrongType' => Yii::t('profind', 'Sólo se permiten documentos en formato PDF, DOC, DOCX, TXT, ODT.'),
|
||||
'allowEmpty' => 'false',
|
||||
),
|
||||
|
||||
// The following rule is used by search().
|
||||
// Please remove those attributes that should not be searched.
|
||||
array('id, id_candidato, fecha, titulo, nombre_fichero', 'safe', 'on' => 'search'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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, 'Candidato', 'id_candidato'),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array customized attribute labels (name=>label)
|
||||
*/
|
||||
public function attributeLabels() {
|
||||
return array(
|
||||
'id' => 'ID',
|
||||
'id_candidato' => 'Candidato',
|
||||
'fecha' => 'Fecha',
|
||||
'titulo' => 'Título',
|
||||
'nombre_fichero' => 'Nombre',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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('id_candidato', $this->id_candidato);
|
||||
$criteria->compare('fecha', $this->fecha, true);
|
||||
$criteria->compare('titulo', $this->titulo, true);
|
||||
$criteria->compare('nombre_fichero', $this->nombre_fichero, true);
|
||||
|
||||
return new CActiveDataProvider($this, array(
|
||||
'criteria' => $criteria,
|
||||
));
|
||||
}
|
||||
|
||||
protected function afterSave() {
|
||||
$this->guardarFicheroDocumento();
|
||||
return parent::afterSave();
|
||||
}
|
||||
|
||||
protected function afterDelete() {
|
||||
$this->eliminarFicheroDocumento();
|
||||
return parent::afterDelete();
|
||||
}
|
||||
|
||||
protected function afterConstruct() {
|
||||
// Valores por defecto
|
||||
$this->fecha = date('Y-m-d H:i:s', time());
|
||||
return parent::afterConstruct();
|
||||
}
|
||||
|
||||
protected function beforeValidate() {
|
||||
if ($this->ficheroDocumento) {
|
||||
$upload = $this->candidato->getUploadPath();
|
||||
$this->nombre_fichero = $this->generarNombreFicheroDocumento();
|
||||
Yii::trace('Nombre para el documento: ' . $this->nombre_fichero, 'application.models.CandidatoDocumento');
|
||||
}
|
||||
return parent::beforeSave();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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 generarNombreFicheroDocumento() {
|
||||
$cid = $this->candidato->id;
|
||||
$old_filename = FileHelper::sanitizeFileName(pathinfo($this->ficheroDocumento, PATHINFO_FILENAME));
|
||||
$ext = pathinfo($this->ficheroDocumento, PATHINFO_EXTENSION);
|
||||
$folder = $this->candidato->getUploadPath();
|
||||
$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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Guarda un documento subido por el usuario
|
||||
* return CUploadedFile fichero subido
|
||||
*/
|
||||
private function guardarFicheroDocumento() {
|
||||
Yii::trace('Guardando el documento ' . $this->ficheroDocumento, 'application.models.CandidatoDocumento');
|
||||
|
||||
if (!$this->candidato)
|
||||
throw new CException(Yii::t('profind', 'Candidato no asignado.'));
|
||||
|
||||
if (!$this->ficheroDocumento)
|
||||
throw new CException(Yii::t('profind', 'Fichero de documento no asignado.'));
|
||||
|
||||
$upload = $this->candidato->getUploadPath();
|
||||
$nombre = $upload . $this->nombre_fichero;
|
||||
return $this->ficheroDocumento->saveAs($nombre);
|
||||
}
|
||||
|
||||
/*
|
||||
* Elimina el documento del usuario
|
||||
* return bool
|
||||
*/
|
||||
private function eliminarFicheroDocumento() {
|
||||
Yii::trace('Eliminando el documento ' . $this->nombre_fichero, 'application.models.CandidatoDocumento');
|
||||
if (!$this->candidato)
|
||||
throw new CException(Yii::t('profind', 'Candidato no asignado.'));
|
||||
|
||||
$upload = $this->candidato->getUploadPath();
|
||||
$nombre = $upload . $this->nombre_fichero;
|
||||
return unlink($nombre);
|
||||
}
|
||||
}
|
||||
@ -765,6 +765,12 @@ textarea {
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
color: #b94a48;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
input.error, select.error, textarea.error {
|
||||
color: #b94a48;
|
||||
border-color: #b94a48;
|
||||
|
||||
107
www/themes/profind/views/candidato/__documentos.php
Normal file
107
www/themes/profind/views/candidato/__documentos.php
Normal file
@ -0,0 +1,107 @@
|
||||
<?php
|
||||
$js_datepicker = <<<JS
|
||||
jQuery(function($) {
|
||||
jQuery('.datepicker').datepicker(
|
||||
jQuery.extend({showMonthAfterYear:false},
|
||||
jQuery.datepicker.regional['es'],
|
||||
{'showAnim':'fold','dateFormat':'dd/mm/yy'}
|
||||
)
|
||||
);
|
||||
});
|
||||
JS;
|
||||
Yii::app()->clientScript->registerScript('js_datepicker', $js_datepicker, CClientScript::POS_END);
|
||||
?>
|
||||
|
||||
|
||||
<div class="row-fluid formSep">
|
||||
<div class="span12">
|
||||
<label class="control-label"><?php echo Yii::t('profind', 'Currículums'); ?></label>
|
||||
<div class="controls">
|
||||
<table class="table templateFrame">
|
||||
<thead class="templateHead">
|
||||
<tr>
|
||||
<th style="width: 20%;"><?php echo Yii::t('profind', 'Fecha'); ?></th>
|
||||
<th style="width: 30%;"><?php echo Yii::t('profind', 'Título'); ?></th>
|
||||
<th style="width: 40%;"><?php echo Yii::t('profind', 'Fichero'); ?></th>
|
||||
<th style="width: 10%;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="templateTarget">
|
||||
<?php foreach($candidato->documentos as $i=>$documento): ?>
|
||||
<tr class="templateContent">
|
||||
<td>
|
||||
<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(
|
||||
'model' => $documento,
|
||||
'attribute' => "[$i]fecha",
|
||||
'language' => 'es',
|
||||
'options' => array('showAnim' => 'fold', 'dateFormat' => 'dd/mm/yy'),
|
||||
'htmlOptions' => array('class' => 'span12'),
|
||||
));
|
||||
?>
|
||||
<?php echo CHtml::error($documento, 'fecha'); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo CHtml::activeTextField($documento, "[$i]titulo", array('class' => 'span12')); ?>
|
||||
<?php echo CHtml::error($documento, 'titulo'); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($documento->getError('nombre_fichero') != '') : ?>
|
||||
<?php echo CHtml::activeFileField($documento, "[$i]titulo", array('class' => 'span12')); ?>
|
||||
<?php echo CHtml::error($documento, 'nombre_fichero'); ?>
|
||||
<?php else : ?>
|
||||
<?php echo CHtml::encode($documento->nombre_fichero); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo CHtml::activeHiddenField($documento, "[$i]id", array('class' => 'pk')); ?>
|
||||
<?php echo CHtml::activeHiddenField($documento, "[$i]id_candidato"); ?>
|
||||
<?php echo CHtml::hiddenField("CandidatoDocumento[$i][_borrar]", '0', array('class' => 'to_remove')); ?>
|
||||
<input type="hidden" class="rowIndex" value="<?php echo $i;?>" />
|
||||
<?php if (!$documento->hasErrors()) : ?>
|
||||
<a class="btn btn-small download" href="#"><i class="icon-download"></i></a>
|
||||
<?php endif; ?>
|
||||
<a class="btn btn-small remove" href="#"><i class="icon-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<a class="btn btn-small add" href="#"><i class="icon-plus"></i> <?php echo Yii::t('profind', 'Añadir un currículum');?></a>
|
||||
<textarea class="hide template">
|
||||
<tr class="templateContent">
|
||||
<td>
|
||||
<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(
|
||||
'name' => 'CandidatoDocumento[{0}][fecha]',
|
||||
'value' => date('dd/mm/yy', time()),
|
||||
'language' => 'es',
|
||||
'options' => array('showAnim' => 'fold', 'dateFormat' => 'dd/mm/yy'),
|
||||
'htmlOptions' => array('class' => 'span12 datepicker'),
|
||||
));
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo CHtml::textField('CandidatoDocumento[{0}][titulo]', Yii::t('profind', 'Documento'), array('class' => 'span12')); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo CHtml::fileField('CandidatoDocumento[{0}][nombre_fichero]'); ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo CHtml::hiddenField('CandidatoDocumento[{0}][id]', '', array('class' => 'pk')); ?>
|
||||
<?php echo CHtml::hiddenField('CandidatoDocumento[{0}][id_candidato]'); ?>
|
||||
<?php echo CHtml::hiddenField('CandidatoDocumento[{0}][_borrar]', '0', array('class' => 'to_remove')); ?>
|
||||
<input type="hidden" class="rowIndex" value="{0}" />
|
||||
|
||||
<a class="btn btn-small remove" href="#"><i class="icon-trash"></i></a>
|
||||
</td>
|
||||
</tr>
|
||||
</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -180,6 +180,11 @@ $form = $this->beginWidget('CActiveForm', array(
|
||||
<?php echo $this->renderPartial('__idiomas', array('candidato' => $candidato)); ?>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend class="control-label" style="text-align: left;"><?php echo Yii::t('profind', 'Currículums'); ?></legend>
|
||||
<?php echo $this->renderPartial('__documentos', array('candidato' => $candidato)); ?>
|
||||
</fieldset>
|
||||
|
||||
|
||||
<fieldset>
|
||||
<legend><?php echo Yii::t('profind', 'Disponibilidad'); ?></legend>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user