色に関しては外部キーを設定していたおかげで、scaffoldingで商品登録画面にプルダウンが表示されたけど、カテゴリに関しては外部キーを設定していないので、自前で実装してやる必要があります。
なので、apps/admin/modules/product/templates/editSuccess.phpにこういうのを追加。
<td>
<?php echo select_tag('category_id[]', objects_for_select(
$category_list, 'getId', 'getCategoryNameForLabel', $joined_category), array (
'size' => 20,
' multiple' => 'multiple'
)) ?>
</td>
で、apps/admin/modules/product/actions/actions.class.phpのexecuteEditに以下のコードを追加。
$joined_category = array();
foreach ($this->product->getCategories() as $category)
{
$joined_category[] = $category->getId();
}
$this->joined_category = $joined_category;
$this->category_list = CategoryPeer::getCategoryList();
上のコードで使ったメソッドを実装するためにlib/model/Product.phpにgetCategoriesメソッドを追加。
public function getCategories()
{
$c = new Criteria();
$c->addJoin(CategoryTablePeer::CATEGORY_ID, CategoryPeer::ID, Criteria::INNER_JOIN);
$c->add(CategoryTablePeer::PRODUCT_ID, $this->getId());
$categories = CategoryPeer::doSelect($c);
return $categories;
}
さらにlib/model/CategoryPeer.phpにgetCategoryListメソッドを追加。
public static function getCategoryList()
{
$category_list = array();
$root_categories = self::doSelectRootCategories();
foreach ($root_categories as $category)
{
$category_list[] = $category;
if ($category->hasSubCategories())
{
foreach ($category->getSubCategories() as $sub_category)
{
$category_list[] = $sub_category;
}
}
}
return $category_list;
}
これでメソッドもそろったし、完璧。
カテゴリ一覧がセレクトボックスに表示され、CategoryTableに該当する商品IDとカテゴリIDのレコードがあれば、あらかじめ選択されているはずです。
ということで、早速レコードを挿入してから表示してみます。
…しかし!何度やってもうまくいかない!コードをいろいろ変えてみてもうまく行かない!
いろいろ調べた結果、XSS対策を有効にした状態でコントローラーからビューに配列を渡す、sfOutputEscaperArrayDecoratorというオブジェクトに変換されてしまうらしい。
なので、select_tagが配列が来るべきなのにオブジェクトが来てしまって、処理できなかったらしい。
sfOutputEscaperArrayDecoratorではなく生の配列として扱うには、$sf_data->getRawというメソッドを使えばいいということがわかったので、listSuccess.phpをこのように修正。
<td>
<?php echo select_tag('category_id[]', objects_for_select(
$category_list, 'getId', 'getCategoryNameForLabel',
$sf_data->getRaw('joined_category')), array (
'size' => 20,
' multiple' => 'multiple'
)) ?>
</td>
みごと、セレクトボックスが最初から選択された状態で表示されました。

