1<?php
2/**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9namespace Piwik\Plugins\DevicesDetection\Columns;
10
11use DeviceDetector\Parser\OperatingSystem;
12use Piwik\Columns\DimensionSegmentFactory;
13use Piwik\Common;
14use Piwik\Metrics\Formatter;
15use Piwik\Piwik;
16use Piwik\Plugin\Segment;
17use Piwik\Segment\SegmentsList;
18use Piwik\Tracker\Request;
19use Piwik\Tracker\Settings;
20use Piwik\Tracker\Visitor;
21use Piwik\Tracker\Action;
22
23class Os extends Base
24{
25    protected $columnName = 'config_os';
26    protected $columnType = 'CHAR(3) NULL';
27    protected $segmentName = 'operatingSystemCode';
28    protected $nameSingular = 'DevicesDetection_ColumnOperatingSystem';
29    protected $namePlural = 'DevicesDetection_OperatingSystems';
30    protected $acceptValues = 'WIN, LIN, MAX, AND, IOS etc.';
31    protected $type = self::TYPE_TEXT;
32
33    public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
34    {
35        $segment = new Segment();
36        $segment->setName('DevicesDetection_OperatingSystemCode');
37        $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
38
39        $segment = new Segment();
40        $segment->setSegment('operatingSystemName');
41        $segment->setName('DevicesDetection_ColumnOperatingSystem');
42        $segment->setAcceptedValues('Windows, Linux, Mac, Android, iOS etc.');
43        $segment->setSqlFilterValue(function ($val) {
44            $oss = OperatingSystem::getAvailableOperatingSystems();
45            $oss = array_map(function($val) {
46                return mb_strtolower($val);
47            }, $oss);
48            $result   = array_search(mb_strtolower($val), $oss);
49
50            if ($result === false) {
51                $result = 'UNK';
52            }
53
54            return $result;
55        });
56        $segment->setSuggestedValuesCallback(function ($idSite, $maxValuesToReturn) {
57            return array_values(OperatingSystem::getAvailableOperatingSystems() + ['Unknown']);
58        });
59        $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
60    }
61
62    public function formatValue($value, $idSite, Formatter $formatter)
63    {
64        return \Piwik\Plugins\DevicesDetection\getOSFamilyFullName($value);
65    }
66
67    public function getName()
68    {
69        return Piwik::translate('DevicesDetection_OperatingSystemFamily');
70    }
71
72    /**
73     * @param Request $request
74     * @param Visitor $visitor
75     * @param Action|null $action
76     * @return mixed
77     */
78    public function onNewVisit(Request $request, Visitor $visitor, $action)
79    {
80        $userAgent = $request->getUserAgent();
81        $parser    = $this->getUAParser($userAgent);
82
83        if ($parser->isBot()) {
84            $os = Settings::OS_BOT;
85        } else {
86            $os = $parser->getOS();
87            $os = $os['short_name'] ?? 'UNK';
88        }
89
90        return $os;
91    }
92}
93