Passed
Push — master ( bada6f...d61b94 )
by Aimeos
04:42
created

TablesMigrateSiteid   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 192
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 100
dl 0
loc 192
c 0
b 0
f 0
rs 10
wmc 21

6 Methods

Rating   Name   Duplication   Size   Complexity  
A isChild() 0 3 2
A getSites() 0 27 3
A before() 0 5 1
A up() 0 18 2
B process() 0 32 9
A map() 0 17 4
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2019-2021
6
 */
7
8
9
namespace Aimeos\Upscheme\Task;
10
11
12
class TablesMigrateSiteid extends Base
13
{
14
	private $resources = [
15
		'db-attribute' => [
16
			'mshop_attribute_type', 'mshop_attribute_list_type', 'mshop_attribute_property_type',
17
			'mshop_attribute_list', 'mshop_attribute_property', 'mshop_attribute'
18
		],
19
		'db-cache' => [
20
			'madmin_cache_tag', 'madmin_cache'
21
		],
22
		'db-catalog' => [
23
			'mshop_catalog_list_type', 'mshop_catalog_list', 'mshop_catalog'
24
		],
25
		'db-coupon' => [
26
			'mshop_coupon_code', 'mshop_coupon'
27
		],
28
		'db-customer' => [
29
			'mshop_customer_list_type', 'mshop_customer_property_type', 'mshop_customer_group',
30
			'mshop_customer_property', 'mshop_customer_list', 'mshop_customer_address', 'mshop_customer',
31
		],
32
		'db-job' => [
33
			'madmin_job',
34
		],
35
		'db-locale' => [
36
			'mshop_locale_site', 'mshop_locale',
37
		],
38
		'db-log' => [
39
			'madmin_log',
40
		],
41
		'db-media' => [
42
			'mshop_media_type', 'mshop_media_list_type', 'mshop_media_property_type',
43
			'mshop_media_list', 'mshop_media_property', 'mshop_media'
44
		],
45
		'db-order' => [
46
			'mshop_order_base_product_attr', 'mshop_order_base_service_attr', 'mshop_order_base_coupon',
47
			'mshop_order_base_product', 'mshop_order_base_service', 'mshop_order_base_address',
48
			'mshop_order_base', 'mshop_order_status', 'mshop_order'
49
		],
50
		'db-plugin' => [
51
			'mshop_plugin_type', 'mshop_plugin'
52
		],
53
		'db-price' => [
54
			'mshop_price_type', 'mshop_price_list_type', 'mshop_price_list', 'mshop_price'
55
		],
56
		'db-product' => [
57
			'mshop_index_attribute', 'mshop_index_catalog', 'mshop_index_price', 'mshop_index_supplier', 'mshop_index_text',
58
			'mshop_product_list_type', 'mshop_product_property_type', 'mshop_product_type',
59
			'mshop_product_list', 'mshop_product_property', 'mshop_product'
60
		],
61
		'db-service' => [
62
			'mshop_service_type', 'mshop_service_list_type', 'mshop_service_list', 'mshop_service'
63
		],
64
		'db-stock' => [
65
			'mshop_stock_type', 'mshop_stock'
66
		],
67
		'db-subscription' => [
68
			'mshop_subscription'
69
		],
70
		'db-supplier' => [
71
			'mshop_supplier_list_type', 'mshop_supplier_list', 'mshop_supplier_address', 'mshop_supplier'
72
		],
73
		'db-tag' => [
74
			'mshop_tag_type', 'mshop_tag'
75
		],
76
		'db-text' => [
77
			'mshop_text_type', 'mshop_text_list_type', 'mshop_text_list', 'mshop_text'
78
		],
79
	];
80
81
82
	public function before() : array
83
	{
84
		return [
85
			'Attribute', 'Cache', 'Catalog', 'Coupon', 'Customer', 'Job', 'Locale', 'Log', 'Media', 'Order',
86
			'Plugin', 'Price', 'Product', 'Service', 'Stock', 'Subscription', 'Supplier', 'Tag', 'Text'
87
		];
88
	}
89
90
91
	public function up()
92
	{
93
		$db = $this->db( 'db-locale' );
94
95
		if( $db->hasColumn( 'mshop_locale_site', 'siteid' ) ) {
96
			return;
97
		}
98
99
		$this->info( 'Update "siteid" columns', 'v' );
100
101
		$db->table( 'mshop_locale_site' )->int( 'siteid' )->default( 0 )->up();
102
103
		$db->dropForeign( 'mshop_locale', ['fk_msloc_siteid', 'fk_msloccu_siteid', 'fk_mslocla_siteid'] );
104
		$db->dropForeign( 'mshop_locale_site', 'mshop_locale_site_siteid_key' ); // PostgreSQL workaround
105
106
		$db->exec( 'UPDATE mshop_locale_site SET siteid = id' );
107
108
		$this->process( $this->resources );
109
	}
110
111
112
	protected function process( array $resources )
113
	{
114
		$db = $this->db( 'db-locale' );
0 ignored issues
show
Unused Code introduced by
The assignment to $db is dead and can be removed.
Loading history...
115
		$sites = $this->getSites();
116
117
		foreach( $resources as $rname => $tables )
118
		{
119
			$db = $this->db( $rname );
120
121
			foreach( $tables as $table )
122
			{
123
				$this->info( sprintf( 'Checking table %1$s', $table ), 'vv', 1 );
124
				$colname = null;
125
126
				if( $db->hasColumn( $table, 'siteid' ) && $db->table( $table )->col( 'siteid' )->type() === 'integer' ) {
127
					$colname = 'siteid';
128
				}
129
130
				if( $db->hasColumn( $table, 'tsiteid' ) && $db->table( $table )->col( 'tsiteid' )->type() === 'integer' ) {
131
					$colname = 'tsiteid';
132
				}
133
134
				if( $colname )
135
				{
136
					$db->table( $table )->string( $colname )->up();
137
138
					foreach( $sites as $siteid => $site )
139
					{
140
						$db->stmt()->update( $table )->set( $colname . ' = ?' )
0 ignored issues
show
Bug introduced by
The call to Doctrine\DBAL\Query\QueryBuilder::set() has too few arguments starting with value. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

140
						$db->stmt()->update( $table )->/** @scrutinizer ignore-call */ set( $colname . ' = ?' )

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
141
							->where( $colname . ' = ?' )->orWhere( $colname . " = ''" )
142
							->setParameters( [$site, $siteid ] )
143
							->execute();
144
					}
145
				}
146
			}
147
		}
148
	}
149
150
151
	protected function getSites()
152
	{
153
		$map = [];
154
155
		$dbm = $this->context()->getDatabaseManager();
0 ignored issues
show
Bug introduced by
The method context() does not exist on Aimeos\Upscheme\Task\TablesMigrateSiteid. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

155
		$dbm = $this->/** @scrutinizer ignore-call */ context()->getDatabaseManager();
Loading history...
156
		$conn = $dbm->acquire( 'db-locale' );
157
		$tconn = $dbm->acquire( 'db-locale' );
158
159
		$type = \Aimeos\MW\DB\Statement\Base::PARAM_INT;
160
		$roots = $conn->create( 'SELECT id, nleft, nright FROM mshop_locale_site WHERE level = 0' )->execute();
161
162
		while( $root = $roots->fetch() )
163
		{
164
			$sql = 'SELECT id, nleft, nright FROM mshop_locale_site WHERE nleft >= ? and nright <= ? ORDER BY nleft';
165
			$result = $tconn->create( $sql )->bind( 1, $root['nleft'], $type )->bind( 2, $root['nright'], $type )->execute();
166
167
			while( $row = $result->fetch() )
168
			{
169
				$map[$row['id']] = $row['id'] . '.';
170
				$this->map( $result, $row, $map, $row['id'] . '.' );
171
			}
172
		}
173
174
		$dbm->release( $tconn, 'db-locale' );
175
		$dbm->release( $conn, 'db-locale' );
176
177
		return $map;
178
	}
179
180
181
	protected function isChild( array $row, array $parent )
182
	{
183
		return $row['nleft'] > $parent['nleft'] && $row['nright'] < $parent['nright'];
184
	}
185
186
187
	protected function map( \Aimeos\MW\DB\Result\Iface $result, array $parent, array &$map, string $site )
188
	{
189
		while( $row = $result->fetch() )
190
		{
191
			while( $this->isChild( $row, $parent ) )
192
			{
193
				$map[$row['id']] = $site . $row['id'] . '.';
194
195
				if( ( $row = $this->map( $result, $row, $map, $site . $row['id'] . '.' ) ) === null ) {
196
					return null;
197
				}
198
			}
199
200
			return $row;
201
		}
202
203
		return null;
204
	}
205
}
206