Completed
Push — master ( 31faa3...626087 )
by Aimeos
02:18
created

Base::getContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2016
6
 * @package Controller
7
 * @subpackage Frontend
8
 */
9
10
11
namespace Aimeos\Controller\Frontend\Basket\Decorator;
12
13
14
/**
15
 * Base for basket frontend controller decorators
16
 *
17
 * @package Controller
18
 * @subpackage Frontend
19
 */
20
abstract class Base
21
	extends \Aimeos\Controller\Frontend\Basket\Base
2 ignored issues
show
Coding Style introduced by
The extends keyword must be on the same line as the class name
Loading history...
Coding Style introduced by
Expected 0 spaces between "Base" and comma; 1 found
Loading history...
22
	implements \Aimeos\Controller\Frontend\Common\Decorator\Iface
1 ignored issue
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	private $controller;
25
26
27
	/**
28
	 * Initializes the controller decorator.
29
	 *
30
	 * @param \Aimeos\Controller\Frontend\Iface $controller Controller object
31
	 * @param \Aimeos\MShop\Context\Item\Iface $context Context object with required objects
32
	 */
33
	public function __construct( \Aimeos\Controller\Frontend\Iface $controller, \Aimeos\MShop\Context\Item\Iface $context )
34
	{
35
		$iface = '\Aimeos\Controller\Frontend\Basket\Iface';
36
		if( !( $controller instanceof $iface ) )
37
		{
38
			$msg = sprintf( 'Class "%1$s" does not implement interface "%2$s"', get_class( $controller ), $iface );
39
			throw new \Aimeos\Controller\Frontend\Exception( $msg );
40
		}
41
42
		$this->controller = $controller;
43
44
		parent::__construct( $context );
45
	}
46
47
48
	/**
49
	 * Passes unknown methods to wrapped objects.
50
	 *
51
	 * @param string $name Name of the method
52
	 * @param array $param List of method parameter
53
	 * @return mixed Returns the value of the called method
54
	 * @throws \Aimeos\Controller\Frontend\Exception If method call failed
55
	 */
56
	public function __call( $name, array $param )
57
	{
58
		return @call_user_func_array( array( $this->controller, $name ), $param );
59
	}
60
61
62
	/**
63
	 * Empties the basket and removing all products, addresses, services, etc.
64
	 * @return void
65
	 */
66
	public function clear()
67
	{
68
		$this->controller->clear();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method clear() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
69
	}
70
71
72
	/**
73
	 * Returns the basket object.
74
	 *
75
	 * @return \Aimeos\MShop\Order\Item\Base\Iface Basket holding products, addresses and delivery/payment options
76
	 */
77
	public function get()
78
	{
79
		return $this->controller->get();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method get() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
80
	}
81
82
83
	/**
84
	 * Explicitely persists the basket content
85
	 */
86
	public function save()
87
	{
88
		$this->controller->save();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method save() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
89
	}
90
91
92
	/**
93
	 * Adds a categorized product to the basket of the user stored in the session.
94
	 *
95
	 * @param string $prodid ID of the base product to add
96
	 * @param integer $quantity Amount of products that should by added
97
	 * @param array $options Possible options are: 'stock'=>true|false and 'variant'=>true|false
98
	 * 	The 'stock'=>false option allows adding products without being in stock.
99
	 * 	The 'variant'=>false option allows adding the selection product to the basket
100
	 * 	instead of the specific sub-product if the variant-building attribute IDs
101
	 * 	doesn't match a specific sub-product or if the attribute IDs are missing.
102
	 * @param array $variantAttributeIds List of variant-building attribute IDs that identify a specific product
103
	 * 	in a selection products
104
	 * @param array $configAttributeIds  List of attribute IDs that doesn't identify a specific product in a
105
	 * 	selection of products but are stored together with the product (e.g. for configurable products)
106
	 * @param array $hiddenAttributeIds List of attribute IDs that should be stored along with the product in the order
107
	 * @param array $customAttributeValues Associative list of attribute IDs and arbitrary values that should be stored
108
	 * 	along with the product in the order
109
	 * @param string $stocktype Unique code of the stock type to deliver the products from
110
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception If the product isn't available
111
	 * @return void
112
	 */
113
	public function addProduct( $prodid, $quantity = 1, array $options = array(), array $variantAttributeIds = array(),
114
		array $configAttributeIds = array(), array $hiddenAttributeIds = array(), array $customAttributeValues = array(),
115
		$stocktype = 'default' )
116
	{
117
		$this->controller->addProduct(
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method addProduct() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
118
			$prodid, $quantity, $options, $variantAttributeIds, $configAttributeIds,
119
			$hiddenAttributeIds, $customAttributeValues, $stocktype
120
		);
121
	}
122
123
124
	/**
125
	 * Deletes a product item from the basket.
126
	 *
127
	 * @param integer $position Position number (key) of the order product item
128
	 * @return void
129
	 */
130
	public function deleteProduct( $position )
131
	{
132
		$this->controller->deleteProduct( $position );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method deleteProduct() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
133
	}
134
135
136
	/**
137
	 * Edits the quantity of a product item in the basket.
138
	 *
139
	 * @param integer $position Position number (key) of the order product item
140
	 * @param integer $quantity New quantiy of the product item
141
	 * @param array $options Possible options are: 'stock'=>true|false
142
	 * @param array $configAttributeCodes Codes of the product config attributes that should be REMOVED
143
	 * @return void
144
	 */
145
	public function editProduct( $position, $quantity, array $options = array(), array $configAttributeCodes = array() )
146
	{
147
		$this->controller->editProduct( $position, $quantity, $options, $configAttributeCodes );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method editProduct() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
148
	}
149
150
151
	/**
152
	 * Adds the given coupon code and updates the basket.
153
	 *
154
	 * @param string $code Coupon code entered by the user
155
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception if the coupon code is invalid or not allowed
156
	 * @return void
157
	 */
158
	public function addCoupon( $code )
159
	{
160
		$this->controller->addCoupon( $code );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method addCoupon() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
161
	}
162
163
164
	/**
165
	 * Removes the given coupon code and its effects from the basket.
166
	 *
167
	 * @param string $code Coupon code entered by the user
168
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception if the coupon code is invalid
169
	 * @return void
170
	 */
171
	public function deleteCoupon( $code )
172
	{
173
		$this->controller->deleteCoupon( $code );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method deleteCoupon() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
174
	}
175
176
177
	/**
178
	 * Sets the address of the customer in the basket.
179
	 *
180
	 * @param string $type Address type constant from \Aimeos\MShop\Order\Item\Base\Address\Base
181
	 * @param \Aimeos\MShop\Common\Item\Address\Iface|array|null $value Address object or array with key/value pairs of address or null to remove address from basket
182
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception If the billing or delivery address is not of any required type of
183
	 * 	if one of the keys is invalid when using an array with key/value pairs
184
	 * @return void
185
	 */
186
	public function setAddress( $type, $value )
187
	{
188
		$this->controller->setAddress( $type, $value );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method setAddress() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
189
	}
190
191
192
	/**
193
	 * Sets the delivery/payment service item based on the service ID.
194
	 *
195
	 * @param string $type Service type code like 'payment' or 'delivery'
196
	 * @param string $id Unique ID of the service item
197
	 * @param array $attributes Associative list of key/value pairs containing the attributes selected or
198
	 * 	entered by the customer when choosing one of the delivery or payment options
199
	 * @throws \Aimeos\Controller\Frontend\Basket\Exception If there is no price to the service item attached
200
	 * @return void
201
	 */
202
	public function setService( $type, $id, array $attributes = array() )
203
	{
204
		$this->controller->setService( $type, $id, $attributes );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Iface as the method setService() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Decorator\Base, Aimeos\Controller\Frontend\Basket\Decorator\Bundle, Aimeos\Controller\Fronte...sket\Decorator\Category, Aimeos\Controller\Frontend\Basket\Decorator\Select, Aimeos\Controller\Frontend\Basket\Standard.

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...
205
	}
206
207
208
	/**
209
	 * Returns the frontend controller
210
	 *
211
	 * @return \Aimeos\Controller\Frontend\Basket\Iface Frontend controller object
212
	 */
213
	protected function getController()
214
	{
215
		return $this->controller;
216
	}
217
}
218