Completed
Push — master ( 7345d8...f8ece9 )
by Vitaly
04:24
created

Gallery   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 119
Duplicated Lines 15.13 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 7
Bugs 2 Features 3
Metric Value
wmc 11
c 7
b 2
f 3
lcom 1
cbo 1
dl 18
loc 119
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 2
A hasImages() 10 18 3
A getCount() 8 16 2
B getImages() 0 26 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: myslyvyi
5
 * Date: 05.01.2016
6
 * Time: 15:25
7
 */
8
namespace samsoncms\api;
9
10
use samson\cms\CMSGallery;
11
use samsoncms\api\MaterialField;
12
use samsoncms\api\Material;
13
use samsonframework\orm\QueryInterface;
14
15
/***
16
 *  Gallery additional field for material.
17
 *  This class enables getting all information about additional fields gallery for specific material.
18
 *  @author [email protected]
19
 */
20
class Gallery
21
{
22
    /** @var integer materialFieldId Table materialField identifier */
23
    protected $materialFieldId = null;
24
25
    /** @var QueryInterface Database query interface */
26
    protected $query;
27
28
    /**
29
     * Constructor Gallery.
30
     * This constructor finds identifier additional field gallery from database record its material and field identifiers.
31
     *
32
     * @param QueryInterface $query Database query interface
33
     * @param integer $materialId material identifier
34
     * @param integer $fieldId field identifier
35
     */
36
    public function __construct(QueryInterface $query, $materialId, $fieldId)
37
    {
38
        /** @var object $materialField additional field value database record*/
39
        $materialField = null;
0 ignored issues
show
Unused Code introduced by
$materialField is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
40
41
        //set query interface
42
        $this->query = $query;
43
44
        //Find additional field value database record by its material and field identifiers.
45
        $materialField = $this->query->entity(MaterialField::ENTITY)
46
            ->where(Material::F_PRIMARY, $materialId)
47
            ->where(Field::F_PRIMARY, $fieldId)
48
            ->where(Material::F_DELETION, 1)
49
            ->first();
50
51
        if ($materialField) {
52
            //Set materialFieldId
53
            $this->materialFieldId = $materialField->id;
54
        }
55
56
    }
57
58
    /**
59
     * Check on empty gallery. If materialFieldId = null and quantity images not more 1 then material not has images.
60
     *
61
     * @return boolean
62
     **/
63
    public function hasImages()
64
    {
65
        /**@var $hasImages */
66
        $hasImages = false;
67
68 View Code Duplication
        if (isset($this->materialFieldId)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69
            // Getting quantity images, if quantity more 0 then material has images
70
            if ($this->query
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface samsonframework\orm\QueryInterface as the method count() does only exist in the following implementations of said interface: samson\activerecord\dbQuery.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
71
            ->entity(CMS::MATERIAL_IMAGES_RELATION_ENTITY)
72
            ->where(Field::F_DELETION, 1)
73
            ->where(MaterialField::F_PRIMARY, $this->materialFieldId)
74
            ->count() > 0) {
75
                $hasImages = true;
76
            }
77
        }
78
79
        return $hasImages;
80
    }
81
82
    /**
83
     * Getting quantity images in additional field gallery
84
     *
85
     * @return integer $count
86
     */
87
    public function getCount()
88
    {
89
        /**@var integer $count quantity images in additional field gallery*/
90
        $count = 0;
91
92 View Code Duplication
        if ($this->hasImages()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
93
            // Getting quantity images for gallery
94
            $count = $this->query
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface samsonframework\orm\QueryInterface as the method count() does only exist in the following implementations of said interface: samson\activerecord\dbQuery.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
95
                ->entity(CMS::MATERIAL_IMAGES_RELATION_ENTITY)
96
                ->where(Field::F_DELETION, 1)
97
                ->where(MaterialField::F_PRIMARY, $this->materialFieldId)
98
                ->count();
99
        }
100
101
        return $count;
102
    }
103
104
    /**
105
     * Get collection of images for material by gallery additional field selector. If none is passed
106
     * all images from gallery table would be returned empty array.
107
     *
108
     * @param integer $currentPage current page with images. Min value = 1
109
     * @param integer $countView quantity view by page
110
     * @return array
111
     */
112
    public function getImages($currentPage = null, $countView = 20)
113
    {
114
        /** @var $images[] Get material images for this gallery */
115
        $images = array();
116
117
        /** @var QueryInterface $query Database query interface*/
118
        $query = null;
0 ignored issues
show
Unused Code introduced by
$query is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
119
120
        if ($this->hasImages()) {
121
            // Select all images in DB by materialFieldId
122
            $query = $this->query
123
                ->entity(CMS::MATERIAL_IMAGES_RELATION_ENTITY)
124
                ->where(Field::F_DELETION, 1)
125
                ->where(MaterialField::F_PRIMARY, $this->materialFieldId);
126
127
            if (isset($currentPage) && $currentPage > 0) {
128
                //Set limit for query
129
                $query->limit(--$currentPage * $countView, $countView);
130
            }
131
132
            // Execute query
133
            $images = $query->exec();
134
        }
135
136
        return $images;
137
    }
138
}