Completed
Push — master ( 9c6577...cc976a )
by zacksleo
02:06
created

RecentlyViewedBehavior   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 87.5%

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 3
dl 0
loc 82
ccs 28
cts 32
cp 0.875
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
B getRecentlyViewed() 0 25 4
B setRecentlyViewed() 0 24 5
A clearRecentlyViewed() 0 12 2
1
<?php
2
3
namespace zacksleo\yii2\behaviors;
4
5
use yii;
6
use yii\base\Behavior;
7
8
/**
9
 * ERecentlyViewedBehavior is a behavior for managing recently viewed model items.
10
 */
11
class RecentlyViewedBehavior extends Behavior
12
{
13
    /**
14
     * @param integer the limit to the number of items in the recently viewed list.
15
     */
16
    public $limit = 8; // 0 = no limit.
17
18
    /**
19
     * Adds an item id to a 'recently viewed items' session object.
20
     * @var string the modelClass of the item to store
21
     * @param integer the id of the item to store
22
     */
23
24 1
    public function setRecentlyViewed($modelClass, $id)
25
    {
26
        // Create the session index
27 1
        $index = $modelClass . '_recently_viewed';
28
        // Check if the session index exists
29 1
        if (!isset(Yii::$app->session[$index])) {
30 1
            $recentlyViewed = [];
31
        } else {
32 1
            $recentlyViewed = Yii::$app->session[$index];
33
            // Remove the id if it is already in the list
34 1
            if (($key = array_search($id, $recentlyViewed)) !== false) {
35 1
                unset($recentlyViewed[$key]);
36
            }
37
            // If a limit is set, and the list is at (or over) the limit, remove oldest item(s)
38 1
            if ($this->limit > 0 && count($recentlyViewed) >= $this->limit) {
39
                $count = count($recentlyViewed) - $this->limit;
40
                $recentlyViewed = array_slice($recentlyViewed, $count);
41
            }
42
        }
43
        // Add the current item id to the end of the array
44 1
        array_push($recentlyViewed, $id);
45
        // Update the session
46 1
        Yii::$app->getSession()->set($index, $recentlyViewed);
0 ignored issues
show
Bug introduced by
The method getSession does only exist in yii\web\Application, but not in yii\console\Application.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
47 1
    }
48
49
    /**
50
     * Retrieves model records from a 'recently viewed items' session object.
51
     * @param string $modelClass the modelClass of the items to retrieve
52
     * @return array|null|static[]
53
     */
54 1
    public function getRecentlyViewed($modelClass)
55
    {
56
        // Create the session index
57 1
        $index = $modelClass . '_recently_viewed';
58 1
        $models = array();
59
        // Check if the session index exists
60 1
        if (isset(Yii::$app->session[$index])) {
61
            /* @var $recentlyViewed \zacksleo\yii2\behaviors\Dictionary */
62 1
            $recentlyViewed = Yii::$app->session[$index];
63
            // Check if a limit is set, and if the list is at (or over) the limit
64 1
            if ($this->limit > 0 && count($recentlyViewed) >= $this->limit) {
65
                $count = count($recentlyViewed) - $this->limit;
66
                // Remove the oldest item(s) (always an index of 0 after each removal)
67
                $recentlyViewed = array_slice($recentlyViewed, $count);
68
            }
69
            // Reverse the array so the most recently added item is first
70 1
            $recentlyViewed = array_reverse($recentlyViewed);
71
            // Create a comma separated list for the db order property
72 1
            $commaSeparated = implode(',', $recentlyViewed);
73
            // Find all of the models with the array of ids recently viewed
74
            // and order the results in the same order as the array
75 1
            $models = $modelClass::find()->where(['id' => $recentlyViewed])->orderBy([new yii\db\Expression("FIELD (id, $commaSeparated)")])->all();
76
        }
77 1
        return $models;
78
    }
79
80 1
    public function clearRecentlyViewed($modelClass)
81
    {
82
        // Create the session index
83 1
        $index = $modelClass . '_recently_viewed';
84
        // Check if the session index exists
85 1
        if (isset(Yii::$app->session[$index])) {
86 1
            unset(Yii::$app->session[$index]);
87
        }
88 1
        echo json_encode([
89 1
            'success' => true
90
        ]);
91 1
    }
92
}
93