Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 24 | class ConnectTestHelper extends \Enlight_Components_Test_Plugin_TestCase |
||
| 25 | { |
||
| 26 | const IMAGE_PROVIDER_URL = 'http://www.shopware.de/ShopwareCommunityCenter/img/logo.png'; |
||
| 27 | |||
| 28 | public function setUp() |
||
| 29 | { |
||
| 30 | parent::setUp(); |
||
| 31 | |||
| 32 | set_error_handler(null); |
||
| 33 | set_exception_handler(null); |
||
| 34 | } |
||
| 35 | |||
| 36 | /** |
||
| 37 | * @return \ShopwarePlugins\Connect\Components\ConnectFactory |
||
| 38 | */ |
||
| 39 | public function getConnectFactory() |
||
| 40 | { |
||
| 41 | if (!$this->connectFactory) { |
||
| 42 | $this->connectFactory = new ConnectFactory(); |
||
| 43 | } |
||
| 44 | |||
| 45 | return $this->connectFactory; |
||
| 46 | } |
||
| 47 | |||
| 48 | /** |
||
| 49 | * @return \Shopware\Connect\SDK |
||
| 50 | */ |
||
| 51 | public function getSDK() |
||
| 52 | { |
||
| 53 | if (!$this->sdk) { |
||
| 54 | $this->sdk = $this->getConnectFactory()->createSdk(); |
||
| 55 | } |
||
| 56 | |||
| 57 | return $this->sdk; |
||
| 58 | } |
||
| 59 | |||
| 60 | /** |
||
| 61 | * @return int |
||
| 62 | */ |
||
| 63 | public function getConnectProductArticleId($sourceId, $shopId=3) |
||
| 64 | { |
||
| 65 | $id = Shopware()->Db()->fetchOne( |
||
| 66 | 'SELECT article_id FROM s_plugin_connect_items WHERE source_id = ? and shop_id = ? LIMIT 1', |
||
| 67 | array($sourceId, $shopId) |
||
| 68 | ); |
||
| 69 | return $id; |
||
| 70 | } |
||
| 71 | |||
| 72 | public function getExternalProductSourceId() |
||
| 73 | { |
||
| 74 | $sql = 'SELECT source_id FROM s_plugin_connect_items WHERE shop_id IS NOT NULL'; |
||
| 75 | $sourceId = Shopware()->Db()->fetchOne($sql); |
||
| 76 | |||
| 77 | return $sourceId; |
||
| 78 | } |
||
| 79 | |||
| 80 | /** |
||
| 81 | * @return \ShopwarePlugins\Connect\Components\Helper |
||
| 82 | */ |
||
| 83 | public function getHelper() |
||
| 84 | { |
||
| 85 | return Shopware()->Plugins()->Backend()->SwagConnect()->getHelper(); |
||
| 86 | } |
||
| 87 | |||
| 88 | |||
| 89 | public function callPrivate($class, $method, $args) |
||
| 90 | { |
||
| 91 | $method = new \ReflectionMethod( |
||
| 92 | $class, $method |
||
| 93 | ); |
||
| 94 | |||
| 95 | $method->setAccessible(true); |
||
| 96 | |||
| 97 | return call_user_func(array($method, 'invoke', $args)); |
||
| 98 | } |
||
| 99 | |||
| 100 | /** |
||
| 101 | * @return ConnectExport |
||
| 102 | */ |
||
| 103 | public function getConnectExport() |
||
| 104 | { |
||
| 105 | return new ConnectExport( |
||
| 106 | $this->getHelper(), |
||
| 107 | $this->getSDK(), |
||
| 108 | Shopware()->Models(), |
||
| 109 | new ProductsAttributesValidator(), |
||
| 110 | new Config(Shopware()->Models()), |
||
| 111 | new ErrorHandler(), |
||
| 112 | Shopware()->Container()->get('events') |
||
| 113 | ); |
||
| 114 | } |
||
| 115 | |||
| 116 | |||
| 117 | /** |
||
| 118 | * @return ImageImport |
||
| 119 | */ |
||
| 120 | public function getImageImport() |
||
| 121 | { |
||
| 122 | return new ImageImport( |
||
| 123 | Shopware()->Models(), |
||
| 124 | $this->getHelper(), |
||
| 125 | Shopware()->Container()->get('thumbnail_manager'), |
||
| 126 | new Logger(Shopware()->Db()) |
||
| 127 | ); |
||
| 128 | } |
||
| 129 | |||
| 130 | public function changeCategoryConnectMappingForCategoryTo($categoryId, $mapping) |
||
| 131 | { |
||
| 132 | $modelManager = Shopware()->Models(); |
||
| 133 | $categoryRepository = $modelManager->getRepository('Shopware\Models\Category\Category'); |
||
| 134 | $category = $categoryRepository->find($categoryId); |
||
| 135 | |||
| 136 | if (!$category) { |
||
| 137 | $this->fail('Could not find category with ID ' . $categoryId); |
||
| 138 | } |
||
| 139 | |||
| 140 | $attribute = $category->getAttribute() ?: new \Shopware\Models\Attribute\Category(); |
||
| 141 | $attribute->setConnectImportMapping($mapping); |
||
| 142 | $attribute->setConnectExportMapping($mapping); |
||
| 143 | $category->setAttribute($attribute); |
||
| 144 | $attribute->setCategory($category); |
||
| 145 | |||
| 146 | $modelManager->persist($category); |
||
| 147 | $modelManager->persist($attribute); |
||
| 148 | |||
| 149 | $modelManager->flush(); |
||
| 150 | } |
||
| 151 | |||
| 152 | public static function dispatchRpcCall($service, $command, array $args) |
||
| 153 | { |
||
| 154 | $sdk = Shopware()->Container()->get('ConnectSDK'); |
||
| 155 | $refl = new \ReflectionObject($sdk); |
||
| 156 | $property = $refl->getProperty('dependencies'); |
||
| 157 | $property->setAccessible(true); |
||
| 158 | $deps = $property->getValue($sdk); |
||
| 159 | $serviceRegistry = $deps->getServiceRegistry(); |
||
| 160 | $callable = $serviceRegistry->getService($service, $command); |
||
| 161 | |||
| 162 | return call_user_func_array(array($callable['provider'], $callable['command']), $args); |
||
| 163 | } |
||
| 164 | |||
| 165 | protected function getProduct($withImage = false, $withVariantImages = false) |
||
| 166 | { |
||
| 167 | $purchasePrice = 6.99; |
||
| 168 | $offerValidUntil = time() + 1 * 365 * 24 * 60 * 60; // One year |
||
| 169 | $number = rand(1, 999999999); |
||
| 170 | $product = new \Shopware\Connect\Struct\Product(array( |
||
| 171 | 'shopId' => 3, |
||
| 172 | 'revisionId' => time(), |
||
| 173 | 'sourceId' => $number, |
||
| 174 | 'ean' => $number, |
||
| 175 | 'sku' => 'sku#' . $number, |
||
| 176 | 'url' => 'http://shopware.de', |
||
| 177 | 'title' => 'MassImport #'. $number, |
||
| 178 | 'shortDescription' => 'Ein Produkt aus shopware Connect', |
||
| 179 | 'longDescription' => 'Ein Produkt aus shopware Connect', |
||
| 180 | 'additionalDescription' => 'Ein Produkt aus shopware Connect', |
||
| 181 | 'vendor' => array( |
||
| 182 | 'url' => 'http://connect.shopware.de/', |
||
| 183 | 'name' => 'shopware Connect', |
||
| 184 | 'logo_url' => self::IMAGE_PROVIDER_URL, |
||
| 185 | 'page_title' => 'shopware Connect title', |
||
| 186 | 'description' => 'shopware Connect description' |
||
| 187 | ), |
||
| 188 | 'stream' => 'Awesome products', |
||
| 189 | 'price' => 9.99, |
||
| 190 | 'purchasePrice' => $purchasePrice, |
||
| 191 | 'purchasePriceHash' => hash_hmac( |
||
| 192 | 'sha256', |
||
| 193 | sprintf('%.3F %d', $purchasePrice, $offerValidUntil), '54642546-0001-48ee-b4d0-4f54af66d822' |
||
| 194 | ), |
||
| 195 | 'offerValidUntil' => $offerValidUntil, |
||
| 196 | 'availability' => 100, |
||
| 197 | 'categories' => array( |
||
| 198 | '/bücher' => 'Bücher', |
||
| 199 | ), |
||
| 200 | 'translations' => array( |
||
| 201 | 'en' => new Translation(array( |
||
| 202 | 'title' => 'MassImport #'. $number . ' EN', |
||
| 203 | 'longDescription' => 'Ein Produkt aus shopware Connect EN', |
||
| 204 | 'shortDescription' => 'Ein Produkt aus shopware Connect short EN', |
||
| 205 | 'additionalDescription' => 'Ein Produkt aus shopware Verbinden Sie mit zusätzlicher Beschreibung EN', |
||
| 206 | 'url' => 'http://shopware.de', |
||
| 207 | )) |
||
| 208 | ) |
||
| 209 | )); |
||
| 210 | |||
| 211 | if ($withImage) { |
||
| 212 | $product->images = array(self::IMAGE_PROVIDER_URL . '?' . $number); |
||
| 213 | } |
||
| 214 | |||
| 215 | if ($withVariantImages) { |
||
| 216 | $product->variantImages = array(self::IMAGE_PROVIDER_URL . '?' . $number . '-variantImage'); |
||
| 217 | } |
||
| 218 | |||
| 219 | return $product; |
||
| 220 | } |
||
| 221 | |||
| 222 | protected function getProperties() |
||
| 223 | { |
||
| 224 | return array( |
||
| 225 | new Property(array( |
||
| 226 | 'groupName' => 'Nike', |
||
| 227 | 'comparable' => false, |
||
| 228 | 'sortMode' => 1, |
||
| 229 | 'option' => 'color', |
||
| 230 | 'filterable' => false, |
||
| 231 | 'value' => 'red' |
||
| 232 | )), |
||
| 233 | new Property(array( |
||
| 234 | 'groupName' => 'Nike', |
||
| 235 | 'comparable' => false, |
||
| 236 | 'sortMode' => 1, |
||
| 237 | 'option' => 'size', |
||
| 238 | 'filterable' => false, |
||
| 239 | 'value' => 'XXL', |
||
| 240 | 'valuePosition' => 1 |
||
| 241 | )), |
||
| 242 | new Property(array( |
||
| 243 | 'groupName' => 'Nike', |
||
| 244 | 'comparable' => false, |
||
| 245 | 'sortMode' => 1, |
||
| 246 | 'option' => 'size', |
||
| 247 | 'filterable' => false, |
||
| 248 | 'value' => '3XL' |
||
| 249 | )) |
||
| 250 | ); |
||
| 251 | } |
||
| 252 | |||
| 253 | protected function getProducts($number = 10, $withImage = false, $withVariantImages = false) |
||
| 254 | { |
||
| 255 | $products = array(); |
||
| 256 | for($i=0; $i<$number; $i++) { |
||
| 257 | $products[] = $this->getProduct($withImage, $withVariantImages); |
||
| 258 | } |
||
| 259 | return $products; |
||
| 260 | } |
||
| 261 | |||
| 262 | protected function getVariants() |
||
| 263 | { |
||
| 264 | $number = $groupId = rand(1, 999999999); |
||
| 265 | $color = array( |
||
| 266 | array('de' => 'Weiss-Blau' . $number, 'en' => 'White-Blue'), |
||
| 267 | array('de' => 'Weiss-Rot' . $number, 'en' => 'White-Red'), |
||
| 268 | array('de' => 'Blau-Rot' . $number, 'en' => 'Blue-Red'), |
||
| 269 | array('de' => 'Schwarz-Rot' . $number, 'en' => 'Black-Red'), |
||
| 270 | ); |
||
| 271 | |||
| 272 | $variants = array(); |
||
| 273 | $mainVariant = $this->getProduct(true); |
||
| 274 | $mainVariantColor = array_pop($color); |
||
| 275 | $mainVariant->variant['Farbe'] = $mainVariantColor['de']; |
||
| 276 | $mainVariant->groupId = $groupId; |
||
| 277 | $variants[] = $mainVariant; |
||
| 278 | |||
| 279 | //add translations |
||
| 280 | $mainVariant->translations['en']->variantLabels = array( |
||
| 281 | 'Farbe' => 'Color', |
||
| 282 | ); |
||
| 283 | $mainVariant->translations['en']->variantValues = array( |
||
| 284 | $mainVariantColor['de'] => $mainVariantColor['en'], |
||
| 285 | ); |
||
| 286 | |||
| 287 | for ($i = 0; $i < 4 - 1; $i++) { |
||
| 288 | $variant = $this->getProduct(true); |
||
| 289 | $variantSourceId = $mainVariant->sourceId . '-' . $i; |
||
| 290 | $variant->title = 'MassImport #' . $variantSourceId; |
||
| 291 | $variant->sourceId = $variantSourceId; |
||
| 292 | $variant->ean = $variantSourceId; |
||
| 293 | $variantColor = array_pop($color); |
||
| 294 | $variant->variant['Farbe'] = $variantColor['de']; |
||
| 295 | $variant->groupId = $groupId; |
||
| 296 | $variant->translations = array( |
||
| 297 | 'en' => new Translation(array( |
||
| 298 | 'title' => 'MassImport #' . $variantSourceId . ' EN', |
||
| 299 | 'longDescription' => $mainVariant->longDescription . ' EN', |
||
| 300 | 'shortDescription' => $mainVariant->shortDescription . ' EN', |
||
| 301 | 'variantLabels' => array( |
||
| 302 | 'Farbe' => 'Color', |
||
| 303 | ), |
||
| 304 | 'variantValues' => array( |
||
| 305 | $variantColor['de'] => $variantColor['en'], |
||
| 306 | ), |
||
| 307 | )), |
||
| 308 | ); |
||
| 309 | |||
| 310 | $variants[] = $variant; |
||
| 311 | } |
||
| 312 | |||
| 313 | return $variants; |
||
| 314 | } |
||
| 315 | |||
| 316 | public function getLocalArticle() |
||
| 317 | { |
||
| 318 | $number = rand(1, 999999999); |
||
| 319 | |||
| 320 | $article = new Article(); |
||
| 321 | $article->fromArray(array( |
||
| 322 | 'name' => 'LocalArticle #'. $number, |
||
| 323 | 'active' => true, |
||
| 324 | )); |
||
| 325 | $tax = Shopware()->Models()->getRepository('Shopware\Models\Tax\Tax')->find(1); |
||
| 326 | $article->setTax($tax); |
||
| 327 | |||
| 328 | $supplier = Shopware()->Models()->getRepository('Shopware\Models\Article\Supplier')->find(1); |
||
| 329 | $article->setSupplier($supplier); |
||
| 330 | |||
| 331 | Shopware()->Models()->persist($article); |
||
| 332 | Shopware()->Models()->flush(); |
||
| 333 | |||
| 334 | $mainDetail = new Detail(); |
||
| 335 | $mainDetail->fromArray(array( |
||
| 336 | 'number' => $number, |
||
| 337 | 'inStock' => 30, |
||
| 338 | 'article' => $article |
||
| 339 | )); |
||
| 340 | $article->setMainDetail($mainDetail); |
||
| 341 | $detailAtrribute = new \Shopware\Models\Attribute\Article(); |
||
| 342 | $detailAtrribute->fromArray(array( |
||
| 343 | 'article' => $article, |
||
| 344 | 'articleDetail' => $mainDetail, |
||
| 345 | )); |
||
| 346 | |||
| 347 | /** @var \Shopware\Models\Customer\Group $customerGroup */ |
||
| 348 | $customerGroup = Shopware()->Models()->getRepository('Shopware\Models\Customer\Group')->findOneByKey('EK'); |
||
| 349 | |||
| 350 | $connectAttribute = new Attribute(); |
||
| 351 | $connectAttribute->fromArray(array( |
||
| 352 | 'isMainVariant' => true, |
||
| 353 | 'article' => $article, |
||
| 354 | 'articleDetail' => $article->getMainDetail(), |
||
| 355 | 'sourceId' => $article->getId(), |
||
| 356 | 'category' => '/bücher', |
||
| 357 | 'fixedPrice' => false, |
||
| 358 | 'purchasePriceHash' => '', |
||
| 359 | 'offerValidUntil' => 0, |
||
| 360 | 'stream' => '', |
||
| 361 | )); |
||
| 362 | |||
| 363 | Shopware()->Models()->persist($mainDetail); |
||
| 364 | Shopware()->Models()->persist($detailAtrribute); |
||
| 365 | Shopware()->Models()->persist($connectAttribute); |
||
| 366 | Shopware()->Models()->flush(); |
||
| 367 | |||
| 368 | // set price via plain SQL because shopware throws exception |
||
| 369 | // undefined index: key when error handler is disabled |
||
| 370 | Shopware()->Db()->executeQuery( |
||
| 371 | 'INSERT INTO `s_articles_prices`(`pricegroup`, `from`, `to`, `articleID`, `articledetailsID`, `price`, `baseprice`) |
||
| 372 | VALUES (?, 1, "beliebig", ?, ?, ?, ?) |
||
| 373 | ', [$customerGroup->getKey(), $article->getId(), $mainDetail->getId(), 8.99, 3.99]); |
||
| 374 | |||
| 375 | return $article; |
||
| 376 | } |
||
| 377 | |||
| 378 | public function getProductToShop() |
||
| 379 | { |
||
| 380 | $manager = Shopware()->Models(); |
||
| 381 | return new ProductToShop( |
||
| 382 | $this->getHelper(), |
||
| 383 | Shopware()->Models(), |
||
| 384 | $this->getImageImport(), |
||
| 385 | new Config(Shopware()->Models()), |
||
| 386 | new VariantConfigurator( |
||
| 387 | $manager, |
||
| 388 | new PdoProductTranslationsGateway(Shopware()->Db()) |
||
| 389 | ), |
||
| 390 | new MarketplaceGateway($manager), |
||
| 391 | new PdoProductTranslationsGateway(Shopware()->Db()), |
||
| 392 | new DefaultCategoryResolver( |
||
| 393 | $manager, |
||
| 394 | $manager->getRepository('Shopware\CustomModels\Connect\RemoteCategory'), |
||
| 395 | $manager->getRepository('Shopware\CustomModels\Connect\ProductToRemoteCategory') |
||
| 396 | ), |
||
| 397 | new PDO(Shopware()->Db()->getConnection()), |
||
| 398 | Shopware()->Container()->get('events') |
||
| 399 | ); |
||
| 400 | } |
||
| 401 | |||
| 402 | protected function insertOrUpdateProducts($number, $withImage, $withVariantImages) |
||
| 403 | { |
||
| 404 | $commands = array(); |
||
| 405 | foreach ($this->getProducts($number, $withImage, $withVariantImages) as $product) { |
||
| 406 | $commands[$product->sourceId] = new \Shopware\Connect\Struct\Change\ToShop\InsertOrUpdate(array( |
||
| 407 | 'product' => $product, |
||
| 408 | 'revision' => time(), |
||
| 409 | )); |
||
| 410 | } |
||
| 411 | |||
| 412 | $this->dispatchRpcCall('products', 'toShop', array( |
||
| 413 | $commands |
||
| 414 | )); |
||
| 415 | |||
| 416 | return array_keys($commands); |
||
| 417 | } |
||
| 418 | |||
| 419 | protected function getRandomUser() |
||
| 420 | { |
||
| 421 | $user = Shopware()->Db()->fetchRow("SELECT * FROM s_user WHERE id = 1 LIMIT 1"); |
||
| 422 | |||
| 423 | $billing = Shopware()->Db()->fetchRow( |
||
| 424 | "SELECT * FROM s_user_billingaddress WHERE userID = :id", |
||
| 425 | array(':id' => $user['id']) |
||
| 426 | ); |
||
| 427 | $billing['stateID'] = isset($billing['stateId'])?$billing['stateID']:'1'; |
||
| 428 | $shipping = Shopware()->Db()->fetchRow( |
||
| 429 | "SELECT * FROM s_user_shippingaddress WHERE userID = :id", |
||
| 430 | array(':id' => $user['id']) |
||
| 431 | ); |
||
| 432 | $shipping['stateID'] = isset($shipping['stateId'])?$shipping['stateID']:'1'; |
||
| 433 | $country = Shopware()->Db()->fetchRow( |
||
| 434 | "SELECT * FROM s_core_countries WHERE id = :id", |
||
| 435 | array(':id' => $billing['countryID']) |
||
| 436 | ); |
||
| 437 | $state = Shopware()->Db()->fetchRow( |
||
| 438 | "SELECT * FROM s_core_countries_states WHERE id = :id", |
||
| 439 | array(':id' => $billing['stateID']) |
||
| 440 | ); |
||
| 441 | $countryShipping = Shopware()->Db()->fetchRow( |
||
| 442 | "SELECT * FROM s_core_countries WHERE id = :id", |
||
| 443 | array(':id' => $shipping['countryID']) |
||
| 444 | ); |
||
| 445 | $payment = Shopware()->Db()->fetchRow( |
||
| 446 | "SELECT * FROM s_core_paymentmeans WHERE id = :id", |
||
| 447 | array(':id' => $user['paymentID']) |
||
| 448 | ); |
||
| 449 | $customerGroup = Shopware()->Db()->fetchRow( |
||
| 450 | "SELECT * FROM s_core_customergroups WHERE groupkey = :key", |
||
| 451 | array(':key' => $user['customergroup']) |
||
| 452 | ); |
||
| 453 | |||
| 454 | $taxFree = (bool) ($countryShipping['taxfree']); |
||
| 455 | if ($countryShipping['taxfree_ustid']) { |
||
| 456 | if ($countryShipping['id'] == $country['id'] && $billing['ustid']) { |
||
| 457 | $taxFree = true; |
||
| 458 | } |
||
| 459 | } |
||
| 460 | |||
| 461 | if ($taxFree) { |
||
| 462 | $customerGroup['tax'] = 0; |
||
| 463 | } |
||
| 464 | |||
| 465 | Shopware()->Session()->sUserGroupData = $customerGroup; |
||
| 466 | |||
| 467 | return array( |
||
| 468 | 'user' => $user, |
||
| 469 | 'billingaddress' => $billing, |
||
| 470 | 'shippingaddress' => $shipping, |
||
| 471 | 'customerGroup' => $customerGroup, |
||
| 472 | 'additional' => array( |
||
| 473 | 'country' => $country, |
||
| 474 | 'state' => $state, |
||
| 475 | 'user' => $user, |
||
| 476 | 'countryShipping' => $countryShipping, |
||
| 477 | 'payment' => $payment, |
||
| 478 | 'charge_vat' => !$taxFree |
||
| 479 | ) |
||
| 480 | ); |
||
| 481 | } |
||
| 482 | } |
||
| 483 |