web-dev-qa-db-ja.com

メニュー項目は、404エラーを表示する代わりに、IDがURLで渡されると、記事コンテンツをロードします

記事1をロードする/ fooというメニュー項目があるという非常に奇妙な問題が発生しています。/foo/2を実行すると、サブメニュー項目がないため、これが404ページを生成すると予想します。親メニュー項目/ fooの下の「2」。しかし、404ページを表示する代わりに、同じメニュー項目の下に第2条のコンテンツをロードしています。

私は.htaccessをチェックしましたが、これはJoomlaに付属している通常のものであり、これがなぜ起こり得るのか理解できません。データベースに存在しない記事IDを入力しようとすると、404が表示されます。ポインタがあればすばらしいでしょう。

6
sifu

ああ、Joomlaの現在のルーティングシステムの喜び。 (私は誰かがルーティングシステムを更新するためにGoogle Summer of Codeプロジェクトを行っていると聞いたと思いましたが、それ以外には何も見ていません。)

したがって、ルーティングについての私の理解は、Joomlaがメニュー項目へのリクエストURI(つまりfoo/2)をできるだけ多く解析しようとすることです。あなたの場合、これはfooだけに一致します。

次に、残りの部分は、そのメニュー項目と一致するコンポーネントのrouter.phpファイルに渡されます。あなたの場合、これはcomponents/com_content/router.phpのc​​om_contentルーターだと思います。

これにより、このクラスのparse関数が呼び出され、セグメントが渡されます(この場合は2になります)。

ルーターには、URI内のセグメントを記事IDなどに解析するためのコード(必要に応じて確認できます)があります。セグメントピースが1つしかない場合、影響を受けるコアピースは次のとおりです。

/*
     * If there is only one segment, then it points to either an article or a category.
     * We test it first to see if it is a category.  If the id and alias match a category,
     * then we assume it is a category.  If they don't we assume it is an article
     */
    if ($count == 1)
    {
        // We check to see if an alias is given.  If not, we assume it is an article
        if (strpos($segments[0], ':') === false)
        {
            $vars['view'] = 'article';
            $vars['id'] = (int) $segments[0];

            return $vars;
        }

        list($id, $alias) = explode(':', $segments[0], 2);

        // First we check if it is a category
        $category = JCategories::getInstance('Content')->get($id);

        if ($category && $category->alias == $alias)
        {
            $vars['view'] = 'category';
            $vars['id'] = $id;

            return $vars;
        }
        else
        {
            $query = $db->getQuery(true)
                ->select($db->quoteName(array('alias', 'catid')))
                ->from($db->quoteName('#__content'))
                ->where($db->quoteName('id') . ' = ' . (int) $id);
            $db->setQuery($query);
            $article = $db->loadObject();

            if ($article)
            {
                if ($article->alias == $alias)
                {
                    $vars['view'] = 'article';
                    $vars['catid'] = (int) $article->catid;
                    $vars['id'] = (int) $id;

                    return $vars;
                }
            }
        }
    }

基本的に、カテゴリーIDか記事IDかを確認します。 id 2の記事があるため、それは通過し、メニューidで送信したものの代わりに、それをidとして次に進みます。

これは、com_contentがコーディングされたものであり、良くも悪くも...:/

2
David Fritsch