Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
51 / 51 |
|
100.00% |
6 / 6 |
CRAP | |
100.00% |
1 / 1 |
VisibilityService | |
100.00% |
51 / 51 |
|
100.00% |
6 / 6 |
22 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
isVisible | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
user | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
7 | |||
page | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
4 | |||
getPathAlias | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
roles | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 |
1 | <?php |
2 | |
3 | namespace Drupal\visitors\Service; |
4 | |
5 | use Drupal\Core\Config\ConfigFactoryInterface; |
6 | use Drupal\Core\Path\CurrentPathStack; |
7 | use Drupal\Core\Path\PathMatcher; |
8 | use Drupal\Core\Session\AccountInterface; |
9 | use Drupal\Core\Session\AccountProxyInterface; |
10 | use Drupal\path_alias\AliasManagerInterface; |
11 | use Drupal\user\UserDataInterface; |
12 | use Drupal\visitors\VisitorsVisibilityInterface; |
13 | use Symfony\Component\HttpFoundation\RequestStack; |
14 | |
15 | /** |
16 | * Service for checking visitors visibility. |
17 | */ |
18 | class VisibilityService implements VisitorsVisibilityInterface { |
19 | |
20 | /** |
21 | * The config object. |
22 | * |
23 | * @var \Drupal\Core\Config\ImmutableConfig |
24 | */ |
25 | protected $config; |
26 | |
27 | /** |
28 | * The current path. |
29 | * |
30 | * @var \Drupal\Core\Path\CurrentPathStack |
31 | */ |
32 | protected $path; |
33 | |
34 | /** |
35 | * The alias manager. |
36 | * |
37 | * @var \Drupal\path_alias\AliasManagerInterface |
38 | */ |
39 | protected $aliasManager; |
40 | |
41 | /** |
42 | * The path matcher. |
43 | * |
44 | * @var \Drupal\Core\Path\PathMatcher |
45 | */ |
46 | protected $pathMatcher; |
47 | |
48 | /** |
49 | * The user data service. |
50 | * |
51 | * @var \Drupal\user\UserDataInterface |
52 | */ |
53 | protected $userData; |
54 | |
55 | /** |
56 | * The request object. |
57 | * |
58 | * @var \Symfony\Component\HttpFoundation\Request |
59 | */ |
60 | protected $request; |
61 | |
62 | /** |
63 | * The current user. |
64 | * |
65 | * @var \Drupal\Core\Session\AccountProxyInterface |
66 | */ |
67 | protected $currentUser; |
68 | |
69 | /** |
70 | * The status codes. |
71 | * |
72 | * @var array |
73 | */ |
74 | protected $statusCodes; |
75 | |
76 | /** |
77 | * Constructs a new VisibilityService. |
78 | * |
79 | * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory |
80 | * The config factory. |
81 | * @param \Drupal\Core\Path\CurrentPathStack $path_current |
82 | * The current path. |
83 | * @param \Drupal\path_alias\AliasManagerInterface|null $alias_manager |
84 | * The alias manager. |
85 | * @param \Drupal\Core\Path\PathMatcher $path_matcher |
86 | * The path matcher. |
87 | * @param \Drupal\user\UserDataInterface $user_data |
88 | * The user data service. |
89 | * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack |
90 | * The request stack. |
91 | * @param \Drupal\Core\Session\AccountProxyInterface $current_user |
92 | * The current user. |
93 | */ |
94 | public function __construct(ConfigFactoryInterface $config_factory, CurrentPathStack $path_current, ?AliasManagerInterface $alias_manager, PathMatcher $path_matcher, UserDataInterface $user_data, RequestStack $request_stack, AccountProxyInterface $current_user) { |
95 | |
96 | $this->config = $config_factory->get('visitors.config'); |
97 | $this->path = $path_current; |
98 | $this->aliasManager = $alias_manager; |
99 | $this->pathMatcher = $path_matcher; |
100 | $this->userData = $user_data; |
101 | $this->request = $request_stack->getCurrentRequest(); |
102 | $this->currentUser = $current_user; |
103 | } |
104 | |
105 | /** |
106 | * {@inheritdoc} |
107 | */ |
108 | public function isVisible(): bool { |
109 | if ($this->config->get('disable_tracking')) { |
110 | return FALSE; |
111 | } |
112 | |
113 | if (!$this->user($this->currentUser)) { |
114 | return FALSE; |
115 | } |
116 | |
117 | return $this->page(); |
118 | } |
119 | |
120 | /** |
121 | * {@inheritdoc} |
122 | */ |
123 | public function user(AccountInterface $account): bool { |
124 | $enabled = FALSE; |
125 | if ($this->config->get('visibility.exclude_user1') && $account->id() == 1) { |
126 | return FALSE; |
127 | } |
128 | |
129 | // Is current user a member of a role that should be tracked? |
130 | if ($this->roles($account)) { |
131 | |
132 | // Use the user's block visibility setting, if necessary. |
133 | $visibility_user_account_mode = $this->config->get('visibility.user_account_mode'); |
134 | if ($visibility_user_account_mode != 0) { |
135 | $user_data_visitors = $this->userData->get('visitors', $account->id()); |
136 | if ($account->id() && isset($user_data_visitors['user_account_users'])) { |
137 | $enabled = $user_data_visitors['user_account_users']; |
138 | } |
139 | else { |
140 | $enabled = ($visibility_user_account_mode == 1); |
141 | } |
142 | } |
143 | else { |
144 | $enabled = TRUE; |
145 | } |
146 | |
147 | } |
148 | |
149 | return $enabled; |
150 | } |
151 | |
152 | /** |
153 | * {@inheritdoc} |
154 | */ |
155 | public function page(): bool { |
156 | $page_match = NULL; |
157 | |
158 | $visibility_request_path_mode = $this->config->get('visibility.request_path_mode'); |
159 | $visibility_request_path_pages = $this->config->get('visibility.request_path_pages'); |
160 | |
161 | // Match path if necessary. |
162 | if (empty($visibility_request_path_pages)) { |
163 | $page_match = TRUE; |
164 | |
165 | return $page_match; |
166 | } |
167 | // Convert path to lowercase. This allows comparison of the same path |
168 | // with different case. Ex: /Page, /page, /PAGE. |
169 | $pages = mb_strtolower($visibility_request_path_pages); |
170 | |
171 | // Compare the lowercase path alias (if any) and internal path. |
172 | $path = $this->path->getPath(); |
173 | $path_alias = $this->getPathAlias($path); |
174 | |
175 | $alias_match = $this->pathMatcher->matchPath($path_alias, $pages); |
176 | $path_match = $this->pathMatcher->matchPath($path, $pages); |
177 | $page_match = $alias_match || ($path != $path_alias && $path_match); |
178 | |
179 | // When $visibility_request_path_mode has a value of 0, the tracking |
180 | // code is displayed on all pages except those listed in $pages. When |
181 | // set to 1, it is displayed only on those pages listed in $pages. |
182 | $page_match = !($visibility_request_path_mode xor $page_match); |
183 | |
184 | return $page_match; |
185 | } |
186 | |
187 | /** |
188 | * Get the path alias. |
189 | */ |
190 | protected function getPathAlias($path) { |
191 | $path_alias = mb_strtolower($path); |
192 | |
193 | if ($this->aliasManager) { |
194 | $path_alias = $this->aliasManager->getAliasByPath($path); |
195 | if (!empty($path_alias)) { |
196 | $path_alias = mb_strtolower($path_alias); |
197 | } |
198 | } |
199 | |
200 | return $path_alias; |
201 | } |
202 | |
203 | /** |
204 | * {@inheritdoc} |
205 | */ |
206 | public function roles(AccountInterface $account): bool { |
207 | $enabled = $visibility_user_role_mode = $this->config->get('visibility.user_role_mode') ?? 0; |
208 | $user_role_roles = $this->config->get('visibility.user_role_roles'); |
209 | |
210 | if (empty($user_role_roles)) { |
211 | return TRUE; |
212 | } |
213 | // One or more roles are selected. |
214 | foreach (array_values($account->getRoles()) as $user_role) { |
215 | // Is the current user a member of one of these roles? |
216 | if (in_array($user_role, $user_role_roles)) { |
217 | // Current user is a member of a role that should be tracked/excluded |
218 | // from tracking. |
219 | $enabled = !$visibility_user_role_mode; |
220 | break; |
221 | } |
222 | } |
223 | |
224 | return $enabled; |
225 | } |
226 | |
227 | } |