source: branches/version-2_5-dev/data/class/pages/upgrade/LC_Page_Upgrade_Download.php @ 19802

Revision 19802, 12.9 KB checked in by Seasoft, 13 years ago (diff)

#834(パラメータの定数名に「URL」を含むにもかかわらず、パスのみのものがある) 一部改修

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2010 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24// {{{ requires
25require_once CLASS_PATH . 'pages/upgrade/LC_Page_Upgrade_Base.php';
26require_once DATA_FILE_PATH . 'module/Tar.php';
27
28/**
29 * オーナーズストアからダウンロードデータを取得する.
30 *
31 * TODO 要リファクタリング
32 *
33 * @package Page
34 * @author LOCKON CO.,LTD.
35 * @version $Id$
36 */
37class LC_Page_Upgrade_Download extends LC_Page_Upgrade_Base {
38
39    // }}}
40    // {{{ functions
41
42    /**
43     * Page を初期化する.
44     *
45     * @return void
46     */
47    function init() {
48        parent::init();
49    }
50
51    /**
52     * Page のプロセス.
53     *
54     * @return void
55     */
56    function process($mode) {
57        $objLog  = new LC_Upgrade_Helper_Log;
58        $objLog->start($mode);
59
60        $objJson = new LC_Upgrade_Helper_Json;
61
62        // アクセスチェック
63        $objLog->log('* auth start');
64        if ($this->isValidAccess($mode) !== true) {
65            // TODO
66            $objJson->setError(OSTORE_E_C_INVALID_ACCESS);
67            $objJson->display();
68            $objLog->error(OSTORE_E_C_INVALID_ACCESS);
69            return;
70        }
71
72        // パラメーチェック
73        $this->initParam();
74        $objLog->log('* post param check start');
75        $arrErr = $this->objForm->checkError();
76        if ($arrErr) {
77            $objJson->setError(OSTORE_E_C_INVALID_PARAM);
78            $objJson->display();
79            $objLog->error(OSTORE_E_C_INVALID_PARAM, $_POST);
80            $objLog->log('* post param check error ' . print_r($arrErr, true));
81            return;
82        }
83
84        $objLog->log('* auto update check start');
85        if ($mode == 'auto_update'
86        && $this->autoUpdateEnable($this->objForm->getValue('product_id')) !== true) {
87            $objJson->setError(OSTORE_E_C_AUTOUP_DISABLE);
88            $objJson->display();
89            $objLog->error(OSTORE_E_C_AUTOUP_DISABLE, $_POST);
90            return;
91        }
92
93        // TODO CSRF対策
94
95        // 認証キーの取得
96        $public_key = $this->getPublicKey();
97        $sha1_key = $this->createSeed();
98
99        // 認証キーチェック
100        $objLog->log('* public key check start');
101        if (empty($public_key)) {
102            $objJson->setError(OSTORE_E_C_NO_KEY);
103            $objJson->display();
104            $objLog->error(OSTORE_E_C_NO_KEY);
105            return;
106        }
107
108        // リクエストを開始
109        $objLog->log('* http request start');
110
111        switch($mode) {
112        case 'patch_download':
113            $arrPostData = array(
114                'eccube_url' => HTTP_URL,
115                'public_key' => sha1($public_key . $sha1_key),
116                'sha1_key'   => $sha1_key,
117                'patch_code' => 'latest'
118            );
119            break;
120        default:
121            $arrPostData = array(
122                'eccube_url' => HTTP_URL,
123                'public_key' => sha1($public_key . $sha1_key),
124                'sha1_key'   => $sha1_key,
125                'product_id' => $this->objForm->getValue('product_id')
126            );
127            break;
128        }
129
130        $objReq = $this->request($mode, $arrPostData);
131
132        // リクエストチェック
133        $objLog->log('* http request check start');
134        if (PEAR::isError($objReq)) {
135            $objJson->setError(OSTORE_E_C_HTTP_REQ);
136            $objJson->display();
137            $objLog->error(OSTORE_E_C_HTTP_REQ, $objReq);
138            return;
139        }
140
141        // レスポンスチェック
142        $objLog->log('* http response check start');
143        if ($objReq->getResponseCode() !== 200) {
144            $objJson->setError(OSTORE_E_C_HTTP_RESP);
145            $objJson->display();
146            $objLog->error(OSTORE_E_C_HTTP_RESP, $objReq);
147            return;
148        }
149
150        $body = $objReq->getResponseBody();
151        $objRet = $objJson->decode($body);
152
153        // JSONデータのチェック
154        $objLog->log('* json data check start');
155        if (empty($objRet)) {
156            $objJson->setError(OSTORE_E_C_FAILED_JSON_PARSE);
157            $objJson->display();
158            $objLog->error(OSTORE_E_C_FAILED_JSON_PARSE, $objReq);
159            return;
160        }
161
162        // ダウンロードデータの保存
163        if ($objRet->status === OSTORE_STATUS_SUCCESS) {
164            $objLog->log('* save file start');
165            $time = time();
166            $dir  = DATA_FILE_PATH . 'downloads/tmp/';
167            $filename = $time . '.tar.gz';
168
169            $data = base64_decode($objRet->data->dl_file);
170
171            $objLog->log("* open ${filename} start");
172            if ($fp = @fopen($dir . $filename, "w")) {
173                @fwrite($fp, $data);
174                @fclose($fp);
175            } else {
176                $objJson->setError(OSTORE_E_C_PERMISSION);
177                $objJson->display();
178                $objLog->error(OSTORE_E_C_PERMISSION, $dir . $filename);
179                return;
180            }
181
182            // ダウンロードアーカイブを展開する
183            $exract_dir = $dir . $time;
184            $objLog->log("* mkdir ${exract_dir} start");
185            if (!@mkdir($exract_dir)) {
186                $objJson->setError(OSTORE_E_C_PERMISSION);
187                $objJson->display();
188                $objLog->error(OSTORE_E_C_PERMISSION, $exract_dir);
189                return;
190            }
191
192            $objLog->log("* extract ${dir}${filename} start");
193            $tar = new Archive_Tar($dir . $filename);
194            $tar->extract($exract_dir);
195
196            $objLog->log("* copy batch start");
197            @include_once CLASS_PATH . 'batch/SC_Batch_Update.php';
198            $objBatch = new SC_Batch_Update();
199            $arrCopyLog = $objBatch->execute($exract_dir);
200
201            $objLog->log("* copy batch check start");
202            if (count($arrCopyLog['err']) > 0) {
203                $objJson->setError(OSTORE_E_C_BATCH_ERR);
204                $objJson->display();
205                $objLog->error(OSTORE_E_C_BATCH_ERR, $arrCopyLog);
206                $this->registerUpdateLog($arrCopyLog, $objRet->data);
207                $this->updateMdlTable($objRet->data);
208                return;
209            }
210
211            // dtb_module_update_logの更新
212            $objLog->log("* insert dtb_module_update start");
213            $this->registerUpdateLog($arrCopyLog, $objRet->data);
214
215            // dtb_moduleの更新
216            $objLog->log("* insert/update dtb_module start");
217            $this->updateMdlTable($objRet->data);
218
219            // DB更新ファイルの読み込み、実行
220            $objLog->log("* file execute start");
221            $this->fileExecute($objRet->data->product_code);
222
223            // 配信サーバへ通知
224            $objLog->log("* notify to lockon server start");
225            $objReq = $this->notifyDownload($mode, $objReq->getResponseCookies());
226
227            $objLog->log('* dl commit result:' . serialize($objReq));
228
229            $productData = $objRet->data;
230            $productData->dl_file = '';
231            $objJson->setSUCCESS($productData, 'インストール/アップデートに成功しました。');
232            $objJson->display();
233            $objLog->end();
234            return;
235        } else {
236            // 配信サーバ側でエラーを補足
237            echo $body;
238            $objLog->error($objRet->errcode, $objReq);
239            return;
240        }
241    }
242
243    /**
244     * デストラクタ
245     *
246     * @return void
247     */
248    function destroy() {
249        parent::destroy();
250    }
251
252    function initParam() {
253        $this->objForm = new SC_FormParam();
254        $this->objForm->addParam(
255            'product_id', 'product_id', INT_LEN, '', array('EXIST_CHECK', 'NUM_CHECK', 'MAX_LENGTH_CHECK')
256        );
257        $this->objForm->setParam($_POST);
258    }
259
260    /**
261     * dtb_moduleを更新する
262     *
263     * @param object $objRet
264     */
265    function updateMdlTable($objRet) {
266        $table = 'dtb_module';
267        $where = 'module_id = ?';
268        $objQuery = new SC_Query;
269
270        $count = $objQuery->count($table, $where, array($objRet->product_id));
271        if ($count) {
272            $arrUpdate = array(
273                'module_code' => $objRet->product_code,
274                'module_name' => $objRet->product_name,
275                'update_date' => 'NOW()'
276            );
277            $objQuery->update($table, $arrUpdate ,$where, array($objRet->product_id));
278        } else {
279            $arrInsert = array(
280                'module_id'   => $objRet->product_id,
281                'module_code' => $objRet->product_code,
282                'module_name' => $objRet->product_name,
283                'auto_update_flg' => '0',
284                'create_date'     => 'NOW()',
285                'update_date' => 'NOW()'
286            );
287            $objQuery->insert($table, $arrInsert);
288        }
289    }
290
291    /**
292     * 配信サーバへダウンロード完了を通知する.
293     *
294     * FIXME エラーコード追加
295     * @param array #arrCookies Cookie配列
296     * @return
297     */
298    function notifyDownload($mode, $arrCookies) {
299        $arrPOSTParams = array(
300            'eccube_url' => HTTP_URL
301        );
302        $objReq = $this->request($mode . '_commit', $arrPOSTParams, $arrCookies);
303        return $objReq;
304    }
305
306    /**
307     * アクセスチェック
308     *
309     * @return boolean
310     */
311    function isValidAccess($mode) {
312        $objLog = new LC_Upgrade_Helper_Log;
313        switch ($mode) {
314        // モジュールダウンロード
315        case 'download':
316            if ($this->isLoggedInAdminPage() === true) {
317                $objLog->log('* admin login ok');
318                return true;
319            }
320            break;
321        // 自動アップロード最新ファイル取得
322        case 'patch_download':
323        // モジュール自動アップロード
324        case 'auto_update':
325            $objForm = new SC_FormParam;
326            $objForm->addParam('public_key', 'public_key', MTEXT_LEN, '', array('EXIST_CHECK', 'ALNUM_CHECK', 'MAX_LENGTH_CHECK'));
327            $objForm->addParam('sha1_key', 'sha1_key', MTEXT_LEN, '', array('EXIST_CHECK', 'ALNUM_CHECK', 'MAX_LENGTH_CHECK'));
328            $objForm->setParam($_POST);
329
330            $objLog->log('* param check start');
331            $arrErr = $objForm->checkError();
332            if ($arrErr) {
333                $objLog->log('* invalid param ' . print_r($arrErr, true));
334                return false;
335            }
336
337            $objLog->log('* public_key check start');
338            $public_key = $this->getPublicKey();
339            if (empty($public_key)) {
340                $objLog->log('* public_key not found');
341                return false;
342            }
343
344            $sha1_key = $objForm->getValue('sha1_key');
345            $public_key_sha1 = $objForm->getValue('public_key');
346
347            $objLog->log('* ip check start');
348            if ($this->isValidIP()
349            && $public_key_sha1 === sha1($public_key . $sha1_key)) {
350                $objLog->log('* auto update login ok');
351                return true;
352            }
353            break;
354        default:
355            $objLog->log('* mode invalid ' . $mode);
356            return false;
357        }
358        return false;
359    }
360
361    function registerUpdateLog($arrLog, $objRet) {
362        $objQuery = new SC_Query;
363        $arrInsert = array(
364           'id'           => $objQuery->nextVal('dtb_module_update_logs_log_id'),
365            'module_id'   => $objRet->product_id,
366            'buckup_path' => $arrLog['buckup_path'],
367            'error_flg'   => count($arrLog['err']),
368            'error'       => implode("\n", $arrLog['err']),
369            'ok'          => implode("\n", $arrLog['ok']),
370            'update_date' => 'NOW()',
371            'create_date' => 'NOW()'
372        );
373        $objQuery->insert('dtb_module_update_logs', $arrInsert);
374    }
375
376    /**
377     * DB更新ファイルの読み込み、実行
378     *
379     * パッチ側でupdate.phpを用意する.
380     * 他の変数・関数とかぶらないよう、
381     * LC_Update_Updater::execute()で処理を実行する.
382     */
383    function fileExecute($productCode) {
384        $file = DATA_FILE_PATH . 'downloads/update/' . $productCode . '_update.php';
385        if (file_exists($file)) {
386            @include_once $file;
387            if (class_exists('LC_Update_Updater')) {
388                $update = new LC_Update_Updater;
389                $update->execute();
390            }
391        }
392    }
393}
394?>
Note: See TracBrowser for help on using the repository browser.