Para resolver alguns problemas de desempenho do Views e respeitar as melhores práticas, gostaria de substituir alguns do PHP que configurei há algum tempo pelos meus próprios manipuladores personalizados .
Por exemplo, eu tenho um campo PHP do Views, excluído da exibição , com essa configuração:
Código do 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 saída :
<?php print $value ; ?>`
Então eu uso esse campo como primeiro critério de classificação ( crescente ), em um critério de classificação Global do PHP:
if ($row1->php> $row2->php) return -1; else return 1;
Ficaria muito grato se você pudesse me colocar no caminho certo: em quais funções devo criar o mesmo código para acabar com o PHP no banco de dados?
Resumo:
Após a pesquisa e o progresso, além da ajuda do @Renrahf, a maior parte da implementação parece correta, detalhados abaixo. Mas ainda estou lutando com um ponto : adicionei um manipulador de campo personalizado para calcular um valor, mas como posso fazer o pedido por esse manipulador?
Editar% s :
O que eu fiz até agora:
arquivo .info
files[] = views_handler_vts_products_sort.inc
files[] = includes/views_handler_vts_count_depconf_field.inc
Arquivo 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
Arquivo
/**
* 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
Arquivo
/*
* 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;
}
}
Pergunta restante:
como encomendar pelo manipulador de campo personalizado? Tentei adicionar
'click sortable'=> TRUE,
OR'sort' => array('handler' => 'views_handler_sort',),
OR$this->query->add_orderby('custom', 'count_depconf_field', 'DESC');
no manipulador de classificação personalizado. Nenhuma funciona, mas retorna a coluna Desconhecida na 'cláusula de ordem'FEITO : Como posso entrar
$row->product_id
e$row->nid
entrarquery()
? Eu preciso dele para construir a subconsulta. : Adicionado um campo de manipulador de visualizações e encontrou os valores da linha em render ($ values) ...- CONCLUÍDO : Qual parte do manipulador de exemplo eu tenho que editar? A função de consulta apenas? Preciso manter todo o código de exemplo ou apenas as peças personalizadas?
Obrigado
Compartilho abaixo a implementação completa de como substituí a classificação do Views PHP por um manipulador de Views personalizado .
arquivo .info
Arquivo de módulo
Arquivo views_handler_my_custom_sort.inc
Um pouco de explicação: depois de entender como implementar os manipuladores de Views, fiquei confuso com a subconsulta:
WHERE nod.nid = node.nid
add_orderby
:$this->query->add_orderby(NULL, $sub_query, 'DESC', 'subquery');
funciona, mas$this->query->add_orderby(NULL, $sub_query, 'DESC');
nãoEsse último ponto foi surpreendente, porque, embora
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 )
trabalhe na entrada direta do SQL, não ocorre na configuração atual.Você precisa especificar o alias da subconsulta e a consulta final será algo 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
As tentativas de calcular os valores para classificar o resultado em um campo de manipulador personalizado não funcionaram porque a classificação de Views é feita com base no banco de dados e o manipulador de campo personalizado é um tipo de campo fictício ... pelo menos essa foi minha conclusão.
fonte