Completed
Push — 2.0 ( c9a79e...627fe0 )
by Christopher
02:59
created

ImageHandlerController::_error()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
/**
3
 * Licensed under The GPL-3.0 License
4
 * For full copyright and license information, please see the LICENSE.txt
5
 * Redistributions of files must retain the above copyright notice.
6
 *
7
 * @since    2.0.0
8
 * @author   Christopher Castro <[email protected]>
9
 * @link     http://www.quickappscms.org
10
 * @license  http://opensource.org/licenses/gpl-3.0.html GPL-3.0 License
11
 */
12
namespace Field\Controller;
13
14
use Cake\Filesystem\File;
15
use Cake\Network\Exception\NotFoundException;
16
use Cake\ORM\TableRegistry;
17
use Cake\Routing\Router;
18
use CMS\Core\Plugin;
19
use Field\Utility\FileToolbox;
20
use Field\Utility\ImageToolbox;
21
22
/**
23
 * Handles file uploading by "Image Field Handler".
24
 *
25
 * @property \Field\Model\Table\FieldInstancesTable $FieldInstances
26
 */
27
class ImageHandlerController extends AppController
28
{
29
30
    /**
31
     * {@inheritDoc}
32
     */
33
    public function upload($name)
34
    {
35
        $instance = $this->_getInstance($name);
36
        require_once Plugin::classPath('Field') . 'Lib/class.upload.php';
37
        $uploader = new \upload($this->request->data['Filedata']);
38
        $maps = [
39
            'min_width' => 'image_min_width',
40
            'min_height' => 'image_min_height',
41
            'max_width' => 'image_max_width',
42
            'max_height' => 'image_max_height',
43
            'min_ratio' => 'image_min_ratio',
44
            'max_ratio' => 'image_max_ratio',
45
            'min_pixels' => 'image_min_pixels',
46
            'max_pixels' => 'image_max_pixels',
47
        ];
48
49
        foreach ($maps as $k => $v) {
50
            if (!empty($instance->settings[$k])) {
51
                $uploader->{$v} = $instance->settings[$k];
52
            }
53
        }
54
55
        $uploader->allowed = 'image/*';
56
57
        // start uploading
58 View Code Duplication
        if (!empty($instance->settings['extensions'])) {
59
            $exts = explode(',', $instance->settings['extensions']);
60
            $exts = array_map('trim', $exts);
61
            $exts = array_map('strtolower', $exts);
62
63
            if (!in_array(strtolower($uploader->file_src_name_ext), $exts)) {
64
                $this->_error(__d('field', 'Invalid file extension.'), 501);
65
            }
66
        }
67
68
        $response = '';
69
        $uploader->file_overwrite = false;
70
        $folder = normalizePath(WWW_ROOT . "/files/{$instance->settings['upload_folder']}/");
71
        $url = normalizePath("/files/{$instance->settings['upload_folder']}/", '/');
72
73
        $uploader->process($folder);
74 View Code Duplication
        if ($uploader->processed) {
75
            $response = json_encode([
76
                'file_url' => Router::url($url . $uploader->file_dst_name, true),
77
                'file_size' => FileToolbox::bytesToSize($uploader->file_src_size),
78
                'file_name' => $uploader->file_dst_name,
79
                'mime_icon' => FileToolbox::fileIcon($uploader->file_src_mime),
80
            ]);
81
        } else {
82
            $this->_error(__d('field', 'File upload error, details: {0}', $uploader->error), 502);
83
        }
84
85
        $this->viewBuilder()->layout('ajax');
86
        $this->title(__d('field', 'Upload Image'));
87
        $this->set(compact('response'));
88
    }
89
90
    /**
91
     * {@inheritDoc}
92
     */
93
    public function delete($name)
94
    {
95
        $this->loadModel('Field.FieldInstances');
96
        $instance = $this->_getInstance($name);
97
98 View Code Duplication
        if ($instance && !empty($this->request->query['file'])) {
99
            $file = normalizePath(WWW_ROOT . "/files/{$instance->settings['upload_folder']}/{$this->request->query['file']}", DS);
100
            $file = new File($file);
101
            $file->delete();
102
        }
103
104
        $response = '';
105
        $this->viewBuilder()->layout('ajax');
106
        $this->title(__d('field', 'Delete Image'));
107
        $this->set(compact('response'));
108
109
        $this->loadModel('Field.FieldInstances');
110
        ImageToolbox::deleteThumbnails(WWW_ROOT . "/files/{$instance->settings['upload_folder']}/{$this->request->query['file']}");
111
    }
112
113
    /**
114
     * Returns an scaled version of the given file image.
115
     *
116
     * The following GET variables must be set on request:
117
     *
118
     * - file: The image's file name to scale.
119
     * - size: A preview size name, sett `ImageToolbox::getPreviews()`
120
     *
121
     * If any of these variables is not present an exception will be throw.
122
     *
123
     * @param string $name EAV attribute name
124
     * @return \Cake\Network\Response
125
     * @throws \Cake\Network\Exception\NotFoundException When field instance
126
     *  is not found.
127
     */
128
    public function thumbnail($name)
129
    {
130
        $this->loadModel('Field.FieldInstances');
131
        $instance = $this->_getInstance($name);
132
133
        if (!$instance) {
134
            throw new NotFoundException(__d('field', 'Invalid field instance.'), 400);
135
        }
136
137
        if (empty($this->request->query['file'])) {
138
            throw new NotFoundException(__d('field', 'Invalid file name.'), 400);
139
        }
140
141
        if (empty($this->request->query['size'])) {
142
            throw new NotFoundException(__d('field', 'Invalid image size.'), 400);
143
        }
144
145
        $imagePath = normalizePath(WWW_ROOT . "/files/{$instance->settings['upload_folder']}/{$this->request->query['file']}");
146
        $tmb = ImageToolbox::thumbnail($imagePath, $this->request->query['size']);
147
148
        if ($tmb !== false) {
149
            $this->response->file($tmb);
150
            return $this->response;
151
        }
152
153
        throw new NotFoundException(__d('field', 'Thumbnail could not be found, check write permissions?'), 500);
154
    }
155
156
    /**
157
     * Get field instance information.
158
     *
159
     * @param string $name EAV attribute name
160
     * @return \Field\Model\Entity\FieldInstance
161
     * @throws \Cake\Network\Exception\NotFoundException When invalid attribute name
162
     *  is given
163
     */
164 View Code Duplication
    protected function _getInstance($name)
165
    {
166
        $this->loadModel('Field.FieldInstances');
167
        $instance = $this->FieldInstances
168
            ->find()
169
            ->contain(['EavAttribute'])
170
            ->where(['EavAttribute.name' => $name])
171
            ->first();
172
173
        if (!$instance) {
174
            $this->_error(__d('field', 'Invalid field instance.'), 504);
175
        }
176
177
        return $instance;
178
    }
179
180
    /**
181
     * Sends a JSON message error.
182
     *
183
     * @param string $message The message
184
     * @param int $code A unique code identifier for this message
185
     * @return void Stops scripts execution
186
     */
187
    protected function _error($message, $code)
188
    {
189
        header("HTTP/1.0 {$code} {$message}");
190
        echo $message;
191
192
        TableRegistry::get('Field.FieldInstances')->connection()->disconnect();
193
        exit(0);
194
    }
195
}
196