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

Revision 22926, 12.9 KB checked in by Seasoft, 11 years ago (diff)

#2287 (環境によりデストラクタが正しく動作しないケースがある)
#2288 (リクエスト単位で実行されるべきログ出力がブロックにも適用されている)
#2043 (typo修正・ソース整形・ソースコメントの改善 for 2.13.0)

  • 不明確な仕様にコメントを残した。
  • 親デストラクタを呼ぶだけの記述は可読性が悪くなると考え削除した。(上述のチケットで OS の仕様に依存したデストラクタとなるため、敢えてアプリケーション側で記述しておく意義は薄れたという認識のもと。)
  • 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-2013 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
24require_once CLASS_REALDIR . 'pages/upgrade/LC_Page_Upgrade_Base.php';
25
26/**
27 * オーナーズストアからダウンロードデータを取得する.
28 *
29 * TODO 要リファクタリング
30 *
31 * @package Page
32 * @author LOCKON CO.,LTD.
33 * @version $Id$
34 */
35class LC_Page_Upgrade_Download extends LC_Page_Upgrade_Base
36{
37    /**
38     * Page を初期化する.
39     *
40     * @return void
41     */
42    function init()
43    {
44        parent::init();
45    }
46
47    /**
48     * Page のプロセス.
49     *
50     * @return void
51     */
52    function process($mode)
53    {
54        $objLog  = new LC_Upgrade_Helper_Log;
55        $objLog->start($mode);
56
57        $objJson = new LC_Upgrade_Helper_Json;
58
59        // アクセスチェック
60        $objLog->log('* auth start');
61        if ($this->isValidAccess($mode) !== true) {
62            // TODO
63            $objJson->setError(OSTORE_E_C_INVALID_ACCESS);
64            $objJson->display();
65            $objLog->error(OSTORE_E_C_INVALID_ACCESS);
66            return;
67        }
68
69        // パラメーチェック
70        $this->initParam();
71        $objLog->log('* post param check start');
72        $arrErr = $this->objForm->checkError();
73        if ($arrErr) {
74            $objJson->setError(OSTORE_E_C_INVALID_PARAM);
75            $objJson->display();
76            $objLog->error(OSTORE_E_C_INVALID_PARAM, $_POST);
77            $objLog->log('* post param check error ' . print_r($arrErr, true));
78            return;
79        }
80
81        $objLog->log('* auto update check start');
82        if ($mode == 'auto_update'
83        && $this->autoUpdateEnable($this->objForm->getValue('product_id')) !== true) {
84            $objJson->setError(OSTORE_E_C_AUTOUP_DISABLE);
85            $objJson->display();
86            $objLog->error(OSTORE_E_C_AUTOUP_DISABLE, $_POST);
87            return;
88        }
89
90        // TODO CSRF対策
91
92        // 認証キーの取得
93        $public_key = $this->getPublicKey();
94        $sha1_key = $this->createSeed();
95
96        // 認証キーチェック
97        $objLog->log('* public key check start');
98        if (empty($public_key)) {
99            $objJson->setError(OSTORE_E_C_NO_KEY);
100            $objJson->display();
101            $objLog->error(OSTORE_E_C_NO_KEY);
102            return;
103        }
104
105        // リクエストを開始
106        $objLog->log('* http request start');
107
108        switch ($mode) {
109            case 'patch_download':
110                $arrPostData = array(
111                    'eccube_url' => HTTP_URL,
112                    'public_key' => sha1($public_key . $sha1_key),
113                    'sha1_key'   => $sha1_key,
114                    'patch_code' => 'latest'
115                );
116                break;
117            default:
118                $arrPostData = array(
119                    'eccube_url' => HTTP_URL,
120                    'public_key' => sha1($public_key . $sha1_key),
121                    'sha1_key'   => $sha1_key,
122                    'product_id' => $this->objForm->getValue('product_id')
123                );
124                break;
125        }
126
127        $objReq = $this->request($mode, $arrPostData);
128
129        // リクエストチェック
130        $objLog->log('* http request check start');
131        if (PEAR::isError($objReq)) {
132            $objJson->setError(OSTORE_E_C_HTTP_REQ);
133            $objJson->display();
134            $objLog->error(OSTORE_E_C_HTTP_REQ, $objReq);
135            return;
136        }
137
138        // レスポンスチェック
139        $objLog->log('* http response check start');
140        if ($objReq->getResponseCode() !== 200) {
141            $objJson->setError(OSTORE_E_C_HTTP_RESP);
142            $objJson->display();
143            $objLog->error(OSTORE_E_C_HTTP_RESP, $objReq);
144            return;
145        }
146
147        $body = $objReq->getResponseBody();
148        $objRet = $objJson->decode($body);
149
150        // JSONデータのチェック
151        $objLog->log('* json data check start');
152        if (empty($objRet)) {
153            $objJson->setError(OSTORE_E_C_FAILED_JSON_PARSE);
154            $objJson->display();
155            $objLog->error(OSTORE_E_C_FAILED_JSON_PARSE, $objReq);
156            return;
157        }
158
159        // ダウンロードデータの保存
160        if ($objRet->status === OSTORE_STATUS_SUCCESS) {
161            $objLog->log('* save file start');
162            $time = time();
163            $dir  = DATA_REALDIR . 'downloads/tmp/';
164            $filename = $time . '.tar.gz';
165
166            $data = base64_decode($objRet->data->dl_file);
167
168            $objLog->log("* open ${filename} start");
169            if ($fp = @fopen($dir . $filename, 'w')) {
170                @fwrite($fp, $data);
171                @fclose($fp);
172            } else {
173                $objJson->setError(OSTORE_E_C_PERMISSION);
174                $objJson->display();
175                $objLog->error(OSTORE_E_C_PERMISSION, $dir . $filename);
176                return;
177            }
178
179            // ダウンロードアーカイブを展開する
180            $exract_dir = $dir . $time;
181            $objLog->log("* mkdir ${exract_dir} start");
182            if (!@mkdir($exract_dir)) {
183                $objJson->setError(OSTORE_E_C_PERMISSION);
184                $objJson->display();
185                $objLog->error(OSTORE_E_C_PERMISSION, $exract_dir);
186                return;
187            }
188
189            $objLog->log("* extract ${dir}${filename} start");
190            $tar = new Archive_Tar($dir . $filename);
191            $tar->extract($exract_dir);
192
193            $objLog->log('* copy batch start');
194            @include_once CLASS_REALDIR . 'batch/SC_Batch_Update.php';
195            $objBatch = new SC_Batch_Update();
196            $arrCopyLog = $objBatch->execute($exract_dir);
197
198            $objLog->log('* copy batch check start');
199            if (count($arrCopyLog['err']) > 0) {
200                $objJson->setError(OSTORE_E_C_BATCH_ERR);
201                $objJson->display();
202                $objLog->error(OSTORE_E_C_BATCH_ERR, $arrCopyLog);
203                $this->registerUpdateLog($arrCopyLog, $objRet->data);
204                $this->updateMdlTable($objRet->data);
205                return;
206            }
207
208            // dtb_module_update_logの更新
209            $objLog->log('* insert dtb_module_update start');
210            $this->registerUpdateLog($arrCopyLog, $objRet->data);
211
212            // dtb_moduleの更新
213            $objLog->log('* insert/update dtb_module start');
214            $this->updateMdlTable($objRet->data);
215
216            // DB更新ファイルの読み込み、実行
217            $objLog->log('* file execute start');
218            $this->fileExecute($objRet->data->product_code);
219
220            // 配信サーバーへ通知
221            $objLog->log('* notify to lockon server start');
222            $objReq = $this->notifyDownload($mode, $objReq->getResponseCookies());
223
224            $objLog->log('* dl commit result:' . serialize($objReq));
225
226            $productData = $objRet->data;
227            $productData->dl_file = '';
228            $objJson->setSUCCESS($productData, 'インストール/アップデートに成功しました。');
229            $objJson->display();
230            $objLog->end();
231            return;
232        } else {
233            // 配信サーバー側でエラーを補足
234            echo $body;
235            $objLog->error($objRet->errcode, $objReq);
236            return;
237        }
238    }
239
240    function initParam()
241    {
242        $this->objForm = new SC_FormParam_Ex();
243        $this->objForm->addParam(
244            'product_id', 'product_id', INT_LEN, '', array('EXIST_CHECK', 'NUM_CHECK', 'MAX_LENGTH_CHECK')
245        );
246        $this->objForm->setParam($_POST);
247    }
248
249    /**
250     * dtb_moduleを更新する
251     *
252     * @param object $objRet
253     */
254    function updateMdlTable($objRet)
255    {
256        $table = 'dtb_module';
257        $where = 'module_id = ?';
258        $objQuery =& SC_Query_Ex::getSingletonInstance();
259
260        $exists = $objQuery->exists($table, $where, array($objRet->product_id));
261        if ($exists) {
262            $arrUpdate = array(
263                'module_code' => $objRet->product_code,
264                'module_name' => $objRet->product_name,
265                'update_date' => 'CURRENT_TIMESTAMP'
266            );
267            $objQuery->update($table, $arrUpdate ,$where, array($objRet->product_id));
268        } else {
269            $arrInsert = array(
270                'module_id'   => $objRet->product_id,
271                'module_code' => $objRet->product_code,
272                'module_name' => $objRet->product_name,
273                'auto_update_flg' => '0',
274                'create_date'     => 'CURRENT_TIMESTAMP',
275                'update_date' => 'CURRENT_TIMESTAMP'
276            );
277            $objQuery->insert($table, $arrInsert);
278        }
279    }
280
281    /**
282     * 配信サーバーへダウンロード完了を通知する.
283     *
284     * FIXME エラーコード追加
285     * @param array #arrCookies Cookie配列
286     * @return
287     */
288    function notifyDownload($mode, $arrCookies)
289    {
290        $arrPOSTParams = array(
291            'eccube_url' => HTTP_URL
292        );
293        $objReq = $this->request($mode . '_commit', $arrPOSTParams, $arrCookies);
294
295        return $objReq;
296    }
297
298    /**
299     * アクセスチェック
300     *
301     * @return boolean
302     */
303    function isValidAccess($mode)
304    {
305        $objLog = new LC_Upgrade_Helper_Log;
306        switch ($mode) {
307        // モジュールダウンロード
308        case 'download':
309            if ($this->isLoggedInAdminPage() === true) {
310                $objLog->log('* admin login ok');
311                return true;
312            }
313            break;
314        // 自動アップロード最新ファイル取得
315        case 'patch_download':
316        // モジュール自動アップロード
317        case 'auto_update':
318            $objForm = new SC_FormParam;
319            $objForm->addParam('public_key', 'public_key', MTEXT_LEN, '', array('EXIST_CHECK', 'ALNUM_CHECK', 'MAX_LENGTH_CHECK'));
320            $objForm->addParam('sha1_key', 'sha1_key', MTEXT_LEN, '', array('EXIST_CHECK', 'ALNUM_CHECK', 'MAX_LENGTH_CHECK'));
321            $objForm->setParam($_POST);
322
323            $objLog->log('* param check start');
324            $arrErr = $objForm->checkError();
325            if ($arrErr) {
326                $objLog->log('* invalid param ' . print_r($arrErr, true));
327                return false;
328            }
329
330            $objLog->log('* public_key check start');
331            $public_key = $this->getPublicKey();
332            if (empty($public_key)) {
333                $objLog->log('* public_key not found');
334                return false;
335            }
336
337            $sha1_key = $objForm->getValue('sha1_key');
338            $public_key_sha1 = $objForm->getValue('public_key');
339
340            $objLog->log('* ip check start');
341            if ($this->isValidIP()
342            && $public_key_sha1 === sha1($public_key . $sha1_key)) {
343                $objLog->log('* auto update login ok');
344                return true;
345            }
346            break;
347        default:
348            $objLog->log('* mode invalid ' . $mode);
349            return false;
350        }
351
352        return false;
353    }
354
355    function registerUpdateLog($arrLog, $objRet)
356    {
357        $objQuery =& SC_Query_Ex::getSingletonInstance();
358        $arrInsert = array(
359            'log_id'      => $objQuery->nextVal('dtb_module_update_logs_log_id'),
360            'module_id'   => $objRet->product_id,
361            'buckup_path' => $arrLog['buckup_path'],
362            'error_flg'   => count($arrLog['err']),
363            'error'       => implode("\n", $arrLog['err']),
364            'ok'          => implode("\n", $arrLog['ok']),
365            'update_date' => 'CURRENT_TIMESTAMP',
366            'create_date' => 'CURRENT_TIMESTAMP',
367        );
368        $objQuery->insert('dtb_module_update_logs', $arrInsert);
369    }
370
371    /**
372     * DB更新ファイルの読み込み、実行
373     *
374     * パッチ側でupdate.phpを用意する.
375     * 他の変数・関数とかぶらないよう、
376     * LC_Update_Updater::execute()で処理を実行する.
377     */
378    function fileExecute($productCode)
379    {
380        $file = DATA_REALDIR . 'downloads/update/' . $productCode . '_update.php';
381        if (file_exists($file)) {
382            @include_once $file;
383            if (class_exists('LC_Update_Updater')) {
384                $update = new LC_Update_Updater;
385                $update->execute();
386            }
387        }
388    }
389}
Note: See TracBrowser for help on using the repository browser.