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

daycry / auth / 16238137167

03 Jul 2025 11:49AM UTC coverage: 59.854%. Remained the same
16238137167

push

github

daycry
Merge branch 'development' of https://github.com/daycry/auth into development

13 of 21 new or added lines in 4 files covered. (61.9%)

28 existing lines in 2 files now uncovered.

1883 of 3146 relevant lines covered (59.85%)

22.26 hits per line

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

0.0
/src/Commands/DiscoverCommand.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of Daycry Auth.
7
 *
8
 * (c) Daycry <daycry9@proton.me>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace Daycry\Auth\Commands;
15

16
use CodeIgniter\CLI\BaseCommand;
17
use CodeIgniter\CLI\CLI;
18
use CodeIgniter\Config\BaseConfig;
19
use CodeIgniter\I18n\Time;
20
use Daycry\Auth\Entities\Api;
21
use Daycry\Auth\Entities\Controller;
22
use Daycry\Auth\Entities\Endpoint;
23
use Daycry\Auth\Models\ApiModel;
24
use Daycry\Auth\Models\ControllerModel;
25
use Daycry\Auth\Models\EndpointModel;
26
use Daycry\ClassFinder\ClassFinder;
27
use Daycry\ClassFinder\Config\ClassFinder as ClassFinderConfig;
28
use ReflectionClass;
29
use ReflectionMethod;
30

31
class DiscoverCommand extends BaseCommand
32
{
33
    protected $group       = 'Auth';
34
    protected $name        = 'auth:discover';
35
    protected $description = 'Discover classes from namespace to import in database.';
36
    protected Time $timeStart;
37
    protected BaseConfig $config;
38
    protected array $allClasses = [];
39

40
    public function run(array $params): void
41
    {
42
        $this->timeStart = Time::now()->subSeconds(1);
×
43
        /** @var ClassFinderConfig $finderConfig */
44
        $finderConfig                  = config('ClassFinder');
×
45
        $finderConfig->finder['files'] = false;
×
46

47
        $api = $this->_checkApiModel();
×
48

49
        foreach (service('settings')->get('Auth.namespaceScope') as $namespace) {
×
50
            // remove "\" for search in class-finder
51
            $namespace = (mb_substr($namespace, 0, 1) === '\\') ? mb_substr($namespace, 1) : $namespace;
×
52

53
            $classes = (new ClassFinder($finderConfig))->getClassesInNamespace($namespace, ClassFinder::RECURSIVE_MODE | ClassFinder::ALLOW_CLASSES);
×
54
            if ($classes) {
×
55
                foreach ($classes as $class) {
×
56
                    $this->allClasses[] = '\\' . $class;
×
57

58
                    $methods = $this->_getMethodsFromCLass($class);
×
59

60
                    $class = (mb_substr($class, 0, 1) !== '\\') ? '\\' . $class : $class;
×
61

62
                    $this->_checkClassController($api, $class, $methods);
×
63
                }
64

65
                unset($classes);
×
66
            }
67
        }
68

69
        $controllerModel = new ControllerModel();
×
70
        $allControllers  = $controllerModel->where('api_id', $api->id)->findColumn('controller');
×
71
        if ($allControllers) {
×
72
            $forRemove = array_diff($allControllers, $this->allClasses);
×
73

NEW
74
            if (! empty($forRemove)) {
×
NEW
75
                $controllerModel->where('api_id', $api->id)
×
NEW
76
                    ->whereIn('controller', $forRemove)
×
NEW
77
                    ->delete();
×
78
            }
79
        }
80

UNCOV
81
        CLI::write('**** FINISHED. ****', 'white', 'green');
×
82
    }
83

84
    private function _checkApiModel(): Api
85
    {
UNCOV
86
        $apiModel = new ApiModel();
×
87
        /** @var ?Api $api */
UNCOV
88
        $api = $apiModel->where('url', site_url())->first();
×
89

90
        if (! $api) {
×
91
            $api = new Api();
×
92
            $api->fill(['url' => site_url()]);
×
93
            $apiModel->save($api);
×
UNCOV
94
            $api->id = $apiModel->getInsertID();
×
95
        } else {
96
            $api->fill(['checked_at' => Time::now()]);
×
UNCOV
97
            $apiModel->save($api);
×
98
        }
99

UNCOV
100
        return $api;
×
101
    }
102

103
    private function _getMethodsFromCLass($namespace): array
104
    {
105
        $f       = new ReflectionClass($namespace);
×
UNCOV
106
        $methods = [];
×
107

UNCOV
108
        $namespaceConverted = (mb_substr($namespace, 0, 1) !== '\\') ? '\\' . $namespace : $namespace;
×
109

110
        foreach ($f->getMethods(ReflectionMethod::IS_PUBLIC) as $m) {
×
111
            if (! str_starts_with($m->name, '__') && $m->class === $namespace && ! in_array($m->name, service('settings')->get('Auth.excludeMethods'), true)) {
×
UNCOV
112
                $methods[] = $namespaceConverted . '::' . $m->name;
×
113
            }
114
        }
115

UNCOV
116
        return $methods;
×
117
    }
118

119
    private function _checkClassController(Api $api, string $class, array $methods = []): void
120
    {
121
        $controllerModel = new ControllerModel();
×
UNCOV
122
        $controller      = $controllerModel->where('api_id', $api->id)->where('controller', $class)->first();
×
123

124
        if (! $controller) {
×
125
            $controller = new Controller();
×
126
            $controller->fill(['api_id' => $api->id, 'controller' => $class]);
×
127
            $controllerModel->save($controller);
×
UNCOV
128
            $controller->id = $controllerModel->getInsertID();
×
129
        }
130

UNCOV
131
        $endpointModel = new EndpointModel();
×
132

UNCOV
133
        $allMethods = (new EndpointModel())->where('controller_id', $controller->id)->findColumn('method');
×
134

135
        foreach ($methods as $method) {
×
UNCOV
136
            $endpoint = $endpointModel->where('controller_id', $controller->id)->where('method', $method)->first();
×
137

138
            if (! $endpoint) {
×
139
                $endpoint = new Endpoint();
×
140
                $endpoint->fill(['controller_id' => $controller->id, 'method' => $method]);
×
141
                $endpointModel->save($endpoint);
×
UNCOV
142
                $endpoint->id = $endpointModel->getInsertID();
×
143
            }
144

145
            $endpoint->checked_at = Time::now();
×
UNCOV
146
            $endpointModel->save($endpoint);
×
147
        }
148

149
        if ($allMethods) {
×
UNCOV
150
            $forRemove = array_diff($allMethods, $methods);
×
151

NEW
152
            if (! empty($forRemove)) {
×
NEW
153
                $endpointModel->where('controller_id', $controller->id)
×
NEW
154
                    ->whereIn('method', $forRemove)
×
NEW
155
                    ->delete();
×
156
            }
157
        }
158

UNCOV
159
        $controller->checked_at = Time::now();
×
UNCOV
160
        $controllerModel->save($controller);
×
161
    }
162
}
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