ゲームリストを作成しようとしていますが、現在、詳細なチーム情報を取得するのに苦労しています。
#__ game
id team_home team_guest
1 1 2
2 2 3
#__ team
id name
1 My Team Name
2 Another Team Name
3 The third Team
マイコード:
// Get the user object.
$user = JFactory::getUser();
// Get the databse object.
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('a.*');
$query->select('b.name', 'home_name');
$query->select('c.name', 'guest_name');
$query->from($db->quoteName('#__game', 'a'));
$query->join('LEFT', $db->quoteName('#__team', 'b') . ' ON ' . $db->quoteName('a.team_home') . ' = ' . $db->quoteName('b.id'));
$query->join('LEFT', $db->quoteName('#__team', 'c') . ' ON ' . $db->quoteName('a.team_guest') . ' = ' . $db->quoteName('c.id'));
$query->where($db->quoteName('a.published') . ' = 1');
$query->order('a.kickoff ASC');
// Implement View Level Access (if set in table)
if (!$user->authorise('core.options', 'com_component'))
{
$columns = $db->getTableColumns('#__game');
if(isset($columns['access']))
{
$groups = implode(',', $user->getAuthorisedViewLevels());
$query->where('a.access IN (' . $groups . ')');
}
}
$db->setQuery((string)$query);
$items = $db->loadObjectList();
echo '<pre>' . var_export($items,true).'</pre>';
$options = array();
if ($items)
{
$options[] = JHtml::_('select.option', '', 'Select an option');
foreach($items as $item)
{
//$options[] = JHtml::_('select.option', $item->id, $item->home_name . ' vs ' . $item->guest_name);
}
}
return $options;
これは、戻りオブジェクト内に「名前」を1つだけ作成し(確かに、家とゲストで同じキーです)、ゲストは家の値を上書きします。
家とゲストの名前が異なるオブジェクトキーに配置されるようにするために、結合用に何を記述する必要がありますか?
問題の詳細説明:
発見したように、クエリのSELECT句の2つの列が同じ列名(またはエイリアス)を共有すると、後者の値が結果セットの前者を上書きします。これを克服するには、一意のエイリアスを割り当てて、2つの繰り返される列名を区別します。
Joomlaには、quoteName()
ヘルパーメソッド内でエイリアスを割り当てる(または割り当てない)ための既製のテクニックがあります。最初のパラメーターとして列名の配列をフィードし、2番目のパラメーターとして対応するエイリアス(またはnull)の配列をフィードするだけです。これが 既存のデモ です。
コードレビュー:
*
_を使用して_#__game
_テーブルのすべての列値を収集する必要はありません。返される列の数が減ると、単一のselect()
呼び出しを含む単一のquoteName()
呼び出しを使用するほうが魅力的になります。qn()
は、quoteName()
メソッドのエイリアスです。これらを使用すると、メソッドの完全な単語のスペルと比較して、スクリプト全体の幅/膨張を減らすのに役立ちます。$query
_を再入力し続ける必要がないことを意味します。ASC
がデフォルトのソート方向なので、これらの文字を削除して同じ機能を楽しむことができます。一方、この宣言型スタイルを使用する場合は、そのままにしておいても害はありません。isset()
の呼び出しから、テーブルに列が呼び出される場合とされない場合があるという可能性に対応しているという印象を受けました。このため、getTableColumns()
の賢明な使い方のようです。ただし、列が常にテーブルに存在する場合、phpのアクセス列チェックを削除し、ユーザーのauthorise()チェックが失敗したときにwhere()
句をクエリに追加するだけです。$query
_を文字列型データとしてキャストする必要はありません。これはJoomlaの以前のバージョンでしばしば実証されましたが、単に不必要です。loadObjectList()
は、結果セットに行がない場合に空の配列を生成するため、構文エラーがないと想定して、foreach()
の前の条件を省略できます。<select>
_タグが含まれる可能性があります。実装された提案:
_$db = JFactory::getDBO();
$query = $db
->getQuery(true)
->select($db->qn(['a.id', 'b.name', 'c.name'], [null, 'home_name', 'guest_name']))
->from($db->qn('#__game', 'a'))
->innerJoin($db->qn('#__team', 'b') . ' ON ' . $db->qn('a.team_home') . ' = ' . $db->qn('b.id'))
->innerJoin($db->qn('#__team', 'c') . ' ON ' . $db->qn('a.team_guest') . ' = ' . $db->qn('c.id'))
->where($db->qn('a.published') . ' = 1')
->order('a.kickoff');
$user = JFactory::getUser();
if (!$user->authorise('core.options', 'com_component'))
{
$columns = $db->getTableColumns('#__game');
if(isset($columns['access']))
{
$groups = implode(',', $user->getAuthorisedViewLevels());
$query->where('a.access IN (' . $groups . ')');
}
}
$db->setQuery($query);
$options = [JHtml::_('select.option', '', 'Select an option')];
foreach ($db->loadObjectList() as $item)
{
$options[] = JHtml::_('select.option', $item->id, $item->home_name . ' vs ' . $item->guest_name);
}
return $options;
_
わかりました。SELECTでASを配列として設定する必要がありました。
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('a.*');
$query->select($db->quoteName(array('b.name'),array('home_name')));
$query->select($db->quoteName(array('c.name'),array('guest_name')));
...