Completed
Push — master ( 3d76e0...38a76c )
by Aimeos
07:49
created

Standard::patch()   B

Complexity

Conditions 5
Paths 11

Size

Total Lines 39
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 39
rs 8.439
c 0
b 0
f 0
cc 5
eloc 22
nc 11
nop 2
1
<?php
2
3
/**
4
 * @license LGPLv3, http://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2017
6
 * @package Client
7
 * @subpackage JsonApi
8
 */
9
10
11
namespace Aimeos\Client\JsonApi\Basket;
12
13
use Psr\Http\Message\ResponseInterface;
14
use Psr\Http\Message\ServerRequestInterface;
15
16
17
/**
18
 * JSON API basket client
19
 *
20
 * @package Client
21
 * @subpackage JsonApi
22
 */
23
class Standard
24
	extends \Aimeos\Client\JsonApi\Base
25
	implements \Aimeos\Client\JsonApi\Iface
26
{
27
	private $controller;
28
29
30
	/**
31
	 * Initializes the client
32
	 *
33
	 * @param \Aimeos\MShop\Context\Item\Iface $context MShop context object
34
	 * @param \Aimeos\MW\View\Iface $view View object
35
	 * @param array $templatePaths List of file system paths where the templates are stored
36
	 * @param string $path Name of the client, e.g "basket"
37
	 */
38
	public function __construct( \Aimeos\MShop\Context\Item\Iface $context, \Aimeos\MW\View\Iface $view, array $templatePaths, $path )
39
	{
40
		parent::__construct( $context, $view, $templatePaths, $path );
41
42
		$this->controller = \Aimeos\Controller\Frontend\Basket\Factory::createController( $this->getContext() );
43
	}
44
45
46
	/**
47
	 * Deletes the resource or the resource list
48
	 *
49
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
50
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
51
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
52
	 */
53
	public function delete( ServerRequestInterface $request, ResponseInterface $response )
54
	{
55
		$view = $this->getView();
56
57
		try
58
		{
59
			$status = 200;
60
			$type = $view->param( 'b_type', 'default' );
61
			$view->items = $this->controller->setType( $type )->clear()->get();
2 ignored issues
show
Bug introduced by
Accessing items on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Common\Iface as the method setType() does only exist in the following implementations of said interface: 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...
62
			$view->total = 1;
1 ignored issue
show
Bug introduced by
Accessing total on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
63
		}
64
		catch( \Aimeos\MShop\Exception $e )
65
		{
66
			$status = 404;
67
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
68
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
69
				'detail' => $e->getTraceAsString(),
70
			) );
71
		}
72
		catch( \Exception $e )
73
		{
74
			$status = 500;
75
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
76
				'title' => $e->getMessage(),
77
				'detail' => $e->getTraceAsString(),
78
			) );
79
		}
80
81
		return $this->render( $response, $view, $status );
82
	}
83
84
85
	/**
86
	 * Returns the resource or the resource list
87
	 *
88
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
89
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
90
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
91
	 */
92
	public function get( ServerRequestInterface $request, ResponseInterface $response )
93
	{
94
		$allow = true;
95
		$view = $this->getView();
96
97
		try
98
		{
99
			if( ( $id = $view->param( 'id' ) ) != '' )
100
			{
101
				$view->items = $this->controller->load( $id, $this->getParts( $view ) );
2 ignored issues
show
Bug introduced by
Accessing items on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Common\Iface as the method load() does only exist in the following implementations of said interface: 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...
102
				$allow = false;
103
			}
104
			else
105
			{
106
				$view->items = $this->controller->setType( $view->param( 'b_type', 'default' ) )->get();
2 ignored issues
show
Bug introduced by
Accessing items on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Common\Iface as the method setType() does only exist in the following implementations of said interface: 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...
107
			}
108
109
			$view->total = 1;
1 ignored issue
show
Bug introduced by
Accessing total on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
110
			$status = 200;
111
		}
112
		catch( \Aimeos\MShop\Exception $e )
113
		{
114
			$status = 404;
115
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
116
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
117
				'detail' => $e->getTraceAsString(),
118
			) );
119
		}
120
		catch( \Exception $e )
121
		{
122
			$status = 500;
123
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
124
				'title' => $e->getMessage(),
125
				'detail' => $e->getTraceAsString(),
126
			) );
127
		}
128
129
		return $this->render( $response, $view, $status, $allow );
130
	}
131
132
133
	/**
134
	 * Updates the resource or the resource list partitially
135
	 *
136
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
137
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
138
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
139
	 */
140
	public function patch( ServerRequestInterface $request, ResponseInterface $response )
141
	{
142
		$view = $this->getView();
143
144
		try
145
		{
146
			$body = (string) $request->getBody();
147
148
			if( ( $payload = json_decode( $body ) ) === null || !isset( $payload->data->attributes ) ) {
149
				throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid JSON in body' ), 400 );
150
			}
151
152
			$basket = $this->controller->setType( $view->param( 'b_type', 'default' ) )->get();
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Common\Iface as the method setType() does only exist in the following implementations of said interface: 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...
153
			$basket->fromArray( (array) $payload->data->attributes );
154
155
			$view->items = $basket;
1 ignored issue
show
Bug introduced by
Accessing items on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
156
			$view->total = 1;
1 ignored issue
show
Bug introduced by
Accessing total on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
157
158
			$status = 200;
159
		}
160
		catch( \Aimeos\MShop\Exception $e )
161
		{
162
			$status = 404;
163
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
164
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
165
				'detail' => $e->getTraceAsString(),
166
			) );
167
		}
168
		catch( \Exception $e )
169
		{
170
			$status = 500;
171
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
172
				'title' => $e->getMessage(),
173
				'detail' => $e->getTraceAsString(),
174
			) );
175
		}
176
177
		return $this->render( $response, $view, $status );
178
	}
179
180
181
	/**
182
	 * Creates or updates the resource or the resource list
183
	 *
184
	 * @param \Psr\Http\Message\ServerRequestInterface $request Request object
185
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
186
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
187
	 */
188
	public function post( ServerRequestInterface $request, ResponseInterface $response )
189
	{
190
		$view = $this->getView();
191
192
		try
193
		{
194
			$this->controller->setType( $view->param( 'b_type', 'default' ) );
1 ignored issue
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Common\Iface as the method setType() does only exist in the following implementations of said interface: 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...
195
196
			$view->items = $this->controller->store();
2 ignored issues
show
Bug introduced by
Accessing items on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
Bug introduced by
It seems like you code against a concrete implementation and not the interface Aimeos\Controller\Frontend\Common\Iface as the method store() does only exist in the following implementations of said interface: Aimeos\Controller\Frontend\Basket\Standard, Aimeos\Controller\Frontend\Order\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...
197
			$view->total = 1;
1 ignored issue
show
Bug introduced by
Accessing total on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
198
199
			$status = 200;
200
		}
201
		catch( \Aimeos\MShop\Exception $e )
202
		{
203
			$status = 404;
204
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
205
				'title' => $this->getContext()->getI18n()->dt( 'mshop', $e->getMessage() ),
206
				'detail' => $e->getTraceAsString(),
207
			) );
208
		}
209
		catch( \Exception $e )
210
		{
211
			$status = 500;
212
			$view->errors = array( array(
1 ignored issue
show
Bug introduced by
Accessing errors on the interface Aimeos\MW\View\Iface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
213
				'title' => $e->getMessage(),
214
				'detail' => $e->getTraceAsString(),
215
			) );
216
		}
217
218
		return $this->render( $response, $view, $status );
219
	}
220
221
222
	/**
223
	 * Returns the integer constant for the basket parts that should be included
224
	 *
225
	 * @param \Aimeos\MW\View\Iface $view View instance
226
	 * @return integer Constant from Aimeos\MShop\Order\Manager\Base\Base
227
	 */
228
	protected function getParts( \Aimeos\MW\View\Iface $view )
229
	{
230
		$available = array(
231
			'address' => \Aimeos\MShop\Order\Manager\Base\Base::PARTS_ADDRESS,
232
			'coupon' => \Aimeos\MShop\Order\Manager\Base\Base::PARTS_COUPON,
233
			'product' => \Aimeos\MShop\Order\Manager\Base\Base::PARTS_PRODUCT,
234
			'service' => \Aimeos\MShop\Order\Manager\Base\Base::PARTS_SERVICE,
235
		);
236
237
		$included = explode( ',', $view->param( 'included', 'address,coupon,product,service' ) );
238
239
		$parts = \Aimeos\MShop\Order\Manager\Base\Base::PARTS_NONE;
240
		foreach( $included as $type )
241
		{
242
			if( isset( $available[$type] ) ) {
243
				$parts |= $available[$type];
244
			}
245
		}
246
247
		return $parts;
248
	}
249
250
251
	/**
252
	 * Returns the response object with the rendered header and body
253
	 *
254
	 * @param \Psr\Http\Message\ResponseInterface $response Response object
255
	 * @param \Aimeos\MW\View\Iface $view View instance
256
	 * @param integer $status HTTP status code
257
	 * @param boolean $allow True to allow all HTTP methods, false for GET only
258
	 * @return \Psr\Http\Message\ResponseInterface Modified response object
259
	 */
260
	protected function render( ResponseInterface $response, \Aimeos\MW\View\Iface $view, $status, $allow = true )
261
	{
262
		/** client/jsonapi/basket/standard/template
263
		 * Relative path to the basket JSON API template
264
		 *
265
		 * The template file contains the code and processing instructions
266
		 * to generate the result shown in the JSON API body. The
267
		 * configuration string is the path to the template file relative
268
		 * to the templates directory (usually in client/jsonapi/templates).
269
		 *
270
		 * You can overwrite the template file configuration in extensions and
271
		 * provide alternative templates. These alternative templates should be
272
		 * named like the default one but with the string "default" replaced by
273
		 * an unique name. You may use the name of your project for this. If
274
		 * you've implemented an alternative client class as well, "standard"
275
		 * should be replaced by the name of the new class.
276
		 *
277
		 * @param string Relative path to the template creating the body for the JSON API
278
		 * @since 2017.04
279
		 * @category Developer
280
		 */
281
		$tplconf = 'client/jsonapi/basket/standard/template';
282
		$default = 'basket/default.php';
283
284
		$body = $view->render( $view->config( $tplconf, $default ) );
285
286
		if( $allow === true ) {
287
			$methods = 'DELETE,GET,PATCH,POST';
288
		} else {
289
			$methods = 'GET';
290
		}
291
292
		return $response->withHeader( 'Allow', $methods )
293
			->withHeader( 'Content-Type', 'application/vnd.api+json' )
294
			->withBody( $view->response()->createStreamFromString( $body ) )
295
			->withStatus( $status );
296
	}
297
}
298