Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 163
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
AccountUserPluginLogic
0.00% covered (danger)
0.00%
0 / 163
0.00% covered (danger)
0.00%
0 / 5
812
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 startup
0.00% covered (danger)
0.00%
0 / 39
0.00% covered (danger)
0.00%
0 / 1
42
 validateImpl
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
30
 executeImpl
0.00% covered (danger)
0.00%
0 / 76
0.00% covered (danger)
0.00%
0 / 1
156
 cleanup
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5namespace PeServer\App\Models\Domain\Page\Account;
6
7use PeServer\App\Models\AppDatabaseCache;
8use PeServer\App\Models\AuditLog;
9use PeServer\App\Models\Dao\Entities\PluginCategoriesEntityDao;
10use PeServer\App\Models\Dao\Entities\PluginCategoryMappingsEntityDao;
11use PeServer\App\Models\Dao\Entities\PluginsEntityDao;
12use PeServer\App\Models\Dao\Entities\PluginUrlsEntityDao;
13use PeServer\App\Models\Data\Dto\PluginCategoryDto;
14use PeServer\App\Models\Domain\Page\PageLogicBase;
15use PeServer\App\Models\Domain\PluginState;
16use PeServer\App\Models\Domain\PluginUrlKey;
17use PeServer\App\Models\Domain\PluginValidator;
18use PeServer\App\Models\SessionKey;
19use PeServer\Core\Collection\Arr;
20use PeServer\Core\Database\DatabaseTableResult;
21use PeServer\Core\Database\IDatabaseContext;
22use PeServer\Core\Http\HttpStatus;
23use PeServer\Core\I18n;
24use PeServer\Core\Mvc\LogicCallMode;
25use PeServer\Core\Mvc\LogicParameter;
26use PeServer\Core\Text;
27use PeServer\Core\Throws\HttpStatusException;
28use PeServer\Core\TypeUtility;
29use PeServer\Core\Uuid;
30
31class AccountUserPluginLogic extends PageLogicBase
32{
33    /**
34     * 新規作成か。
35     *
36     * 編集時は偽になる。
37     *
38     * @var boolean
39     */
40    private bool $isRegister;
41
42    /**
43     * プラグインカテゴリ一覧。
44     *
45     * @var PluginCategoryDto[]
46     */
47    private array $pluginCategories = [];
48
49    public function __construct(LogicParameter $parameter, private AppDatabaseCache $dbCache, bool $isRegister)
50    {
51        parent::__construct($parameter);
52
53        $this->isRegister = $isRegister;
54    }
55
56    #region PageLogicBase
57
58    protected function startup(LogicCallMode $callMode): void
59    {
60        $keys = [
61            'account_plugin_plugin_id',
62            'account_plugin_plugin_name',
63            'account_plugin_display_name',
64            'account_plugin_check_url',
65            'account_plugin_lp_url',
66            'account_plugin_project_url',
67            'account_plugin_description',
68            'account_plugin_state',
69            'plugin_categories',
70            'plugin_category_ids',
71            'plugin_category_mappings',
72        ];
73
74        $database = $this->openDatabase();
75        $pluginCategoriesEntityDao = new PluginCategoriesEntityDao($database);
76        $this->pluginCategories = $pluginCategoriesEntityDao->selectAllPluginCategories();
77
78        foreach ($this->pluginCategories as $category) {
79            $keys[] = 'plugin_category_' . $category->pluginCategoryId;
80        }
81
82        if (!$this->isRegister) {
83            $keys = array_merge($keys, [
84                'from_account_plugin_plugin_id',
85            ]);
86        }
87
88        $this->registerParameterKeys($keys, true);
89
90        if (!$this->isRegister) {
91            $pluginId = Uuid::adjustGuid($this->getRequest('plugin_id'));
92
93            if ($callMode === LogicCallMode::Initialize) {
94                $this->setValue('account_plugin_plugin_id', $pluginId);
95                $this->setValue('from_account_plugin_plugin_id', $pluginId);
96            } else {
97                $fromPluginId = $this->getRequest('from_account_plugin_plugin_id');
98                // プラグインIDが変更されているので死んでもらう(二つとも合うように加工された場合はもう無理、要求を粛々と処理する)
99                if (!Uuid::isEqualGuid($pluginId, $fromPluginId)) {
100                    throw new HttpStatusException(HttpStatus::BadRequest);
101                }
102                // プラグインIDとプラグイン名は原本を使用する
103                $database = $this->openDatabase();
104                $pluginsEntityDao = new PluginsEntityDao($database);
105                // ルーティングでこのプラグイン所有者が保証されているのでプラグインIDのみで取得
106                $map = $pluginsEntityDao->selectPluginIds($pluginId);
107                $this->setValue('account_plugin_plugin_id', $map->fields['plugin_id']);
108                $this->setValue('account_plugin_plugin_name', $map->fields['plugin_name']);
109                $this->setValue('account_plugin_state', $map->fields['plugin_name']);
110            }
111        } else {
112            $this->setValue('account_plugin_state', Text::EMPTY);
113            $this->setValue('plugin_category_mappings', []);
114        }
115    }
116
117    protected function validateImpl(LogicCallMode $callMode): void
118    {
119        if ($callMode === LogicCallMode::Initialize) {
120            return;
121        }
122
123        if ($this->isRegister) {
124            $this->validation('account_plugin_plugin_id', function (string $key, string $value) {
125                $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
126                if ($pluginValidator->isPluginId($key, $value)) {
127                    $database = $this->openDatabase();
128                    $pluginValidator->isFreePluginId($database, $key, $value);
129                }
130            });
131            $this->validation('account_plugin_plugin_name', function (string $key, string $value) {
132                $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
133                if ($pluginValidator->isPluginName($key, $value)) {
134                    $database = $this->openDatabase();
135                    $pluginValidator->isFreePluginName($database, $key, $value);
136                }
137            });
138        }
139
140        $this->validation('account_plugin_display_name', function (string $key, string $value) {
141            $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
142            $pluginValidator->isDisplayName($key, $value);
143        });
144
145        $this->validation('account_plugin_check_url', function (string $key, string $value) {
146            $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
147            $pluginValidator->isCheckUrl($key, $value);
148        });
149
150        $this->validation('account_plugin_lp_url', function (string $key, string $value) {
151            $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
152            $pluginValidator->isWebsite($key, $value);
153        });
154
155        $this->validation('account_plugin_project_url', function (string $key, string $value) {
156            $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
157            $pluginValidator->isWebsite($key, $value);
158        });
159
160        $this->validation('account_plugin_description', function (string $key, string $value) {
161            $pluginValidator = new PluginValidator($this, $this->validator, $this->environment);
162            $pluginValidator->isDescription($key, $value);
163        });
164    }
165
166    protected function executeImpl(LogicCallMode $callMode): void
167    {
168        if ($callMode === LogicCallMode::Initialize) {
169            if (!$this->isRegister) {
170                // 既存データを引っ張ってくる
171                $pluginId = $this->getRequest('plugin_id');
172
173                $database = $this->openDatabase();
174                $pluginsEntityDao = new PluginsEntityDao($database);
175                $pluginUrlsEntityDao = new PluginUrlsEntityDao($database);
176                $pluginCategoryMappingsEntityDao = new PluginCategoryMappingsEntityDao($database);
177
178                // ルーティングでこのプラグイン所有者が保証されているのでプラグインIDのみで取得
179                $editMap = $pluginsEntityDao->selectEditPlugin($pluginId);
180                $this->setValue('account_plugin_plugin_name', $editMap->fields['plugin_name']);
181                $this->setValue('account_plugin_display_name', $editMap->fields['display_name']);
182                $this->setValue('account_plugin_description', $editMap->fields['description']);
183
184                $urlMap = $pluginUrlsEntityDao->selectUrls($pluginId);
185                $this->setValue('account_plugin_check_url', $urlMap[PluginUrlKey::CHECK] ?? Text::EMPTY);
186                $this->setValue('account_plugin_lp_url', $urlMap[PluginUrlKey::LANDING] ?? Text::EMPTY);
187                $this->setValue('account_plugin_project_url', $urlMap[PluginUrlKey::PROJECT] ?? Text::EMPTY);
188
189                $pluginCategoryMappings = $pluginCategoryMappingsEntityDao->selectPluginCategoriesByPluginId($pluginId);
190                $this->setValue('plugin_category_mappings', $pluginCategoryMappings);
191            }
192
193            return;
194        }
195
196        $userInfo = $this->requireSession(SessionKey::ACCOUNT);
197
198        $params = [
199            'user_id' => $userInfo->userId,
200            'display_name' => $this->getRequest('account_plugin_display_name'),
201            'urls' => [
202                PluginUrlKey::CHECK => $this->getRequest('account_plugin_check_url'),
203                PluginUrlKey::LANDING => $this->getRequest('account_plugin_lp_url'),
204                PluginUrlKey::PROJECT => $this->getRequest('account_plugin_project_url'),
205            ],
206            'description' => $this->getRequest('account_plugin_description'),
207        ];
208
209        if ($this->isRegister) {
210            $params['plugin_id'] = Uuid::adjustGuid($this->getRequest('account_plugin_plugin_id'));
211            $params['plugin_name'] = $this->getRequest('account_plugin_plugin_name');
212        } else {
213            $params['plugin_id'] = Uuid::adjustGuid($this->getRequest('plugin_id'));
214        }
215
216        $database = $this->openDatabase();
217        $database->transaction(function (IDatabaseContext $context) use ($params) {
218            $pluginsEntityDao = new PluginsEntityDao($context);
219            $pluginUrlsEntityDao = new PluginUrlsEntityDao($context);
220            $pluginCategoryMappingsEntityDao = new PluginCategoryMappingsEntityDao($context);
221
222            $pluginCategories = [];
223            foreach ($this->pluginCategories as $category) {
224                if (TypeUtility::parseBoolean($this->getRequest('plugin_category_' . $category->pluginCategoryId))) {
225                    $pluginCategories[] = $category->pluginCategoryId;
226                }
227            }
228
229            if ($this->isRegister) {
230                $pluginsEntityDao->insertPlugin(
231                    $params['plugin_id'],
232                    $params['user_id'],
233                    $params['plugin_name'], //@phpstan-ignore-line
234                    $params['display_name'],
235                    PluginState::ENABLED,
236                    $params['description'],
237                    Text::EMPTY
238                );
239            } else {
240                $pluginsEntityDao->updateEditPlugin(
241                    $params['plugin_id'],
242                    $params['user_id'],
243                    $params['display_name'],
244                    $params['description']
245                );
246            }
247
248            $pluginUrlsEntityDao->deleteByPluginId($params['plugin_id']);
249            /** @var array<string,string> */
250            $urls = $params['urls'];
251            foreach ($urls as $k => $v) {
252                $pluginUrlsEntityDao->insertUrl($params['plugin_id'], $k, $v);
253            }
254
255            $pluginCategoryMappingsEntityDao->deletePluginCategoryMappings($params['plugin_id']);
256            foreach ($this->pluginCategories as $pluginCategory) {
257                if (TypeUtility::parseBoolean($this->getRequest('plugin_category_' . $pluginCategory->pluginCategoryId))) {
258                    $pluginCategoryMappingsEntityDao->insertPluginCategoryMapping($params['plugin_id'], $pluginCategory->pluginCategoryId);
259                }
260            }
261
262            if ($this->isRegister) {
263                //@phpstan-ignore-next-line
264                $this->writeAuditLogCurrentUser(AuditLog::USER_PLUGIN_REGISTER, ['plugin_id' => $params['plugin_id'], 'plugin_name' => $params['plugin_name']], $context);
265            } else {
266                $this->writeAuditLogCurrentUser(AuditLog::USER_PLUGIN_UPDATE, ['plugin_id' => $params['plugin_id']], $context);
267            }
268
269            return true;
270        });
271
272        $this->result['plugin_id'] = $params['plugin_id'];
273        if ($this->isRegister) {
274            $this->addTemporaryMessage(I18n::message('message/flash/register_plugin'));
275        } else {
276            $this->addTemporaryMessage(I18n::message('message/flash/update_plugin'));
277        }
278        $this->dbCache->exportPluginInformation();
279    }
280
281    protected function cleanup(LogicCallMode $callMode): void
282    {
283        $this->setValue('plugin_categories', $this->pluginCategories);
284
285        $pluginCategoryIds = array_map(function ($i) {
286            return $i->pluginCategoryId;
287        }, $this->pluginCategories);
288        $this->setValue('plugin_category_ids', $pluginCategoryIds);
289
290        if ($callMode === LogicCallMode::Submit) {
291            $pluginCategories = [];
292            foreach ($pluginCategoryIds as $pluginCategoryId) {
293                if (TypeUtility::parseBoolean($this->getRequest('plugin_category_' . $pluginCategoryId))) {
294                    $pluginCategories[] = $pluginCategoryId;
295                }
296            }
297
298            $this->setValue('plugin_category_mappings', $pluginCategories);
299        }
300    }
301
302    #endregion
303}