Campo para una imagen en la configuración

abril 2, 2016 • Publicado en Software y Hardware
Etiquetas:

En la anterior entrada expliqué cómo crear una vista para el manejo de variables de configuración. El ejemplo se limitaba a dos campos de texto, y en teoría agregar otros campos básicos (texto, área de texto, numérico y color) no debería representar problema alguno. Pero al hacer págnas configuración es muy común encontrar campos para imágenes. El presente ejemplo extiende la anterior nota para agregar este tipo de variables a la configuración y por lo tanto debe haber realizado el anterior ejemplo para poder realizar esta actividad.

El primer punto a tener en cuenta es buscar la forma de subir la imagen. Uno pensaría que SuiteCRM integraría un punto de entrada de este tipo, pero por lo que pude entrever cada módulo crea su propio mecanismo, y el resultado es que cada uno tiene sus propias particularidades. En definitiva es aconsejable crear uno propio. Recuerde que la declaración del EntryPoint se hace en el directorio de Aplicaciones, pero el archivo del EntryPoint puede estar en cualquier directorio. Por facilidad mnemotécnica la ubico en el Configurator porque al fin de cuentas lo usaremos con este módulo.

/<directorio_crm>/custom/modules/Configurator/UploadImageFile.php

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
/*********************************************************************************
 * Entry point para subir una imagen
 ********************************************************************************/


require_once('include/JSON.php');
require_once('include/entryPoint.php');
require_once 'include/upload_file.php';

//Si no tenemos sección o nombre, retornar error
if(!isset($_REQUEST['section']) && !isset($_REQUEST['name'])) {
    $returnArray['data']='not_recognize';
    echo $json->encode($returnArray);
    sugar_cleanup();
    exit();
}

global $sugar_config;
//Solo aceptamos jpg, jpeg y png.
//No podemos aceptar gif ni bmp porque internamente SUgar los descarta
$supportedExtensions = array('jpg', 'png', 'jpeg');

//Declaramos las variables del sistema
$json = getJSONobj();
$rmdir=true;
$returnArray = array();
$upload_ok = false;

//Obtenemos los datos de la foto
$section = $_REQUEST['section'];
$name = $_REQUEST['name'];

//Declarar el directorio donde quedará la imagen
$upload_path = $section . '/' . $name ;
//Debe venir el archivo file_1
if(isset($_FILES['file_1'])){
	//Declarar el mecanismo para manipular el archivo temporal
    $upload = new UploadFile('file_1');
    //Confirmar que hay archivo
    if($upload->confirm_upload()) {
		//Determinar dónde quedará la imagen
        $upload_dir  = 'upload://' . $upload_path;
        //Asegurar que podremos subir la imagen
        UploadStream::ensureDir($upload_dir);
        //Verificar que se subió la imagen a la posición temporal
        if(!verify_uploaded_image($upload->temp_file_location)){
			//Si no se subió, declarar el error
            $returnArray['data']='other';
            $returnArray['path'] = '';
            echo $json->encode($returnArray);
            sugar_cleanup();
            exit();
        }
        //Determinar el directorio donde se almacenará definitivamente la imagen
        $file_name = $upload_dir."/".$upload->get_stored_file_name();
        //Guardar la imagen en la ubicación definitiva
        if($upload->final_move($file_name)) {
            $upload_ok = true;
        }
    }
}

//Si no se almacenó laimagen en la posición definitiva
if(!$upload_ok) {
	//Declarar el error
    $returnArray['data']='not_recognize';
    echo $json->encode($returnArray);
    sugar_cleanup();
    exit();
}

//Determinar la url del upload
$returnArray['upload']=$upload->get_upload_url();

//Si el archivo existe
if(file_exists($file_name) && is_file($file_name)) {
	//Obtener los datos del archivo y declarar las variables
    $encoded_file_name = rawurlencode($upload->get_stored_file_name());
	$returnArray['filename'] = $file_name;
    $returnArray['path'] = $upload_path . '/' . $encoded_file_name;
    $returnArray['url']= 'cache/images/'.$encoded_file_name;
    //Verificar que se subió la imagen
    if(!verify_uploaded_image($file_name, false)) {
        $returnArray['data']='other';
        $returnArray['path'] = '';
        unlink($file_name);
    } else {
		//Sino, copiarla
		copy($file_name, sugar_cached('images/'.$upload->get_stored_file_name()));
	}
	//Si hay 'data' es porque ubo un problema 
    if(!empty($returnArray['data'])){
        echo $json->encode($returnArray);
    }else{ //Sino, ndicar en data que el proceso se concluyó bien
        $rmdir=false;
        $returnArray['data']='ok';
        echo $json->encode($returnArray);
    }
}else{ //SI no existe el archivo, informar del error
    $returnArray['data']='file_error';
    echo $json->encode($returnArray);
}
sugar_cleanup();
exit();

/<directorio_crm>/custom/Extension/application/Ext/EntryPointRegistry/UploadImageFile.php

<?php
	$entry_point_registry['UploadImageFile'] = array(
		'file' => 'custom/modules/Configurator/UploadImageFile.php',
		'auth' => true,
	);

Ejecutamos la acción de “Reparar y Reconstruir“, y tendremos a nuestra disposición el punto de entrada para subir una imagen.

Ahora modificamos la declaración de la vista y agregamos la línea de la foto en la sección donde se declaran las variables de la configuración del paquete (líneas 22 a 30 del ejemplo de la anterior entrada).

/<directorio_crm>/custom/modules/Configurator/views/view.<acción>.php

        //Declarar la instancia para administrar
        //la configuración
        $cfg = new Configurator();
		//Declarar los elementos de la configuración
		//en caso de aun no estar declarados
		if (!array_key_exists('<paquete>', $cfg->config)) {
		    $cfg->config['<paquete>'] = array(
		        'name' => '',
		        'code' => '',
		    );
			$cfg->saveConfig();
		}
		
		//Agregar la nueva variable
		if(!isset($cfg->config['<paquete>']['logo'])) {
			$cfg->config['<paquete>']['logo'] = '';
			$cfg->saveConfig();
		}

También se deberá agregar las modificaciones a la traducción para incluir los nuevos campos

/<directorio_crm>/custom/Extension/modules/Configurator/Ext/Language/en_us.<paquete>.php

	$mod_strings['LBL_<PAQUETE>_LOGO'] = 'Current Logo:';
	$mod_strings['LBL_<PAQUETE>_LOGO_HELP'] = 'This logo is displayed in the tickets.';
	$mod_strings['LBL_<PAQUETE>_NEW_LOGO'] = 'Select Logo:';

A continuación creamos la plantilla con los agregados para hacer uso del entryPoint. Igual que en el anterior ejemplo no hay funciones para chequeo de variables así que se deja al lector la labor correspondiente.

/<directorio_crm>/custom/modules/Configurator/tpls/<acción>.tpl

{*

/*********************************************************************************
 * Vista para la administración de la información del centro comercial
 ********************************************************************************/

*}
<div class='moduleTitle'>
	<h2>{$MOD.LBL_<ACCIÓN>_SETTINGS}</h2>
	<div class='clear'></div>
</div>
<form name="<Paquete>Settings" enctype='multipart/form-data' method="POST" action="index.php" onSubmit="return (add_checks(document.<Paquete>Settings) && check_form('<Paquete>Settings'));">
<input type='hidden' name='action' value='<acción>'/>
<input type='hidden' name='module' value='Configurator'/>
<input type='hidden' name='save' value='true'/>
<span class='error'>{$error.main}</span>
<table width="100%" cellpadding="0" cellspacing="1" border="0" class="actionsContainer">
<tr>

	<td>
		<input title="{$APP.LBL_SAVE_BUTTON_TITLE}" accessKey="{$APP.LBL_SAVE_BUTTON_KEY}" class="button primary" id="<Paquete>Settings_save_button" type="submit"  name="save" value="  {$APP.LBL_SAVE_BUTTON_LABEL}  " >
		&nbsp;<input title="{$MOD.LBL_SAVE_BUTTON_TITLE}"  id="<Paquete>Settings_restore_button"  class="button"  type="submit" name="restore" value="  {$MOD.LBL_RESTORE_BUTTON_LABEL}  " >
		&nbsp;<input title="{$MOD.LBL_CANCEL_BUTTON_TITLE}" id="<Paquete>Settings_cancel_button"   onclick="document.location.href='index.php?module=Configurator&action=index'" class="button"  type="button" name="cancel" value="  {$APP.LBL_CANCEL_BUTTON_LABEL}  " > </td>
	</tr>
</table>


<table width="100%" border="0" cellspacing="1" cellpadding="0" class="edit view">
<tr>
	<th align="left" scope="row" colspan="4"><h4>{$MOD.LBL_<ACCIÓN>_DESCRIPTION}</h4></th>
</tr>

	<tr>
		<td scope="row" width='15%' nowrap>{$MOD.LBL_<PAQUETE>_NAME} </td>
		<td width='35%'>
			<input type='text' name='<paquete>_name' value='{$config.<paquete>.name}'>
		</td>
		<td scope="row" width='15%' nowrap>{$MOD.LBL_<PAQUETE>_CODE} </td>
		<td width='35%'>
			<input type='text' name='<paquete>_code' value='{$config.<paquete>.code}'>
		</td>
	</tr>
	<tr>
        <td  scope="row" width='12%' nowrap>
        {$MOD.LBL_<PAQUETE>_LOGO}&nbsp;{sugar_help text=$MOD.LBL_<PAQUETE>_LOGO_HELP}
        </td>
        <td width='35%' >
            <img id="<paquete>_logo_image" style="width: auto; max-height: 150px;" src='{$config.<paquete>.logo}' alt='{$MOD.LBL_<PAQUETE>_LOGO}'>
        </td>
    </tr>
    <tr>
        <td  scope="row" width='12%' nowrap>
            {$MOD.LBL_<PAQUETE>_NEW_LOGO}&nbsp;{sugar_help text=$MOD.LBL_<PAQUETE>_NEW_LOGO_HELP_NO_SPACE}
        </td>
        <td  width='35%'>
            <div id="container_upload"></div>
            <input type='text' id='<paquete>_logo' name='<paquete>_logo' value='{$config.<paquete>.logo}' style="display:none">
        </td>
    </tr>


</table>


<table  width="100%" border="0" cellspacing="1" cellpadding="0" class="edit view">
{if $logger_visible}
<tr>
<th align="left" scope="row" colspan="6"><h4>{$MOD.LBL_LOGGER}</h4></th>
</tr>
	<tr>
		<td  scope="row" valign='middle'>{$MOD.LBL_LOGGER_FILENAME}</td>
		<td   valign='middle' ><input type='text' name = 'logger_file_name'  value="{$config.logger.file.name}"></td>
		<td  scope="row">{$MOD.LBL_LOGGER_FILE_EXTENSION}</td>
		<td ><input name ="logger_file_ext" type="text" size="5" value="{$config.logger.file.ext}"></td>
		<td scope="row">{$MOD.LBL_LOGGER_FILENAME_SUFFIX}</td>
		<td ><select name = "logger_file_suffix" selected='{$config.logger.file.suffix}'>{$filename_suffix}</select></td>
	</tr>
	<tr>
		<td scope="row">{$MOD.LBL_LOGGER_MAX_LOG_SIZE} </td>
		<td > <input name="logger_file_maxSize" size="4" value="{$config.logger.file.maxSize}"></td>
		<td scope="row">{$MOD.LBL_LOGGER_DEFAULT_DATE_FORMAT}</td>
		<td  ><input name ="logger_file_dateFormat" type="text" value="{$config.logger.file.dateFormat}"></td>
	</tr>
	<tr>
		<td scope="row">{$MOD.LBL_LOGGER_LOG_LEVEL} </td>
		<td > <select name="logger_level">{$log_levels}</select></td>
		<td scope="row">{$MOD.LBL_LOGGER_MAX_LOGS} </td>
		<td > <input name="logger_file_maxLogs" value="{$config.logger.file.maxLogs}"></td>
	</tr>
{/if}
	<tr>
	    <td><a href="index.php?module=Configurator&action=LogView" target="_blank">{$MOD.LBL_LOGVIEW}</a></td>
	</tr>
</table>


<div style="padding-top: 2px;">
<input title="{$APP.LBL_SAVE_BUTTON_TITLE}" class="button primary"  type="submit" name="save" value="  {$APP.LBL_SAVE_BUTTON_LABEL}  " class="button primary"/>
		&nbsp;<input title="{$MOD.LBL_SAVE_BUTTON_TITLE}"  class="button"  type="submit" name="restore" value="  {$MOD.LBL_RESTORE_BUTTON_LABEL} " />
		&nbsp;<input title="{$MOD.LBL_CANCEL_BUTTON_TITLE}"  onclick="document.location.href='index.php?module=Configurator&action=index'" class="button"  type="button" name="cancel" value="  {$APP.LBL_CANCEL_BUTTON_LABEL}  " />
</div>
{$JAVASCRIPT}

</form>
<div id='upload_panel' style="display:none">
    <form id="upload_form" name="upload_form" method="POST" action='index.php' enctype="multipart/form-data">
        <input type="file" id="my_file_<paquete>" name="file_1" size="20" onchange="uploadCheck('<paquete>')"/>
        {sugar_getimage name="sqsWait" ext=".gif" alt=$mod_strings.LBL_LOADING other_attributes='id="loading_img_<paquete>" style="display:none" '}
    </form>
</div>
{if $error.<paquete>_logo}
<script type='text/javascript'>
{literal}$(function(){alert('{/literal}{$error.<paquete>_logo}{literal}');});{/literal}
</script>
{/if}
{literal}
<script type='text/javascript'>
function init_logo(){
    document.getElementById('upload_panel').style.display="inline";
    document.getElementById('upload_panel').style.position="absolute";
    YAHOO.util.Dom.setX('upload_panel', YAHOO.util.Dom.getX('container_upload'));
    YAHOO.util.Dom.setY('upload_panel', YAHOO.util.Dom.getY('container_upload')-5);
}
YAHOO.util.Event.onDOMReady(function(){
    init_logo();
});
function toggleDisplay_2(div_string){
    toggleDisplay(div_string);
    init_logo();
}
 function uploadCheck(varname){
    //AJAX call for checking the file size and comparing with php.ini settings.
    var callback = {
        upload:function(r) {
            eval("var file_type = " + r.responseText);
            var forQuotes = varname;
            document.getElementById('loading_img_'+forQuotes).style.display="none";
            bad_image = SUGAR.language.get('Configurator',(forQuotes == 'quotes')?'LBL_ALERT_TYPE_JPEG':'LBL_ALERT_TYPE_IMAGE');
            switch(file_type['data']){
                case 'other':
                    alert(bad_image);
                    document.getElementById('my_file_' + forQuotes).value='';
                    break;
                case 'size':
                    alert(SUGAR.language.get('Configurator','LBL_ALERT_SIZE_RATIO'));
                    document.getElementById(forQuotes + "_logo").value=file_type['path'];
                    document.getElementById(forQuotes + "_logo_image").src=file_type['url'];
                    break;
                case 'file_error':
                    alert(SUGAR.language.get('Configurator','ERR_ALERT_FILE_UPLOAD'));
                    document.getElementById('my_file_' + forQuotes).value='';
                    break;
                //File good
                case 'ok':
                    document.getElementById(forQuotes + "_logo").value=file_type['url'];
                    document.getElementById(forQuotes + "_logo_image").src=file_type['url'];
                    break;
                //error in getimagesize because unsupported type
                default:
                   alert(bad_image);
                   document.getElementById('my_file_' + forQuotes).value='';
            }
            setTimeout(function() { init_logo(); }, 100);
        },
        failure:function(r){
            alert(SUGAR.language.get('app_strings','LBL_AJAX_FAILURE'));
        }
    }
    document.getElementById("<paquete>_logo").value='';
    document.getElementById('loading_img_<paquete>').style.display="inline";
    var file_name = document.getElementById('my_file_<paquete>').value;
    postData = '&entryPoint=UploadImageFile&section=<paquete>&name=logo';
    YAHOO.util.Connect.setForm(document.getElementById('upload_form'), true,true);
    if(file_name){
        if(postData.substring(0,1) == '&'){
            postData=postData.substring(1);
        }
        YAHOO.util.Connect.asyncRequest('POST', 'index.php', callback, postData);
    }
}

</script>
{/literal}

Dejar un Comentario