Completed
Push — master ( 692071...1e7a7e )
by Mahmoud
02:16
created

PortServiceProviderTrait::loadConfigs()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 9.4285
cc 3
eloc 6
nc 3
nop 1
1
<?php
2
3
namespace App\Port\Provider\Traits;
4
5
use App;
6
use App\Port\Butler\Portals\Facade\PortButler;
7
use App\Port\Exception\Exceptions\UnsupportedFractalSerializerException;
8
use DB;
9
use File;
10
use Illuminate\Support\Facades\Config;
11
use Illuminate\Support\Facades\View;
12
use Log;
13
14
/**
15
 * Class PortServiceProviderTrait.
16
 *
17
 * @author  Mahmoud Zalt <[email protected]>
18
 */
19
trait PortServiceProviderTrait
20
{
21
22
    /**
23
     * Write the DB queries in the Log and Display them in the
24
     * terminal (in case you want to see them while executing the tests).
25
     *
26
     * @param bool|false $terminal
27
     */
28
    public function debugDatabaseQueries($log = true, $terminal = false)
29
    {
30
        if (Config::get('database.query_debugging')) {
31
            DB::listen(function ($event) use ($terminal, $log) {
32
                $fullQuery = vsprintf(str_replace(['%', '?'], ['%%', '%s'], $event->sql), $event->bindings);
33
34
                $text = $event->connectionName . ' (' . $event->time . '): ' . $fullQuery;
35
36
                if ($terminal) {
37
                    dump($text);
38
                }
39
40
                if ($log) {
41
                    Log::info($text);
42
                }
43
            });
44
        }
45
    }
46
47
    /**
48
     * By default Laravel takes (server/database/factories) as the
49
     * path to the factories, this function changes the path to load
50
     * the factories from the infrastructure directory.
51
     */
52
    public function changeTheDefaultDatabaseModelsFactoriesPath($customPath)
53
    {
54
        App::singleton(\Illuminate\Database\Eloquent\Factory::class, function ($app) use ($customPath) {
55
            $faker = $app->make(\Faker\Generator::class);
56
57
            return \Illuminate\Database\Eloquent\Factory::construct($faker, base_path() . $customPath);
58
        });
59
    }
60
61
    /**
62
     * Get the containers Service Providers full classes names.
63
     *
64
     * @return  array
65
     */
66
    public function getMainServiceProviders()
67
    {
68
        $containersNamespace = PortButler::getContainersNamespace();
69
70
        $allServiceProviders = [];
71
72
        foreach (PortButler::getContainersNames() as $containerName) {
73
            // append the Module main service provider
74
            $allServiceProviders[] = PortButler::buildMainServiceProvider($containersNamespace, $containerName);
75
        }
76
77
        return array_unique($allServiceProviders) ? : [];
78
    }
79
80
    /**
81
     * Load views from inside the Containers
82
     */
83
    public function autoLoadViewsFromContainers()
84
    {
85
        foreach (PortButler::getContainersNames() as $containerName) {
86
87
            $containerViewDirectory = base_path('app/Containers/' . $containerName . '/UI/WEB/Views/');
88
89
            if (File::isDirectory($containerViewDirectory)) {
90
                View::addLocation($containerViewDirectory);
91
            }
92
        }
93
    }
94
95
    /**
96
     * Load migrations files from Containers to Laravel
97
     */
98
    public function autoMigrationsFromContainers()
99
    {
100
        foreach (PortButler::getContainersNames() as $containerName) {
101
102
            $containerMigrationDirectory = base_path('app/Containers/' . $containerName . '/Data/Migrations');
103
104
            if (File::isDirectory($containerMigrationDirectory)) {
105
106
                App::afterResolving('migrator', function ($migrator) use ($containerMigrationDirectory) {
107
                    foreach ((array)$containerMigrationDirectory as $path) {
108
                        $migrator->path($path);
109
                    }
110
                });
111
            }
112
        }
113
    }
114
115
    /**
116
     * TODO: needs refactoring, was created in 5 min
117
     *
118
     * @return  array
119
     */
120
    public function getAllContainersConsoleCommandsForAutoLoading()
121
    {
122
        $classes = [];
123 View Code Duplication
        foreach (PortButler::getContainersNames() as $containerName) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
124
            $containerCommandsDirectory = base_path('app/Containers/' . $containerName . '/UI/CLI/Commands/');
125
            if (File::isDirectory($containerCommandsDirectory)) {
126
                $files = \File::allFiles($containerCommandsDirectory);
127
                foreach ($files as $consoleFile) {
128
                    if (\File::isFile($consoleFile)) {
129
                        $pathName = $consoleFile->getPathname();
130
                        $classes[] = PortButler::getClassFullNameFromFile($pathName);
131
                    }
132
                }
133
            }
134
        };
135
136
        return $classes;
137
    }
138
139
    /**
140
     * Auto load Containers and Port config files into Laravel
141
     */
142
    public function autoLoadConfigFiles()
143
    {
144
        $this->autoLoadContainersConfigFiles();
145
        $this->autoLoadPortConfigFiles();
146
    }
147
148
    /**
149
     *
150
     */
151
    protected function autoLoadContainersConfigFiles()
152
    {
153
        foreach (PortButler::getContainersNames() as $containerName) {
154
            $this->loadConfigs(base_path('app/Containers/' . $containerName . '/Configs'));
155
        }
156
    }
157
158
    /**
159
     *
160
     */
161
    protected function autoLoadPortConfigFiles()
162
    {
163
        $this->loadConfigs(base_path('app/Port/Configs'));
164
    }
165
166
    /**
167
     * @param $directory
168
     */
169
    private function loadConfigs($directory)
170
    {
171
        if (File::isDirectory($directory)) {
172
173
            $files = File::allFiles($directory);
174
175
            foreach ($files as $file) {
176
                // build the key from the file name (just remove the .php extension from the file name)
177
                $fileNameOnly = str_replace('.php', '', $file->getFilename());
178
179
                // merge the config file
180
                $this->mergeConfigFrom($file->getPathname(), $fileNameOnly);
0 ignored issues
show
Bug introduced by
It seems like mergeConfigFrom() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
181
            }
182
        }
183
    }
184
185
186
    /**
187
     * By default the Dingo API package (in the config file) creates an instance of the
188
     * fractal manager which takes the default serializer (specified by the fractal
189
     * package itself, and there's no way to override change it from the configurations of
190
     * the Dingo package).
191
     *
192
     * Here I am replacing the current default serializer (DataArraySerializer) by the
193
     * (JsonApiSerializer).
194
     *
195
     * "Serializers are what build the final response after taking the transformers data".
196
     */
197
    public function overrideDefaultFractalSerializer()
198
    {
199
        $serializerName = Config::get('api.serializer');
200
201
        // if DataArray `\League\Fractal\Serializer\DataArraySerializer` do noting since it's set by default by the Dingo API
202
        if ($serializerName !== 'DataArray') {
203
            app('Dingo\Api\Transformer\Factory')->setAdapter(function () use ($serializerName) {
204
                switch ($serializerName) {
205
                    case 'JsonApi':
206
                        $serializer = new \League\Fractal\Serializer\JsonApiSerializer(Config::get('api.domain'));
207
                        break;
208
                    case 'Array':
209
                        $serializer = new \League\Fractal\Serializer\ArraySerializer(Config::get('api.domain'));
210
                        break;
211
                    default:
212
                        throw new UnsupportedFractalSerializerException('Unsupported ' . $serializerName);
213
                }
214
215
                $fractal = new \League\Fractal\Manager();
216
                $fractal->setSerializer($serializer);
217
218
                return new \Dingo\Api\Transformer\Adapter\Fractal($fractal, 'include', ',', false);
219
            });
220
        }
221
    }
222
}
223