[EC-CUBE 2.13]管理画面で「更新情報の取得に失敗しました」が出た時の対処
- 公開日:2015/4/6
私は今回初めて見たエラーだったけど、調べてみると情報も多く、よくあるエラーのようです。
「更新情報の取得に失敗しました」とは?
本来なら管理画面の右側に表示される更新情報を「file_get_contents()」で取得しているのですが、うまくいかず、失敗してエラーが出ているという状態です。
なのでエラー対処できたら、以下のように右側に更新情報が表示されるようになります。
すでに紹介されている対処法はあまりおすすめ出来ない
「file_get_contents()」で取得を失敗した場合に「fsockopen()」を使って更新情報を取得するという方法が、上記のコミュニティに紹介してありますが、これでは対処しきれずエラーが消えないことがあるようです。
EC-CUBEの管理画面で「更新情報の取得に失敗しました。」というエラーが出たら?
こちらの記事によると、更新情報取得後のHTTPステータスコードによる分岐でコミュニティの修正コードには想定されていない「HTTP/1.1 302 Found」が起こりうるからだそうです。
それと、classファイルを直接編集してしまっています。ここはclass_extendsの拡張クラスを編集する方が望ましいと思います。
というわけでそれらを踏まえた対処法
LC_Page_Admin_Home.phpファイルをオーバーライド
data/class/pages/admin/LC_Page_Admin_Home.php ファイルにある「lfGetInfo()」をごっそり丸ごと、コピーします。
コピー先: data/class_extends/page_extends/admin/LC_Page_Admin_Home_Ex.php
取得失敗時の分岐文追加とクラスを追加
「file_get_contents()」で取得を失敗した場合の分岐文を追加します。
/** * リリース情報を取得する. * * @return array 取得した情報配列 */ public function lfGetInfo() { // 更新情報の取得ON/OFF確認 if (!ECCUBE_INFO) return array(); // パラメーター「UPDATE_HTTP」が空文字の場合、処理しない。 // XXX これと別に on/off を持たせるべきか。 if (strlen(UPDATE_HTTP) == 0) return array(); $query = ''; // サイト情報の送信可否設定 // XXX インストール時に問い合わせて送信可否設定を行うように設定すべきか。 // XXX (URLは強制送信すべきではないと思うが)バージョンは強制送信すべきか。 if (UPDATE_SEND_SITE_INFO === true) { $query = '?site_url=' . HTTP_URL . '&eccube_version=' . ECCUBE_VERSION; } $url = UPDATE_HTTP . $query; // タイムアウト時間設定 $context = array('http' => array('timeout' => HTTP_REQUEST_TIMEOUT)); $jsonStr = @file_get_contents($url, false, stream_context_create($context)); // *** Error「更新情報の取得に失敗しました」対応 --- ここから if ( empty($jsonStr) ) { $jsonStr = $this->do_get($url); } // *** Error「更新情報の取得に失敗しました」対応 --- ここまで $arrTmpData = is_string($jsonStr) ? SC_Utils_Ex::jsonDecode($jsonStr) : null; if (empty($arrTmpData)) { SC_Utils_Ex::sfErrorHeader('>> 更新情報の取得に失敗しました。'); return array(); } $arrInfo = array(); foreach ($arrTmpData as $objData) { $arrInfo[] = get_object_vars($objData); } return $arrInfo; }
新しいクラスを2つ追加する
LC_Page_Admin_Home_Ex.phpにコピーした「lfGetInfo()」に続けて以下を追記します。
// *** Error「更新情報の取得に失敗しました」対応 --- ここから function do_get($url) { $res = $this->get_contents($url); $res_array = explode("\r\n", $res); switch ($res_array[0]) { case 'HTTP/1.0 200 OK': case 'HTTP/1.1 200 OK': $ra = explode("\r\n\r\n", $res, 2); $res = $ra[1]; break; case 'HTTP/1.1 302 Found': case 'HTTP/1.1 302 MovedTemporarily': foreach ($res_array as $res_row) { if (strstr($res_row, 'Location: ')) { $crr_url = str_replace('Location: ', '', $res_row); break; } } $res = $this->get_contents($crr_url); $ra = explode("\r\n\r\n", $res, 2); $res = $ra[1]; break; default: $res = ''; } return $res; } function get_contents($url) { $url_array = parse_url($url); $host = $url_array['host']; $path = $url_array['path']; if (array_key_exists('port', $url_array)) { $port = $url_array['port']; } else { switch ($url_array['scheme']) { case 'http': $port = 80; break; } } $query = $url_array['query']; $res = false; if (isset($host) && isset($port)) { $fp = fsockopen($host, $port, $errno, $errstr, 30); if ($fp) { $req = "GET " . $path . "?" . $query . " HTTP/1.0\r\n" . "Host: " . $host . "\r\n" . "\r\n"; socket_set_timeout($fp, 10); if (fputs($fp, $req, strlen($req))) { $res = ''; while (!feof($fp)) { $res .= fgets($fp); } } fclose($fp); } } return $res; } // *** Error「更新情報の取得に失敗しました」対応 --- ここまで
これでOKです。