Passed
Push — develop ( 15bc6b...5ea31b )
by Nikolay
05:50 queued 12s
created

UploadAndConvertFiles   A

Complexity

Total Complexity 18

Size/Duplication

Total Lines 137
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 18
eloc 93
dl 0
loc 137
rs 10
c 1
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
B statusUploadFile() 0 35 9
B uploadResumable() 0 87 9
1
<?php
2
/**
3
 * Copyright (C) MIKO LLC - All Rights Reserved
4
 * Unauthorized copying of this file, via any medium is strictly prohibited
5
 * Proprietary and confidential
6
 * Written by Nikolay Beketov, 7 2020
7
 *
8
 */
9
10
namespace MikoPBX\Core\System;
11
12
namespace MikoPBX\Core\System;
13
14
use MikoPBX\Core\Workers\WorkerMergeUploadedFile;
15
use Phalcon\Di;
16
use Phalcon\Http\Message\Stream;
17
use Phalcon\Http\Message\StreamFactory;
18
use Phalcon\Http\Message\UploadedFile;
19
20
class UploadAndConvertFiles
21
{
22
    /**
23
     * Process resumable upload files
24
     *
25
     * @param $parameters
26
     */
27
    public static function uploadResumable($parameters): array
28
    {
29
        $data['result'] = 'ERROR';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
30
        $di             = Di::getDefault();
31
        if ($di === null) {
32
            return ['result' => 'ERROR', 'data' => 'Dependency injector not initialized'];
33
        }
34
        $upload_id            = $parameters['upload_id'];
35
        $resumableFilename    = $parameters['resumableFilename'];
36
        $resumableIdentifier  = $parameters['resumableIdentifier'];
37
        $resumableChunkNumber = $parameters['resumableChunkNumber'];
38
        $resumableTotalSize   = $parameters['resumableTotalSize'];
39
        $uploadPath              = $di->getShared('config')->path('core.uploadPath');
40
41
        $factory = new StreamFactory();
42
43
        foreach ($parameters['files'] as $file_data) {
44
            $stream   = $factory->createStreamFromFile($file_data['file_path'], 'r');
45
            $file = new UploadedFile(
46
                $stream,
47
                $file_data['file_size'],
48
                $file_data['file_error'],
49
                $file_data['file_name'],
50
                $file_data['file_type']
51
            );
52
53
            if (isset($resumableIdentifier) && trim($resumableIdentifier) !== '') {
54
                $temp_dir         = $uploadPath . '/' . Util::trimExtensionForFile(basename($resumableFilename));
55
                $temp_dst_file    = $uploadPath . '/' . $upload_id . '/' . basename($resumableFilename);
56
                $chunks_dest_file = $temp_dir . '/' . $resumableFilename . '.part' . $resumableChunkNumber;
57
            } else {
58
                $temp_dir         = $uploadPath . '/' . $upload_id;
59
                $temp_dst_file    = $temp_dir . '/' . basename($file->getClientFilename());
60
                $chunks_dest_file = $temp_dst_file;
61
            }
62
            if ( ! Util::mwMkdir($temp_dir) || ! Util::mwMkdir(dirname($temp_dst_file))) {
63
                Util::sysLogMsg('UploadFile', "Error create dir '$temp_dir'");
64
                return ['result' => 'ERROR', 'data' => "Error create dir 'temp_dir'"];
65
            }
66
            $file->moveTo($chunks_dest_file);
67
            // if (file_exists($file->))
68
            if ($resumableFilename) {
69
                $data['result'] = 'Success';
70
                // Передача файлов частями.
71
                $result = Util::createFileFromChunks($temp_dir, $resumableTotalSize);
72
                if ($result === true) {
73
                    $merge_settings = [
74
                        'data'   => [
75
                            'result_file'          => $temp_dst_file,
76
                            'temp_dir'             => $temp_dir,
77
                            'resumableFilename'    => $resumableFilename,
78
                            'resumableTotalChunks' => $resumableChunkNumber,
79
                        ],
80
                        'action' => 'merge',
81
                    ];
82
                    $settings_file  = "{$temp_dir}/merge_settings";
83
                    file_put_contents(
84
                        $settings_file,
85
                        json_encode($merge_settings, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)
86
                    );
87
88
                    // Отправляем задачу на склеивание файла.
89
                    $phpPath              = Util::which('php');
90
                    $workerFilesMergerPath = Util::getFilePathByClassName(WorkerMergeUploadedFile::class);
91
                    Util::mwExecBg("{$phpPath} -f {$workerFilesMergerPath} '{$settings_file}'");
92
93
                    $data['upload_id'] = $upload_id;
94
                    $data['filename']  = $temp_dst_file;
95
                    $data['d_status']  = 'INPROGRESS';
96
                }
97
            } else {
98
                $data['result'] = 'Success';
99
                // Передача файла целиком.
100
                $data['upload_id'] = $upload_id;
101
                $data['filename']  = $temp_dst_file;
102
                $data['d_status']  = 'UPLOAD_COMPLETE';
103
                file_put_contents($temp_dir . '/progress', '100');
104
105
                Util::mwExecBg(
106
                    '/etc/rc/shell_functions.sh killprocesses ' . $temp_dir . ' -TERM 0;rm -rf ' . $temp_dir,
107
                    '/dev/null',
108
                    120
109
                );
110
            }
111
        }
112
113
        return $data;
114
    }
115
116
    /**
117
     * Returns Status of uploading process
118
     * @param $postData
119
     *
120
     * @return array
121
     */
122
    public static function statusUploadFile($postData):array
123
    {
124
        $result['result'] = 'ERROR';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Loading history...
125
        $di             = Di::getDefault();
126
        if ($di === null) {
127
            return ['result' => 'ERROR', 'data' => 'Dependency injector not initialized'];
128
        }
129
        $uploadPath = $di->getShared('config')->path('core.uploadPath');
130
        if ($postData && isset($postData['id'])) {
131
            $upload_id     = $postData['id'];
132
            $progress_dir  = $uploadPath . '/' . $upload_id;
133
            $progress_file = $progress_dir . '/progress';
134
135
            if (empty($upload_id)) {
136
                $result['result']            = 'ERROR';
137
                $result['d_status_progress'] = '0';
138
                $result['d_status']          = 'ID_NOT_SET';
139
            } elseif ( ! file_exists($progress_file) && file_exists($progress_dir)) {
140
                $result['result']            = 'Success';
141
                $result['d_status_progress'] = '0';
142
                $result['d_status']          = 'INPROGRESS';
143
            } elseif ( ! file_exists($progress_dir)) {
144
                $result['result']            = 'ERROR';
145
                $result['d_status_progress'] = '0';
146
                $result['d_status']          = 'NOT_FOUND';
147
            } elseif ('100' === file_get_contents($progress_file)) {
148
                $result['result']            = 'Success';
149
                $result['d_status_progress'] = '100';
150
                $result['d_status']          = 'UPLOAD_COMPLETE';
151
            } else {
152
                $result['result']            = 'Success';
153
                $result['d_status_progress'] = file_get_contents($progress_file);
154
            }
155
        }
156
        return $result;
157
    }
158
}