Completed
Push — master ( 6e437b...87f5e0 )
by Benjamin
06:43
created

AbTesting::getCompletedGoals()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 4
cts 5
cp 0.8
rs 9.9332
c 0
b 0
f 0
cc 2
nc 2
nop 0
crap 2.032
1
<?php
2
3
namespace Ben182\AbTesting;
4
5
use Ben182\AbTesting\Models\Goal;
6
use Illuminate\Support\Collection;
7
use Ben182\AbTesting\Models\Experiment;
8
use Ben182\AbTesting\Exceptions\InvalidConfiguration;
9
10
class AbTesting
11
{
12
    protected $experiments;
13
14
    const SESSION_KEY_EXPERIMENTS = 'ab_testing_experiment';
15
    const SESSION_KEY_GOALS = 'ab_testing_goals';
16
17 48
    public function __construct()
18
    {
19 48
        $this->experiments = new Collection;
20 48
    }
21
22 48
    protected function start()
23
    {
24 48
        $configExperiments = config('ab-testing.experiments');
25 48
        $configGoals = config('ab-testing.goals');
26
27 48
        if (count($configExperiments) !== count(array_unique($configExperiments))) {
28 3
            throw InvalidConfiguration::experiment();
29
        }
30
31 45
        if (count($configGoals) !== count(array_unique($configGoals))) {
32 3
            throw InvalidConfiguration::goal();
33
        }
34
35 42
        foreach ($configExperiments as $configExperiment) {
36 42
            $this->experiments[] = $experiment = Experiment::firstOrCreate([
37 42
                'name' => $configExperiment,
38
            ], [
39 42
                'visitors' => 0,
40
            ]);
41
42 42
            foreach ($configGoals as $configGoal) {
43 42
                $experiment->goals()->firstOrCreate([
44 42
                    'name' => $configGoal,
45
                ], [
46 42
                    'hit' => 0,
47
                ]);
48
            }
49
        }
50
51 42
        session([
52 42
            self::SESSION_KEY_GOALS => new Collection,
53
        ]);
54 42
    }
55
56 48
    public function pageview()
57
    {
58 48
        if (! session(self::SESSION_KEY_EXPERIMENTS)) {
59 48
            $this->start();
60 42
            $this->setNextExperiment();
61
        }
62 42
    }
63
64 42
    protected function setNextExperiment()
65
    {
66 42
        $next = $this->getNextExperiment();
67 42
        $next->incrementVisitor();
68
69 42
        session([
70 42
            self::SESSION_KEY_EXPERIMENTS => $next,
71
        ]);
72 42
    }
73
74 42
    protected function getNextExperiment()
75
    {
76 42
        $sorted = $this->experiments->sortBy('visitors');
77
78 42
        return $sorted->first();
79
    }
80
81 9
    public function isExperiment($name)
82
    {
83 9
        $this->pageview();
84
85 9
        return $this->getExperiment()->name === $name;
86
    }
87
88 15
    public function completeGoal($goal)
89
    {
90 15
        if (! $this->getExperiment()) {
91 12
            $this->pageview();
92
        }
93
94 15
        $goal = $this->getExperiment()->goals->where('name', $goal)->first();
95
96 15
        if (! $goal) {
97 3
            return false;
98
        }
99
100 12
        if (session(self::SESSION_KEY_GOALS)->contains($goal->id)) {
101 3
            return false;
102
        }
103
104 12
        session(self::SESSION_KEY_GOALS)->push($goal->id);
105
106 12
        return tap($goal)->incrementHit();
107
    }
108
109 27
    public function getExperiment()
110
    {
111 27
        return session(self::SESSION_KEY_EXPERIMENTS);
112
    }
113
114 3
    public function getCompletedGoals()
115
    {
116 3
        if (! session(self::SESSION_KEY_GOALS)) {
117
            return false;
118
        }
119
120
        return session(self::SESSION_KEY_GOALS)->map(function ($goalId) {
121 3
            return Goal::find($goalId);
122 3
        });
123
    }
124
}
125