Passed
Push — master ( a228a3...2f45dd )
by Chris
14:02
created

ModelPrinter::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 3
nc 1
nop 5
dl 0
loc 11
ccs 0
cts 4
cp 0
crap 2
rs 10
c 1
b 0
f 1
1
<?php
2
3
namespace Leonidas\Console\Library;
4
5
use Leonidas\Console\Library\Abstracts\AbstractTypedClassPrinter;
6
use Leonidas\Contracts\System\Model\CommentableInterface;
7
use Leonidas\Contracts\System\Model\FilterableInterface;
8
use Leonidas\Contracts\System\Model\HierarchicalInterface;
9
use Leonidas\Contracts\System\Model\MimeInterface;
10
use Leonidas\Contracts\System\Model\MutableAuthoredInterface;
11
use Leonidas\Contracts\System\Model\MutableContentInterface;
12
use Leonidas\Contracts\System\Model\MutableDatableInterface;
13
use Leonidas\Contracts\System\Model\MutablePostModelInterface;
14
use Leonidas\Contracts\System\Model\MutableTermModelInterface;
15
use Leonidas\Contracts\System\Model\MutableUserModelInterface;
16
use Leonidas\Contracts\System\Model\PingableInterface;
17
use Leonidas\Contracts\System\Model\RestrictableInterface;
18
use Leonidas\Contracts\Util\AutoInvokerInterface;
19
use Leonidas\Library\System\Model\Abstracts\AllAccessGrantedTrait;
20
use Leonidas\Library\System\Model\Abstracts\LazyLoadableRelationshipsTrait;
21
use Leonidas\Library\System\Model\Abstracts\Post\FilterablePostModelTrait;
22
use Leonidas\Library\System\Model\Abstracts\Post\HierarchicalPostModelTrait;
23
use Leonidas\Library\System\Model\Abstracts\Post\MimePostModelTrait;
24
use Leonidas\Library\System\Model\Abstracts\Post\MutableAuthoredPostModelTrait;
25
use Leonidas\Library\System\Model\Abstracts\Post\MutableCommentablePostModelTrait;
26
use Leonidas\Library\System\Model\Abstracts\Post\MutableContentPostModelTrait;
27
use Leonidas\Library\System\Model\Abstracts\Post\MutableDatablePostModelTrait;
28
use Leonidas\Library\System\Model\Abstracts\Post\MutablePingablePostModelTrait;
29
use Leonidas\Library\System\Model\Abstracts\Post\MutablePostModelTrait;
30
use Leonidas\Library\System\Model\Abstracts\Post\RestrictablePostModelTrait;
31
use Leonidas\Library\System\Model\Abstracts\Post\ValidatesPostTypeTrait;
32
use Leonidas\Library\System\Model\Abstracts\Term\HierarchicalTermTrait;
33
use Leonidas\Library\System\Model\Abstracts\Term\MutableTermModelTrait;
34
use Leonidas\Library\System\Model\Abstracts\Term\ValidatesTaxonomyTrait;
35
use Leonidas\Library\System\Model\Abstracts\User\MutableUserModelTrait;
36
use Leonidas\Library\System\Model\Abstracts\User\ValidatesRoleTrait;
37
use Nette\PhpGenerator\PhpNamespace;
38
use ReflectionClass;
39
use WP_Comment;
0 ignored issues
show
Bug introduced by
The type WP_Comment was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
40
use WP_Post;
41
use WP_Term;
0 ignored issues
show
Bug introduced by
The type WP_Term was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
42
use WP_User;
0 ignored issues
show
Bug introduced by
The type WP_User was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
43
44
class ModelPrinter extends AbstractTypedClassPrinter
45
{
46
    public const TEMPLATES = [
47
        'post' => WP_Post::class,
48
        'post:h' => WP_Post::class,
49
        'attachment' => WP_Post::class,
50
        'term' => WP_Term::class,
51
        'term:h' => WP_Term::class,
52
        'user' => WP_User::class,
53
        // 'comment' => WP_Comment::class,
54
    ];
55
56
    public const CORES = [
57
        'post' => 'post',
58
        'post:h' => 'post',
59
        'attachment' => 'post',
60
        'term' => 'term',
61
        'term:h' => 'term',
62
        'user' => 'user',
63
        // 'comment' => 'comment',
64
    ];
65
66
    public const VALIDATORS = [
67
        'post' => ValidatesPostTypeTrait::class,
68
        'post:h' => ValidatesPostTypeTrait::class,
69
        'attachment' => ValidatesPostTypeTrait::class,
70
        'term' => ValidatesTaxonomyTrait::class,
71
        'user' => ValidatesRoleTrait::class,
72
    ];
73
74
    public const ASSERTIONS = [
75
        'post' => "\$this->assertPostType($%s, '%s');",
76
        'post:h' => "\$this->assertPostType($%s, '%s');",
77
        'attachment' => "\$this->assertPostType($%s, '%s');",
78
        'term' => "\$this->assertTaxonomy($%s, '%s');",
79
        'term:h' => "\$this->assertTaxonomy($%s, '%s');",
80
        'user' => "\$this->assertRole($%s, '%s');",
81
    ];
82
83
    public const PARTIALS = [
84
        'post' => [
85
            FilterableInterface::class => FilterablePostModelTrait::class,
86
            MutableAuthoredInterface::class => MutableAuthoredPostModelTrait::class,
87
            MutableContentInterface::class => MutableContentPostModelTrait::class,
88
            MutablePostModelInterface::class => MutablePostModelTrait::class,
89
            PingableInterface::class => MutablePingablePostModelTrait::class,
90
            CommentableInterface::class => MutableCommentablePostModelTrait::class,
91
            RestrictableInterface::class => RestrictablePostModelTrait::class,
92
            MimeInterface::class => MimePostModelTrait::class,
93
            MutableDatableInterface::class => MutableDatablePostModelTrait::class,
94
        ],
95
        'post:h' => [
96
            '@post',
97
            HierarchicalInterface::class => HierarchicalPostModelTrait::class,
98
        ],
99
        'attachment' => [
100
            '@post',
101
        ],
102
        'term' => [
103
            MutableTermModelInterface::class => MutableTermModelTrait::class,
104
        ],
105
        'term:h' => [
106
            '@term',
107
            HierarchicalInterface::class => HierarchicalTermTrait::class,
108
        ],
109
        'user' => [
110
            MutableUserModelInterface::class => MutableUserModelTrait::class,
111
        ],
112
        // 'comment' => [],
113
    ];
114
115
    protected string $entity;
116
117
    protected string $template;
118
119
    public function __construct(
120
        string $namespace,
121
        string $class,
122
        string $type,
123
        string $entity,
124
        string $template = 'post'
125
    ) {
126
        parent::__construct($namespace, $class, $type);
127
128
        $this->entity = $entity;
129
        $this->template = $template;
130
    }
131
132
    protected function setupClass(PhpNamespace $namespace)
133
    {
134
        $accessTrait = AllAccessGrantedTrait::class;
135
        $lazyLoadTrait = LazyLoadableRelationshipsTrait::class;
136
        $invoker = AutoInvokerInterface::class;
137
        $template = static::TEMPLATES[$this->template];
138
        $core = static::CORES[$this->template];
139
        $validator = static::VALIDATORS[$this->template];
140
        $assertion = static::ASSERTIONS[$this->template];
141
142
        $class = $namespace
143
            ->addUse($this->type)
144
            ->addUse($accessTrait)
145
            ->addUse($lazyLoadTrait)
146
            ->addUse($validator)
147
            ->addUse($invoker)
148
            ->addUse($template)
149
            ->addClass($this->class);
150
151
        $class->addImplement($this->type);
152
        $class->addTrait($accessTrait);
153
        $class->addTrait($lazyLoadTrait);
154
        $class->addTrait($validator);
155
156
        foreach ($this->getResolvedPartials() as $partial) {
157
            $namespace->addUse($partial);
158
            $class->addTrait($partial);
159
        }
160
161
        $constructor = $class->addMethod('__construct')->setPublic();
162
163
        $constructor->addParameter($core)->setType($template);
164
        $constructor->addParameter('autoInvoker')->setType($invoker);
165
166
        $constructor->addBody(sprintf($assertion, $core, $this->entity) . "\n");
167
        $constructor->addBody(sprintf('$this->%s = $%s;', $core, $core));
168
        $constructor->addBody('$this->autoInvoker = $autoInvoker;' . "\n");
169
170
        $getAccessTemplate = $this->isPostTemplate()
171
            ? '$this->getAccessProvider = new %sTemplateTags($this, $%s);'
172
            : '$this->getAccessProvider = new %sGetAccessProvider($this);';
173
174
        $constructor->addBody(sprintf($getAccessTemplate, $this->class, $core));
175
        $constructor->addBody(sprintf(
176
            '$this->setAccessProvider = new %sSetAccessProvider($this);',
177
            $this->class
178
        ));
179
180
        return $class;
181
    }
182
183
    protected function isPostTemplate(): bool
184
    {
185
        return in_array($this->template, ['post', 'post:h', 'attachment']);
186
    }
187
188
    protected function getResolvedPartials(): array
189
    {
190
        $partials = [];
191
192
        foreach (static::PARTIALS[$this->template] as $partial) {
193
            if (str_starts_with($partial, '@')) {
194
                $partials = array_merge(
195
                    static::PARTIALS[substr($partial, 1)],
196
                    $partials
197
                );
198
            } else {
199
                $partials[] = $partial;
200
            }
201
        }
202
203
        if ($this->isDoingTypeMatch()) {
204
            $reflection = new ReflectionClass($this->type);
205
            $extensions = $reflection->getInterfaceNames();
206
207
            $partials = array_filter(
208
                $partials,
209
                fn ($contract) => in_array($contract, $extensions),
210
                ARRAY_FILTER_USE_KEY
211
            );
212
        }
213
214
        return $partials;
215
    }
216
}
217