Para abordar algunos problemas de rendimiento de Vistas y respetar las mejores prácticas, me gustaría reemplazar algunas Vistas PHP que configuré hace algún tiempo por mis propios controladores personalizados .
Por ejemplo, tengo un campo PHP Vistas, excluido de la pantalla , con esa configuración:
Código de valor:
if( $row->sticky ==1 ) {
return 100;
} else {
if ( isset($row->product_id) && $row->product_id != "" ){
$query = "SELECT COUNT(statut.entity_id) FROM field_data_field_statut_depart statut"
. " INNER JOIN field_data_field_product product ON statut.entity_id= product.field_product_product_id"
. " INNER JOIN field_data_field_date_depart depart ON statut.entity_id = depart.entity_id"
. " WHERE product.entity_id = ". $row->nid." AND field_statut_depart_value IN (2,3) AND field_date_depart_value > NOW(); ";
$select = db_query($query);
$count = $select->fetchField();
return $count;
}
else {
return -1;
}
}
Código de salida :
<?php print $value ; ?>`
Luego uso ese campo como primer criterio de clasificación ( ascendente ), en un criterio de clasificación de PHP Global:
if ($row1->php> $row2->php) return -1; else return 1;
Estaría realmente agradecido si pudiera ponerme en el camino correcto: ¿en qué función (es) construiré ese mismo código para terminar con PHP en la base de datos?
Resumen :
Después de la búsqueda y el progreso, más la ayuda de @Renrahf, la mayor parte de la implementación parece correcta, detallada a continuación. Pero todavía estoy luchando con un punto : agregué un controlador de campo personalizado para calcular un valor, pero ¿cómo puedo ordenar por ese controlador?
Ediciones:
Lo que hice hasta ahora:
archivo .info
files[] = views_handler_vts_products_sort.inc
files[] = includes/views_handler_vts_count_depconf_field.inc
Archivo de módulo
/**
* Implements hook_views_data().
*/
function vts_views_handler_views_data() {
$data['custom']['table']['group'] = t('Custom');
$data['custom']['table']['join'] = array(
// #global is a special flag which let's a table appear all the time.
'#global' => array(),
);
$data['custom']['custom_handler'] = array(
'title' => t('Vts custom Sort Handler'),
'help' => 'Sorts products by sticky first then by custom statut field',
'sort' => array(
'handler' => 'views_handler_vts_products_sort',
),
);
$data['custom']['count_depconf_field'] = array(
'title' => t('Sum of products with status confirmed '),
'help' => t('Calculate Sum of products with status confirmed, to order lists".'),
'field' => array(
'handler' => 'views_handler_vts_count_depconf_field',
'click sortable'=> TRUE,
),
/*'sort' => array(
'handler' => 'views_handler_sort',
), */
);
return $data;
}
function vts_views_handler_views_api() {
return array(
'api' => 3,
'path' => drupal_get_path('module', 'vts_views_handler'),
);
}
views_handler_vts_products_sort
archivo
/**
* Base sort handler that has no options and performs a simple sort.
*
* @ingroup views_sort_handlers
*/
class views_handler_vts_products_sort extends views_handler_sort {
function query() {
$this->ensure_my_table();
// Add the field.
$this->query->add_orderby('node', 'sticky', 'DESC');
}
}
views_handler_vts_count_depconf_field
archivo
/*
* A simple field to calculate the value I wish to order by.
*/
class views_handler_vts_count_depconf_field extends views_handler_field {
function query() {
//do nothing
}
function render($values) {
$count = 0;
$product_id = isset($values-> commerce_product_field_data_field_product_product_id)? $values-> commerce_product_field_data_field_product_product_id: NULL;
if(!is_null($product_id)){
$query = "SELECT COUNT(statut.entity_id) FROM field_data_field_statut_depart statut"
. " INNER JOIN field_data_field_product product ON statut.entity_id= product.field_product_product_id"
. " INNER JOIN field_data_field_date_depart depart ON statut.entity_id = depart.entity_id"
. " WHERE product.entity_id = " . $values->nid . " AND field_statut_depart_value IN (2,3) AND field_date_depart_value > NOW(); ";
$select = db_query($query);
$count = $select->fetchField();
}
return $count;
}
}
Pregunta restante:
¿Cómo ordenar por el controlador de campo personalizado? Intenté agregar
'click sortable'=> TRUE,
OR'sort' => array('handler' => 'views_handler_sort',),
OR$this->query->add_orderby('custom', 'count_depconf_field', 'DESC');
en el controlador de clasificación personalizado. Ninguno funciona, pero devuelve la columna Desconocido en 'cláusula de pedido'HECHO : ¿Cómo puedo entrar
$row->product_id
y$row->nid
entrarquery()
? Lo necesito para construir la subconsulta. : Se agregó un campo de controlador de vistas y se encontraron los valores de fila en render ($ valores) ...- HECHO : ¿Qué parte del controlador de ejemplo debo editar? La función de consulta solamente? ¿Necesito mantener todo el código de ejemplo o solo las partes personalizadas?
Gracias
Comparto a continuación la implementación completa sobre cómo reemplacé la ordenación de Vistas PHP por un controlador de Vistas personalizado .
archivo .info
Archivo de módulo
archivo views_handler_my_custom_sort.inc
Un poco de explicación: después de comprender cómo implementar los manejadores de Vistas, me confundí con la subconsulta:
WHERE nod.nid = node.nid
add_orderby
:$this->query->add_orderby(NULL, $sub_query, 'DESC', 'subquery');
funciona, pero$this->query->add_orderby(NULL, $sub_query, 'DESC');
noEste último punto fue sorprendente porque, aunque
SELECT TITLE FROM node ORDER BY (SELECT COUNT(field_product_product_id) FROM field_data_field_product p LEFT JOIN node nod ON nod.nid = p.entity_id WHERE nod.nid = node.nid )
funciona en la entrada directa de SQL, no lo hace en la configuración actual.Debe especificar el alias de subconsulta y la consulta final será algo así como
SELECT TITLE, (SELECT COUNT(field_product_product_id) FROM field_data_field_product p LEFT JOIN node nod ON nod.nid = p.entity_id WHERE nod.nid = node.nid ) as subquery FROM node ORDER BY subquery
Los intentos de calcular los valores para ordenar el resultado en un campo de controlador personalizado, no funcionaron porque la clasificación de las vistas se realiza en una base de datos y el controlador de campo personalizado es una especie de campo ficticio ... al menos esta fue mi conclusión.
fuente