Completed
Push — master ( 7bf2c4...ed6650 )
by Danilo
03:26
created

Language::setLanguageRedis()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 32
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 3
nop 2
dl 0
loc 32
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace PhpBotFramework\Localization;
4
5
trait Language {
6
7
    /**
8
     * \addtogroup Localization Localization
9
     * @{
10
     */
11
12
    /** \brief Store the language for a multi-language bot */
13
    public $language;
14
15
    /** \brief Table contaning bot users data in the sql database. */
16
    public $user_table = '"User"';
17
18
    /** \brief Name of the column that represents the user id in the sql database */
19
    public $id_column = 'chat_id';
20
21
    /**
22
     * \brief Get current user language from the database, and set it in $language.
23
     * @param $default_language <i>Optional</i>. Default language to return in case of errors.
24
     * @return Language set for the current user, $default_language on errors.
0 ignored issues
show
Comprehensibility Bug introduced by
The return type Language is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
25
     */
26
    public function getLanguageDatabase($default_language = 'en') {
27
28
        // If we have no database
29
        if (!isset($this->_database)) {
30
31
            // Set the language to english
32
            $this->language = $default_language;
33
34
            // Return english
35
            return $default_language;
36
37
        }
38
39
        // Get the language from the bot
40
        $sth = $this->pdo->prepare('SELECT language FROM ' . $this->user_table . ' WHERE ' . $this->id_column . ' = :chat_id');
0 ignored issues
show
Bug introduced by
The property pdo does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
41
        $sth->bindParam(':chat_id', $this->_chat_id);
0 ignored issues
show
Bug introduced by
The property _chat_id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
42
43
        try {
44
45
            $sth->execute();
46
47
        } catch (PDOException $e) {
0 ignored issues
show
Bug introduced by
The class PhpBotFramework\Localization\PDOException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
48
49
            echo $e->getMessage();
50
51
        }
52
53
        $row = $sth->fetch();
54
55
        $sth = null;
0 ignored issues
show
Unused Code introduced by
$sth is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
56
57
        // If we got the language
58
        if (isset($row['language'])) {
59
60
            // Set the language in the bot
61
            $this->language = $row['language'];
62
63
            // And return it
64
            return $row['language'];
65
66
        }
67
68
        // If we couldn't get it, set the language to english
69
        $this->language = $default_language;
70
71
        // and return english
72
        return $this->language;
73
74
    }
75
76
    /**
77
     * \brief Get current user language from redis, as a cache, and set it in language.
78
     * \details Using redis database as cache, seeks the language in it, if there isn't
79
     * then get the language from the sql database and store it (with default expiring of one day) in redis.
80
     * It also change $language parameter of the bot to the language returned.
81
     * @param $default_language <i>Optional</i>. Default language to return in case of errors.
82
     * @param $expiring_time <i>Optional</i>. Set the expiring time for the language on redis each time it is took from the sql database.
83
     * @return Language for the current user, $default_language on errors.
0 ignored issues
show
Comprehensibility Bug introduced by
The return type Language is a trait, and thus cannot be used for type-hinting in PHP. Maybe consider adding an interface and use that for type-hinting?

In PHP traits cannot be used for type-hinting as they do not define a well-defined structure. This is because any class that uses a trait can rename that trait’s methods.

If you would like to return an object that has a guaranteed set of methods, you could create a companion interface that lists these methods explicitly.

Loading history...
84
     */
85
    public function getLanguageRedis($default_language = 'en', $expiring_time = '86400') : string {
86
87
        // If redis or pdo connection are not set
88
        if (!isset($this->redis) || !isset($this->pdo)) {
89
90
            // return default language
91
            return $default_language;
92
93
        }
94
95
        // Does it exists on redis?
96 View Code Duplication
        if ($this->redis->exists($this->_chat_id . ':language')) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97
98
            // Get the value
99
            $this->language = $this->redis->get($this->_chat_id . ':language');
0 ignored issues
show
Bug introduced by
The property redis does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
100
            return $this->language;
101
102
        }
103
104
        // Set the value from the db
105
        $this->redis->setEx($this->_chat_id . ':language', $expiring_time, $this->getLanguageDatabase($default_language));
106
107
        // and return it
108
        return $this->language;
109
110
    }
111
112
    /**
113
     * \brief Set the current user language in both redis, sql database and $language.
114
     * \details Save it on database first, then create the expiring key on redis.
115
     * @param $language The new language to set.
116
     * @param $expiring_time <i>Optional</i>. Time for the language key in redis to expire.
117
     * @return On sucess, return true, throw exception otherwise.
118
     */
119
    public function setLanguageRedis($language, $expiring_time = '86400') {
120
121
        // Check database connection
122
        if (!isset($this->_database) && !isset($this->redis)) {
123
            throw new BotException('Database connection not set');
124
        }
125
126
        // Update the language in the database
127
        $sth = $this->pdo->prepare('UPDATE ' . $this->user_table . ' SET language = :language WHERE ' . $this->id_column . ' = :id');
128
        $sth->bindParam(':language', $language);
129
        $sth->bindParam(':id', $this->_chat_id);
130
131
        try {
132
133
            $sth->execute();
134
135
        } catch (PDOException $e) {
0 ignored issues
show
Bug introduced by
The class PhpBotFramework\Localization\PDOException does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
136
137
            throw new BotException($e->getMessage());
138
139
        }
140
141
        // Destroy statement
142
        $sth = null;
0 ignored issues
show
Unused Code introduced by
$sth is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
143
144
        // Set the language in redis with expiring
145
        $this->redis->setEx($this->_chat_id . ':language', $expiring_time, $language);
146
147
        // Set language in the bot variable
148
        $this->language = $language;
149
150
    }
151
152
    /** @} */
153
154
}
155