Bonjour,

Je suis en train d'ajouter une fonction de filtrage des oeuvres par type, matériau, support utilisé sur un site de galerie d'art.
Le formulaire de filtrage est déjà créé et les valeurs récupérées par POST après assainissement des données (filter_input).
J'en suis à la partie d'attaque de la base de données par jointure sur 2 tables.

En base de données MySQL, les tables suivantes ont été créées : "Artwork".
Artwork contient des colonnes du même nom que les tables suivantes : "Matter", "Type", "Support", "Dimensions", "Theme", "Status".
Ces colonnes stockent les identifiants des tables correspondantes (clés étrangères).
Pour l'instant, j'ai un problème pour créer ces clés étrangères : cf ce post.
En attendant de pouvoir régler ce problème, je continue avec le code PHP.

La classe ArtworkDao manipule les données de la classe ArtworkDto qui stocke bien sûr les données de la table Artwork.
Même schéma pour les autres classes : MatterDao, TypeDao, ...

Dans ArtworkDao, afin de faire le lien entre les 2 tables ArtworkDto et MatterDto, j'utilise une jointure.

ArtworkDao->readFilteredData
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
 *  reading the reference, the title and the filename of only the filtered artwork entries
 *  according to the filters
 *  @param array $array the array of filters
 *  @param array $dimensions the array of the artworks dimensions
 *  @param array $matter the array of the matters (charcoal, watercolor, acrylic, ...)
 *  @param array $status the array of the possible status for the artworks (sold, exhibited, available)
 *  @param array $support the array of the supports that can be used
 *  @param array $theme the array of the themes (portrait, nude, still-life, scenes, seascape, landscape)
 *  @param array $type the array of the types of art (drawing, painting, ...)
 * 
 *  @return returns an associated array of ArtworkDto (entities)
*/
// type, matter, support, theme, year, status
public function readFilteredData ($arrayOfFilters, $dimensions, $matter, $status, $support, $theme, $type)
{
    $filteringCriteria = "";
    // Checking if the parameter is an array containing any value
    // If so, an additional criteria is created to use in the SELECT query
    if (isset($arrayOfFilters) && !empty($arrayOfFilters))
    {
        foreach ($arrayOfFilters as $key => $value)
        {
            if (isset($value) && $value != 'empty')
            {
                $filteringCriteria .= ' AND m.'.$key.'=\''.$value.'\'';
            }
        }
    }
 
 
    $current_timestamp = date('Y-m-d H:i:s');
    $query = 'SELECT a.ref,a.title,a.filename,a.publicationDate,a.expiryDate,m.matter'
            . ' FROM shart\models\dto\ArtworkDto a LEFT JOIN shart\models\dto\MatterDto m'
            . ' ON a.matter = m.idMatter'
            . ' WHERE a.ref IS NOT NULL AND a.ref<>\'\''
            .       ' AND a.filename IS NOT NULL AND a.filename<>\'\''
            . 	' AND a.publicationDate < \''.$current_timestamp.'\''
            . 	' AND a.expiryDate > \''.$current_timestamp.'\''
            .       $filteringCriteria
            . ' ORDER BY a.publicationDate DESC, a.ref DESC'
            ;
 
    echo '<h1>'.$query.'</h1>';
 
    $result = $this->executeQuery ($query, $this->getNumberOfArtworks());
    return isset($result[0]) ? $result : NULL;
}
Avec ce code, j'obtiens la requête suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
SELECT a.ref,a.title,a.filename,a.publicationDate,a.expiryDate,m.matter FROM shart\models\dto\ArtworkDto a LEFT JOIN shart\models\dto\MatterDto m ON a.matter = m.idMatter WHERE a.ref IS NOT NULL AND a.ref<>'' AND a.filename IS NOT NULL AND a.filename<>'' AND a.publicationDate < '2020-05-03 13:20:46' AND a.expiryDate > '2020-05-03 13:20:46' AND m.matter='acrylique' ORDER BY a.publicationDate DESC, a.ref DESC
Cette requête fonctionne bien si je la saisis dans MySQL (après avoir remplacé les namespaces par les noms des tables correspondantes). Mais dans PHP, j'obtiens l'erreur suivante :
Exception is : Doctrine\ORM\Query\QueryException: [Semantical Error] line 0, col 144 near 'm ON a.matter': Error: Identification Variable shart\models\dto\MatterDto used in join path expression but was not defined before. in /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/QueryException.php:47
Stack trace:
#0 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(413): Doctrine\ORM\Query\QueryException::semanticalError('line 0, col 144...')
#1 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(913): Doctrine\ORM\Query\Parser->semanticalError('line 0, col 144...')
#2 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(1567): Doctrine\ORM\Query\Parser->JoinAssociationPathExpression()
#3 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(1453): Doctrine\ORM\Query\Parser->Join()
#4 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(1413): Doctrine\ORM\Query\Parser->JoinVariableDeclaration()
#5 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(1171): Doctrine\ORM\Query\Parser->IdentificationVariableDeclaration()
#6 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(758): Doctrine\ORM\Query\Parser->FromClause()
#7 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(727): Doctrine\ORM\Query\Parser->SelectStatement()
#8 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(213): Doctrine\ORM\Query\Parser->QueryLanguage()
#9 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/Parser.php(288): Doctrine\ORM\Query\Parser->getAST()
#10 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query.php(230): Doctrine\ORM\Query\Parser->parse()
#11 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query.php(241): Doctrine\ORM\Query->_parse()
#12 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/AbstractQuery.php(595): Doctrine\ORM\Query->_doExecute()
#13 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/AbstractQuery.php(420): Doctrine\ORM\AbstractQuery->execute(Array, 1)
#14 /var/www/devel.stephane-herve-art.local/models/dao/AbstractDao.class.php(69): Doctrine\ORM\AbstractQuery->getResult()
#15 /var/www/devel.stephane-herve-art.local/models/dao/ArtworkDao.class.php(106): AbstractDao->executeQuery('SELECT a.ref,a....', 500)
#16 /var/www/devel.stephane-herve-art.local/controllers/FrontController.class.php(200): ArtworkDao->readFilteredData(Array, Array, Array, Array, Array, Array, Array)
#17 /var/www/devel.stephane-herve-art.local/controllers/FrontController.class.php(65): FrontController->setContent()
#18 /var/www/devel.stephane-herve-art.local/index.php(60): FrontController->__construct()
#19 {main}


Fatal error: Uncaught Doctrine\DBAL\ConnectionException: There is no active transaction. in /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/DBAL/ConnectionException.php:42 Stack trace: #0 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/DBAL/Connection.php(947): Doctrine\DBAL\ConnectionException::noActiveTransaction() #1 /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/EntityManager.php(251): Doctrine\DBAL\Connection->rollback() #2 /var/www/devel.stephane-herve-art.local/models/dao/AbstractDao.class.php(71): Doctrine\ORM\EntityManager->rollback() #3 /var/www/devel.stephane-herve-art.local/models/dao/ArtworkDao.class.php(106): AbstractDao->executeQuery('SELECT a.ref,a....', 500) #4 /var/www/devel.stephane-herve-art.local/controllers/FrontController.class.php(200): ArtworkDao->readFilteredData(Array, Array, Array, Array, Array, Array, Array) #5 /var/www/devel.stephane-herve-art.local/controllers/FrontController.class.php(65): FrontController->setContent() #6 /var in /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/DBAL/ConnectionException.php on line 42
Il semble ne pas connaître "shart\models\dto\MatterDto" alors que le namespace est bien déclaré dans MatterDto :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
namespace shart\models\dto;
 
use Doctrine\ORM\Mapping as ORM,
    Doctrine\Common\Collections\ArrayCollection,
    Doctrine\Common\Persistence\PersistentObject;
 
/*
** Class of a matter used in the art work
*/
 
/**
 ** Matter Entity
 **
 **     @Entity
 **     @Table(name="Matter")
**/
class MatterDto extends Dto
{
/* reste du code ici  */
}
J'ajoute que je récupère bien les données de MatterDto dans une variable tableau. Je l'ai testé par un var_dump dans le FrontController et je passe cette variable en argument ($matter) de la fonction. Donc il devrait avoir tout le nécessaire pour faire le traitement.
Dump de $matter :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
array(8) {
  [0]=>
  object(shart\models\dto\MatterDto)#212 (3) {
    ["tablename":protected]=>
    string(6) "Matter"
    ["id":protected]=>
    int(1)
    ["matter":protected]=>
    string(9) "acrylique"
  }
  [1]=>
  object(shart\models\dto\MatterDto)#227 (3) {
    ["tablename":protected]=>
    string(6) "Matter"
    ["id":protected]=>
    int(2)
    ["matter":protected]=>
    string(9) "aquarelle"
  }
  [2]=>
etc.
Même en remplaçant "shart\models\dto\MatterDto" par "Matter" (le nom de la table dans MySQL), j'obtiens la même erreur :
Exception is : Doctrine\ORM\Query\QueryException: [Semantical Error] line 0, col 124 near 'm ON a.matter': Error: Identification Variable Matter used in join path expression but was not defined before. in /var/www/devel.stephane-herve-art.local/lib/doctrine-2.2.0/Doctrine/ORM/Query/QueryException.php:47
Stack trace:
...
Est-ce que vous comprenez ce qui peut l'empêcher de reconnaître l'existence du namespace "shart\models\dto\MatterDto" ?