Completed
Push — trunk ( 0e7a2e...6a6c5e )
by SuperNova.WS
07:28
created

userOptions   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
dl 0
loc 204
ccs 0
cts 78
cp 0
rs 10
c 0
b 0
f 0
wmc 24

9 Methods

Rating   Name   Duplication   Size   Complexity  
C load() 0 34 8
A __isset() 0 3 1
A user_change() 0 4 1
A __get() 0 3 2
A __construct() 0 2 1
A cached_name() 0 2 1
A __set() 0 5 1
C __flush() 0 36 8
A __unset() 0 4 1
1
<?php
2
3
namespace Player;
4
5
use Common\oldArrayAccessNd;
6
7
/**
8
 * Class Player\userOptions
9
 *
10
 * Загрузка и сохранение настроек пользователя в БД
11
 *
12
 * Унаследованная поддержка многомерных индексов
13
 * Многоуровневое кэширование: память PHP -> память системы (xCache) -> БД
14
 * isset() работает на кэше в памяти PHP и не проверяет дальше
15
 * Поддержка удаления записей из БД и кэша через unset()
16
 * Поддержка отложенной записи
17
 *
18
 */
19
class userOptions extends oldArrayAccessNd {
20
  protected $user_id = 0;
21
  protected $loaded = false;
22
  protected $defaults = array(
23
    PLAYER_OPTION_MENU_SORT             => '',
24
    PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON => PLAYER_OPTION_MENU_HIDE_SHOW_BUTTON_FIXED,
25
    PLAYER_OPTION_MENU_SHOW_ON_BUTTON   => 0,
26
    PLAYER_OPTION_MENU_HIDE_ON_BUTTON   => 0,
27
    PLAYER_OPTION_MENU_HIDE_ON_LEAVE    => 0,
28
    PLAYER_OPTION_MENU_UNPIN_ABSOLUTE   => 0,
29
    PLAYER_OPTION_MENU_ITEMS_AS_BUTTONS => 0,
30
    PLAYER_OPTION_MENU_WHITE_TEXT       => 0,
31
    PLAYER_OPTION_MENU_OLD              => 0,
32
33
    PLAYER_OPTION_SOUND_ENABLED => 0,
34
35
    PLAYER_OPTION_FLEET_SHIP_SORT         => PLAYER_OPTION_SORT_DEFAULT,
36
    PLAYER_OPTION_FLEET_SHIP_SORT_INVERSE => PLAYER_OPTION_SORT_ORDER_PLAIN,
37
38
    PLAYER_OPTION_CURRENCY_DEFAULT => 'RUR',
39
40
    PLAYER_OPTION_FLEET_SPY_DEFAULT => 1,
41
    // PLAYER_OPTION_FLEET_MESS_AMOUNT_MAX => 99,
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
42
43
    PLAYER_OPTION_UNIVERSE_ICON_SPYING      => 1,
44
    PLAYER_OPTION_UNIVERSE_ICON_MISSILE     => 1,
45
    PLAYER_OPTION_UNIVERSE_ICON_PM          => 1,
46
    PLAYER_OPTION_UNIVERSE_ICON_STATS       => 1,
47
    PLAYER_OPTION_UNIVERSE_ICON_PROFILE     => 1,
48
    PLAYER_OPTION_UNIVERSE_ICON_BUDDY       => 1,
49
    PLAYER_OPTION_UNIVERSE_OLD              => 0,
50
    PLAYER_OPTION_UNIVERSE_DISABLE_COLONIZE => 0,
51
52
    PLAYER_OPTION_PLANET_SORT         => 0,
53
    PLAYER_OPTION_PLANET_SORT_INVERSE => 0,
54
    PLAYER_OPTION_TOOLTIP_DELAY       => 500,
55
56
    PLAYER_OPTION_BASE_FONT_SIZE => FONT_SIZE_PERCENT_DEFAULT_STRING,
57
58
    PLAYER_OPTION_BUILD_AUTOCONVERT_HIDE => 0,
59
60
    PLAYER_OPTION_NAVBAR_PLANET_VERTICAL        => 0,
61
    PLAYER_OPTION_NAVBAR_RESEARCH_WIDE          => 0,
62
    PLAYER_OPTION_NAVBAR_DISABLE_EXPEDITIONS    => 0,
63
    PLAYER_OPTION_NAVBAR_DISABLE_FLYING_FLEETS  => 0,
64
    PLAYER_OPTION_NAVBAR_DISABLE_RESEARCH       => 0,
65
    PLAYER_OPTION_NAVBAR_DISABLE_PLANET         => 0,
66
    PLAYER_OPTION_NAVBAR_DISABLE_HANGAR         => 0,
67
    PLAYER_OPTION_NAVBAR_DISABLE_QUESTS         => 0,
68
    PLAYER_OPTION_NAVBAR_DISABLE_META_MATTER    => 0,
69
    PLAYER_OPTION_NAVBAR_PLANET_OLD             => 0,
70
    PLAYER_OPTION_NAVBAR_PLANET_DISABLE_STORAGE => 0,
71
72
    PLAYER_OPTION_BUILDING_SORT         => array(
73
      QUE_RESEARCH   => PLAYER_OPTION_SORT_DEFAULT,
74
      QUE_STRUCTURES => PLAYER_OPTION_SORT_DEFAULT,
75
      SUBQUE_FLEET   => PLAYER_OPTION_SORT_DEFAULT,
76
      SUBQUE_DEFENSE => PLAYER_OPTION_SORT_DEFAULT,
77
    ),
78
    PLAYER_OPTION_BUILDING_SORT_INVERSE => array(
79
      QUE_RESEARCH   => PLAYER_OPTION_SORT_ORDER_PLAIN,
80
      QUE_STRUCTURES => PLAYER_OPTION_SORT_ORDER_PLAIN,
81
      SUBQUE_FLEET   => PLAYER_OPTION_SORT_ORDER_PLAIN,
82
      SUBQUE_DEFENSE => PLAYER_OPTION_SORT_ORDER_PLAIN,
83
    ),
84
85
    PLAYER_OPTION_ANIMATION_DISABLED     => 0,
86
    PLAYER_OPTION_DESIGN_DISABLE_BORDERS => 0,
87
    PLAYER_OPTION_TECH_TREE_TABLE        => 0,
88
89
    PLAYER_OPTION_PROGRESS_BARS_DISABLED => 0,
90
91
    PLAYER_OPTION_FLEET_SHIP_SELECT_OLD       => 0,
92
    PLAYER_OPTION_FLEET_SHIP_HIDE_SPEED       => 0,
93
    PLAYER_OPTION_FLEET_SHIP_HIDE_CAPACITY    => 0,
94
    PLAYER_OPTION_FLEET_SHIP_HIDE_CONSUMPTION => 0,
95
96
    PLAYER_OPTION_TUTORIAL_DISABLED => 1,
97
    PLAYER_OPTION_TUTORIAL_WINDOWED => 0,
98
    PLAYER_OPTION_TUTORIAL_CURRENT  => 1,
99
    PLAYER_OPTION_TUTORIAL_FINISHED => 0,
100
101
    PLAYER_OPTION_QUEST_LIST_FILTER => QUEST_STATUS_ALL,
102
103
    PLAYER_OPTION_LOGIN_REWARDED_LAST       => SN_DATE_PREHISTORIC_SQL,
104
    PLAYER_OPTION_LOGIN_REWARD_STREAK_BEGAN => SN_DATE_PREHISTORIC_SQL,
105
  );
106
107
  public $data = array(); // Container // TODO - make protected
108
109
  public $to_write = array(); // TODO - make protected
110
  public $to_delete = array(); // TODO - make protected
111
112
  public function __get($offset) {
113
    // TODO: Implement __get() method.
114
    return $this->__isset($offset) ? $this->data[$offset] : null;
115
  }
116
117
  public function __set($offset, $value = null) {
118
//    if(!$this->__isset($offset) || $this->__get($offset) != $value)
0 ignored issues
show
Unused Code Comprehensibility introduced by
68% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
119
    {
120
      $this->data[$offset] = $value; // Сразу записываем данные во внутренний кэш
121
      $this->to_write[$offset] = 1; // Индекс измененного элемента для работы подсистемы отложенной записи
122
    }
123
  }
124
125
  public function __isset($offset) {
126
    // TODO: Implement __isset() method.
127
    return isset($this->data[$offset]);
128
  }
129
130
  public function __unset($offset) {
131
    // TODO: Implement __unset() method.
132
    unset($this->data[$offset]);
133
    $this->to_delete[$offset] = 1;
134
  }
135
136
  public function __flush() {
137
    // TODO Implement
138
139
    $update_cache = false;
140
141
    if (!empty($this->to_write)) {
142
      foreach ($this->to_write as $key => $cork) {
143
        $value = is_array($this->data[$key]) ? serialize($this->data[$key]) : $this->data[$key]; // Сериализация для массивов при сохранении в БД
144
        $this->to_write[$key] = "({$this->user_id}, '" . db_escape($key) . "', '" . db_escape($value) . "')";
145
      }
146
147
      doquery("REPLACE INTO `{{player_options}}` (`player_id`, `option_id`, `value`) VALUES " . implode(',', $this->to_write));
148
149
      $this->to_write = array();
150
      $update_cache = true;
151
    }
152
153
    if (!empty($this->to_delete)) {
154
      foreach ($this->to_delete as $key => &$value) {
155
        $value = is_string($key) ? "'" . db_escape($key) . "'" : $key;
156
      }
157
158
      doquery("DELETE FROM `{{player_options}}` WHERE `player_id` = {$this->user_id} AND `option_id` IN (" . implode(',', $this->to_delete) . ") ");
159
160
      $this->to_delete = array();
161
      $update_cache = true;
162
    }
163
164
    if ($update_cache) {
165
      global $sn_cache;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
166
167
      $field_name = $this->cached_name();
168
      $sn_cache->$field_name = $this->data;
169
    }
170
171
    return true;
172
  }
173
174
175
  public function __construct($user_id) {
176
    $this->user_change($user_id);
177
  }
178
179
  public function user_change($user_id, $forceLoad = false) {
180
    $this->loaded = false;
181
    $this->user_id = round(floatval($user_id));
182
    $this->load($forceLoad);
183
  }
184
185
  protected function cached_name() {
186
    return 'options_' . $this->user_id;
187
  }
188
189
  protected function load($forceLoad = false) {
190
    global $sn_cache;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
191
192
    if ($this->loaded) {
193
      return;
194
    }
195
196
    $this->data = $this->defaults;
197
    $this->to_write = array();
198
    $this->to_delete = array();
199
200
    if (!$this->user_id) {
201
      $this->loaded = true;
202
203
      return;
204
    }
205
206
    $field_name = $this->cached_name();
207
    if (!$forceLoad) {
208
      $a_data = $sn_cache->$field_name;
209
210
      if (!empty($a_data)) {
211
        $this->data = array_replace_recursive($this->data, $a_data);
212
213
        return;
214
      }
215
    }
216
217
    $query = doquery("SELECT * FROM `{{player_options}}` WHERE `player_id` = {$this->user_id} FOR UPDATE");
218
    while ($row = db_fetch($query)) {
219
      // $this->data[$row['option_id']] = $row['value'];
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
220
      $this->data[$row['option_id']] = is_string($row['value']) && ($temp = unserialize($row['value'])) !== false ? $temp : $row['value']; // Десериализация
221
    }
222
    $sn_cache->$field_name = $this->data;
223
  }
224
225
}
226