Completed
Pull Request — master (#26)
by
unknown
01:58
created

ServiceProvider::configProvider()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Arrilot\BitrixModels;
4
5
use Arrilot\BitrixBlade\BladeProvider;
6
use Arrilot\BitrixModels\Debug\IlluminateQueryDebugger;
7
use Arrilot\BitrixModels\Models\EloquentModel;
8
use Bitrix\Main\Config\Configuration;
9
use DB;
10
use Illuminate\Container\Container;
11
use Illuminate\Events\Dispatcher;
12
use Illuminate\Pagination\Paginator;
13
use Illuminate\Database\Capsule\Manager as Capsule;
14
15
class ServiceProvider
16
{
17
    protected static $configProvider;
18
    protected static $cacheManagerProvider;
19
    public static $illuminateDatabaseIsUsed = false;
20
    /**
21
     * Register the service provider.
22
     *
23
     * @return void
24
     */
25
    public static function register()
26
    {
27
        self::bootstrapIlluminatePagination();
28
    }
29
30
    /**
31
     * Register eloquent.
32
     *
33
     * @return void
34
     */
35
    public static function registerEloquent()
36
    {
37
        $capsule = self::bootstrapIlluminateDatabase();
38
        class_alias(Capsule::class, 'DB');
39
40
        if ($_COOKIE["show_sql_stat"] == "Y") {
41
            Capsule::enableQueryLog();
42
43
            $em = \Bitrix\Main\EventManager::getInstance();
44
            $em->addEventHandler('main', 'OnAfterEpilog', [IlluminateQueryDebugger::class, 'onAfterEpilogHandler']);
45
        }
46
47
        static::addEventListenersForHelpersHighloadblockTables($capsule);
0 ignored issues
show
Bug introduced by
Since addEventListenersForHelpersHighloadblockTables() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of addEventListenersForHelpersHighloadblockTables() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
48
    }
49
50
    /**
51
     * Bootstrap illuminate/pagination
52
     */
53
    protected static function bootstrapIlluminatePagination()
54
    {
55
        if (class_exists(BladeProvider::class)) {
56
            Paginator::viewFactoryResolver(function () {
57
                return BladeProvider::getViewFactory();
58
            });
59
        }
60
61
        Paginator::$defaultView = 'pagination.default';
62
        Paginator::$defaultSimpleView = 'pagination.simple-default';
63
64
        Paginator::currentPathResolver(function () {
65
            return $GLOBALS['APPLICATION']->getCurPage();
66
        });
67
68
        Paginator::currentPageResolver(function ($pageName = 'page') {
69
            $page = $_GET[$pageName];
70
71
            if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int)$page >= 1) {
72
                return $page;
73
            }
74
75
            return 1;
76
        });
77
    }
78
79
    /**
80
     * Bootstrap illuminate/database
81
     * @return Capsule
82
     */
83
    protected static function bootstrapIlluminateDatabase()
84
    {
85
        $config = self::getBitrixDbConfig();
86
87
        $capsule = new Capsule(self::instantiateServiceContainer());
88
        $capsule->addConnection([
89
            'driver'    => 'mysql',
90
            'host'      => $config['host'],
91
            'database'  => $config['database'],
92
            'username'  => $config['login'],
93
            'password'  => $config['password'],
94
            'charset'   => 'utf8',
95
            'collation' => 'utf8_unicode_ci',
96
            'prefix'    => '',
97
            'strict'    => false,
98
        ]);
99
100
        if (class_exists(Dispatcher::class)) {
101
            $capsule->setEventDispatcher(new Dispatcher());
102
        }
103
104
        $capsule->setAsGlobal();
105
        $capsule->bootEloquent();
106
107
        static::$illuminateDatabaseIsUsed = true;
108
109
        return $capsule;
110
    }
111
112
    /**
113
     * Instantiate service container if it's not instantiated yet.
114
     */
115
    protected static function instantiateServiceContainer()
116
    {
117
        $container = Container::getInstance();
118
119
        if (!$container) {
120
            $container = new Container();
121
            Container::setInstance($container);
122
        }
123
124
        return $container;
125
    }
126
127
    /**
128
     * Get bitrix database configuration array.
129
     *
130
     * @return array
131
     */
132
    protected static function getBitrixDbConfig()
133
    {
134
        $config = Configuration::getInstance();
135
        $connections = $config->get('connections');
136
137
        return $connections['default'];
138
    }
139
140
    /**
141
     * Для множественных полей Highload блоков битрикс использует вспомогательные таблицы.
142
     * Данный метод вешает обработчики на eloquent события добавления и обновления записей которые будут актуализировать и эти таблицы.
143
     *
144
     * @param Capsule $capsule
145
     */
146
    private static function addEventListenersForHelpersHighloadblockTables(Capsule $capsule)
147
    {
148
        $dispatcher = $capsule->getEventDispatcher();
149
        if (!$dispatcher) {
150
            return;
151
        }
152
153
        $dispatcher->listen(['eloquent.deleted: *'], function($event, $payload) {
154
            /** @var EloquentModel $model */
155
            $model = $payload[0];
156
            if (empty($model->multipleHighloadBlockFields)) {
157
                return;
158
            }
159
160
            $modelTable = $model->getTable();
161
            foreach ($model->multipleHighloadBlockFields as $multipleHighloadBlockField) {
162
                if (!empty($model['ID'])) {
163
                    $tableName = $modelTable.'_'.strtolower($multipleHighloadBlockField);
164
                    DB::table($tableName)->where('ID', $model['ID'])->delete();
165
                }
166
            }
167
        });
168
169
        $dispatcher->listen(['eloquent.updated: *', 'eloquent.created: *'], function($event, $payload) {
170
            /** @var EloquentModel $model */
171
            $model = $payload[0];
172
            if (empty($model->multipleHighloadBlockFields)) {
173
                return;
174
            }
175
176
            $dirty = $model->getDirty();
177
            $modelTable = $model->getTable();
178
            foreach ($model->multipleHighloadBlockFields as $multipleHighloadBlockField) {
179
                if (isset($dirty[$multipleHighloadBlockField]) && !empty($model['ID'])) {
180
                    $tableName = $modelTable.'_'.strtolower($multipleHighloadBlockField);
181
182
                    if (substr($event, 0, 16) === 'eloquent.updated') {
183
                        DB::table($tableName)->where('ID', $model['ID'])->delete();
184
                    }
185
186
                    $unserializedValues = unserialize($dirty[$multipleHighloadBlockField]);
187
                    if (!$unserializedValues) {
188
                        continue;
189
                    }
190
191
                    $newRows = [];
192
                    foreach ($unserializedValues as $unserializedValue) {
193
                        $newRows[] = [
194
                            'ID' => $model['ID'],
195
                            'VALUE' => $unserializedValue,
196
                        ];
197
                    }
198
199
                    if ($newRows) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $newRows of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
200
                        DB::table($tableName)->insert($newRows);
201
                    }
202
                }
203
            }
204
        });
205
    }
206
    
207
    public static function registerConfigProvider($provider)
208
    {
209
        static::$configProvider = $provider;
210
    }
211
    
212
    /**
213
     * @return \COption
214
     */
215
    public static function configProvider()
216
    {
217
        if (!static::$configProvider) {
218
            static::$configProvider = new \COption();
219
        }
220
        
221
        return static::$configProvider;
222
    }
223
    
224
    public static function registerCacheManagerProvider($provider)
225
    {
226
        static::$cacheManagerProvider = $provider;
227
    }
228
    
229
    /**
230
     * @return \CCacheManager
231
     */
232
    public static function cacheManagerProvider()
233
    {
234
        if (!static::$cacheManagerProvider) {
235
            global $CACHE_MANAGER;
236
            static::$cacheManagerProvider = $CACHE_MANAGER;
237
        }
238
        
239
        return static::$cacheManagerProvider;
240
    }
241
}
242