Passed
Push — master ( 4ede65...0180bc )
by Peter
02:42
created

Page::protectPostData()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
c 0
b 0
f 0
nc 2
nop 2
dl 0
loc 17
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Website\Service\Execute;
6
7
use AbterPhp\Admin\Service\Execute\RepoServiceAbstract;
8
use AbterPhp\Framework\Constant\Session;
9
use AbterPhp\Framework\Domain\Entities\IStringerEntity;
10
use AbterPhp\Website\Constant\Authorization;
11
use AbterPhp\Website\Domain\Entities\Page as Entity;
12
use AbterPhp\Website\Domain\Entities\Page\Assets;
13
use AbterPhp\Website\Domain\Entities\Page\Meta;
14
use AbterPhp\Website\Domain\Entities\PageCategory;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, AbterPhp\Website\Service\Execute\PageCategory. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
use AbterPhp\Website\Orm\PageRepo as GridRepo;
16
use AbterPhp\Website\Validation\Factory\Page as ValidatorFactory;
17
use Casbin\Enforcer;
18
use Cocur\Slugify\Slugify;
19
use Opulence\Events\Dispatchers\IEventDispatcher;
20
use Opulence\Http\Requests\UploadedFile;
21
use Opulence\Orm\IUnitOfWork;
22
use Opulence\Sessions\ISession;
23
24
class Page extends RepoServiceAbstract
25
{
26
    /** @var Slugify */
27
    protected $slugify;
28
29
    /** @var GridRepo */
30
    protected $repo;
31
32
    /** @var ISession */
33
    protected $session;
34
35
    /** @var Enforcer */
36
    protected $enforcer;
37
38
    /**
39
     * Page constructor.
40
     *
41
     * @param GridRepo         $repo
42
     * @param ValidatorFactory $validatorFactory
43
     * @param IUnitOfWork      $unitOfWork
44
     * @param IEventDispatcher $eventDispatcher
45
     * @param Slugify          $slugify
46
     * @param ISession         $session
47
     * @param Enforcer         $enforcer
48
     */
49
    public function __construct(
50
        GridRepo $repo,
51
        ValidatorFactory $validatorFactory,
52
        IUnitOfWork $unitOfWork,
53
        IEventDispatcher $eventDispatcher,
54
        Slugify $slugify,
55
        ISession $session,
56
        Enforcer $enforcer
57
    ) {
58
        parent::__construct($repo, $validatorFactory, $unitOfWork, $eventDispatcher);
59
60
        $this->slugify  = $slugify;
61
        $this->session  = $session;
62
        $this->enforcer = $enforcer;
63
    }
64
65
    /**
66
     * @param string $entityId
67
     *
68
     * @return Entity
69
     */
70
    public function createEntity(string $entityId): IStringerEntity
71
    {
72
        return new Entity($entityId, '', '', '', '', '', false);
73
    }
74
75
    /**
76
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
77
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
78
     * @SuppressWarnings(PHPMD.NPathComplexity)
79
     *
80
     * @param IStringerEntity $entity
81
     * @param array           $postData
82
     * @param UploadedFile[]  $fileData
83
     *
84
     * @return Entity
85
     */
86
    protected function fillEntity(IStringerEntity $entity, array $postData, array $fileData): IStringerEntity
87
    {
88
        assert($entity instanceof Entity, new \InvalidArgumentException());
89
90
        $postData = $this->protectPostData($entity, $postData);
91
92
        $title = $postData['title'];
93
94
        $identifier = $postData['identifier'] ?? $entity->getIdentifier();
95
        $identifier = $identifier ?: $title;
96
        $identifier = $this->slugify->slugify($identifier);
97
98
        $classes = $postData['classes'] ?? '';
99
        $lead    = $postData['lead'];
100
        $body    = $postData['body'];
101
102
        $isDraft = !empty($postData['is_draft']);
103
104
        $category = null;
105
        if (!empty($postData['category_id'])) {
106
            $category = new PageCategory($postData['category_id'], '', '');
107
        }
108
109
        $layoutId = $postData['layout_id'];
110
        $layout   = '';
111
        if (empty($layoutId)) {
112
            $layoutId = null;
113
            $layout   = $postData['layout'] ?? '';
114
        }
115
116
        $meta   = $this->getMeta($postData);
117
        $assets = $this->getAssets($postData, $identifier);
118
119
        $entity
120
            ->setIdentifier($identifier)
121
            ->setTitle($title)
122
            ->setClasses($classes)
123
            ->setLead($lead)
124
            ->setBody($body)
125
            ->setIsDraft($isDraft)
126
            ->setCategory($category)
127
            ->setLayoutId($layoutId)
128
            ->setLayout($layout)
129
            ->setMeta($meta)
130
            ->setAssets($assets);
131
132
        return $entity;
133
    }
134
135
    /**
136
     * @param Entity $entity
137
     * @param array  $postData
138
     *
139
     * @return array
140
     * @throws \Casbin\Exceptions\CasbinException
141
     */
142
    protected function protectPostData(Entity $entity, array $postData): array
143
    {
144
        $username        = $this->session->get(Session::USERNAME);
145
        $advancedAllowed = $this->enforcer->enforce(
146
            $username,
147
            Authorization::RESOURCE_PAGES,
148
            Authorization::ROLE_ADVANCED_WRITE
149
        );
150
151
        if ($advancedAllowed) {
152
            return $postData;
153
        }
154
155
        $postData['layout_id'] = $postData['layout_id'] ?? $entity->getLayoutId();
156
        $postData['layout_id'] = $entity->getLayoutId();
157
158
        return $postData;
159
    }
160
161
    /**
162
     * @SuppressWarnings(PHPMD.NPathComplexity)
163
     *
164
     * @param array $postData
165
     *
166
     * @return Meta
167
     */
168
    protected function getMeta(array $postData): Meta
169
    {
170
        $description   = $postData['description'] ?? '';
171
        $robots        = $postData['robots'] ?? '';
172
        $author        = $postData['author'] ?? '';
173
        $copyright     = $postData['copyright'] ?? '';
174
        $keywords      = $postData['keywords'] ?? '';
175
        $ogTitle       = $postData['og-title'] ?? '';
176
        $ogImage       = $postData['og-image'] ?? '';
177
        $ogDescription = $postData['og-description'] ?? '';
178
179
        $entity = new Meta(
180
            $description,
181
            $robots,
182
            $author,
183
            $copyright,
184
            $keywords,
185
            $ogTitle,
186
            $ogImage,
187
            $ogDescription
188
        );
189
190
        return $entity;
191
    }
192
193
    /**
194
     * @SuppressWarnings(PHPMD.NPathComplexity)
195
     *
196
     * @param array  $postData
197
     * @param string $identifier
198
     *
199
     * @return Assets
200
     */
201
    protected function getAssets(array $postData, string $identifier): Assets
202
    {
203
        $header   = $postData['header'] ?? '';
204
        $footer   = $postData['footer'] ?? '';
205
        $cssFiles = empty($postData['css-files']) ? [] : explode('\r\n', $postData['css-files']);
206
        $jsFiles  = empty($postData['js-files']) ? [] : explode('\r\n', $postData['js-files']);
207
208
        return new Assets(
209
            $identifier,
210
            $header,
211
            $footer,
212
            $cssFiles,
213
            $jsFiles,
214
            null
215
        );
216
    }
217
218
    /**
219
     * @param string $entityId
220
     *
221
     * @return IStringerEntity
222
     * @throws \Opulence\Orm\OrmException
223
     */
224
    public function retrieveEntityWithLayout(string $entityId): IStringerEntity
225
    {
226
        $entity = $this->repo->getById($entityId);
227
228
        $entity = $this->repo->getWithLayout($entity->getIdentifier());
229
230
        return $entity;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $entity could return the type null which is incompatible with the type-hinted return AbterPhp\Framework\Domain\Entities\IStringerEntity. Consider adding an additional type-check to rule them out.
Loading history...
231
    }
232
}
233