Completed
Push — development ( a150a5...f82eb6 )
by Andrij
17:01
created

ImagesManager::getImageOriginPath()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 5
eloc 11
nc 5
nop 1
dl 0
loc 20
rs 8.8571
1
<?php
2
3
namespace xbanners\src\Managers;
4
5
use Propel\Runtime\Exception\PropelException;
6
use xbanners\models\BannerImageI18nQuery;
7
use xbanners\models\BannerImageQuery;
8
use xbanners\models\Base\Banners;
9
use CI;
10
use DirectoryIterator;
11
use Exception;
12
use MY_Controller;
13
use Propel\Runtime\ActiveQuery\Criteria;
14
15
/**
16
 * User: mark
17
 * Date: 19.03.15
18
 * Time: 15:46
19
 */
20
class ImagesManager
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
21
{
0 ignored issues
show
introduced by
Opening brace of a class must be on the same line as the definition
Loading history...
22
23
    /**
24
     * Path name for origins images folder without uploads path
25
     */
26
    const IMAGES_ORIGIN_DIR_PATH = '/uploads/images/bimages/';
27
28
    /**
29
     * Path name for origins images folder without uploads path
30
     */
31
    const IMAGES_TUNED_DIR_PATH = '/uploads/banners/tuned/';
32
33
    /**
34
     * Image file input name
35
     */
36
    const IMAGE_FILE_FIELD = 'file-image';
37
38
    /**
39
     * Image upload file allowed types
40
     */
41
    const IMAGES_UPLOAD_ALLOWED_TYPES = 'jpg|gif|png|jpeg';
42
43
    /**
44
     * Image file max size
45
     */
46
    const IMAGE_MAX_SIZE = '51200';
47
48
    /**
49
     * @var ImagesManager instance
50
     */
51
    private static $instance = NULL;
52
53
    private function __construct() {
54
55
    }
56
57
    /**
58
     * Get ImagesManager instance
59
     * @return ImagesManager instance
60
     */
61
    public static function getInstance() {
62
        if (self::$instance === null) {
63
            self::$instance = new self();
64
        }
65
        return self::$instance;
66
    }
67
68
    /**
69
     * Delete images if they not used
70
     * @deprecated
71
     */
72
    public function deleteNotExistingImages() {
73
        $images = BannerImageI18nQuery::create()->find();
74
75
        $imagesSrc = [];
76
        foreach ($images as $image) {
77
            $imagesSrc[$image->getSrc()] = $image;
78
        }
79
80
        foreach (new DirectoryIterator('.' . self::IMAGES_ORIGIN_DIR_PATH) as $imageFile) {
81
            if (!$imageFile->isDot() && $imageFile->isFile()) {
82
                if (!$imagesSrc[$imageFile->getFilename()]) {
83
                    $this->deleteImageFile('.' . self::IMAGES_ORIGIN_DIR_PATH . $imageFile->getFilename());
84
                }
85
            }
86
        }
87
    }
88
89
    /** Get tuned image path
0 ignored issues
show
introduced by
The open comment tag must be the only content on the line
Loading history...
90
     * @param string $image_name - banner image name
0 ignored issues
show
Documentation introduced by
Should the type for parameter $image_name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
91
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
92
     */
93
    public function getImageOriginPath($image_name = NULL) {
94
95
        if ($image_name) {
96
97
            $path1 = ltrim(self::IMAGES_ORIGIN_DIR_PATH, '/') . $image_name;
98
            $fullPath1 = FCPATH . $path1;
99
100
            if (file_exists($fullPath1)) {
101
                return '/' . $path1;
102
            }
103
104
            $path2 = 'uploads/banners/origins/' . $image_name;
105
            $fullPath2 = FCPATH . $path2;
106
            if (file_exists($fullPath2)) {
107
                return '/' . $path2;
108
            }
109
            return $image_name ? self::IMAGES_ORIGIN_DIR_PATH . $image_name : NULL;
110
        }
111
112
    }
113
114
    /** Get origin image path
0 ignored issues
show
introduced by
The open comment tag must be the only content on the line
Loading history...
115
     * @param string $image_name - banner image name
0 ignored issues
show
Documentation introduced by
Should the type for parameter $image_name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
116
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
117
     */
118
    public function getImageTunedPath($image_name = NULL) {
119
        return $image_name ? self::IMAGES_TUNED_DIR_PATH . $image_name : NULL;
120
    }
121
122
    /**
123
     * Delete image files: origin image and tuned image from uploads
124
     * @param int $imageId
125
     * @param null|string $locale
126
     * @return bool
127
     * @throws PropelException
0 ignored issues
show
introduced by
Comment missing or not on the next line for @throws tag in function comment
Loading history...
128
     */
129
    public function delete($imageId, $locale = NULL) {
130
        if (!$imageId) {
131
            return FALSE;
132
        }
133
134
        $images = BannerImageQuery::create()
135
            ->_if($locale)
0 ignored issues
show
Documentation introduced by
$locale is of type null|string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
136
            ->joinWithI18n($locale)
137
            ->_endif()
138
            ->findPk($imageId);
139
140
        if (!$images) {
141
            return FALSE;
142
        }
143
144
        foreach ($images->getBannerImageI18ns() as $image) {
145
            $image_path = '.' . self::IMAGES_ORIGIN_DIR_PATH . $image->getSrc();
146
            $image->setSrc(NULL);
147
            $image->save();
148
149
            $this->deleteImageFile($image_path);
150
        }
151
152
        return TRUE;
153
    }
154
155
    /**
156
     * Delete image file
157
     * @param string $image_path - path to image file
158
     * @return bool
159
     */
160
    private function deleteImageFile($image_path) {
161
        if (file_exists($image_path) && is_file($image_path)) {
162
            chmod($image_path, 0777);
163
            return unlink($image_path);
164
        }
165
        return FALSE;
166
    }
167
168
    /**
169
     * @param string $path
170
     */
171
    protected function buildImagePath($path) {
172
        $buildPath = '';
173
        foreach (explode('/', $path) as $part) {
174
            if ($part != '') {
175
                $buildPath .= $part . '/';
176
                file_exists($buildPath) || mkdir($buildPath) && chmod($buildPath, 0777);
177
            }
178
        }
179
    }
180
181
    /**
182
     * Save image file
183
     * @param $imageId
0 ignored issues
show
introduced by
Missing parameter type
Loading history...
184
     * @param $locale
0 ignored issues
show
introduced by
Missing parameter type
Loading history...
185
     * @return string
186
     * @throws Exception
0 ignored issues
show
introduced by
Comment missing or not on the next line for @throws tag in function comment
Loading history...
187
     */
188
    public function saveImage($imageId = NULL, $locale = NULL) {
189
190
        if (!file_exists(self::IMAGES_ORIGIN_DIR_PATH)) {
191
            $this->buildImagePath(self::IMAGES_ORIGIN_DIR_PATH);
192
        }
193
194
        $config['upload_path'] = '.' . self::IMAGES_ORIGIN_DIR_PATH;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$config was never initialized. Although not strictly required by PHP, it is generally a good practice to add $config = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
195
        $config['allowed_types'] = self::IMAGES_UPLOAD_ALLOWED_TYPES;
196
        $config['max_size'] = self::IMAGE_MAX_SIZE;
197
198
        CI::$APP->load->library('upload', $config);
199
200
        if (!CI::$APP->upload->do_upload(self::IMAGE_FILE_FIELD)) {
201
            throw new Exception(strip_tags(CI::$APP->upload->display_errors()));
202
        } else {
203
            if ($imageId && $locale) {
204
                $this->delete($imageId, $locale);
205
            }
206
207
            $data = CI::$APP->upload->data();
208
209
            $imageFileName = time() . $data['file_ext'];
210
            $imageFilePath = $data['file_path'] . $imageFileName;
211
            chmod($data['full_path'], 0777);
212
            copy($data['full_path'], $imageFilePath);
213
            chmod($imageFilePath, 0777);
214
            unlink($data['full_path']);
215
216
            return $imageFileName;
217
        }
218
    }
219
220
    /**
221
     * Upload image
222
     * @throws \Exception
0 ignored issues
show
introduced by
Comment missing or not on the next line for @throws tag in function comment
Loading history...
223
     */
224
    public function uploadImage() {
225
        $_POST['maximumSize'] = self::IMAGE_MAX_SIZE;
226
227
        if ($this->checkImageUploadErrors()) {
228
            try {
229
                $pictureCut = \PictureCut::createSingleton();
230
231
                if ($pictureCut->upload()) {
232
                    echo $pictureCut->toJson();
233
                } else {
234
                    echo $pictureCut->exceptionsToJson();
235
                }
236
            } catch (Exception $e) {
237
                echo $e->getMessage();
238
            }
239
        }
240
    }
241
242
    /**
243
     * Check on errors exists while upload file
244
     * @return bool
245
     */
246
    private function checkImageUploadErrors() {
247
        $file = $_FILES[self::IMAGE_FILE_FIELD];
248
        $fileSize = round($file['size'] / 1024);
249
250
        if (!strstr($file['type'], self::IMAGES_UPLOAD_ALLOWED_TYPES)) {
251
            $error_message = lang('You can upload only images', 'xbanners');
252
        }
253
254
        if ($fileSize > self::IMAGE_MAX_SIZE) {
255
            $error_message = lang('You can not upload file with size more than:', 'xbanners') . ' ' . self::IMAGE_MAX_SIZE . 'KB';
256
        }
257
258
        if ($error_message) {
259
            echo json_encode(
260
                [
261
                 'status'       => false,
262
                 'errorMessage' => $error_message,
263
                ]
264
            );
265
266
            return FALSE;
267
        }
268
269
        return TRUE;
270
    }
271
272
    /**
273
     * Get images ordered by page types
274
     * @param Banners $banner - banner object
275
     * @param string $locale - locale name
276
     * @return array
277
     */
278
    public function getImagesByPageType($banner, $locale) {
279
        $pages = BannerPageTypesManager::getInstance()->getPages($banner->getPageType(), $locale);
280
281
        $orderCriteria = new Criteria();
282
        $orderCriteria->addDescendingOrderByColumn('Position');
283
284
        $images = $banner->getBannerImages($orderCriteria);
285
286
        if ($pages === null && count($images)) {
287
            $pagesGroupName = lang('Images', 'xbanners');
288
            $resultImages[$pagesGroupName]['images'] = [];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$resultImages was never initialized. Although not strictly required by PHP, it is generally a good practice to add $resultImages = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
289
290 View Code Duplication
            foreach ($images as $image) {
291
                $image->setLocale($locale);
292
                if ($image->getActive()) {
293
                    $resultImages[$pagesGroupName]['images'][] = $image;
294
                }
295
            }
296
297 View Code Duplication
            foreach ($images as $image) {
298
                $image->setLocale($locale);
299
                if (!$image->getActive()) {
300
                    array_push($resultImages[$pagesGroupName]['images'], $image);
301
                }
302
            }
303
            return $resultImages;
304
        }
305
306
        $resultImages = [];
307
        foreach ($images as $image) {
308
            $image->setLocale($locale);
309
            $imagePage = $pages[$image->getAllowedPage()];
310
            $pagesGroupName = $imagePage['name'] ? $imagePage['name'] : lang('Images without relation', 'xbanners');
311
            $resultImages[$pagesGroupName]['images'] = $resultImages[$pagesGroupName]['images'] ? $resultImages[$pagesGroupName]['images'] : [];
312
313
            if ($image->getActive()) {
314
                $resultImages[$pagesGroupName]['images'][] = $image;
315
            }
316
        }
317
318
        foreach ($images as $image) {
319
            $image->setLocale($locale);
320
            $imagePage = $pages[$image->getAllowedPage()];
321
            $pagesGroupName = $imagePage['name'] ? $imagePage['name'] : lang('Images without relation', 'xbanners');
322
323
            if (!$image->getActive()) {
324
                array_push($resultImages[$pagesGroupName]['images'], $image);
325
            }
326
        }
327
328
        return $resultImages;
329
    }
330
331
    /**
332
     * Prepare banner image data for save into DB
333
     * @param array $data - image data array
334
     * @param $bannerId - banner id
0 ignored issues
show
introduced by
Missing parameter type
Loading history...
335
     * @param $locale - locale name
0 ignored issues
show
introduced by
Missing parameter type
Loading history...
336
     * @return array
337
     */
338
    public function prepareImageData(array $data, $bannerId, $locale) {
339
        $host = CI::$APP->input->server('HTTP_HOST');
340
341
        $data['url'] = (false === strpos($data['url'], $host)) ? $data['url'] : preg_replace("/^(https?:\/\/)?$host\/?/i", '/', $data['url']);
342
        $data['url'] = strstr($data['url'], 'http') || $data['url'][0] === '/' ? $data['url'] : '' . $data['url'];
343
344
        $data['allowed_page'] = !$data['allowed_page_all'] && $data['allowed_page'] ? (int) $data['allowed_page'] : 0;
345
        $data['target'] = $data['target'] ? 1 : 0;
346
        $data['permanent'] = $data['permanent'] ? 1 : 0;
347
        $data['active'] = isset($data['active']) ? 1 : 0;
348
        $data['active_from'] = $data['active_from'] && !$data['permanent'] ? strtotime($data['active_from']) : NULL;
349
        //        $data['active_from'] = $data['active_to'] && !$data['active_from'] ? time() : $data['active_from'];
350
        $data['active_to'] = $data['active_to'] && !$data['permanent'] ? strtotime($data['active_to']) : NULL;
351
352
        if (($data['active_from'] > $data['active_to'] && ($data['active_from'] && $data['active_to']))
353
            || ((time() > $data['active_to']) && $data['active_to'])
354
        ) {
355
            $data['active'] = 0;
356
        }
357
        $data['banner_id'] = $bannerId;
358
        $data['locale'] = $locale ? $locale : MY_Controller::defaultLocale();
359
        $data['src'] = $data['src'] ? $data['src'] : NULL;
360
        $data['clicks'] = $data['clicks'] ? (int) $data['clicks'] : 0;
361
362
        return $data;
363
    }
364
365
    /**
366
     * Make inactive banner images that has time out active_to date
367
     */
368
    public function setInactiveOnTimeOut() {
369
        return BannerImageQuery::create()
370
            ->filterByActive(1)
371
            ->where('BannerImage.ActiveTo < ?', time())
372
            ->update(['Active' => 0]);
373
    }
374
375
}