Een view maken met Drupal- en niet-Drupal tabellen

Moeilijkheidsgraad

Zelf een view maken in Drupal is niet nodig tenzij je dingen wilt doen die niet standaard voorzien zijn.

Zo kan je op dit ogenblik geen view maken met tabellen die niet door Drupal zijn gegenereerd. Soms is dit wel interessant. Zo kan je gebruik maken van stocklijsten of andere grote tabellen die je niet wilt importeren in een Drupal inhoudstype omdat ze te groot zijn.

Ik werk een voorbeeld uit waarbij ik de leden van onze schaakclub (= Drupal inhoudstype) combineer met de grote database van de Belgische schaakfederatie (23000 spelers). Ik haal daar onder andere de sterkte van de spelers uit.

Screen001892.png

Ik ga hier om het makkelijk te maken, de tabel in mijn Drupal database integreren.

Screen001888.png

Zo staat de tabel nu tussen alle Drupal tabellen. Het kan ook anders, maar dan moet je tamelijk wat programmeren.


Screen001889.png

Een glimp van de tabel.
Screen001891.png

Nu gaan we een node aanmaken vanuit een inhoudstype dat een bodyveld heeft. We zetten het in PHP formaat (PHP filter module)

We overlopen de php code.

Eerst gaan we in de 2 eerste regels gebruik maken van Drupal Entities om straks de afbeedlingsstijl te kunnen toepassen op de afbeeldingen. We maken ook connectie met de database (host, user, paswoord, database) en bouwen een veiligheid in als de connectie mislukt.

use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;

$conn = mysqli_connect("localhost","freewe1q_proj","your password","freewe1q_proj");


// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

Daarna bouwen we de SQL op die de view gaat gebruiken. Voor elk veld in Drupal die je gebruikt in de view, anders dan het titelveld, moet je een regel maken met de nid als join (= connectie). Merk op dat ik ook de verbinding reeds maak met de niet-Drupal tabel. (=schaakgegevens). Ik heb ook een voorwaarde ingesteld. Het type (=inhoudstype) moet 'schakers' zijn.

$sql="SELECT * FROM dr8a_node_field_data
LEFT OUTER JOIN dr8a_node__body ON dr8a_node__body.entity_id = dr8a_node_field_data.nid
LEFT OUTER JOIN dr8a_node__field_stamnummer ON dr8a_node__field_stamnummer.entity_id = dr8a_node_field_data.nid
LEFT OUTER JOIN dr8a_node__field_image ON dr8a_node__field_image.entity_id = dr8a_node_field_data.nid
LEFT OUTER JOIN schaakgegevens ON dr8a_node__field_stamnummer.field_stamnummer_value=schaakgegevens.TRICULE
WHERE type='schakers'";

$result = mysqli_query($conn, $sql);

Nu doorloop je alle rijen die de SQL genereert. Met de echo commando in php laat ik dit ook op de pagina verschijnen. $row[veld] laat toe om zo alle veldwaarden te tonen. Ook die van de externe tabel. Als er voor een titel, meerdere waarden zijn (het afbeeldingsveld is meervoudig) dan krijg je meerdere rijen. Ik wil dit niet. Daarom kijk ik of de titel niet dezelfde is als de vorige.

  while($row = mysqli_fetch_assoc($result)) {

$nieuwetitel=$row[title];
if ($nieuwetitel!=$vorigetitel){
     echo "<div style='width:50%;float:left;'>";
        echo "<div><H2>".$row[title]."</H2>" . $row[body_value]." ". $row[field_stamnummer_value]."<br>"; 
       echo "Ranking vanuit de niet-Drupal tabel: ".$row[ELO_CALCUL]."<br>";
        
$vorigetitel=$nieuwetitel;

}

Tenslotte  behandel ik het afbeeldingsveld. Dit is een referentieveld. Vandaar dat ik een beetje moet programmeren.  Kijk ook hoe makkelijk ik de afbeeldingsstijl aanspreek.

  $fid= $row[field_image_target_id];

      if (!empty($fid)) {
     
       $file_object = File::load($fid);
       $file_uri = $file_object->uri->value;
       $file_url = file_create_url($file_uri);    
       $file_naam= $file_object->filename->value;        
       $style = ImageStyle::load('vierkant_250');   
       $image_url = $style->buildUrl($file_object->uri->value);      
       echo "</br><img src='$image_url'>";

                      }

De volledige code:

<?php

use Drupal\file\Entity\File;
use Drupal\image\Entity\ImageStyle;

$conn = mysqli_connect("localhost","freewe1q_proj","your password","freewe1q_proj");


// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }

$sql="SELECT * FROM dr8a_node_field_data
LEFT OUTER JOIN dr8a_node__body ON dr8a_node__body.entity_id = dr8a_node_field_data.nid
LEFT OUTER JOIN dr8a_node__field_stamnummer ON dr8a_node__field_stamnummer.entity_id = dr8a_node_field_data.nid
LEFT OUTER JOIN dr8a_node__field_image ON dr8a_node__field_image.entity_id = dr8a_node_field_data.nid
LEFT OUTER JOIN schaakgegevens ON dr8a_node__field_stamnummer.field_stamnummer_value=schaakgegevens.TRICULE
WHERE type='schakers'";

$result = mysqli_query($conn, $sql);

if (mysqli_num_rows($result) > 0) {
    // output data of each row

$vorigetitel="dummy";

    while($row = mysqli_fetch_assoc($result)) {

$nieuwetitel=$row[title];
if ($nieuwetitel!=$vorigetitel){
     echo "<div style='width:50%;float:left;'>";
        echo "<div><H2>".$row[title]."</H2>" . $row[body_value]." ". $row[field_stamnummer_value]."<br>"; 
       echo "Ranking vanuit de niet-Drupal tabel: ".$row[ELO_CALCUL]."<br>";
        
$vorigetitel=$nieuwetitel;

}


        $fid= $row[field_image_target_id];

      if (!empty($fid)) {
     
       $file_object = File::load($fid);
       $file_uri = $file_object->uri->value;
       $file_url = file_create_url($file_uri);   
       $file_naam= $file_object->filename->value;       
       $style = ImageStyle::load('vierkant_250');   
       $image_url = $style->buildUrl($file_object->uri->value);         
       echo "</br><img src='$image_url'>";

                      }
echo "</div>";

    }

} else {
    echo "0 results";
}

mysqli_close($conn);

?>