Completed
Push — master ( b53863...ac109f )
by Aimeos
07:38
created

Factory::createClient()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 59
Code Lines 14

Duplication

Lines 59
Ratio 100 %

Importance

Changes 0
Metric Value
dl 59
loc 59
rs 8.7117
c 0
b 0
f 0
cc 6
eloc 14
nc 8
nop 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\Locale;
12
13
14
/**
15
 * Factory for locale JSON API client
16
 *
17
 * @package Client
18
 * @subpackage JsonApi
19
 */
20 View Code Duplication
class Factory
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in 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...
21
	extends \Aimeos\Client\JsonApi\Common\Factory\Base
0 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\Client\JsonApi\Common\Factory\Iface
0 ignored issues
show
Coding Style introduced by
The implements keyword must be on the same line as the class name
Loading history...
23
{
24
	/**
25
	 * Creates a locale client object.
26
	 *
27
	 * @param \Aimeos\MShop\Context\Item\Iface $context Shop context instance with necessary objects
28
	 * @param array $templatePaths List of file system paths where the templates are stored
29
	 * @param string $path Name of the client separated by slashes, e.g "product"
30
	 * @param string|null $name Client name (default: "Standard")
31
	 * @return \Aimeos\Client\JsonApi\Iface JSON API client
32
	 * @throws \Aimeos\Client\JsonApi\Exception If requested client implementation couldn't be found or initialisation fails
33
	 */
34
	public static function createClient( \Aimeos\MShop\Context\Item\Iface $context, array $templatePaths, $path, $name = null )
35
	{
36
		if( ctype_alnum( $path ) === false )
37
		{
38
			$path = ( is_string( $path ) ? $path : '<not a string>' );
39
			throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid client "%1$s"', $path ), 400 );
40
		}
41
42
		/** client/jsonapi/locale/name
43
		 * Class name of the used locale client implementation
44
		 *
45
		 * Each default JSON API client can be replace by an alternative imlementation.
46
		 * To use this implementation, you have to set the last part of the class
47
		 * name as configuration value so the client factory knows which class it
48
		 * has to instantiate.
49
		 *
50
		 * For example, if the name of the default class is
51
		 *
52
		 *  \Aimeos\Client\JsonApi\Locale\Standard
53
		 *
54
		 * and you want to replace it with your own version named
55
		 *
56
		 *  \Aimeos\Client\JsonApi\Locale\Mylocale
57
		 *
58
		 * then you have to set the this configuration option:
59
		 *
60
		 *  client/jsonapi/locale/name = Mylocale
61
		 *
62
		 * The value is the last part of your own class name and it's case sensitive,
63
		 * so take care that the configuration value is exactly named like the last
64
		 * part of the class name.
65
		 *
66
		 * The allowed characters of the class name are A-Z, a-z and 0-9. No other
67
		 * characters are possible! You should always start the last part of the class
68
		 * name with an upper case character and continue only with lower case characters
69
		 * or numbers. Avoid chamel case names like "MyLocale"!
70
		 *
71
		 * @param string Last part of the class name
72
		 * @since 2017.03
73
		 * @category Developer
74
		 */
75
		if( $name === null ) {
76
			$name = $context->getConfig()->get( 'client/jsonapi/locale/name', 'Standard' );
77
		}
78
79
		if( ctype_alnum( $name ) === false )
80
		{
81
			$classname = is_string( $name ) ? '\\Aimeos\\Client\\JsonApi\\Locale\\' . $name : '<not a string>';
82
			throw new \Aimeos\Client\JsonApi\Exception( sprintf( 'Invalid characters in class name "%1$s"', $classname ) );
83
		}
84
85
		$view = $context->getView();
86
		$iface = '\\Aimeos\\Client\\JsonApi\\Iface';
87
		$classname = '\\Aimeos\\Client\\JsonApi\\Locale\\' . $name;
88
89
		$client = self::createClientBase( $classname, $iface, $context, $view, $templatePaths, $path );
90
91
		return self::addClientDecorators( $client, $context, $view, $templatePaths, $path );
0 ignored issues
show
Bug Best Practice introduced by
The return type of return self::addClientDe...$templatePaths, $path); (Aimeos\Client\JsonApi\Common\Iface) is incompatible with the return type declared by the interface Aimeos\Client\JsonApi\Co...ory\Iface::createClient of type Aimeos\Admin\JsonAdm\Iface.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
92
	}
93
94
}
95
96