GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( bbf2ff...d7ffda )
by Robert
12:47
created

FileMutex   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 78.05%

Importance

Changes 0
Metric Value
wmc 13
lcom 1
cbo 4
dl 0
loc 139
ccs 32
cts 41
cp 0.7805
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 11 3
B acquireLock() 0 39 6
A releaseLock() 0 23 3
A getLockFilePath() 0 4 1
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\mutex;
9
10
use Yii;
11
use yii\base\InvalidConfigException;
12
use yii\helpers\FileHelper;
13
14
/**
15
 * FileMutex implements mutex "lock" mechanism via local file system files.
16
 *
17
 * This component relies on PHP `flock()` function.
18
 *
19
 * Application configuration example:
20
 *
21
 * ```php
22
 * [
23
 *     'components' => [
24
 *         'mutex' => [
25
 *             'class' => 'yii\mutex\FileMutex'
26
 *         ],
27
 *     ],
28
 * ]
29
 * ```
30
 *
31
 * > Note: this component can maintain the locks only for the single web server,
32
 * > it probably will not suffice in case you are using cloud server solution.
33
 *
34
 * > Warning: due to `flock()` function nature this component is unreliable when
35
 * > using a multithreaded server API like ISAPI.
36
 *
37
 * @see Mutex
38
 *
39
 * @author resurtm <[email protected]>
40
 * @since 2.0
41
 */
42
class FileMutex extends Mutex
43
{
44
    use RetryAcquireTrait;
45
46
    /**
47
     * @var string the directory to store mutex files. You may use [path alias](guide:concept-aliases) here.
48
     * Defaults to the "mutex" subdirectory under the application runtime path.
49
     */
50
    public $mutexPath = '@runtime/mutex';
51
    /**
52
     * @var int the permission to be set for newly created mutex files.
53
     * This value will be used by PHP chmod() function. No umask will be applied.
54
     * If not set, the permission will be determined by the current environment.
55
     */
56
    public $fileMode;
57
    /**
58
     * @var int the permission to be set for newly created directories.
59
     * This value will be used by PHP chmod() function. No umask will be applied.
60
     * Defaults to 0775, meaning the directory is read-writable by owner and group,
61
     * but read-only for other users.
62
     */
63
    public $dirMode = 0775;
64
    /**
65
     * @var bool whether file handling should assume a Windows file system.
66
     * This value will determine how [[releaseLock()]] goes about deleting the lock file.
67
     * If not set, it will be determined by checking the DIRECTORY_SEPARATOR constant.
68
     * @since 2.0.16
69
     */
70
    public $isWindows;
71
72
    /**
73
     * @var resource[] stores all opened lock files. Keys are lock names and values are file handles.
74
     */
75
    private $_files = [];
76
77
78
    /**
79
     * Initializes mutex component implementation dedicated for UNIX, GNU/Linux, Mac OS X, and other UNIX-like
80
     * operating systems.
81
     * @throws InvalidConfigException
82
     */
83 13
    public function init()
84
    {
85 13
        parent::init();
86 13
        $this->mutexPath = Yii::getAlias($this->mutexPath);
0 ignored issues
show
Documentation Bug introduced by
It seems like \Yii::getAlias($this->mutexPath) can also be of type boolean. However, the property $mutexPath is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
87 13
        if (!is_dir($this->mutexPath)) {
88 1
            FileHelper::createDirectory($this->mutexPath, $this->dirMode, true);
0 ignored issues
show
Bug introduced by
It seems like $this->mutexPath can also be of type boolean; however, yii\helpers\BaseFileHelper::createDirectory() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
89
        }
90 13
        if ($this->isWindows === null) {
91 13
            $this->isWindows = DIRECTORY_SEPARATOR === '\\';
92
        }
93 13
    }
94
95
    /**
96
     * Acquires lock by given name.
97
     * @param string $name of the lock to be acquired.
98
     * @param int $timeout time (in seconds) to wait for lock to become released.
99
     * @return bool acquiring result.
100
     */
101 13
    protected function acquireLock($name, $timeout = 0)
102
    {
103 13
        $filePath = $this->getLockFilePath($name);
104 13
        return $this->retryAcquire($timeout, function () use ($filePath, $name) {
105 13
            $file = fopen($filePath, 'w+');
106 13
            if ($file === false) {
107
                return false;
108
            }
109
110 13
            if ($this->fileMode !== null) {
111
                @chmod($filePath, $this->fileMode);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
112
            }
113
114 13
            if (!flock($file, LOCK_EX | LOCK_NB)) {
115 4
                fclose($file);
116 4
                return false;
117
            }
118
119
            // Under unix we delete the lock file before releasing the related handle. Thus it's possible that we've acquired a lock on
120
            // a non-existing file here (race condition). We must compare the inode of the lock file handle with the inode of the actual lock file.
121
            // If they do not match we simply continue the loop since we can assume the inodes will be equal on the next try.
122
            // Example of race condition without inode-comparison:
123
            // Script A: locks file
124
            // Script B: opens file
125
            // Script A: unlinks and unlocks file
126
            // Script B: locks handle of *unlinked* file
127
            // Script C: opens and locks *new* file
128
            // In this case we would have acquired two locks for the same file path.
129 13
            if (DIRECTORY_SEPARATOR !== '\\' && fstat($file)['ino'] !== @fileinode($filePath)) {
130
                clearstatcache(true, $filePath);
131
                flock($file, LOCK_UN);
132
                fclose($file);
133
                return false;
134
            }
135
136 13
            $this->_files[$name] = $file;
137 13
            return true;
138 13
        });
139
    }
140
141
    /**
142
     * Releases lock by given name.
143
     * @param string $name of the lock to be released.
144
     * @return bool release result.
145
     */
146 13
    protected function releaseLock($name)
147
    {
148 13
        if (!isset($this->_files[$name])) {
149 7
            return false;
150
        }
151
152 13
        if ($this->isWindows) {
153
            // Under windows it's not possible to delete a file opened via fopen (either by own or other process).
154
            // That's why we must first unlock and close the handle and then *try* to delete the lock file.
155
            flock($this->_files[$name], LOCK_UN);
156
            fclose($this->_files[$name]);
157
            @unlink($this->getLockFilePath($name));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
158
        } else {
159
            // Under unix it's possible to delete a file opened via fopen (either by own or other process).
160
            // That's why we must unlink (the currently locked) lock file first and then unlock and close the handle.
161 13
            unlink($this->getLockFilePath($name));
162 13
            flock($this->_files[$name], LOCK_UN);
163 13
            fclose($this->_files[$name]);
164
        }
165
166 13
        unset($this->_files[$name]);
167 13
        return true;
168
    }
169
170
    /**
171
     * Generate path for lock file.
172
     * @param string $name
173
     * @return string
174
     * @since 2.0.10
175
     */
176 13
    protected function getLockFilePath($name)
177
    {
178 13
        return $this->mutexPath . DIRECTORY_SEPARATOR . md5($name) . '.lock';
179
    }
180
}
181