We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 17546
    • 75 Posts
    Bonjour à tous,

    Voilà, je me suis frotté au xPDO, et, ça fait mal, très mal ! l’impression de devoir escalader une montagne avec des biscottes comme seul outil !

    Je souhaiterais réaliser quelque chose somme toute assez simple, du moins, sur le papier; Réaliser une requête qui me permettrait de retourner des enregistrements obéissant à des critères tel que:
    Lire toutes les ressources situé dans un conteneur (donc notion de modx_site_content.parent = 5 par exemple), et qui possède plusieurs tv ayant une valeur définie (via une tv de type list), d’ou la notion de jointure (je suppose) avec ’modx_site_tmplvar_contentvalues’.
    Mais, je me trouve bloquer devant xPDO comme un singe devant un monolithe ! je cherche, je tatonne, je bidouille du code, mais rien n’en sort !
    Quelqu’un a déjà réussit de manière élégante à pondre un code assez ’propre’ pour être compréhensible et limpide.

    Un peu d’aide ne serait pas le malvenu !

    Low
      Low
    • Bonjour low,

      Je ne me suis pas encore frotté à xPDO, mais ta "notion" de modx_site_content.parent = 5 me semble étonnant, ne serait-ce pas plus modResource.parent que tu cherches à cibler ? (le content étant un objet de modResource si j’ai bien tout suivi…).

      En tout cas, si tu n’as pas déjà mis le nez dedans, tu peux jeter un coup d’oeil à la documentation d’xPDO 2 (notamment sur la récupération d’objets), tu trouvera certainement des exemples de code qui te permettront d’avancer.
      Les repos de Splittingred et d’Opengeek sont également de bonnes sources de lecture smiley.

      Bon courage en tout cas!
        • 5811
        • 1,717 Posts
        Voilà comment je pense que je ferai sous revo. Script php à placer et executer à la racine du site, après avoir changer le nom de la tv (articleCategory), sa valeur (Geography) et l’id du document parent (3).

        <?php
        
        define('MODX_BASE_PATH', '');  // 	script à placer à la racine du site
        define('MODX_BASE_URL', '/');
        
        require_once MODX_BASE_PATH.'config.core.php';
        
        require_once MODX_CORE_PATH.'config/'.MODX_CONFIG_KEY.'.inc.php';
        require_once MODX_CORE_PATH.'model/modx/modx.class.php';
        $modx = new modX();
        $modx->initialize('web');
        
        $tmplVarResourceTbl = $modx->getTableName('modTemplateVarResource');
        $tmplVarTbl = $modx->getTableName('modTemplateVar');
        
        $tvName = $modx->quote('articleCategory');			// nom de la tv
        $tvValue = $modx->quote('Geography');				// la valeur de tv recherchee
        
        $fields = array('id','createdon','pagetitle','introtext','content');
        
        $c = $modx->newQuery('modResource');
        $c->select($fields);
        $c->where(array('parent' => 3));  // id du document parent (j'ai pris 3 car correspond à mes données)
        $c->andCondition("EXISTS (SELECT 1 FROM {$tmplVarResourceTbl} tvr JOIN {$tmplVarTbl} tv ON tvr.value LIKE {$tvValue} AND tv.name = {$tvName} AND tv.id = tvr.tmplvarid WHERE tvr.contentid = modResource.id)");
         
        $c->prepare();
        $modx->log(modX::LOG_LEVEL_INFO, $c->toSQL());		// pour tracer la requete sql executée. Voir la log MODx
        echo $c->toSQL();
        
        $results = $modx->getCollection('modResource', $c);
        
        foreach($results as $res) echo $res->get('pagetitle');  // juste histoire de voir les titres des resources resultats
        
        ?>

        En l’occurence ici on a trouvé les occurences de documents qui satisfont les conditions. Par contre tu n’as pas les valeurs de tvs dans le resultat.
        Si tu veux la valeur des tvs, il faut effectivement faire une jointure.
          • 17546
          • 75 Posts
          @Romain Je faisait notion surtout d’un acquis, le *.parent n’étant là que pour situé le champs, mais il n’était pas primordial de le préciser. Mais en effet, c’est le modResource.
          Je crois que je manque cruellement de recul par rapport à xPDO2, et tenter, en vain, de trouver une solution rapide à un problème somme tout assez basic, c’est là mon erreur.

          @coroico Je vais jeter un oeil intéressé à ton script, c’est, au premier coup d’oeil, exactement ce que je recherche.

          Merci à vous deux pour vos réponses éclairés et instructif.
          Je regrette juste que l’évolution de modx prenne ce tournant, car le choix d’un cms, à première vue, est celle du gain de temps, et... modx revo est tout le contraire pour une personne qui aime bien codé en php objet, mais qui déteste la complexité inutile et anti-productif.

          Bonne soirée.
          Cdlt.
          Olivier.

            Low
            • 17546
            • 75 Posts
            Bonjour,

            Je fais un petit retour sur ce que j’ai fait, en regard des réponses données:
            Le code suivant est une fonction permettant de retourner les ressources IDs, avec comme critère de recherche le parent conteneur et les valeurs des TVs (opérateur ’=’).
            function _testing($conteneur, $tvs, $json) {
            	global $modx;
            	$modResource = $modx->getTableName('modResource');
            	$modTemplateVarResource = $modx->getTableName('modTemplateVarResource');
            	$modTemplateVar = $modx->getTableName('modTemplateVar');
            	$fields = array('modResource.id id','modResource.pagetitle pagetitle');
            	$query = $modx->newQuery('modResource');
            	$tv_id = 0;
            	foreach($tvs as $tv_name => $tv_value) {
            		if ($tv_value) {
            			$tv_id++;
            			$query->leftJoin('modTemplateVarResource','mtvr' . $tv_id, 'mtvr' . $tv_id . '.contentid = modResource.id');
            			$query->leftJoin('modTemplateVar','mtv' . $tv_id, 'mtv' . $tv_id . '.id = mtvr' . $tv_id . '.tmplvarid');
            			$query->andCondition(array(
            				'mtv' . $tv_id . '.name:=' => $tv_name,
            				'mtvr' . $tv_id . '.value:=' => $tv_value
            				));
            			$fields[] = 'mtvr' . $tv_id . '.value ' . $tv_name;
            		}
            	}
            	$query->andCondition(array('modResource.parent:='=>$conteneur));
            	$query->select($fields);
            	$query->prepare();
            	$results = $modx->getCollection('modResource', $query);
            	if ($results) {
            		$code=1;
            		foreach($results as $res) {$id[] = $res->get('id');}
            		$debug=array('resourceIds'=>print_r($id,true);
            	}else{
            		$code=0;
            		$message='Pas de résultat';
            	}
            	$data = array('code'=>$code,'html'=>$html, 'debug'=>$debug, 'message'=>$message);
            	if ($json) return json_encode($data);
            	return $data;
            }
            
            $tvs = array(
            	'nom_template_variable' => 'valeur recherché',
            	'nom_autre_template_variable' => 'valeur recherché'
            	);
            
            echo _testing('4', $tvs, true);
            

            C’est un prototype, qui fonctionne (sauf erreur de copié/collé/modification). Le résultat est retournée au format JSON, car cette fonction est appelé dans ce contexte en AJAX, pour un moteur multi-critère. Je me suis servit, dans une version plus complète de cette fonction, de getResources pour récupérer et mettre en page le résultat (valeur $html), en utilisant les paramètres parents=$conteneur, resources=implode(’,’,$id), includeTVs=1, et un tpl pour le rendu, et accessoirement un sortby...
            Néanmoins, pour parfaire le résultat, j’ai dut modifié le getResources (version 1.3.0) à la ligne 150, en définissant une condition AND au lieu de OR, sinon, il me ressortait toutes les ressources sans faire cas du filtre.
            Cette fonction n’est pas en l’état parfaite, et je suppose qu’il y a des éléments qui manquent (condition des recherches des TVs) ou en trop.

            Merci encore pour la contribution initiale, qui m’a permit de réaliser cette fonction, et aussi à l’aide de la documentation, qui somme toute, est assez complète pour peu que l’on se prenne la peine de la lire, RTFM, CQFD.

            Low
              Low