ServiceProvider::getBitrixDbConfig()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 7
rs 10
cc 1
nc 1
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\BaseBitrixModel;
8
use Arrilot\BitrixModels\Models\EloquentModel;
9
use Bitrix\Main\Config\Configuration;
10
use DB;
11
use Illuminate\Container\Container;
12
use Illuminate\Events\Dispatcher;
13
use Illuminate\Pagination\Paginator;
14
use Illuminate\Database\Capsule\Manager as Capsule;
15
16
class ServiceProvider
17
{
18
    public static $illuminateDatabaseIsUsed = false;
19
20
    /**
21
     * Register the service provider.
22
     *
23
     * @return void
24
     */
25
    public static function register()
26
    {
27
        BaseBitrixModel::setCurrentLanguage(strtoupper(LANGUAGE_ID));
28
        self::bootstrapIlluminatePagination();
29
    }
30
31
    /**
32
     * Register eloquent.
33
     *
34
     * @return void
35
     */
36
    public static function registerEloquent()
37
    {
38
        $capsule = self::bootstrapIlluminateDatabase();
39
        class_alias(Capsule::class, 'DB');
40
41
        if ($_COOKIE["show_sql_stat"] == "Y") {
42
            Capsule::enableQueryLog();
43
44
            $em = \Bitrix\Main\EventManager::getInstance();
45
            $em->addEventHandler('main', 'OnAfterEpilog', [IlluminateQueryDebugger::class, 'onAfterEpilogHandler']);
46
        }
47
48
        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...
49
    }
50
51
    /**
52
     * Bootstrap illuminate/pagination
53
     */
54
    protected static function bootstrapIlluminatePagination()
55
    {
56
        if (class_exists(BladeProvider::class)) {
57
            Paginator::viewFactoryResolver(function () {
58
                return BladeProvider::getViewFactory();
59
            });
60
        }
61
62
        Paginator::$defaultView = 'pagination.default';
63
        Paginator::$defaultSimpleView = 'pagination.simple-default';
64
65
        Paginator::currentPathResolver(function () {
66
            return $GLOBALS['APPLICATION']->getCurPage();
67
        });
68
69
        Paginator::currentPageResolver(function ($pageName = 'page') {
70
            $page = $_GET[$pageName];
71
72
            if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int)$page >= 1) {
73
                return $page;
74
            }
75
76
            return 1;
77
        });
78
    }
79
80
    /**
81
     * Bootstrap illuminate/database
82
     * @return Capsule
83
     */
84
    protected static function bootstrapIlluminateDatabase()
85
    {
86
        $capsule = new Capsule(self::instantiateServiceContainer());
87
88
	if ($dbConfig = Configuration::getInstance()->get('bitrix-models.illuminate-database')) {
89
		foreach ($dbConfig['connections'] as $name => $connection) {
90
			$capsule->addConnection($connection, $name);
91
		}
92
93
		$capsule->getDatabaseManager()->setDefaultConnection((isset($dbConfig['default'])) ? $dbConfig['default'] : 'default');
94
	} else {
95
		$config = self::getBitrixDbConfig();
96
97
		$capsule->addConnection([
98
			'driver' => 'mysql',
99
			'host' => $config['host'],
100
			'database' => $config['database'],
101
			'username' => $config['login'],
102
			'password' => $config['password'],
103
			'charset' => 'utf8',
104
			'collation' => 'utf8_unicode_ci',
105
			'prefix' => '',
106
			'strict' => false,
107
		]);
108
	}
109
110
        if (class_exists(Dispatcher::class)) {
111
            $capsule->setEventDispatcher(new Dispatcher());
112
        }
113
114
        $capsule->setAsGlobal();
115
        $capsule->bootEloquent();
116
117
        static::$illuminateDatabaseIsUsed = true;
118
119
        return $capsule;
120
    }
121
122
    /**
123
     * Instantiate service container if it's not instantiated yet.
124
     */
125
    protected static function instantiateServiceContainer()
126
    {
127
        $container = Container::getInstance();
128
129
        if (!$container) {
130
            $container = new Container();
131
            Container::setInstance($container);
132
        }
133
134
        return $container;
135
    }
136
137
    /**
138
     * Get bitrix database configuration array.
139
     *
140
     * @return array
141
     */
142
    protected static function getBitrixDbConfig()
143
    {
144
        $config = Configuration::getInstance();
145
        $connections = $config->get('connections');
146
147
        return $connections['default'];
148
    }
149
150
    /**
151
     * Для множественных полей Highload блоков битрикс использует вспомогательные таблицы.
152
     * Данный метод вешает обработчики на eloquent события добавления и обновления записей которые будут актуализировать и эти таблицы.
153
     *
154
     * @param Capsule $capsule
155
     */
156
    private static function addEventListenersForHelpersHighloadblockTables(Capsule $capsule)
157
    {
158
        $dispatcher = $capsule->getEventDispatcher();
159
        if (!$dispatcher) {
160
            return;
161
        }
162
163
        $dispatcher->listen(['eloquent.deleted: *'], function($event, $payload) {
164
            /** @var EloquentModel $model */
165
            $model = $payload[0];
166
            if (empty($model->multipleHighloadBlockFields)) {
167
                return;
168
            }
169
170
            $modelTable = $model->getTable();
171
            foreach ($model->multipleHighloadBlockFields as $multipleHighloadBlockField) {
172
                if (!empty($model['ID'])) {
173
                    $tableName = $modelTable.'_'.strtolower($multipleHighloadBlockField);
174
                    DB::table($tableName)->where('ID', $model['ID'])->delete();
175
                }
176
            }
177
        });
178
179
        $dispatcher->listen(['eloquent.updated: *', 'eloquent.created: *'], function($event, $payload) {
180
            /** @var EloquentModel $model */
181
            $model = $payload[0];
182
            if (empty($model->multipleHighloadBlockFields)) {
183
                return;
184
            }
185
186
            $dirty = $model->getDirty();
187
            $modelTable = $model->getTable();
188
            foreach ($model->multipleHighloadBlockFields as $multipleHighloadBlockField) {
189
                if (isset($dirty[$multipleHighloadBlockField]) && !empty($model['ID'])) {
190
                    $tableName = $modelTable.'_'.strtolower($multipleHighloadBlockField);
191
192
                    if (substr($event, 0, 16) === 'eloquent.updated') {
193
                        DB::table($tableName)->where('ID', $model['ID'])->delete();
194
                    }
195
196
                    $unserializedValues = unserialize($dirty[$multipleHighloadBlockField]);
197
                    if (!$unserializedValues) {
198
                        continue;
199
                    }
200
201
                    $newRows = [];
202
                    foreach ($unserializedValues as $unserializedValue) {
203
                        $newRows[] = [
204
                            'ID' => $model['ID'],
205
                            'VALUE' => $unserializedValue,
206
                        ];
207
                    }
208
209
                    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...
210
                        DB::table($tableName)->insert($newRows);
211
                    }
212
                }
213
            }
214
        });
215
    }
216
}
217