source: branches/version-2_13-dev/data/class/SC_UploadFile.php @ 23484

Revision 23484, 21.1 KB checked in by shutta, 10 years ago (diff)

#2495 ファイルアップロード時のエラーチェックが不十分
makeTempFileメソッド側にも、UPLOAD_ERR_INI_SIZEエラーの場合を追加。
あと、エラーメッセージの追記は不要だと思うので、そこも修正。

  • 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
24/* アップロードファイル管理クラス */
25class SC_UploadFile
26{
27    public $temp_dir;
28    public $save_dir;
29
30    /** ファイルinputタグのname */
31    public $keyname = array();
32
33    /** 横サイズ */
34    public $width = array();
35
36    /** 縦サイズ */
37    public $height = array();
38
39    /** 指定する拡張子 */
40    public $arrExt = array();
41
42    /** 保存されたファイル名 */
43    public $temp_file = array();
44
45    /** DBから読み出したファイル名 */
46    public $save_file = array();
47
48    /** 項目名 */
49    public $disp_name = array();
50
51    /** 制限サイズ */
52    public $size = array();
53
54    /** 必須の場合:true */
55    public $necessary = array();
56
57    /** 画像の場合:true */
58    public $image = array();
59
60    // ファイル管理クラス
61    public function __construct($temp_dir, $save_dir)
62    {
63        $this->temp_dir = rtrim($temp_dir, '/') . '/';
64        $this->save_dir = rtrim($save_dir, '/') . '/';
65        $this->file_max = 0;
66    }
67
68    // ファイル情報追加
69    public function addFile($disp_name, $keyname, $arrExt, $size, $necessary=false, $width=0, $height=0, $image=true)
70    {
71        $this->disp_name[] = $disp_name;
72        $this->keyname[] = $keyname;
73        $this->width[] = $width;
74        $this->height[] = $height;
75        $this->arrExt[] = $arrExt;
76        $this->size[] = $size;
77        $this->necessary[] = $necessary;
78        $this->image[] = $image;
79    }
80    // サムネイル画像の作成
81    public function makeThumb($src_file, $width, $height, $dst_file)
82    {
83        $objThumb = new gdthumb();
84        $ret = $objThumb->Main($src_file, $width, $height, $dst_file);
85
86        if ($ret[0] != 1) {
87            // エラーメッセージの表示
88            echo $ret[1];
89            exit;
90        }
91
92        return basename($ret[1]);
93    }
94
95    // アップロードされたファイルを保存する。
96    public function makeTempFile($keyname, $rename = IMAGE_RENAME)
97    {
98        $objErr = new SC_CheckError_Ex();
99        $cnt = 0;
100        $arrKeyname = array_flip($this->keyname);
101
102        if ($_FILES[$keyname]['error'] === UPLOAD_ERR_OK) {
103            foreach ($this->keyname as $val) {
104                // 一致したキーのファイルに情報を保存する。
105                if ($val == $keyname) {
106                    // 拡張子チェック
107                    $objErr->doFunc(array($this->disp_name[$cnt], $keyname, $this->arrExt[$cnt]), array('FILE_EXT_CHECK'));
108                    // ファイルサイズチェック
109                    $objErr->doFunc(array($this->disp_name[$cnt], $keyname, $this->size[$cnt]), array('FILE_SIZE_CHECK'));
110                    // エラーがない場合
111                    if (!isset($objErr->arrErr[$keyname])) {
112                        // 画像ファイルの場合
113                        if ($this->image[$cnt]) {
114                            // 保存用の画像名を取得する
115                            $dst_file = $this->lfGetTmpImageName($rename, $keyname);
116                            $this->temp_file[$cnt] = $this->makeThumb($_FILES[$keyname]['tmp_name'], $this->width[$cnt], $this->height[$cnt], $dst_file);
117                        // 画像ファイル以外の場合
118                        } else {
119                            // 一意なファイル名を作成する。
120                            if ($rename) {
121                                $uniqname = date('mdHi') . '_' . uniqid('').'.';
122                                $this->temp_file[$cnt] = preg_replace("/^.*\./", $uniqname, $_FILES[$keyname]['name']);
123                            } else {
124                                $this->temp_file[$cnt] = $_FILES[$keyname]['name'];
125                            }
126                            if (move_uploaded_file($_FILES[$keyname]['tmp_name'], $this->temp_dir . $this->temp_file[$cnt])) {
127                                GC_Utils_Ex::gfPrintLog($_FILES[$keyname]['name'].' -> '. $this->temp_dir . $this->temp_file[$cnt]);
128                            } else {
129                                $objErr->arrErr[$keyname] = '※ ファイルのアップロードに失敗しました。<br />';
130                                GC_Utils_Ex::gfPrintLog('File Upload Error!: ' . $_FILES[$keyname]['name'].' -> '. $this->temp_dir . $this->temp_file[$cnt]);
131                            }
132                        }
133                    }
134                }
135                $cnt++;
136            }
137        } elseif ($_FILES[$keyname]['error'] === UPLOAD_ERR_NO_FILE) {
138            $objErr->arrErr[$keyname] = '※ '
139                . $this->disp_name[$arrKeyname[$keyname]]
140                . 'が選択されていません。'
141                . '<br />';
142        } elseif ($_FILES[$keyname]['error'] === UPLOAD_ERR_INI_SIZE) {
143            $objErr->arrErr[$keyname] = '※ '
144                . $this->disp_name[$arrKeyname[$keyname]]
145                . 'のアップロードに失敗しました。'
146                . '(.htaccessファイルのphp_value upload_max_filesizeを調整してください)'
147                . '<br />';
148        } else {
149            $objErr->arrErr[$keyname] = '※ '
150                . $this->disp_name[$arrKeyname[$keyname]]
151                . 'のアップロードに失敗しました。'
152                . 'エラーコードは[' . $_FILES[$keyname]['error'] . ']です。'
153                . '<br />';
154        }
155
156        return $objErr->arrErr[$keyname];
157    }
158
159    // アップロードされたダウンロードファイルを保存する。
160    public function makeTempDownFile($keyname='down_file')
161    {
162        $objErr = new SC_CheckError_Ex();
163        $cnt = 0;
164        $arrKeyname = array_flip($this->keyname);
165
166        if ($_FILES[$keyname]['error'] === UPLOAD_ERR_OK) {
167            foreach ($this->keyname as $val) {
168                // 一致したキーのファイルに情報を保存する。
169                if ($val == $keyname) {
170                    // 拡張子チェック
171                    $objErr->doFunc(array($this->disp_name[$cnt], $keyname, $this->arrExt[$cnt]), array('FILE_EXT_CHECK'));
172                    // ファイルサイズチェック
173                    $objErr->doFunc(array($this->disp_name[$cnt], $keyname, $this->size[$cnt]), array('FILE_SIZE_CHECK'));
174                    // エラーがない場合
175                    if (!isset($objErr->arrErr[$keyname])) {
176                        // 一意なファイル名を作成する。
177                        $uniqname = date('mdHi') . '_' . uniqid('').'.';
178                        $this->temp_file[$cnt] = preg_replace("/^.*\./", $uniqname, $_FILES[$keyname]['name']);
179                        $result  = copy($_FILES[$keyname]['tmp_name'], $this->temp_dir . $this->temp_file[$cnt]);
180                        GC_Utils_Ex::gfPrintLog($result.' -> '. $this->temp_dir . $this->temp_file[$cnt]);
181                        SC_Utils_Ex::extendTimeOut();
182                    }
183                }
184                $cnt++;
185            }
186        } elseif ($_FILES[$keyname]['error'] === UPLOAD_ERR_NO_FILE) {
187            $objErr->arrErr[$keyname] = '※ '
188                . $this->disp_name[$arrKeyname[$keyname]]
189                . 'が選択されていません。'
190                . '<br />';
191        } elseif ($_FILES[$keyname]['error'] === UPLOAD_ERR_INI_SIZE) {
192            $objErr->arrErr[$keyname] = '※ '
193                . $this->disp_name[$arrKeyname[$keyname]]
194                . 'のアップロードに失敗しました。'
195                . '(.htaccessファイルのphp_value upload_max_filesizeを調整してください)'
196                . '<br />';
197        } else {
198            $objErr->arrErr[$keyname] = '※ '
199                . $this->disp_name[$arrKeyname[$keyname]]
200                . 'のアップロードに失敗しました。'
201                . 'エラーコードは[' . $_FILES[$keyname]['error'] . ']です。'
202                . '<br />';
203        }
204
205        return $objErr->arrErr[$keyname];
206    }
207
208    // 画像を削除する。
209    public function deleteFile($keyname)
210    {
211        $objImage = new SC_Image_Ex($this->temp_dir);
212        $cnt = 0;
213        foreach ($this->keyname as $val) {
214            if ($val == $keyname) {
215                // 一時ファイルの場合削除する。
216                if ($this->temp_file[$cnt] != '') {
217                    $objImage->deleteImage($this->temp_file[$cnt], $this->temp_dir);
218                }
219                $this->temp_file[$cnt] = '';
220                $this->save_file[$cnt] = '';
221            }
222            $cnt++;
223        }
224    }
225
226    // 画像を削除する。
227    public function deleteKikakuFile($keyname)
228    {
229        $objImage = new SC_Image_Ex($this->temp_dir);
230        $cnt = 0;
231        foreach ($this->keyname as $val) {
232            if ($val == $keyname) {
233                // 一時ファイルの場合削除する。
234                if ($this->temp_file[$cnt] != '') {
235                    $objImage->deleteImage($this->temp_file[$cnt], $this->temp_dir);
236                }
237                $this->temp_file[$cnt] = '';
238                //$this->save_file[$cnt] = '';
239            }
240            $cnt++;
241        }
242    }
243
244    // 一時ファイルパスを取得する。
245    public function getTempFilePath($keyname)
246    {
247        $cnt = 0;
248        $filepath = '';
249        foreach ($this->keyname as $val) {
250            if ($val == $keyname) {
251                if ($this->temp_file[$cnt] != '') {
252                    $filepath = $this->temp_dir . $this->temp_file[$cnt];
253                }
254            }
255            $cnt++;
256        }
257
258        return $filepath;
259    }
260
261    // 一時ファイルを保存ディレクトリに移す
262    public function moveTempFile()
263    {
264        $objImage = new SC_Image_Ex($this->temp_dir);
265
266        for ($cnt = 0; $cnt < count($this->keyname); $cnt++) {
267            if (isset($this->temp_file[$cnt]) && $this->temp_file[$cnt] != '') {
268                $objImage->moveTempImage($this->temp_file[$cnt], $this->save_dir);
269
270                // すでに保存ファイルがあった場合は削除する。
271                if (isset($this->save_file[$cnt])
272                    && $this->save_file[$cnt] != ''
273                    && !preg_match('|^sub/|', $this->save_file[$cnt])
274                ) {
275                    $objImage->deleteImage($this->save_file[$cnt], $this->save_dir);
276                }
277            }
278        }
279    }
280
281    // ダウンロード一時ファイルを保存ディレクトリに移す
282    public function moveTempDownFile()
283    {
284        $objImage = new SC_Image_Ex($this->temp_dir);
285        for ($cnt = 0; $cnt < count($this->keyname); $cnt++) {
286            if (isset($this->temp_file[$cnt]) && $this->temp_file[$cnt] != '') {
287                $objImage->moveTempImage($this->temp_file[$cnt], $this->save_dir);
288                // すでに保存ファイルがあった場合は削除する。
289                if (isset($this->save_file[$cnt])
290                    && $this->save_file[$cnt] != ''
291                    && !preg_match('|^sub/|', $this->save_file[$cnt])
292                ) {
293                    $objImage->deleteImage($this->save_file[$cnt], $this->save_dir);
294                }
295            }
296        }
297    }
298
299    // HIDDEN用のファイル名配列を返す
300    public function getHiddenFileList()
301    {
302        $cnt = 0;
303        $arrRet = array();
304        foreach ($this->keyname as $val) {
305            if (isset($this->temp_file[$cnt])) {
306                $arrRet['temp_' . $val] = $this->temp_file[$cnt];
307            }
308            if (isset($this->save_file[$cnt]) && $this->save_file[$cnt] != '') {
309                $arrRet['save_' . $val] = $this->save_file[$cnt];
310            }
311            $cnt++;
312        }
313
314        return $arrRet;
315    }
316
317    // HIDDENで送られてきたファイル名を取得する
318    public function setHiddenFileList($arrPOST)
319    {
320        $cnt = 0;
321        foreach ($this->keyname as $val) {
322            $key = 'temp_' . $val;
323            if (isset($arrPOST[$key]) && !empty($arrPOST[$key])) {
324                $this->temp_file[$cnt] = $arrPOST[$key];
325            }
326            $key = 'save_' . $val;
327            if (isset($arrPOST[$key]) && !empty($arrPOST[$key])) {
328                $this->save_file[$cnt] = $arrPOST[$key];
329            }
330            $cnt++;
331        }
332    }
333
334    public function setHiddenKikakuFileList($arrPOST)
335    {
336        $cnt = 0;
337        foreach ($this->keyname as $val) {
338            $key = 'temp_' . $val;
339            if (isset($arrPOST[$key])) {
340                $this->temp_file[$cnt] = $arrPOST[$key];
341            }
342            $key = 'save_' . $val;
343            if (isset($arrPOST[$key]) && !empty($arrPOST[$key])) {
344                $this->save_file[$cnt] = $arrPOST[$key];
345            }
346            $cnt++;
347        }
348    }
349
350    // フォームに渡す用のファイル情報配列を返す
351    public function getFormFileList($temp_url, $save_url, $real_size = false)
352    {
353        $arrRet = array();
354        $cnt = 0;
355        foreach ($this->keyname as $val) {
356            if (isset($this->temp_file[$cnt]) && $this->temp_file[$cnt] != '') {
357                // パスのスラッシュ/が連続しないようにする。
358                $arrRet[$val]['filepath'] = rtrim($temp_url, '/') . '/' . $this->temp_file[$cnt];
359
360                $arrRet[$val]['real_filepath'] = $this->temp_dir . $this->temp_file[$cnt];
361            } elseif (isset($this->save_file[$cnt]) && $this->save_file[$cnt] != '') {
362                // パスのスラッシュ/が連続しないようにする。
363                $arrRet[$val]['filepath'] = rtrim($save_url, '/') . '/' . $this->save_file[$cnt];
364
365                $arrRet[$val]['real_filepath'] = $this->save_dir . $this->save_file[$cnt];
366            }
367            if (isset($arrRet[$val]['filepath']) && !empty($arrRet[$val]['filepath'])) {
368                if ($real_size) {
369                    if (is_file($arrRet[$val]['real_filepath'])) {
370                        list($width, $height) = getimagesize($arrRet[$val]['real_filepath']);
371                    }
372                    // ファイル横幅
373                    $arrRet[$val]['width'] = $width;
374                    // ファイル縦幅
375                    $arrRet[$val]['height'] = $height;
376                } else {
377                    // ファイル横幅
378                    $arrRet[$val]['width'] = $this->width[$cnt];
379                    // ファイル縦幅
380                    $arrRet[$val]['height'] = $this->height[$cnt];
381                }
382                // 表示名
383                $arrRet[$val]['disp_name'] = $this->disp_name[$cnt];
384            }
385            $cnt++;
386        }
387
388        return $arrRet;
389    }
390
391    // フォームに渡す用のダウンロードファイル情報を返す
392    public function getFormDownFile()
393    {
394        $arrRet = '';
395        for ($cnt = 0; $cnt < count($this->keyname); $cnt++) {
396            if (isset($this->temp_file[$cnt]) && $this->temp_file[$cnt] != '') {
397                $arrRet = $this->temp_file[$cnt];
398            } elseif (isset($this->save_file[$cnt]) && $this->save_file[$cnt] != '') {
399                $arrRet = $this->save_file[$cnt];
400            }
401        }
402
403        return $arrRet;
404    }
405    public function getFormKikakuDownFile()
406    {
407        $arrRet = array();
408        $cnt = 0;
409        foreach ($this->keyname as $val) {
410            if (isset($this->temp_file[$cnt])) {
411                $arrRet[$val] = $this->temp_file[$cnt];
412            } elseif (isset($this->save_file[$cnt]) && $this->save_file[$cnt] != '') {
413                $arrRet[$val] = $this->save_file[$cnt];
414            }
415            $cnt++;
416        }
417
418        return $arrRet;
419    }
420
421    // DB保存用のファイル名配列を返す
422    public function getDBFileList()
423    {
424        $cnt = 0;
425        $dbFileList = array();
426        foreach ($this->keyname as $val) {
427            if (isset($this->temp_file[$cnt]) && $this->temp_file[$cnt] != '') {
428                $dbFileList[$val] = $this->temp_file[$cnt];
429            } else {
430                $dbFileList[$val] = isset($this->save_file[$cnt]) ? $this->save_file[$cnt] : '';
431            }
432            $cnt++;
433        }
434
435        return $dbFileList;
436    }
437
438    // DBで保存されたファイル名配列をセットする
439    public function setDBFileList($arrVal)
440    {
441        $cnt = 0;
442        foreach ($this->keyname as $val) {
443            if (isset($arrVal[$val]) && $arrVal[$val] != '') {
444                $this->save_file[$cnt] = $arrVal[$val];
445            }
446            $cnt++;
447        }
448    }
449
450    // DBで保存されたダウンロードファイル名をセットする
451    public function setDBDownFile($arrVal)
452    {
453        if (isset($arrVal['down_realfilename']) && $arrVal['down_realfilename'] != '') {
454            $this->save_file[0] = $arrVal['down_realfilename'];
455        }
456    }
457
458    // DBで保存されたダウンロードファイル名をセットする(setDBDownFileと統合予定)
459    public function setPostFileList($arrPost)
460    {
461        for ($cnt = 0;$cnt < count($this->keyname); $cnt++) {
462            if (isset($arrPost['temp_down_realfilename:' . ($cnt+1)])) {
463                $this->temp_file[$cnt] = $arrPost['temp_down_realfilename:' . ($cnt+1)];
464            }
465        }
466    }
467
468    // 画像をセットする
469    public function setDBImageList($arrVal)
470    {
471        $cnt = 0;
472        foreach ($this->keyname as $val) {
473            if ($arrVal[$val] != '' && $val == 'tv_products_image') {
474                $this->save_file[$cnt] = $arrVal[$val];
475            }
476            $cnt++;
477        }
478    }
479
480    // DB上のファイルの内削除要求があったファイルを削除する。
481    public function deleteDBFile($arrVal)
482    {
483        $objImage = new SC_Image_Ex($this->temp_dir);
484        $cnt = 0;
485        foreach ($this->keyname as $val) {
486            if ($arrVal[$val] != '') {
487                if ($this->save_file[$cnt] == '' && !preg_match('|^sub/|', $arrVal[$val])) {
488                    $objImage->deleteImage($arrVal[$val], $this->save_dir);
489                }
490            }
491            $cnt++;
492        }
493    }
494
495    // DB上のダウンロードファイルの内削除要求があったファイルを削除する。
496    public function deleteDBDownFile($arrVal)
497    {
498        $objImage = new SC_Image_Ex($this->temp_dir);
499        $cnt = 0;
500        if ($arrVal['down_realfilename'] != '') {
501            if ($this->save_file[$cnt] == '' && !preg_match('|^sub/|', $arrVal['down_realfilename'])) {
502                $objImage->deleteImage($arrVal['down_realfilename'], $this->save_dir);
503            }
504        }
505    }
506
507    // 必須判定
508    public function checkExists($keyname = '')
509    {
510        $cnt = 0;
511        $arrRet = array();
512        foreach ($this->keyname as $val) {
513            if ($val == $keyname || $keyname == '') {
514                // 必須であればエラーチェック
515                if ($this->necessary[$cnt] == true) {
516                    if (!isset($this->save_file[$cnt])) $this->save_file[$cnt] = '';
517                    if (!isset($this->temp_file[$cnt])) $this->temp_file[$cnt] = '';
518                    if ($this->save_file[$cnt] == ''
519                        && $this->temp_file[$cnt] == ''
520                    ) {
521                        $arrRet[$val] = '※ ' . $this->disp_name[$cnt] . 'がアップロードされていません。<br>';
522                    }
523                }
524            }
525            $cnt++;
526        }
527
528        return $arrRet;
529    }
530
531    // 拡大率を指定して画像保存
532    public function saveResizeImage($keyname, $to_w, $to_h)
533    {
534        $path = '';
535
536        // keynameの添付ファイルを取得
537        $arrImageKey = array_flip($this->keyname);
538        $file = $this->temp_file[$arrImageKey[$keyname]];
539        $filepath = $this->temp_dir . $file;
540
541        $path = $this->makeThumb($filepath, $to_w, $to_h);
542
543        // ファイル名だけ返す
544        return basename($path);
545    }
546
547    /**
548     * 一時保存用のファイル名を生成する
549     *
550     * @param  string $rename
551     * @param  int    $keyname
552     * @return string
553     */
554    public function lfGetTmpImageName($rename, $keyname = '', $uploadfile = '')
555    {
556        if ($rename === true) {
557            // 一意なIDを取得し、画像名をリネームし保存
558            $uniqname = date('mdHi') . '_' . uniqid('');
559        } else {
560            // アップロードした画像名で保存
561            $uploadfile = strlen($uploadfile) > 0 ? $uploadfile : $_FILES[$keyname]['name'];
562            $uniqname =  preg_replace('/(.+)\.(.+?)$/','$1', $uploadfile);
563        }
564        $dst_file = $this->temp_dir . $uniqname;
565
566        return $dst_file;
567    }
568}
Note: See TracBrowser for help on using the repository browser.