Completed
Push — master ( fb089c...ff496f )
by Mahmoud
03:01
created

overrideDefaultFractalSerializer()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 25
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 16
nc 2
nop 0
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 App\Port\Middleware\PortKernel;
9
use DB;
10
use File;
11
use Illuminate\Support\Facades\Config;
12
use Illuminate\Support\Facades\View;
13
use Log;
14
15
/**
16
 * Class PortServiceProviderTrait.
17
 *
18
 * @author  Mahmoud Zalt <[email protected]>
19
 */
20
trait PortServiceProviderTrait
21
{
22
23
    /**
24
     * Write the DB queries in the Log and Display them in the
25
     * terminal (in case you want to see them while executing the tests).
26
     *
27
     * @param bool|false $terminal
28
     */
29
    public function debugDatabaseQueries($log = true, $terminal = false)
30
    {
31
        if (Config::get('database.query_debugging')) {
32
            DB::listen(function ($event) use ($terminal, $log) {
33
                $fullQuery = vsprintf(str_replace(['%', '?'], ['%%', '%s'], $event->sql), $event->bindings);
34
35
                $text = $event->connectionName . ' (' . $event->time . '): ' . $fullQuery;
36
37
                if ($terminal) {
38
                    dump($text);
39
                }
40
41
                if ($log) {
42
                    Log::info($text);
43
                }
44
            });
45
        }
46
    }
47
48
    /**
49
     * By default Laravel takes (server/database/factories) as the
50
     * path to the factories, this function changes the path to load
51
     * the factories from the infrastructure directory.
52
     */
53
    public function changeTheDefaultDatabaseModelsFactoriesPath($customPath)
54
    {
55
        App::singleton(\Illuminate\Database\Eloquent\Factory::class, function ($app) use ($customPath) {
56
            $faker = $app->make(\Faker\Generator::class);
57
58
            return \Illuminate\Database\Eloquent\Factory::construct($faker, base_path() . $customPath);
59
        });
60
    }
61
62
    /**
63
     * Get the containers Service Providers full classes names.
64
     *
65
     * @return  array
66
     */
67
    public function getMainServiceProviders()
68
    {
69
        $containersNamespace = PortButler::getContainersNamespace();
70
71
        $allServiceProviders = [];
72
73
        foreach (PortButler::getContainersNames() as $containerName) {
74
            // append the Module main service provider
75
            $allServiceProviders[] = PortButler::buildMainServiceProvider($containersNamespace, $containerName);
76
        }
77
78
        return array_unique($allServiceProviders) ? : [];
79
    }
80
81
    /**
82
     * Load views from inside the Containers
83
     */
84
    public function autoLoadViewsFromContainers()
85
    {
86
        foreach (PortButler::getContainersNames() as $containerName) {
87
88
            $containerViewDirectory = base_path('app/Containers/' . $containerName . '/UI/WEB/Views/');
89
90
            if (File::isDirectory($containerViewDirectory)) {
91
                View::addLocation($containerViewDirectory);
92
            }
93
        }
94
    }
95
96
97
    /**
98
     * TODO: needs refactoring, was created in 5 min
99
     *
100
     * @return  array
101
     */
102
    public function getAllContainersConsoleCommandsForAutoLoading()
103
    {
104
        $classes = [];
105 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...
106
            $containerCommandsDirectory = base_path('app/Containers/' . $containerName . '/UI/CLI/Commands/');
107
            if (File::isDirectory($containerCommandsDirectory)) {
108
                $files = \File::allFiles($containerCommandsDirectory);
109
                foreach ($files as $consoleFile) {
110
                    if (\File::isFile($consoleFile)) {
111
                        $pathName = $consoleFile->getPathname();
112
                        $classes[] = PortButler::getClassFullNameFromFile($pathName);
113
                    }
114
                }
115
            }
116
        };
117
118
        return $classes;
119
    }
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
    /**
139
     * By default the Dingo API package (in the config file) creates an instance of the
140
     * fractal manager which takes the default serializer (specified by the fractal
141
     * package itself, and there's no way to override change it from the configurations of
142
     * the Dingo package).
143
     *
144
     * Here I am replacing the current default serializer (DataArraySerializer) by the
145
     * (JsonApiSerializer).
146
     *
147
     * "Serializers are what build the final response after taking the transformers data".
148
     */
149
    public function overrideDefaultFractalSerializer()
150
    {
151
        $serializerName = Config::get('api.serializer');
152
153
        // if DataArray `\League\Fractal\Serializer\DataArraySerializer` do noting since it's set by default by the Dingo API
154
        if ($serializerName !== 'DataArray') {
155
            app('Dingo\Api\Transformer\Factory')->setAdapter(function () use ($serializerName) {
156
                switch ($serializerName) {
157
                    case 'JsonApi':
158
                        $serializer = new \League\Fractal\Serializer\JsonApiSerializer(Config::get('api.domain'));
159
                        break;
160
                    case 'Array':
161
                        $serializer = new \League\Fractal\Serializer\ArraySerializer(Config::get('api.domain'));
162
                        break;
163
                    default:
164
                        throw new UnsupportedFractalSerializerException('Unsupported ' . $serializerName);
165
                }
166
167
                $fractal = new \League\Fractal\Manager();
168
                $fractal->setSerializer($serializer);
169
170
                return new \Dingo\Api\Transformer\Adapter\Fractal($fractal, 'include', ',', false);
171
            });
172
        }
173
    }
174
175
    /**
176
     * @param array $middlewares
177
     * @param array $middlewareGroups
178
     * @param array $routeMiddlewares
179
     */
180
    public function registerAllMiddlewares(array $middlewares = [], array $middlewareGroups = [], array $routeMiddlewares = [])
181
    {
182
        // Registering single and grouped middleware's
183
        (App::make(PortKernel::class))
184
            ->registerMiddlewares($middlewares)
185
            ->registerMiddlewareGroups($middlewareGroups);
186
187
        // Registering Route Middleware's
188
        foreach ($routeMiddlewares as $key => $routeMiddleware){
189
            $this->app['router']->middleware($key, $routeMiddleware);
0 ignored issues
show
Bug introduced by
The property app does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
190
        }
191
192
    }
193
194
195
}
196