Completed
Push — dev-master ( 29e920...408a96 )
by Vijay
03:32
created

Users::profileImageExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace FFCMS\Mappers;
4
5
use FFCMS\{Traits, Models};
6
7
/**
8
 * Users Mapper Class.
9
 *
10
 * @author Vijay Mahrra <[email protected]>
11
 * @copyright (c) Copyright 2016 Vijay Mahrra
12
 * @license GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html)
13
 *
14
 * @property int    $id
15
 * @property string $uuid
16
 * @property string $password
17
 * @property string $email
18
 * @property string $firstname
19
 * @property string $lastname
20
 * @property string $scopes
21
 * @property string $status
22
 * @property string $password_question
23
 * @property string $password_answer
24
 * @property string $created
25
 * @property string $login_count
26
 * @property string $login_last
27
 */
28
class Users extends Mapper
29
{
30
    use Traits\UrlHelper;
31
32
    /**
33
     * Fields and their visibility to clients, boolean or string of visible field name
34
     *
35
     * @var array $fieldsVisible
36
     */
37
    public $fieldsVisible = [
38
        'uuid'              => 'id',
39
        'password'          => false,
40
        'scopes'            => false,
41
        'login_count'       => false,
42
    ];
43
44
    /**
45
     * Fields that are editable to clients, boolean or string of visible field name
46
     *
47
     * @var array $fieldsEditable
48
     */
49
    public $fieldsEditable = [
50
        'email',
51
        'firstname',
52
        'lastname',
53
        'password_question',
54
        'password_answer',
55
    ];
56
57
    /**
58
     * Filter rules for fields
59
     *
60
     * @var array $filterRules
61
     * @link https://github.com/Wixel/GUMP
62
     */
63
    public $filterRules = [
64
        'uuid'              => 'trim|sanitize_string|lower',
65
        'password'          => 'trim|sanitize_string',
66
        'email'             => 'trim|sanitize_string|sanitize_email|lower',
67
        'firstname'         => 'trim|sanitize_string',
68
        'lastname'          => 'trim|sanitize_string',
69
        'scopes'            => 'trim|sanitize_string|lower',
70
        'status'            => 'trim|sanitize_string|lower',
71
        'password_question' => 'trim|sanitize_string',
72
        'password_answer'   => 'trim|sanitize_string',
73
        'created'           => 'trim|sanitize_string',
74
        'login_count'       => 'sanitize_numbers|whole_number',
75
        'login_last'        => 'trim|sanitize_string',
76
    ];
77
78
    /**
79
     * Validation rules for fields
80
     *
81
     * @var array $validationRules
82
     * @link https://github.com/Wixel/GUMP
83
     */
84
    public $validationRules = [
85
        'uuid'              => 'alpha_dash',
86
        'email'             => 'valid_email',
87
        'firstname'         => 'valid_name',
88
    ];
89
90
    protected $profileImageFileName = 'profile.png';
91
92
    /**
93
     * Return the URL path to the image if exists or false
94
     *
95
     * @param null|string $uuid the user uuid
0 ignored issues
show
Bug introduced by
There is no parameter named $uuid. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
96
     * @return string return the url path or false if not exists
97
     */
98
    public function profileImageUrlPath($filename = null): string
99
    {
100
        if (empty($filename)) {
101
            $filename = $this->profileImageFileName;
102
        }
103
        $f3 = \Base::instance();
104
        return $f3->get('assets.url') . '/img/users/' . $this->uuid . '/' . $filename;
105
    }
106
107
    /**
108
     * Create if needed, and return the dir to the user profile image
109
     *
110
     * @return string $dir to the profile image
111
     */
112
    public function profileImageDirPath(): string
113
    {
114
        $f3  = \Base::instance();
115
        $dir = $f3->get('assets.dir') . '/img/users/' . $this->uuid;
116
        if (!file_exists($dir)) {
117
            mkdir($dir, 0777, true);
118
        }
119
        return $dir . '/';
120
    }
121
122
    /**
123
     * Create if needed, and return the path to the user profile image
124
     *
125
     * @param null|string $filename filename for image
126
     * @return string $path to the profile image
127
     */
128
    public function profileImageFilePath($filename = null): string
129
    {
130
        if (empty($filename)) {
131
            $filename = $this->profileImageFileName;
132
        }
133
        return $this->profileImageDirPath() . $filename;
134
    }
135
136
    /**
137
     * Return the URL path to the image if exists or false
138
     *
139
     * @param string $uuid the user uuid
0 ignored issues
show
Bug introduced by
There is no parameter named $uuid. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
140
     * @return null|string $path to the profile image
141
     * @return bool true if the profile image exists
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean?

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...
142
     */
143
    public function profileImageExists($filename = null)
144
    {
145
        return file_exists($this->profileImageFilePath($filename));
146
    }
147
148
    /**
149
     * Return the URL path to the image if exists or false
150
     *
151
     * @param null|string $uuid the user uuid
0 ignored issues
show
Bug introduced by
There is no parameter named $uuid. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
152
     * @return false|string return the url path or false if not exists
153
     */
154
    public function profileImageUrl($filename = null)
155
    {
156
        $url = $this->profileImageExists($filename) ? $this->profileImageUrlPath($filename) : false;
157
        if (empty($url)) {
158
            return false;
159
        }
160
        return $url . '?' . filesize($this->profileImageFilePath($filename));
161
    }
162
163
164
    /**
165
     * Create profile image from given file
166
     *
167
     * @param string $file path to file
168
     * @return boolean if the file was written and and asset record created
0 ignored issues
show
Documentation introduced by
Should the return type not be false|array? Also, consider making the array more specific, something like array<String>, or String[].

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.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
169
     */
170
    public function profileImageCreate($file)
171
    {
172
        if (!file_exists($file)) {
173
            throw new Exceptions\Exception('Profile image creation file does not exist.');
174
        }
175
        $f3 = \Base::instance();
176
177
        // read exif metadata
178
        $reader = \PHPExif\Reader\Reader::factory(\PHPExif\Reader\Reader::TYPE_NATIVE);
179
        $exif = $reader->read($file);
180
        $metadata = $exif->getData();
181
        unset($exif);
182
183
        // load image
184
        $img = new \Image($file);
185
186
        // make sure maximum width/height not exceeded
187
        $max    = $f3->get('assets.image.max');
188
        $height = $img->height();
189
        $width  = $img->width();
190
        if ($width > $max['width'] || $height > $max['height']) {
191
            $height = $height > $max['height'] ? $max['height'] : $height;
192
            $width  = $width > $max['width'] ? $max['width'] : $width;
193
            $img->resize($width, $height);
194
        }
195
196
        // remove pre-existing cached-images
197
        $dirPath = $this->profileImageDirPath();
198
        foreach (glob($dirPath . '/*.jpg') as $file) {
199
            unlink($file);
200
        }
201
202
        // convert to .png, create new profile image file, overwrites existing
203
        $profileImagePath = $this->profileImageFilePath();
204
        if (!$f3->write($profileImagePath, $img->dump('png', $f3->get('assets.image.default.quality.png')))) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $f3->write($profileImage...default.quality.png'))) of type integer|false is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
205
            return false;
206
        }
207
208
        // create asset table entry
209
        $asset = new Assets;
210
211
        // load pre existing asset
212
        $asset->load(['users_uuid = ? AND ' . $this->db->quoteKey('key') . ' = ?', $this->uuid, 'profile']);
213
214
        // set values
215
        $asset->users_uuid = $this->uuid;
216
        $asset->filename = $profileImagePath;
217
        $asset->name = $this->firstname . ' ' . $this->lastname;
218
        $asset->description = $this->firstname . ' ' . $this->lastname . ' Profile Image';
219
        $asset->size = filesize($profileImagePath);
220
        $asset->url = $this->url($this->profileImageUrl());
0 ignored issues
show
Security Bug introduced by
It seems like $this->profileImageUrl() targeting FFCMS\Mappers\Users::profileImageUrl() can also be of type false; however, FFCMS\Traits\UrlHelper::url() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
221
        $asset->type = 'image/png';
222
        $asset->key = 'profile';
223
        $asset->groups = 'users';
224
        $asset->categories = 'profile';
0 ignored issues
show
Documentation introduced by
The property categories does not exist on object<FFCMS\Mappers\Assets>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
225
        $asset->tags = 'users,profile';
226
        $asset->metadata = json_encode($metadata, JSON_PRETTY_PRINT);
227
228
        return $asset->save();
229
    }
230
}
231