• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bvlion / AppTanServer / 20205654148

14 Dec 2025 09:04AM UTC coverage: 25.627%. First build
20205654148

push

github

bvlion
format

12 of 49 new or added lines in 18 files covered. (24.49%)

143 of 558 relevant lines covered (25.63%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Application/Service/SearchWord/MasterProjectionService.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace App\Application\Service\SearchWord;
6

7
use App\Domain\SearchWordEvent\EventType;
8
use App\Domain\SearchWordEvent\SearchWordEvent;
9
use App\Domain\SearchWordEvent\SearchWordEventRepository;
10
use App\Domain\SearchWordsMaster\SearchWordsMaster;
11
use App\Domain\SearchWordsMaster\SearchWordsMasterRepository;
12

13
class MasterProjectionService
14
{
15
  public function __construct(
16
    private SearchWordEventRepository $eventRepository,
17
    private SearchWordsMasterRepository $masterRepository,
18
    private AIWordGenerator $generator,
19
    private GcfCaller $gcfCaller
20
  ) {
NEW
21
  }
×
22

23
  public function updateFromInitOrRefresh(SearchWordEvent $event): void
24
  {
25
    $package = $event->getPackageName();
×
26
    $appName = $event->getWord();
×
27
    $description = $event->getContext()['description'] ?? null;
×
28

29
    if (!$this->masterRepository->existsGeneratedWords($package, $appName)) {
×
30
      $words = $this->generator->generateWords($package, $appName, $description);
×
31
      $hasLowWeight = false;
×
32
      foreach ($words as $word) {
×
33
        if ($word['weight'] <= 65) {
×
34
          $hasLowWeight = true;
×
35
          break;
×
36
        }
37
      }
38
      // 2つの読みと5個未満の単語と、タイトルとパッケージだけでは生成できない場合は1度スクレイピングする
NEW
39
      if ((count($words) < 7 || $hasLowWeight) && $event->getEventType() !== EventType::ScrapingInit) {
×
40
        $newEvent = new SearchWordEvent(
×
41
          id: null,
×
42
          packageName: $package,
×
43
          word: $appName,
×
44
          eventType: EventType::ScrapingInit,
×
45
          context: ['description' => $this->gcfCaller->fetchDescriptionByPackageName($package)],
×
46
          timestamp: new \DateTime()
×
47
        );
×
48
        $this->eventRepository->save($newEvent);
×
49
        $this->updateFromInitOrRefresh($newEvent);
×
50
        return;
×
51
      }
52
      foreach ($words as $word) {
×
53
        $kana = $this->getKana($word['word']);
×
54
        $this->masterRepository->insert(new SearchWordsMaster(
×
55
          packageName: $package,
×
56
          word: $word['word'],
×
57
          kana: $kana,
×
58
          appName: $appName
×
59
        ));
×
60
        $this->eventRepository->save(new SearchWordEvent(
×
61
          id: null,
×
62
          packageName: $package,
×
63
          word: $word['word'],
×
64
          eventType: EventType::AiGenerated,
×
65
          eventWeight: $word['weight'] / 100,
×
66
          context: ['app_name' => $appName, 'kana' => $kana],
×
67
          timestamp: new \DateTime()
×
68
        ));
×
69
      }
70
    }
71
  }
72

73
  public function registerGeneratedWord(SearchWordEvent $event): void
74
  {
75
    $package = $event->getPackageName();
×
76
    $word = $event->getWord();
×
77
    $appName = $event->getContext()['app_name'] ?? '';
×
78
    $kana = $event->getContext()['kana'] ?? '';
×
79

80
    if (!$this->masterRepository->exists($package, $word, $appName)) {
×
81
      $this->masterRepository->insert(new SearchWordsMaster(
×
82
        packageName: $package,
×
83
        word: $word,
×
84
        kana: $kana,
×
85
        appName: $appName,
×
86
        source: 'imported'
×
87
      ));
×
88
    }
89
  }
90

91
  private function getKana(string $word): string
92
  {
93
    exec('echo ' . escapeshellarg($word) . ' | ' . $_ENV['MECAB_PATH'] . ' -Oyomi', $res);
×
94
    if (count($res) === 0) {
×
95
      return '';
×
96
    }
97
    return preg_replace_callback('/[ァ-ヶー]+/u', function ($matches) {
×
NEW
98
        return mb_convert_kana($matches[0], 'c', 'UTF-8');
×
99
    }, $res[0]);
×
100
  }
101
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc