モバイルフレンドリーなosCommerce MS1J
前回オープンリダイレクト脆弱性をなんとかしたら、今度は
「ずーっと『モバイルフレンドリーではありません』って警告されてるのもなんとかなる?」
とのご相談。
もちろん直せばなんとかならんことはないでしょ、とソースを見ると、必殺のtableタグ組みレイアウト(^_^;) それでも関連部分がブロックになってるだけマシか。
最近のスマートフォンはほぼPCと同機能だけど、画面のヨコ幅が狭くて縦長なのだけはどうにもならない→要するにPCとスマートフォンで「見せ方」を変えて、狭幅縦長用のレイアウトにしてやれば良いってこと。
PCとスマートフォンを識別するのはブラウザのユーザーエージェントを使うのが楽なので、mod_rewriteでちょいちょいと。
.htaccess
RewriteCond %{ENV:X_SPHONE} ^NULL$
RewriteCond %{HTTP_USER_AGENT} Android [NC]
RewriteRule .* - [E=X_SPHONE:SMARTPHONE]
RewriteCond %{ENV:X_SPHONE} ^NULL$
RewriteCond %{HTTP_USER_AGENT} iPhone [NC,OR]
RewriteCond %{HTTP_USER_AGENT} iPod [NC]
RewriteRule .* - [E=X_SPHONE:SMARTPHONE]
これで、ブラウザのユーザーエージェントに
・Android
・iPhone
・iPod
が含まれる場合は環境変数X_SPHONEにSMARTPHONEという文字列が入るようになりましたんで、以後はこれで識別して分岐すればいい。
osCommerce MS1Jの基本レイアウトは3ペインなので、縦長にするには両側の領域を消し、その部分に書かれてた情報のうち必要なものをヘッダかフッタに移動するのが良さそう。
まず、両側を消します。
<!-- left_navigation //-->
<?php require(DIR_WS_INCLUDES . 'column_left.php'); ?>
<!-- left_navigation_eof //-->
</table></td>
ここと
<!-- right_navigation //-->
<?php require(DIR_WS_INCLUDES . 'column_right.php'); ?>
<!-- right_navigation_eof //-->
</table></td>
ここが問題の両側ペインなんで、この前後にそれぞれ
if (!$getenv('X_SPHONE')) :
?>
判定開始と
endif;
?>
判定終了と書いとけば、この部分は環境変数X_SPHONEに値があるとき(=スマートフォン)は読み込まれません。これで1ペイン。
モバイル用はAMP(Accelerated Mobile Pages)を導入する等全然変えたい場合はdefault_m.phpとか別ファイル化して
RewriteRule ^default\.php(.*)$ default_m.php$1
とかすればスマホ時はdefault_m.phpを読むようにも出来る。
あとは
includes/header.php
に必要部分を書き足したファイルを作っといて、環境に応じて
require(DIR_WS_INCLUDES . 'header.php');
を変えるようにしとけばいいだけ。CSSとかも同じ理屈ですが、実際にやってみたらビューポートを設定し、サイドバー部分を消して1ペイン化だけで「モバイルフレンドリー」になってました。
<meta name="viewport" content="width=device-width">
そのままだと動線がなくなるので、ページ間移動の手段としてサイドバーに有ったメーカー一覧を移植。
<tr>
<td class="main">
メーカー
<?php
echo tep_draw_form('manufacturers', tep_href_link(FILENAME_DEFAULT), 'get');
$manufacturers_query = tep_db_query("select manufacturers_id, manufacturers_name from " . TABLE_MANUFACTURERS . " order by manufacturers_name");
// Display a drop-down
$manufacturers_array = array();
if (MAX_MANUFACTURERS_LIST < 2) {
$manufacturers_array[] = array('id' => '', 'text' => PULL_DOWN_DEFAULT);
}
while ($manufacturers = tep_db_fetch_array($manufacturers_query)) {
$manufacturers_name = ((strlen($manufacturers['manufacturers_name']) > MAX_DISPLAY_MANUFACTURER_NAME_LEN) ? mb_substr($manufacturers['manufacturers_name'], 0, MAX_DISPLAY_MANUFACTURER_NAME_LEN) . '..' : $manufacturers['manufacturers_name']);
$manufacturers_array[] = array('id' => $manufacturers['manufacturers_id'],
'text' => $manufacturers_name);
}
echo tep_draw_pull_down_menu('manufacturers_id', $manufacturers_array, $HTTP_GET_VARS['manufacturers_id'], 'onChange="this.form.submit();" size="' . MAX_MANUFACTURERS_LIST . '" style="width: 100%"') . tep_hide_session_id();
?>
</form>
</td>
</tr>
<!-- manufacturers_eof //-->
カテゴリ一覧も移植。
//カレント下にカテゴリがなければ終了
$categories_query = tep_db_query('SELECT categories_id FROM '. TABLE_CATEGORIES . ' WHERE parent_id = ' . (int)$current_category_id);
$category_check = tep_db_num_rows($categories_query);
if ($category_check < 1) {
return;
}
?>
<!-- categories //-->
<tr>
<td class="main">
カテゴリー
<?php
echo tep_draw_form('categories', tep_href_link(FILENAME_DEFAULT), 'get');
$categories_array[] = array('id' => '', 'text' => PULL_DOWN_DEFAULT);
$categories_query = tep_db_query("select c.categories_id, cd.categories_name, c.parent_id from " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd where c.parent_id = '" . (int)$current_category_id . "' and c.categories_id = cd.categories_id and cd.language_id='" . (int)$languages_id ."' order by sort_order, cd.categories_name");
while ($categories = tep_db_fetch_array($categories_query)) {
$categories_array[] = array(
'text' => $categories['categories_name'],
'id' => tep_get_cpath((int)$categories['categories_id']),
);
}
echo tep_draw_pull_down_menu('cPath', $categories_array, $HTTP_GET_VARS['cPath'], 'onChange="this.form.submit();" size="' . MAX_MANUFACTURERS_LIST . '" style="width: 100%"') . tep_hide_session_id();
?>
</form>
</td>
</tr>
<!-- categories_eof //-->
もっと綺麗にも書けるけど、とりあえず動けばいいや(^_^;)
あとは適当な場所に改造ファイルを置いて、要るところからrequireしとけばいい。
UAによって出力HTMLが変わるので、.htaccessに
Header set Vary User-Agent
も書いといたほうが良さそう。
ちゃんとヘッダー出てますね(^_^)