Clonación de registros

El CRUD facilita la clonación de registros. Para ello:

  • Permite mostrar un icono que realizará la clonación.
  • Puede hacer clonaciones automáticas de filas (sin tablas relacionadas).
  • Proporciona los medios para hacer clonaciones personalizadas.

Tipos de clonación

Hay cuatro tipos de clonación:

  1. Nula (predeterminada). No se permite hacer clonación.
  2. Sencilla. Se clona una fila automáticamente.
  3. Personalizada. Hay que programar un modelo para realizar la clonación.
  4. Múltiple. Se clona la fila así como el resto de filas de las tablas relacionadas recursivamente.

Las siguientes constantes están disponibles:

const CLONE_TYPE_NONE     = 0;   // No clonado (predeterminado)
const CLONE_TYPE_SINGLE   = 1;   // Clonado de filas únicas sencillo automático
const CLONE_TYPE_MANUAL   = 2;   // Clonado no automático, hay que usar modelos
const CLONE_TYPE_MULTIPLE = 3;   // Clonado recursivo (experimental)

Es obligatorio establecer el tipo de clonación. Para ello hay que asignar la propiedad cloneType de la clase CRUD (preferiblemente en una función como initData():

$this->cloneType = self::CLONE_TYPE_SINGLE;

Clonación sencilla

La clonación sencilla hace una copia de la fila sin clonar las tablas relacionadas. Se puede elegir entre:

  • Clonar y guardar silenciosamente la fila.
  • No clonar, sino mostrar el formulario de creación de fila, con los datos cargados. La clonación será efectiva al pulsar el botón Guardar.

Para elegir qué hacer hay que establecer la propiedad cloneResult de la clase CRUD. Las siguientes constantes están disponibles:

const CLONE_RESULT_NONE = 0;    // No hacer nada (se requiere cuando se usó CLONE_TYPE_MANUAL)
const CLONE_RESULT_PREPARE = 1; // Para clonar, mostrar el formulario de creación
const CLONE_RESULT_SAVE = 2;    // Simplemente clonar y guardar, sin mostrar formularios.

Por ejemplo para activar la clonación sencilla e inmediata:

$this->cloneType   = self::CLONE_TYPE_SINGLE;
$this->cloneResult = self::CLONE_RESULT_SAVE;

Clonación parcial

La clonación sencilla, por defecto, copia toda la fila salvo la clave o claves primarias. Es posible especificar qué campos deben copiarse únicamente, o bien qué campos no deben copiarse. Para ello se pueden usar las propiedades cloneIncludeFields y cloneExcludeFields del CRUD, respectivamente. Estas propiedades son arrays.

Las restricciones de campos se pueden usar tanto al clonar silenciosamente como al clonar con formulario de creación.

Después de la clonación

En ocasiones puede ser interesante llamar a una función determinada después de clonar. Se puede usar la propiedad cloneModel del CRUD para especificar un callable al que llamar después de clonar. El callable recibirá dos parámetros:

  1. Una clave primaria desempaquetada (array devuelto por PKView) de la fila que se ha clonado.
  2. La clave primaria empaquetada de la fila nueva.

Clonación personalizada

La clonación personalizada permite programar con detalle la operación de clonación. Es el único medio (por el momento) para clonar filas junto a las tablas relacionadas.

En la clonación personalizada se deja todo en manos de la programación. Se requiere establecer la propiedad cloneModel del CRUD para especificar un callable al que llamar para realizar la clonación. El callable recibirá un único parámetro: La clave primaria desempaquetada (array devuelto por PKView) de la fila que ha de clonarse.

Clonación múltiple

Es igual que la sencilla, pero luego clona el resto de filas de tablas relacionadas en cascada (con algunas limitaciones).

$this->cloneType   = self::CLONE_TYPE_MULTIPLE;
$this->cloneResult = self::CLONE_RESULT_SAVE;

Las opciones cloneIncludeFields y cloneExcludeFields funcionan igual que en clonación sencilla, pero solo para la primera tabla que se clona, no para las restantes.

Clonación múltiple parcial

Se puede usar las propiedades cloneMultipleIncludeFields y cloneMultipleExcludeFields para declarar tablas y campos a ser clonados únicamente o tablas y campos para ser excluidos. Esto solo afecta a las tablas relacionadas, no afecta a la tabla principal (para la tabla principal hay que usar cloneIncludeFields y cloneExcludeFields): - En la inclusión, solo lo indicado se clonará. - En la exclusión, se clonará todo salvo lo indicado.

Estas propiedades necesariamente deben tener como clave la tabla que se quiera incluir/excluir, y como valor el/los campos afectados, o '_' que indica 'todos'.

Ejemplo de inclusión:

// Solo clonar la tabla relacionada srv_instalacion
$this->cloneMultipleIncludeFields = ['srv_instalacion' => '_'];

// Solo clonar la tabla relacionada srv_instalación y solo la fecha.
$this->cloneMultipleIncludeFields = ['srv_instalacion' => 'fecha'];

// Solo clonar la tabla relacionada srv_instalación y solo la fecha y hora.
$this->cloneMultipleIncludeFields = ['srv_instalacion' => ['fecha', 'hora']];

NOTA: Es muy importante si se hace la inclusión de algunos campos (o sea, no se usa '' sino que se especifican los campos concretos a incluir) se incluyan aquellos que forman parte de las relaciones entre tablas. En caso de duda es mejor usar '' para incluir todo lo necesario y usar la exclusión para descartar lo que no se quiere.

Ejemplo de exclusión:

// No clonar la tabla srv_instalacion por completo
$this->cloneMultipleExcludeFields = ['srv_instalacion' => '_'];

// No clonar el campo fecha de la tabla srv_instalacion
$this->cloneMultipleExcludeFields = ['srv_instalacion' => 'fecha'];

// No clonar ni fecha ni hora de la tabla srv_instalacion
$this->cloneMultipleExcludeFields = ['srv_instalacion' => ['fecha', 'hora']]

La inclusión y la exclusión se pueden usar simultáneamente: Si se incluye una tabla completa, en la exclusión puede excluirse después algunos campos.