web-dev-qa-db-fra.com

Réécriture du code selon le guide Joomla, mais page affichant une erreur 404

Je suis en train de réécrire un ancien code en fonction de la dernière référence, bien que la description de la page apparaisse correctement dans l'ancien code.

Mais une fois réécrit dans un nouveau code, la page est redirigée vers 404 en tant que page non trouvée.

Ancien code

function loadProduct($vid){
    $db = JFactory::getDbo();

    $sql = "Select *, 
            (select prod_name from #__usedtoy_products where id=v.v_prod_id)
            as prod_name  from #__usedtoy_variants AS v
            Where v.state='1' and v.id = " . $db->quote($vid);
    $db->setQuery($sql);

    if ($rows = $db->loadObjectlist()) {
        return $rows[0];
    } else {
        if ($db->getErrorNum()) {
            JError::raiseError(500, "Something went horribly wrong, the query returned the error ". $db->getErrorMsg());
        } else {
            JError::raiseError(404, "404, Page does not Exists ". $db->getErrorMsg());
        }
    }
}

à

Code amélioré - ça marche

function loadProduct($vid){
    $mainframe =JFactory::getApplication();
    $option = JRequest::getCmd('option');
    $db =JFactory::getDBO();
    global $Itemid;
    $query = $db->getQuery(true);

    $query->select('#__usedtoy_variants.id');
    $query->from($db->quoteName('#__usedtoy_variants'));
    $query->where($db->quoteName('#__usedtoy_variants.id')." = ".$db->quote($vid), 'AND');
    $query->where($db->quoteName('#__usedtoy_variants.v_prod_id')." = ".$db->quote($pid));
    $query = "Select *, 
              (select prod_name from #__usedtoy_products where id=v.v_prod_id)
              as prod_name  from #__usedtoy_variants AS v
              Where v.state='1' and v.id = " . $db->quote($vid);
    $db->setQuery($query);

    if ($rows = $db->loadObjectlist()) {
        return $rows[0];
    } else {
        if ($db->getErrorNum()) {
            JError::raiseError(500, "Something went horribly wrong, the query returned the error ". $db->getErrorMsg());
        } else {
            JError::raiseError(404, "404, Page does not Exists ". $db->getErrorMsg());
        }
    }
}

Nouveau code final - ça ne marche pas

function loadProduct($vid){
    $mainframe =JFactory::getApplication();
    $option = JRequest::getCmd('option');
    $db =JFactory::getDBO();
    global $Itemid;
    $query = $db->getQuery(true);

    $query->select('#__usedtoy_variants.id');
    $query->from($db->quoteName('#__usedtoy_variants'));
    $query->where($db->quoteName('#__usedtoy_variants.id')." = ".$db->quote($vid), 'AND');
    $query->where($db->quoteName('#__usedtoy_variants.v_prod_id')." = ".$db->quote($pid));

    $query->select(array('v.*', 'p.prod_name'))
          ->from($db->quoteName('#__usedtoy_variants', 'v'))
          ->join('LEFT', $db->quoteName('#__usedtoy_products', 'p') . ' ON (' . $db->quoteName('p.id') . ' = ' . $db->quoteName('v.v_prod_id') . ')')
          ->where($db->quoteName('v.state')." = ".$db->quote(1), 'AND')
          ->where($db->quoteName('v.id')." = ".$db->quote($vid));

    $db->setQuery($query);

    if ($rows = $db->loadObjectlist()) {
        return $rows[0];
    } else {
        if ($db->getErrorNum()) {
            JError::raiseError(500, "Something went horribly wrong, the query returned the error ". $db->getErrorMsg());
        } else {
            JError::raiseError(404, "404, Page does not Exists ". $db->getErrorMsg());
        }
    }
}

Référence - https://docs.joomla.org/Selecting_data_using_JDatabase#Selecting_Records_from_Multiple_Tables

Quelqu'un peut-il préciser le problème?

1
Ruchika

La réponse courte est parce que vous avez deux requêtes qui vont bien ensemble. Dans votre version de "code amélioré", vous créez l'objet de requête, puis vous le remplacez par une requête de type chaîne.

J'ai supprimé tout le code qui n'a pas de rôle comme celui-ci:

function loadProduct($vid){
    $db = JFactory::getDBO();
    $query = $db->getQuery(true);
    $query->select('v.*, p.prod_name')
      ->from($db->qn('#__usedtoy_variants', 'v'))
      ->join('LEFT', $db->qn('#__usedtoy_products', 'p') . ' ON (' . $db->qn('p.id') . ' = ' . $db->qn('v.v_prod_id') . ')')
      ->where($db->qn('v.state')." = 1 AND " . $db->qn('v.id')." = ".$db->q($vid));
    $db->setQuery($query);  

    if ($result = $db->loadObject()) {
        return $result;
    } else {
        if ($db->getErrorNum()) {
            JError::raiseError(500, "Something went horribly wrong, the query returned the error ". $db->getErrorMsg());
        } else {
            JError::raiseError(404, "404, Page does not Exists ". $db->getErrorMsg());
        }
    }
}

Remarque: qn et q sont des noms courts pratiques pour quoteName et quote. Si vous voulez seulement un maximum de 1 enregistrement, utilisez l'utilisateur $ db-> loadObject () au lieu de objectList.

2
jamesgarrett

Pour mémoire, je trouve que la réponse de @ jamesgarrett est parfaitement adéquate. Je veux simplement proposer aux chercheurs une syntaxe alternative.

$db = JFactory::getDBO();
try {
    $query = $db->getQuery(true)
                ->select("A.*, B.prod_name")
                ->from("#__usedtoy_variants A")
                ->leftJoin("#__usedtoy_products B ON A.id = B.v_prod_id")
                ->where("A.state = 1 AND A.id = " . (int)$vid);
    $db->setQuery($query);
    if (!$result = $db->loadObject()) {  // one-dimensional, not multi-dimensional
        JFactory::getApplication()->enqueueMessage('Potential Logic Failure - No Rows Returned', 'notice');
        return false;
    }
    return $result;
} catch (Exception $e) {
    JFactory::getApplication()->enqueueMessage('Syntax Failure', 'error');  // use these to debug: $query->dump() && $e->getMessage()
    return false;
}
  • Je préfère les blocs try {} catch {}, Car j’ai l’impression qu’ils simplifient la gestion des erreurs/en éliminent les erreurs.
  • Le chaînage des méthodes peut être effectué à partir de getQuery(). Cela évite d'avoir à répéter $query Pour chaque appel de méthode de requête.
  • J'ai supprimé chaque qn() et q() non essentielles pour réduire le fardeau de code et ai jeté $vid Sous forme d'entier pour des raisons de sécurité, en supposant que vid pour un identifiant de table (entier). Si $vid N'est pas un entier, utilisez q() dessus.
  • leftJoin() est une méthode de jointure dédiée.
  • Je vérifie la présence d'un jeu de résultats vide avec ! Et publie un avis JFactory::getApplication()->enqueueMessage(), puis renvoie false lorsqu'il n'y a pas de lignes. Selon la conception de votre projet, ce résultat peut ne pas être un "échec logique".
  • Je propose une réponse vague "Echec de la syntaxe" lorsque la requête est interrompue conformément aux meilleures pratiques. Si vous voulez remplir le texte enqueueMessage() avec quelque chose de plus informatif lorsque vous déboguez, utilisez les appels dump() et/ou getMessage() que j'ai laissés sous forme de commentaires en ligne . Une fois le débogage terminé, assurez-vous de supprimer de la vue les détails de requête/erreur spécifiques.
  • En tant que suggestion non associée, je vous exhorte à ne pas utiliser global dans votre appel de fonction. De nombreux développeurs considèrent que cela est "négligé" et ajoute inutilement des variables à la portée globale. Si vous pouvez obtenir le même effet en passant des variables comme arguments dans la fonction, faites-le.
0
mickmackusa