Afin de résoudre certains problèmes de performances de Views et de respecter les meilleures pratiques, je voudrais remplacer certains Views PHP que j'ai configurés il y a quelque temps par mes propres gestionnaires personnalisés .
Par exemple, j'ai un champ Vues PHP, exclu de l'affichage , avec cette configuration:
Code de valeur:
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;
}
}
Code de sortie :
<?php print $value ; ?>`
Ensuite, j'utilise ce champ comme premier critère de tri ( croissant ), dans un critère de tri Global PHP:
if ($row1->php> $row2->php) return -1; else return 1;
Je serais vraiment reconnaissant si vous pouviez me mettre sur la bonne voie: dans quelle (s) fonction (s) devrais-je construire ce même code pour finir avec PHP dans la base de données?
Résumé :
Après la recherche et la progression, ainsi que l'aide de @Renrahf, la plupart de la mise en œuvre semble correcte, détaillée ci-dessous. Mais je me bats toujours avec un point : j'ai ajouté un gestionnaire de champs personnalisé pour calculer une valeur, mais comment puis-je commander par ce gestionnaire?
Modifications:
Ce que j'ai fait jusqu'à présent:
Fichier .info
files[] = views_handler_vts_products_sort.inc
files[] = includes/views_handler_vts_count_depconf_field.inc
Fichier de module
/**
* 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
fichier
/**
* 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
fichier
/*
* 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;
}
}
Question restante:
comment commander par le gestionnaire de champs personnalisé? J'ai essayé d'ajouter
'click sortable'=> TRUE,
OU'sort' => array('handler' => 'views_handler_sort',),
OU$this->query->add_orderby('custom', 'count_depconf_field', 'DESC');
dans un gestionnaire de tri personnalisé. Aucun ne fonctionne mais retourne une colonne inconnue dans la 'clause de commande'FAIT : Comment puis - je obtenir
$row->product_id
et à l'$row->nid
intérieurquery()
? J'en ai besoin pour construire la sous-requête. : Ajout d'un champ de gestionnaire de vues et recherche des valeurs de ligne dans le rendu (valeurs $) ...- Terminé : quelle partie de l'exemple de gestionnaire dois-je modifier? La fonction de requête uniquement? Dois-je conserver l'intégralité du code d'exemple ou uniquement les parties personnalisées?
Je vous remercie
Je partage ci-dessous l'implémentation complète de la façon dont j'ai fait pour remplacer le tri des vues PHP par un gestionnaire de vues personnalisé .
Fichier .info
Fichier de module
Fichier views_handler_my_custom_sort.inc
Un peu d'explication: après avoir compris comment implémenter les gestionnaires de vues, je me suis confondu avec la sous-requête:
WHERE nod.nid = node.nid
add_orderby
:$this->query->add_orderby(NULL, $sub_query, 'DESC', 'subquery');
fonctionne, mais$this->query->add_orderby(NULL, $sub_query, 'DESC');
ne fonctionne pasCe dernier point était surprenant car bien qu'il
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 )
fonctionne en entrée directe SQL, il ne l'est pas dans la configuration actuelle.Vous devez spécifier l'alias de sous-requête et la requête finale sera quelque chose comme
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
Le tente de calculer les valeurs pour trier le résultat dans un champ de gestionnaire personnalisé, n'a pas fonctionné car le tri des vues est effectué sur une base de données et le gestionnaire de champ personnalisé est une sorte de champ factice ... du moins, c'était ma conclusion.
la source