¿Cómo clonar la colección en Magento?


12

Tengo una colección en un método donde quiero realizar dos operaciones diferentes en esta colección. Por lo tanto, quiero dos copias separadas de la misma colección, y luego asignar una de las dos colecciones a la colección original nuevamente y devolverla.

Para simplificar esto, supongamos que tengo una colección de objetos llamada $collection.

Ahora, lo estoy intentando con la clonación de PHP, ya que no sé si hay alguna clonación de colección de Magento incorporada o no.

$coll1 = clone $collection;
$coll2 = clone $collection;

Ahora estoy tratando de realizar diferentes operaciones en estos dos clones separados de la colección original, algo así.

$coll1->getSelect()->where('some where condition');
$coll2->getSelect()->where('some different where condition');
if($coll1->count() == 0) {
    $collection = $coll2;
} else {
    $collection = $coll1;
}

Pero lo extraño es que ambas colecciones clonadas tienen las condiciones asignadas. La condición $ coll1 se aplica a $ coll2 junto con la condición de $ coll2 y viceversa.

¿Alguien sabe como lograr esto?

¡Gracias!

Respuestas:


14

El uso del operador de clonación PHP, donde se desea la clonación profunda, requiere que las clases que almacenan objetos en propiedades implementen un método __clone para copiar los objetos. Si no lo definen, las propiedades en ambas instancias harán referencia al mismo objeto.

Magento no implementa __clone en sus resúmenes de colección y, por lo tanto, no admite la clonación profunda como desea.

Mi sugerencia es buscar otras formas de lograr lo que desea hacer, ya que clonar una colección podría ser bastante costoso.

El ejemplo que dio (por ejemplo) podría cambiarse para clonar la selección, modificarla para seleccionar un recuento de los registros que habría cargado y luego, según ese resultado, modificar la colección. Esto también funcionaría mejor ya que no estaría cargando una colección y contándola solo para determinar cuál usar.

EDITAR: lo siguiente muestra cómo obtener un conteo sin cargar o modificar la colección.

$collection = Mage::getModel(...)->getCollection();

$count = $collection->getSelectCountSql();
$count->where('some where condition');
if ($count->query()->fetchColumn() == 0) {
    ...
} else {
    ...
}

Solo un pequeño detalle: la información de dónde se guarda $collection->getSelect()y no en la colección misma.
Fabian Blechschmidt

Gracias por responder. Pero después de aplicar la condición where solo quiero saber el recuento de la colección, y en función de ese recuento solo quiero decidir si usar una condición where diferente o no. ¿Puedes publicar un fragmento de código para comprender mejor cómo hacerlo?
MagExt

Respuesta actualizada con un ejemplo de código. Como señaló @FabianBlechschmidt, dónde está en la selección, que es de dónde proviene su problema específico, ya que no se clona cuando se clona el objeto de colección y ambos terminan refiriéndose a la misma instancia de objeto de selección.
davidalger

Gracias por actualizar No he intentado esto, ya que obtuve la solución solo algo así.
MagExt

En realidad, si hay un problema al clonar la colección, serializar y deserializar puede ser útil en el proceso. También hay otras alternativas para clonar en PHP que son bastante decentes. Pero, en general, David está en lo correcto ... básicamente, cuando clona el objeto, clona los punteros a los Objetos anidados también, aunque su respuesta no indica correctamente el problema subyacente.
mprototype

1

Para ampliar la respuesta de @ davidalger, puede restablecer la selección si desea realizar una operación diferente a un conteo, de esta manera:

$select= $collection->getSelectCountSql()->reset();

$select
    ->from('newsletter_subscriber', array('some_column'))
    ->distinct();

Sin embargo, tenga cuidado, esto podría tener efectos perjudiciales más adelante en el proceso ya que esto modifica la colección.

Una mejor manera sería clonar la selección de alguna manera, pero una copia superficial no la cortaría ya que el objeto contiene tipos complejos (Varien_Db_Select ni Zend_Db_Select tienen un __clonemétodo).

Una forma de evitar esto es guardar los datos seleccionados, modificarlos, ejecutar su consulta y luego volver a colocar los datos seleccionados originales.

Vea aquí un ejemplo: https://ka.lpe.sh/2013/05/23/magento-clone-collection-how-to-clone-collection-in-magento/

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.