TemplateDomain   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 33.33%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 6
dl 0
loc 155
rs 10
c 0
b 0
f 0
ccs 23
cts 69
cp 0.3333

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 1
B resolveTemplateType() 0 18 5
A createLocal() 0 14 3
C createGlobal() 0 36 8
A edit() 0 9 1
A delete() 0 8 1
1
<?php
2
3
namespace Synapse\Cmf\Framework\Theme\Template\Domain;
4
5
use Majora\Framework\Domain\ActionDispatcherDomain;
6
use Majora\Framework\Domain\Action\ActionFactory;
7
use Synapse\Cmf\Framework\Theme\ContentType\Loader\LoaderInterface as ContentTypeLoader;
8
use Synapse\Cmf\Framework\Theme\ContentType\Model\ContentTypeInterface;
9
use Synapse\Cmf\Framework\Theme\Content\Entity\Content;
10
use Synapse\Cmf\Framework\Theme\Content\Model\ContentInterface;
11
use Synapse\Cmf\Framework\Theme\Content\Resolver\ContentResolver;
12
use Synapse\Cmf\Framework\Theme\TemplateType\Loader\LoaderInterface as TemplateTypeLoader;
13
use Synapse\Cmf\Framework\Theme\TemplateType\Model\TemplateTypeInterface;
14
use Synapse\Cmf\Framework\Theme\Template\Model\TemplateInterface;
15
use Synapse\Cmf\Framework\Theme\Zone\Entity\ZoneCollection;
16
17
/**
18
 * Template domain use cases class.
19
 */
20
class TemplateDomain extends ActionDispatcherDomain implements DomainInterface
21
{
22
    /**
23
     * @var ActionFactory
24
     */
25
    protected $commandFactory;
26
27
    /**
28
     * @var ContentResolver
29
     */
30
    protected $contentResolver;
31
32
    /**
33
     * @var ContentTypeLoader
34
     */
35
    protected $contentTypeLoader;
36
37
    /**
38
     * @var TemplateTypeLoader
39
     */
40
    protected $templateTypeLoader;
41
42
    /**
43
     * Construct.
44
     *
45
     * @param ActionFactory      $commandFactory
46
     * @param ContentResolver    $contentResolver
47
     * @param ContentTypeLoader  $contentTypeLoader
48
     * @param TemplateTypeLoader $templateTypeLoader
49
     */
50 4
    public function __construct(
51
        ActionFactory $commandFactory,
52
        ContentResolver $contentResolver,
53
        ContentTypeLoader  $contentTypeLoader,
54
        TemplateTypeLoader $templateTypeLoader
55
    ) {
56 4
        parent::__construct($commandFactory);
57
58 4
        $this->commandFactory = $commandFactory; // backward compatibility
59 4
        $this->contentResolver = $contentResolver;
60 4
        $this->contentTypeLoader = $contentTypeLoader;
61 4
        $this->templateTypeLoader = $templateTypeLoader;
62 4
    }
63
64
    /**
65
     * Resolve given template type name as TemplateType object.
66
     *
67
     * @param mixed $templateType
68
     *
69
     * @return TemplateTypeInterface
70
     *
71
     * @throws InvalidArgumentException If template type isnt a TemplateTypeInterface or an unknown name
72
     */
73 4
    private function resolveTemplateType($templateType)
74
    {
75 4
        if (is_string($templateType)
76 4
            && !$templateType = $this->templateTypeLoader->retrieve($templateTypeName = $templateType)) {
77
            throw new \InvalidArgumentException(sprintf('Given template type name is invalid, "%s" given.',
78
                $templateTypeName
79
            ));
80
        }
81 4
        if ($templateType instanceof TemplateTypeInterface) {
82 4
            return $templateType;
83
        }
84
85
        throw new \InvalidArgumentException(sprintf(
86
            '%s only supports template type names or template type objects, "%s" given.',
87
            __CLASS__,
88
            is_object($templateType) ? get_class($templateType) : $templateType
89
        ));
90
    }
91
92
    /**
93
     * @see DomainInterface::createLocal()
94
     */
95 4
    public function createLocal($content, $templateType, ZoneCollection $zones = null)
96
    {
97
        // create and resolve promise
98 4
        return $this->commandFactory
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Majora\Framework\Domain\Action\ActionInterface as the method setContent() does only exist in the following implementations of said interface: Synapse\Cmf\Framework\Th...mand\CreateLocalCommand.

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...
99 4
            ->createAction('create_local')
100 4
                ->setContent($content instanceof Content
101 3
                    ? $content
102 4
                    : $this->contentResolver->resolve($content)
103 2
                )
104 4
                ->setTemplateType($this->resolveTemplateType($templateType))
105 4
                ->setZones($zones ?: new ZoneCollection())
106 4
            ->resolve()
107 2
        ;
108
    }
109
110
    /**
111
     * @see DomainInterface::createGlobal()
112
     */
113
    public function createGlobal($contentType, $templateType, ZoneCollection $zones = null)
114
    {
115
        // resolve given content as content type
116
        switch (true) {
117
118
            case is_string($contentType) && is_a($contentType, ContentInterface::class, true):
119
                $contentType = $this->contentTypeTypeLoader->retrieveByContentClass($contentType);
0 ignored issues
show
Bug introduced by
The property contentTypeTypeLoader does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
120
                break;
121
122
            case $contentType instanceof Content:
123
                $contentType = $contentType->getType();
124
                break;
125
126
            case is_string($contentType):
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
127
                $contentType = $this->contentTypeLoader->retrieve($contentType);
128
129
            case $contentType instanceof ContentTypeInterface:
130
                break;
131
132
            default:
133
                throw new \InvalidArgumentException(sprintf(
134
                    '%s() only supports content class or object, or content object or name, "%s" given.',
135
                    __CLASS__,
136
                    is_object($contentType) ? get_class($contentType) : $contentType
137
                ));
138
        }
139
140
        // create and resolve promise
141
        return $this->commandFactory
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Majora\Framework\Domain\Action\ActionInterface as the method setContentType() does only exist in the following implementations of said interface: Synapse\Cmf\Framework\Th...and\CreateGlobalCommand.

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...
142
            ->createAction('create_global')
143
                ->setContentType($contentType)
144
                ->setTemplateType($this->resolveTemplateType($templateType))
145
                ->setZones($zones ?: new ZoneCollection())
146
            ->resolve()
147
        ;
148
    }
149
150
    /**
151
     * @see DomainInterface::edit()
152
     */
153
    public function edit(TemplateInterface $template, ...$arguments)
154
    {
155
        return $this->commandFactory
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Majora\Framework\Domain\Action\ActionInterface as the method init() does only exist in the following implementations of said interface: Majora\Framework\Domain\Action\AbstractAction, Synapse\Cmf\Framework\Me...e\Action\AbstractAction, Synapse\Cmf\Framework\Me...n\Dal\AbstractDalAction, Synapse\Cmf\Framework\Me...Action\Dal\CreateAction, Synapse\Cmf\Framework\Me...Action\Dal\UploadAction, Synapse\Cmf\Framework\Me...e\Action\AbstractAction, Synapse\Cmf\Framework\Me...n\Dal\AbstractDalAction, Synapse\Cmf\Framework\Me...Action\Dal\CreateAction, Synapse\Cmf\Framework\Me...Action\Dal\DeleteAction, Synapse\Cmf\Framework\Me...Action\Dal\UpdateAction, Synapse\Cmf\Framework\Me...e\Action\AbstractAction, Synapse\Cmf\Framework\Me...n\Dal\AbstractDalAction, Synapse\Cmf\Framework\Me...Action\Dal\CreateAction, Synapse\Cmf\Framework\Me...Action\Dal\DeleteAction, Synapse\Cmf\Framework\Me...Action\Dal\FormatAction, Synapse\Cmf\Framework\Me...Action\Dal\UpdateAction, Synapse\Cmf\Framework\Me...Action\Dal\UploadAction, Synapse\Cmf\Framework\Th...n\Command\DeleteCommand, Synapse\Cmf\Framework\Th...n\Command\UpdateCommand, Synapse\Cmf\Framework\Th...n\Command\UpdateCommand, Synapse\Cmf\Framework\Th...and\AddComponentCommand, Synapse\Cmf\Framework\Th...\RemoveComponentCommand, Synapse\Cmf\Framework\Th...n\Command\UpdateCommand, Synapse\Page\Bundle\Action\Page\AbstractAction, Synapse\Page\Bundle\Action\Page\CreateAction, Synapse\Page\Bundle\Action\Page\DeleteAction, Synapse\Page\Bundle\Action\Page\UpdateAction.

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...
156
            ->createAction('update')
157
                ->init($template)
158
                ->denormalize($arguments)
159
            ->resolve()
160
        ;
161
    }
162
163
    /**
164
     * @see DomainInterface::delete()
165
     */
166
    public function delete(TemplateInterface $template)
167
    {
168
        return $this->commandFactory
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Majora\Framework\Domain\Action\ActionInterface as the method init() does only exist in the following implementations of said interface: Majora\Framework\Domain\Action\AbstractAction, Synapse\Cmf\Framework\Me...e\Action\AbstractAction, Synapse\Cmf\Framework\Me...n\Dal\AbstractDalAction, Synapse\Cmf\Framework\Me...Action\Dal\CreateAction, Synapse\Cmf\Framework\Me...Action\Dal\UploadAction, Synapse\Cmf\Framework\Me...e\Action\AbstractAction, Synapse\Cmf\Framework\Me...n\Dal\AbstractDalAction, Synapse\Cmf\Framework\Me...Action\Dal\CreateAction, Synapse\Cmf\Framework\Me...Action\Dal\DeleteAction, Synapse\Cmf\Framework\Me...Action\Dal\UpdateAction, Synapse\Cmf\Framework\Me...e\Action\AbstractAction, Synapse\Cmf\Framework\Me...n\Dal\AbstractDalAction, Synapse\Cmf\Framework\Me...Action\Dal\CreateAction, Synapse\Cmf\Framework\Me...Action\Dal\DeleteAction, Synapse\Cmf\Framework\Me...Action\Dal\FormatAction, Synapse\Cmf\Framework\Me...Action\Dal\UpdateAction, Synapse\Cmf\Framework\Me...Action\Dal\UploadAction, Synapse\Cmf\Framework\Th...n\Command\DeleteCommand, Synapse\Cmf\Framework\Th...n\Command\UpdateCommand, Synapse\Cmf\Framework\Th...n\Command\UpdateCommand, Synapse\Cmf\Framework\Th...and\AddComponentCommand, Synapse\Cmf\Framework\Th...\RemoveComponentCommand, Synapse\Cmf\Framework\Th...n\Command\UpdateCommand, Synapse\Page\Bundle\Action\Page\AbstractAction, Synapse\Page\Bundle\Action\Page\CreateAction, Synapse\Page\Bundle\Action\Page\DeleteAction, Synapse\Page\Bundle\Action\Page\UpdateAction.

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...
169
            ->createAction('delete')
170
                ->init($template)
171
            ->resolve()
172
        ;
173
    }
174
}
175