Skip to content

Commit 9102298

Browse files
authored
Merge pull request #1 from digifa/2.3.2
v2.3.2
2 parents 1a3f3d0 + 7488035 commit 9102298

16 files changed

+565
-176
lines changed

src/DataCollector/DeviceDataCollector.php

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,17 @@
1313

1414
namespace MobileDetectBundle\DataCollector;
1515

16-
use MobileDetectBundle\EventListener\RequestResponseListener;
16+
use MobileDetectBundle\EventListener\RequestResponseListenerInterface;
1717
use MobileDetectBundle\Helper\DeviceView;
18+
use MobileDetectBundle\Helper\DeviceViewInterface;
1819
use Symfony\Component\HttpFoundation\Request;
1920
use Symfony\Component\HttpFoundation\Response;
2021
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
2122

2223
/**
2324
* @author Jonas HAOUZI <haouzijonas@gmail.com>
2425
*/
25-
class DeviceDataCollector extends DataCollector
26+
class DeviceDataCollector extends DataCollector implements DeviceDataCollectorInterface
2627
{
2728
/**
2829
* @var DeviceView
@@ -50,68 +51,89 @@ public function collect(
5051
$this->data['currentView'] = $this->deviceView->getViewType();
5152
$this->data['views'] = [
5253
[
53-
'type' => DeviceView::VIEW_FULL,
54+
'type' => DeviceViewInterface::VIEW_FULL,
5455
'label' => 'Full',
5556
'link' => $this->generateSwitchLink(
5657
$request,
57-
DeviceView::VIEW_FULL
58+
DeviceViewInterface::VIEW_FULL
5859
),
5960
'isCurrent' => $this->deviceView->isFullView(),
60-
'enabled' => $this->canUseView(DeviceView::VIEW_FULL, $request->getSchemeAndHttpHost()),
61+
'enabled' => $this->canUseView(DeviceViewInterface::VIEW_FULL, $request->getSchemeAndHttpHost()),
6162
],
6263
[
63-
'type' => DeviceView::VIEW_TABLET,
64+
'type' => DeviceViewInterface::VIEW_TABLET,
6465
'label' => 'Tablet',
6566
'link' => $this->generateSwitchLink(
6667
$request,
67-
DeviceView::VIEW_TABLET
68+
DeviceViewInterface::VIEW_TABLET
6869
),
6970
'isCurrent' => $this->deviceView->isTabletView(),
70-
'enabled' => $this->canUseView(DeviceView::VIEW_TABLET, $request->getSchemeAndHttpHost()),
71+
'enabled' => $this->canUseView(DeviceViewInterface::VIEW_TABLET, $request->getSchemeAndHttpHost()),
7172
],
7273
[
73-
'type' => DeviceView::VIEW_MOBILE,
74+
'type' => DeviceViewInterface::VIEW_MOBILE,
7475
'label' => 'Mobile',
7576
'link' => $this->generateSwitchLink(
7677
$request,
77-
DeviceView::VIEW_MOBILE
78+
DeviceViewInterface::VIEW_MOBILE
7879
),
7980
'isCurrent' => $this->deviceView->isMobileView(),
80-
'enabled' => $this->canUseView(DeviceView::VIEW_MOBILE, $request->getSchemeAndHttpHost()),
81+
'enabled' => $this->canUseView(DeviceViewInterface::VIEW_MOBILE, $request->getSchemeAndHttpHost()),
8182
],
8283
];
8384
}
8485

86+
/**
87+
* Get the current view being displayed.
88+
*/
8589
public function getCurrentView(): string
8690
{
8791
return $this->data['currentView'];
8892
}
8993

94+
/**
95+
* Gets the views from the data array.
96+
*/
9097
public function getViews(): array
9198
{
9299
return $this->data['views'];
93100
}
94101

102+
/**
103+
* Sets the redirect configuration.
104+
*/
95105
public function setRedirectConfig(array $redirectConfig): void
96106
{
97107
$this->redirectConfig = $redirectConfig;
98108
}
99109

110+
/**
111+
* Get the name of the collector device.
112+
*/
100113
public function getName(): string
101114
{
102115
return 'device.collector';
103116
}
104117

118+
/**
119+
* Gets the data.
120+
*/
105121
public function getData(): array
106122
{
107123
return $this->data;
108124
}
109125

126+
/**
127+
* Resets the data to an empty array.
128+
*/
110129
public function reset(): void
111130
{
112131
$this->data = [];
113132
}
114133

134+
/**
135+
* Check if the view can be used based on configuration settings.
136+
*/
115137
protected function canUseView(string $view, ?string $host): bool
116138
{
117139
if (!\is_array($this->redirectConfig)
@@ -125,7 +147,7 @@ protected function canUseView(string $view, ?string $host): bool
125147
if (true === $this->redirectConfig[$view]['is_enabled']
126148
&& isset($this->redirectConfig[$view]['host'], $this->redirectConfig[$view]['action'])
127149
&& !empty($this->redirectConfig[$view]['host'])
128-
&& \in_array($this->redirectConfig[$view]['action'], [RequestResponseListener::REDIRECT, RequestResponseListener::REDIRECT_WITHOUT_PATH], true)
150+
&& \in_array($this->redirectConfig[$view]['action'], [RequestResponseListenerInterface::REDIRECT, RequestResponseListenerInterface::REDIRECT_WITHOUT_PATH], true)
129151
) {
130152
$parseHost = parse_url((string) $this->redirectConfig[$view]['host']);
131153
$redirectHost = $parseHost['scheme'].'://'.$parseHost['host'];
@@ -141,6 +163,9 @@ protected function canUseView(string $view, ?string $host): bool
141163
return true;
142164
}
143165

166+
/**
167+
* Generates a switch link for switching the view based on the provided view parameter.
168+
*/
144169
private function generateSwitchLink(
145170
Request $request,
146171
string $view,
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MobileDetectBundle\DataCollector;
6+
7+
use Symfony\Component\HttpFoundation\Request;
8+
use Symfony\Component\HttpFoundation\Response;
9+
10+
/**
11+
* @author Jonas HAOUZI <haouzijonas@gmail.com>
12+
*/
13+
interface DeviceDataCollectorInterface
14+
{
15+
/**
16+
* Returns an array of all the properties that should be serialized when this object is serialized with `serialize()`.
17+
*/
18+
public function __sleep(): array;
19+
20+
/**
21+
* Resurrects the object after it has been unserialized with `unserialize()`.
22+
*/
23+
public function __wakeup();
24+
25+
/**
26+
* Collects data for the given Request and Response.
27+
*/
28+
public function collect(Request $request, Response $response, ?\Throwable $exception = null): void;
29+
30+
/**
31+
* Returns the current view name as a string.
32+
*/
33+
public function getCurrentView(): string;
34+
35+
/**
36+
* Returns an array of views associated with this object.
37+
*/
38+
public function getViews(): array;
39+
40+
/**
41+
* Sets the redirect configuration for the Symfony application.
42+
*/
43+
public function setRedirectConfig(array $redirectConfig): void;
44+
45+
/**
46+
* Gets the name of the Symfony application.
47+
*/
48+
public function getName(): string;
49+
50+
/**
51+
* Retrieves the data stored in the Symfony application.
52+
*/
53+
public function getData(): array;
54+
55+
/**
56+
* Resets any configuration or data in the Symfony application to its default state.
57+
*/
58+
public function reset(): void;
59+
}

src/DependencyInjection/Configuration.php

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
namespace MobileDetectBundle\DependencyInjection;
1515

16-
use MobileDetectBundle\EventListener\RequestResponseListener;
17-
use MobileDetectBundle\Helper\DeviceView;
16+
use MobileDetectBundle\EventListener\RequestResponseListenerInterface;
17+
use MobileDetectBundle\Helper\DeviceViewInterface;
1818
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
1919
use Symfony\Component\Config\Definition\ConfigurationInterface;
2020
use Symfony\Component\HttpFoundation\Response;
@@ -44,7 +44,7 @@ public function getConfigTreeBuilder(): TreeBuilder
4444
->booleanNode('is_enabled')->defaultFalse()->end()
4545
->scalarNode('host')->defaultNull()->end()
4646
->scalarNode('status_code')->defaultValue(Response::HTTP_FOUND)->cannotBeEmpty()->end()
47-
->scalarNode('action')->defaultValue(RequestResponseListener::REDIRECT)->cannotBeEmpty()->end()
47+
->scalarNode('action')->defaultValue(RequestResponseListenerInterface::REDIRECT)->cannotBeEmpty()->end()
4848
->end()
4949
->end()
5050
->arrayNode('tablet')
@@ -53,7 +53,7 @@ public function getConfigTreeBuilder(): TreeBuilder
5353
->booleanNode('is_enabled')->defaultFalse()->end()
5454
->scalarNode('host')->defaultNull()->end()
5555
->scalarNode('status_code')->defaultValue(Response::HTTP_FOUND)->cannotBeEmpty()->end()
56-
->scalarNode('action')->defaultValue(RequestResponseListener::REDIRECT)->cannotBeEmpty()->end()
56+
->scalarNode('action')->defaultValue(RequestResponseListenerInterface::REDIRECT)->cannotBeEmpty()->end()
5757
->end()
5858
->end()
5959
->arrayNode('full')
@@ -62,7 +62,7 @@ public function getConfigTreeBuilder(): TreeBuilder
6262
->booleanNode('is_enabled')->defaultFalse()->end()
6363
->scalarNode('host')->defaultNull()->end()
6464
->scalarNode('status_code')->defaultValue(Response::HTTP_FOUND)->cannotBeEmpty()->end()
65-
->scalarNode('action')->defaultValue(RequestResponseListener::REDIRECT)->cannotBeEmpty()->end()
65+
->scalarNode('action')->defaultValue(RequestResponseListenerInterface::REDIRECT)->cannotBeEmpty()->end()
6666
->end()
6767
->end()
6868
->booleanNode('detect_tablet_as_mobile')->defaultFalse()->end()
@@ -74,13 +74,13 @@ public function getConfigTreeBuilder(): TreeBuilder
7474
->booleanNode('save_referer_path')->defaultTrue()->end()
7575
->end()
7676
->end()
77-
->scalarNode('cookie_key')->defaultValue(DeviceView::COOKIE_KEY_DEFAULT)->cannotBeEmpty()->end()
78-
->scalarNode('cookie_path')->defaultValue(DeviceView::COOKIE_PATH_DEFAULT)->cannotBeEmpty()->end()
79-
->scalarNode('cookie_domain')->defaultValue(DeviceView::COOKIE_DOMAIN_DEFAULT)->cannotBeEmpty()->end()
80-
->booleanNode('cookie_secure')->defaultValue(DeviceView::COOKIE_SECURE_DEFAULT)->end()
81-
->booleanNode('cookie_httpOnly')->defaultValue(DeviceView::COOKIE_HTTP_ONLY_DEFAULT)->end()
82-
->scalarNode('cookie_expire_datetime_modifier')->defaultValue(DeviceView::COOKIE_EXPIRE_DATETIME_MODIFIER_DEFAULT)->cannotBeEmpty()->end()
83-
->scalarNode('switch_param')->defaultValue(DeviceView::SWITCH_PARAM_DEFAULT)->cannotBeEmpty()->end()
77+
->scalarNode('cookie_key')->defaultValue(DeviceViewInterface::COOKIE_KEY_DEFAULT)->cannotBeEmpty()->end()
78+
->scalarNode('cookie_path')->defaultValue(DeviceViewInterface::COOKIE_PATH_DEFAULT)->cannotBeEmpty()->end()
79+
->scalarNode('cookie_domain')->defaultValue(DeviceViewInterface::COOKIE_DOMAIN_DEFAULT)->cannotBeEmpty()->end()
80+
->booleanNode('cookie_secure')->defaultValue(DeviceViewInterface::COOKIE_SECURE_DEFAULT)->end()
81+
->booleanNode('cookie_httpOnly')->defaultValue(DeviceViewInterface::COOKIE_HTTP_ONLY_DEFAULT)->end()
82+
->scalarNode('cookie_expire_datetime_modifier')->defaultValue(DeviceViewInterface::COOKIE_EXPIRE_DATETIME_MODIFIER_DEFAULT)->cannotBeEmpty()->end()
83+
->scalarNode('switch_param')->defaultValue(DeviceViewInterface::SWITCH_PARAM_DEFAULT)->cannotBeEmpty()->end()
8484
->end()
8585
;
8686

src/DependencyInjection/MobileDetectExtension.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ public function load(array $configs, ContainerBuilder $container): void
5858
$container->setParameter('mobile_detect.switch_param', $config['switch_param']);
5959
}
6060

61+
/**
62+
* Validates a given URL.
63+
*/
6164
protected function validHost(?string $url): bool
6265
{
6366
return (bool) filter_var($url, \FILTER_VALIDATE_URL);

src/DeviceDetector/MobileDetector.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,19 @@ class MobileDetector extends MobileDetect implements MobileDetectorInterface
2424

2525
public const VERSION_TYPE_FLOAT = 'float';
2626

27+
/**
28+
* Get the list of user agents by fetching browsers.
29+
*/
2730
public static function getUserAgents(): array
2831
{
2932
return self::getBrowsers();
3033
}
3134

35+
/**
36+
* Get the CloudFront headers from the current request.
37+
*
38+
* @deprecated use self::getCloudFrontHttpHeaders() instead
39+
*/
3240
public function getCfHeaders(): array
3341
{
3442
return $this->getCloudFrontHttpHeaders();

src/EventListener/RequestResponseListener.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,8 @@
2727
* @author suncat2000 <nikolay.kotovsky@gmail.com>
2828
* @author HenriVesala <henri.vesala@gmail.com>
2929
*/
30-
class RequestResponseListener
30+
class RequestResponseListener implements RequestResponseListenerInterface
3131
{
32-
public const REDIRECT = 'redirect';
33-
public const NO_REDIRECT = 'no_redirect';
34-
public const REDIRECT_WITHOUT_PATH = 'redirect_without_path';
35-
36-
public const MOBILE = 'mobile';
37-
public const TABLET = 'tablet';
38-
public const FULL = 'full';
39-
4032
/**
4133
* @var RouterInterface
4234
*/
@@ -88,6 +80,9 @@ public function __construct(
8880
$this->isFullPath = $fullPath;
8981
}
9082

83+
/**
84+
* Handles the request and performs necessary actions based on the device view type.
85+
*/
9186
public function handleRequest(RequestEvent $event): void
9287
{
9388
// only handle master request, do not handle sub request like esi includes
@@ -150,6 +145,9 @@ public function needsResponseModification(): bool
150145
return $this->needModifyResponse;
151146
}
152147

148+
/**
149+
* Handles the response event by modifying the response if needed.
150+
*/
153151
public function handleResponse(ResponseEvent $event): void
154152
{
155153
if ($this->needModifyResponse && $this->modifyResponseClosure instanceof \Closure) {
@@ -160,6 +158,9 @@ public function handleResponse(ResponseEvent $event): void
160158
}
161159
}
162160

161+
/**
162+
* Gets the RedirectResponse with a cookie based on the switch parameter in the request.
163+
*/
163164
protected function getRedirectResponseBySwitchParam(Request $request): RedirectResponseWithCookie
164165
{
165166
if ($this->mustRedirect($request, $this->deviceView->getViewType())) {
@@ -202,6 +203,9 @@ protected function mustRedirect(Request $request, string $viewType): bool
202203
return $request->getSchemeAndHttpHost() !== $this->redirectConf[$viewType]['host'];
203204
}
204205

206+
/**
207+
* Gets the specified routing option for a given route name.
208+
*/
205209
protected function getRoutingOption(string $routeName, string $optionName): ?string
206210
{
207211
$option = null;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MobileDetectBundle\EventListener;
6+
7+
use Symfony\Component\HttpKernel\Event\RequestEvent;
8+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
9+
10+
/**
11+
* @author suncat2000 <nikolay.kotovsky@gmail.com>
12+
* @author HenriVesala <henri.vesala@gmail.com>
13+
*/
14+
interface RequestResponseListenerInterface
15+
{
16+
public const REDIRECT = 'redirect';
17+
public const NO_REDIRECT = 'no_redirect';
18+
public const REDIRECT_WITHOUT_PATH = 'redirect_without_path';
19+
20+
public const MOBILE = 'mobile';
21+
public const TABLET = 'tablet';
22+
public const FULL = 'full';
23+
24+
/**
25+
* Handle the incoming request event and perform necessary actions.
26+
* This method will be invoked when a request event is triggered in the application.
27+
*/
28+
public function handleRequest(RequestEvent $event): void;
29+
30+
/**
31+
* Will this request listener modify the response? This flag will be set during the "handleRequest" phase.
32+
* Made public for testability.
33+
*/
34+
public function needsResponseModification(): bool;
35+
36+
/**
37+
* Handles the response event by performing certain actions based on the given ResponseEvent object.
38+
*/
39+
public function handleResponse(ResponseEvent $event): void;
40+
}

0 commit comments

Comments
 (0)