Complex classes like ProductToShop often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ProductToShop, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 45 | class ProductToShop implements ProductToShopBase |
||
| 46 | { |
||
| 47 | /** |
||
| 48 | * @var Helper |
||
| 49 | */ |
||
| 50 | private $helper; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * @var ModelManager |
||
| 54 | */ |
||
| 55 | private $manager; |
||
| 56 | |||
| 57 | /** |
||
| 58 | * @var \ShopwarePlugins\Connect\Components\Config |
||
| 59 | */ |
||
| 60 | private $config; |
||
| 61 | |||
| 62 | /** |
||
| 63 | * @var ImageImport |
||
| 64 | */ |
||
| 65 | private $imageImport; |
||
| 66 | |||
| 67 | /** |
||
| 68 | * @var \ShopwarePlugins\Connect\Components\VariantConfigurator |
||
| 69 | */ |
||
| 70 | private $variantConfigurator; |
||
| 71 | |||
| 72 | /** |
||
| 73 | * @var MarketplaceGateway |
||
| 74 | */ |
||
| 75 | private $marketplaceGateway; |
||
| 76 | |||
| 77 | /** |
||
| 78 | * @var ProductTranslationsGateway |
||
| 79 | */ |
||
| 80 | private $productTranslationsGateway; |
||
| 81 | |||
| 82 | /** |
||
| 83 | * @var \Shopware\Models\Shop\Repository |
||
| 84 | */ |
||
| 85 | private $shopRepository; |
||
| 86 | |||
| 87 | private $localeRepository; |
||
| 88 | |||
| 89 | /** |
||
| 90 | * @var CategoryResolver |
||
| 91 | */ |
||
| 92 | private $categoryResolver; |
||
| 93 | |||
| 94 | /** |
||
| 95 | * @var \Shopware\Connect\Gateway |
||
| 96 | */ |
||
| 97 | private $connectGateway; |
||
| 98 | |||
| 99 | /** |
||
| 100 | * @var \Enlight_Event_EventManager |
||
| 101 | */ |
||
| 102 | private $eventManager; |
||
| 103 | |||
| 104 | /** |
||
| 105 | * @var CategoryDenormalization |
||
| 106 | */ |
||
| 107 | private $categoryDenormalization; |
||
| 108 | |||
| 109 | /** |
||
| 110 | * @param Helper $helper |
||
| 111 | * @param ModelManager $manager |
||
| 112 | * @param ImageImport $imageImport |
||
| 113 | * @param \ShopwarePlugins\Connect\Components\Config $config |
||
| 114 | * @param VariantConfigurator $variantConfigurator |
||
| 115 | * @param \ShopwarePlugins\Connect\Components\Marketplace\MarketplaceGateway $marketplaceGateway |
||
| 116 | * @param ProductTranslationsGateway $productTranslationsGateway |
||
| 117 | * @param CategoryResolver $categoryResolver |
||
| 118 | * @param Gateway $connectGateway |
||
| 119 | * @param \Enlight_Event_EventManager $eventManager |
||
| 120 | * @param CategoryDenormalization $categoryDenormalization |
||
| 121 | */ |
||
| 122 | public function __construct( |
||
| 123 | Helper $helper, |
||
| 124 | ModelManager $manager, |
||
| 125 | ImageImport $imageImport, |
||
| 126 | Config $config, |
||
| 127 | VariantConfigurator $variantConfigurator, |
||
| 128 | MarketplaceGateway $marketplaceGateway, |
||
| 129 | ProductTranslationsGateway $productTranslationsGateway, |
||
| 130 | CategoryResolver $categoryResolver, |
||
| 131 | Gateway $connectGateway, |
||
| 132 | \Enlight_Event_EventManager $eventManager, |
||
| 133 | CategoryDenormalization $categoryDenormalization |
||
| 134 | ) { |
||
| 135 | $this->helper = $helper; |
||
| 136 | $this->manager = $manager; |
||
| 137 | $this->config = $config; |
||
| 138 | $this->imageImport = $imageImport; |
||
| 139 | $this->variantConfigurator = $variantConfigurator; |
||
| 140 | $this->marketplaceGateway = $marketplaceGateway; |
||
| 141 | $this->productTranslationsGateway = $productTranslationsGateway; |
||
| 142 | $this->categoryResolver = $categoryResolver; |
||
| 143 | $this->connectGateway = $connectGateway; |
||
| 144 | $this->eventManager = $eventManager; |
||
| 145 | $this->categoryDenormalization = $categoryDenormalization; |
||
| 146 | } |
||
| 147 | |||
| 148 | /** |
||
| 149 | * Start transaction |
||
| 150 | * |
||
| 151 | * Starts a transaction, which includes all insertOrUpdate and delete |
||
| 152 | * operations, as well as the revision updates. |
||
| 153 | * |
||
| 154 | * @return void |
||
| 155 | */ |
||
| 156 | public function startTransaction() |
||
| 157 | { |
||
| 158 | $this->manager->getConnection()->beginTransaction(); |
||
| 159 | } |
||
| 160 | |||
| 161 | /** |
||
| 162 | * Commit transaction |
||
| 163 | * |
||
| 164 | * Commits the transactions, once all operations are queued. |
||
| 165 | * |
||
| 166 | * @return void |
||
| 167 | */ |
||
| 168 | public function commit() |
||
| 169 | { |
||
| 170 | $this->manager->getConnection()->commit(); |
||
| 171 | } |
||
| 172 | |||
| 173 | /** |
||
| 174 | * Import or update given product |
||
| 175 | * |
||
| 176 | * Store product in your shop database as an external product. The |
||
| 177 | * associated sourceId |
||
| 178 | * |
||
| 179 | * @param Product $product |
||
| 180 | */ |
||
| 181 | public function insertOrUpdate(Product $product) |
||
| 182 | { |
||
| 183 | /** @var Product $product */ |
||
| 184 | $product = $this->eventManager->filter( |
||
| 185 | 'Connect_ProductToShop_InsertOrUpdate_Before', |
||
| 186 | $product |
||
| 187 | ); |
||
| 188 | |||
| 189 | // todo@dn: Set dummy values and make product inactive |
||
| 190 | if (empty($product->title) || empty($product->vendor)) { |
||
| 191 | return; |
||
| 192 | } |
||
| 193 | |||
| 194 | if (!empty($product->sku)) { |
||
| 195 | $number = 'SC-' . $product->shopId . '-' . $product->sku; |
||
| 196 | $duplicatedDetail = $this->helper->getDetailByNumber($number); |
||
| 197 | if ($duplicatedDetail |
||
| 198 | && $this->helper->getConnectAttributeByModel($duplicatedDetail)->getSourceId() != $product->sourceId |
||
| 199 | ) { |
||
| 200 | $this->deleteDetail($duplicatedDetail); |
||
| 201 | } |
||
| 202 | } else { |
||
| 203 | $number = 'SC-' . $product->shopId . '-' . $product->sourceId; |
||
| 204 | } |
||
| 205 | |||
| 206 | $detail = $this->helper->getArticleDetailModelByProduct($product); |
||
| 207 | $detail = $this->eventManager->filter( |
||
| 208 | 'Connect_Merchant_Get_Article_Detail_After', |
||
| 209 | $detail, |
||
| 210 | [ |
||
| 211 | 'product' => $product, |
||
| 212 | 'subject' => $this |
||
| 213 | ] |
||
| 214 | ); |
||
| 215 | |||
| 216 | $isMainVariant = false; |
||
| 217 | if ($detail === null) { |
||
| 218 | $active = $this->config->getConfig('activateProductsAutomatically', false) ? true : false; |
||
| 219 | if ($product->groupId !== null) { |
||
| 220 | $model = $this->helper->getArticleByRemoteProduct($product); |
||
| 221 | if (!$model instanceof \Shopware\Models\Article\Article) { |
||
|
|
|||
| 222 | $model = $this->helper->createProductModel($product); |
||
| 223 | $model->setActive($active); |
||
| 224 | $isMainVariant = true; |
||
| 225 | } |
||
| 226 | } else { |
||
| 227 | $model = $this->helper->getConnectArticleModel($product->sourceId, $product->shopId); |
||
| 228 | if (!$model instanceof \Shopware\Models\Article\Article) { |
||
| 229 | $model = $this->helper->createProductModel($product); |
||
| 230 | $model->setActive($active); |
||
| 231 | } |
||
| 232 | } |
||
| 233 | |||
| 234 | $detail = new DetailModel(); |
||
| 235 | $detail->setActive($model->getActive()); |
||
| 236 | $this->manager->persist($detail); |
||
| 237 | $detail->setArticle($model); |
||
| 238 | $model->getDetails()->add($detail); |
||
| 239 | if (!empty($product->variant)) { |
||
| 240 | $this->variantConfigurator->configureVariantAttributes($product, $detail); |
||
| 241 | } |
||
| 242 | } else { |
||
| 243 | $model = $detail->getArticle(); |
||
| 244 | // fix for isMainVariant flag |
||
| 245 | // in connect attribute table |
||
| 246 | $mainDetail = $model->getMainDetail(); |
||
| 247 | if ($detail->getId() === $mainDetail->getId()) { |
||
| 248 | $isMainVariant = true; |
||
| 249 | } |
||
| 250 | |||
| 251 | if (empty($product->variant) && $model->getConfiguratorSet()) { |
||
| 252 | $this->manager->getConnection()->executeQuery( |
||
| 253 | 'UPDATE s_articles SET configurator_set_id = NULL WHERE id = ?', |
||
| 254 | [$model->getId()] |
||
| 255 | ); |
||
| 256 | } |
||
| 257 | } |
||
| 258 | |||
| 259 | $detail->setNumber($number); |
||
| 260 | |||
| 261 | /** @var \Shopware\Models\Category\Category $category */ |
||
| 262 | foreach ($model->getCategories() as $category) { |
||
| 263 | $attribute = $category->getAttribute(); |
||
| 264 | if (!$attribute) { |
||
| 265 | continue; |
||
| 266 | } |
||
| 267 | |||
| 268 | if ($attribute->getConnectImported()) { |
||
| 269 | $model->removeCategory($category); |
||
| 270 | } |
||
| 271 | } |
||
| 272 | |||
| 273 | $detailAttribute = $detail->getAttribute(); |
||
| 274 | if (!$detailAttribute) { |
||
| 275 | $detailAttribute = new AttributeModel(); |
||
| 276 | $detail->setAttribute($detailAttribute); |
||
| 277 | $model->setAttribute($detailAttribute); |
||
| 278 | $detailAttribute->setArticle($model); |
||
| 279 | $detailAttribute->setArticleDetail($detail); |
||
| 280 | } |
||
| 281 | |||
| 282 | $connectAttribute = $this->helper->getConnectAttributeByModel($detail) ?: new ConnectAttribute; |
||
| 283 | // configure main variant and groupId |
||
| 284 | if ($isMainVariant === true) { |
||
| 285 | $connectAttribute->setIsMainVariant(true); |
||
| 286 | } |
||
| 287 | $connectAttribute->setGroupId($product->groupId); |
||
| 288 | |||
| 289 | list($updateFields, $flag) = $this->getUpdateFields($model, $detail, $connectAttribute, $product); |
||
| 290 | /* |
||
| 291 | * Make sure, that the following properties are set for |
||
| 292 | * - new products |
||
| 293 | * - products that have been configured to receive these updates |
||
| 294 | */ |
||
| 295 | if ($updateFields['name']) { |
||
| 296 | $model->setName($product->title); |
||
| 297 | } |
||
| 298 | if ($updateFields['shortDescription']) { |
||
| 299 | $model->setDescription($product->shortDescription); |
||
| 300 | } |
||
| 301 | if ($updateFields['longDescription']) { |
||
| 302 | $model->setDescriptionLong($product->longDescription); |
||
| 303 | } |
||
| 304 | |||
| 305 | if ($updateFields['additionalDescription']) { |
||
| 306 | $detailAttribute->setConnectProductDescription($product->additionalDescription); |
||
| 307 | } |
||
| 308 | |||
| 309 | $this->saveVat($product, $model); |
||
| 310 | |||
| 311 | if ($product->vendor !== null) { |
||
| 312 | $repo = $this->manager->getRepository('Shopware\Models\Article\Supplier'); |
||
| 313 | $supplier = $repo->findOneBy(['name' => $product->vendor]); |
||
| 314 | if ($supplier === null) { |
||
| 315 | $supplier = $this->createSupplier($product->vendor); |
||
| 316 | } |
||
| 317 | $model->setSupplier($supplier); |
||
| 318 | } |
||
| 319 | |||
| 320 | //set product properties |
||
| 321 | $this->applyProductProperties($model, $product); |
||
| 322 | |||
| 323 | // apply marketplace attributes |
||
| 324 | $detailAttribute = $this->applyMarketplaceAttributes($detailAttribute, $product); |
||
| 325 | |||
| 326 | $connectAttribute->setShopId($product->shopId); |
||
| 327 | $connectAttribute->setSourceId($product->sourceId); |
||
| 328 | $connectAttribute->setExportStatus(null); |
||
| 329 | $connectAttribute->setPurchasePrice($product->purchasePrice); |
||
| 330 | $connectAttribute->setFixedPrice($product->fixedPrice); |
||
| 331 | $connectAttribute->setStream($product->stream); |
||
| 332 | |||
| 333 | // store product categories to connect attribute |
||
| 334 | $connectAttribute->setCategory($product->categories); |
||
| 335 | |||
| 336 | $connectAttribute->setLastUpdateFlag($flag); |
||
| 337 | // store purchasePriceHash and offerValidUntil |
||
| 338 | $connectAttribute->setPurchasePriceHash($product->purchasePriceHash); |
||
| 339 | $connectAttribute->setOfferValidUntil($product->offerValidUntil); |
||
| 340 | |||
| 341 | $detail->setInStock($product->availability); |
||
| 342 | $detail->setEan($product->ean); |
||
| 343 | $detail->setShippingTime($product->deliveryWorkDays); |
||
| 344 | $releaseDate = new \DateTime(); |
||
| 345 | $releaseDate->setTimestamp($product->deliveryDate); |
||
| 346 | $detail->setReleaseDate($releaseDate); |
||
| 347 | $detail->setMinPurchase($product->minPurchaseQuantity); |
||
| 348 | |||
| 349 | // some shops have feature "sell not in stock", |
||
| 350 | // then end customer should be able to by the product with stock = 0 |
||
| 351 | $shopConfiguration = $this->connectGateway->getShopConfiguration($product->shopId); |
||
| 352 | if ($shopConfiguration && $shopConfiguration->sellNotInStock) { |
||
| 353 | $model->setLastStock(false); |
||
| 354 | } else { |
||
| 355 | $model->setLastStock(true); |
||
| 356 | } |
||
| 357 | |||
| 358 | // if connect product has unit |
||
| 359 | // find local unit with units mapping |
||
| 360 | // and add to detail model |
||
| 361 | if (array_key_exists('unit', $product->attributes) && $product->attributes['unit']) { |
||
| 362 | $detailAttribute->setConnectRemoteUnit($product->attributes['unit']); |
||
| 363 | if ($this->config->getConfig($product->attributes['unit']) == null) { |
||
| 364 | $this->config->setConfig($product->attributes['unit'], '', null, 'units'); |
||
| 365 | } |
||
| 366 | |||
| 367 | /** @var \ShopwarePlugins\Connect\Components\Utils\UnitMapper $unitMapper */ |
||
| 368 | $unitMapper = new UnitMapper($this->config, $this->manager); |
||
| 369 | |||
| 370 | $shopwareUnit = $unitMapper->getShopwareUnit($product->attributes['unit']); |
||
| 371 | |||
| 372 | /** @var \Shopware\Models\Article\Unit $unit */ |
||
| 373 | $unit = $this->helper->getUnit($shopwareUnit); |
||
| 374 | $detail->setUnit($unit); |
||
| 375 | $detail->setPurchaseUnit($product->attributes['quantity']); |
||
| 376 | $detail->setReferenceUnit($product->attributes['ref_quantity']); |
||
| 377 | } else { |
||
| 378 | $detail->setUnit(null); |
||
| 379 | $detail->setPurchaseUnit(null); |
||
| 380 | $detail->setReferenceUnit(null); |
||
| 381 | } |
||
| 382 | |||
| 383 | // set dimension |
||
| 384 | if (array_key_exists('dimension', $product->attributes) && $product->attributes['dimension']) { |
||
| 385 | $dimension = explode('x', $product->attributes['dimension']); |
||
| 386 | $detail->setLen($dimension[0]); |
||
| 387 | $detail->setWidth($dimension[1]); |
||
| 388 | $detail->setHeight($dimension[2]); |
||
| 389 | } else { |
||
| 390 | $detail->setLen(null); |
||
| 391 | $detail->setWidth(null); |
||
| 392 | $detail->setHeight(null); |
||
| 393 | } |
||
| 394 | |||
| 395 | // set weight |
||
| 396 | if (array_key_exists('weight', $product->attributes) && $product->attributes['weight']) { |
||
| 397 | $detail->setWeight($product->attributes['weight']); |
||
| 398 | } |
||
| 399 | |||
| 400 | //set package unit |
||
| 401 | if (array_key_exists(Product::ATTRIBUTE_PACKAGEUNIT, $product->attributes)) { |
||
| 402 | $detail->setPackUnit($product->attributes[Product::ATTRIBUTE_PACKAGEUNIT]); |
||
| 403 | } |
||
| 404 | |||
| 405 | //set basic unit |
||
| 406 | if (array_key_exists(Product::ATTRIBUTE_BASICUNIT, $product->attributes)) { |
||
| 407 | $detail->setMinPurchase($product->attributes[Product::ATTRIBUTE_BASICUNIT]); |
||
| 408 | } |
||
| 409 | |||
| 410 | //set manufacturer no. |
||
| 411 | if (array_key_exists(Product::ATTRIBUTE_MANUFACTURERNUMBER, $product->attributes)) { |
||
| 412 | $detail->setSupplierNumber($product->attributes[Product::ATTRIBUTE_MANUFACTURERNUMBER]); |
||
| 413 | } |
||
| 414 | |||
| 415 | // Whenever a product is updated, store a json encoded list of all fields that are updated optionally |
||
| 416 | // This way a customer will be able to apply the most recent changes any time later |
||
| 417 | $connectAttribute->setLastUpdate(json_encode([ |
||
| 418 | 'shortDescription' => $product->shortDescription, |
||
| 419 | 'longDescription' => $product->longDescription, |
||
| 420 | 'additionalDescription' => $product->additionalDescription, |
||
| 421 | 'purchasePrice' => $product->purchasePrice, |
||
| 422 | 'image' => $product->images, |
||
| 423 | 'variantImages' => $product->variantImages, |
||
| 424 | 'price' => $product->price * ($product->vat + 1), |
||
| 425 | 'name' => $product->title, |
||
| 426 | 'vat' => $product->vat |
||
| 427 | ])); |
||
| 428 | |||
| 429 | if ($model->getMainDetail() === null) { |
||
| 430 | $model->setMainDetail($detail); |
||
| 431 | } |
||
| 432 | |||
| 433 | if ($detail->getAttribute() === null) { |
||
| 434 | $detail->setAttribute($detailAttribute); |
||
| 435 | $detailAttribute->setArticle($model); |
||
| 436 | } |
||
| 437 | |||
| 438 | $connectAttribute->setArticle($model); |
||
| 439 | $connectAttribute->setArticleDetail($detail); |
||
| 440 | |||
| 441 | $this->eventManager->notify( |
||
| 442 | 'Connect_Merchant_Saving_ArticleAttribute_Before', |
||
| 443 | [ |
||
| 444 | 'subject' => $this, |
||
| 445 | 'connectAttribute' => $connectAttribute |
||
| 446 | ] |
||
| 447 | ); |
||
| 448 | |||
| 449 | $this->manager->persist($model); |
||
| 450 | $this->manager->flush(); |
||
| 451 | |||
| 452 | $this->categoryResolver->storeRemoteCategories($product->categories, $model->getId()); |
||
| 453 | $categories = $this->categoryResolver->resolve($product->categories); |
||
| 454 | if (count($categories) > 0) { |
||
| 455 | $detailAttribute->setConnectMappedCategory(true); |
||
| 456 | } |
||
| 457 | |||
| 458 | $this->manager->persist($connectAttribute); |
||
| 459 | $this->manager->persist($detail); |
||
| 460 | //article has to be flushed |
||
| 461 | $this->manager->persist($detailAttribute); |
||
| 462 | $this->manager->flush(); |
||
| 463 | |||
| 464 | $this->categoryDenormalization->disableTransactions(); |
||
| 465 | foreach ($categories as $category) { |
||
| 466 | $this->categoryDenormalization->addAssignment($model->getId(), $category); |
||
| 467 | $this->manager->getConnection()->executeQuery( |
||
| 468 | 'INSERT IGNORE INTO `s_articles_categories` (`articleID`, `categoryID`) VALUES (?,?)', |
||
| 469 | [$model->getId(), $category] |
||
| 470 | ); |
||
| 471 | } |
||
| 472 | $this->categoryDenormalization->enableTransactions(); |
||
| 473 | |||
| 474 | $defaultCustomerGroup = $this->helper->getDefaultCustomerGroup(); |
||
| 475 | // Only set prices, if fixedPrice is active or price updates are configured |
||
| 476 | if (count($detail->getPrices()) == 0 || $connectAttribute->getFixedPrice() || $updateFields['price']) { |
||
| 477 | $this->setPrice($model, $detail, $product); |
||
| 478 | } |
||
| 479 | // If the price is not being update, update the purchasePrice anyway |
||
| 480 | $this->setPurchasePrice($detail, $product->purchasePrice, $defaultCustomerGroup); |
||
| 481 | |||
| 482 | $this->manager->clear(); |
||
| 483 | |||
| 484 | $this->addArticleTranslations($model, $product); |
||
| 485 | |||
| 486 | //clear cache for that article |
||
| 487 | $this->helper->clearArticleCache($model->getId()); |
||
| 488 | |||
| 489 | if ($updateFields['image']) { |
||
| 490 | // Reload the model in order to not to work an the already flushed model |
||
| 491 | $model = $this->helper->getArticleModelByProduct($product); |
||
| 492 | // import only global images for article |
||
| 493 | $this->imageImport->importImagesForArticle(array_diff($product->images, $product->variantImages), $model); |
||
| 494 | // Reload the article detail model in order to not to work an the already flushed model |
||
| 495 | $detail = $this->helper->getArticleDetailModelByProduct($product); |
||
| 496 | // import only specific images for variant |
||
| 497 | $this->imageImport->importImagesForDetail($product->variantImages, $detail); |
||
| 498 | } |
||
| 499 | |||
| 500 | $this->eventManager->notify( |
||
| 501 | 'Connect_ProductToShop_InsertOrUpdate_After', |
||
| 502 | [ |
||
| 503 | 'connectProduct' => $product, |
||
| 504 | 'shopArticleDetail' => $detail |
||
| 505 | ] |
||
| 506 | ); |
||
| 507 | |||
| 508 | $stream = $this->getOrCreateStream($product); |
||
| 509 | $this->addProductToStream($stream, $model); |
||
| 510 | } |
||
| 511 | |||
| 512 | /** |
||
| 513 | * @param ProductModel $article |
||
| 514 | * @param Product $product |
||
| 515 | */ |
||
| 516 | private function applyProductProperties(ProductModel $article, Product $product) |
||
| 608 | |||
| 609 | /** |
||
| 610 | * @param Product $product |
||
| 611 | * @return ProductStream |
||
| 612 | */ |
||
| 613 | private function getOrCreateStream(Product $product) |
||
| 640 | |||
| 641 | /** |
||
| 642 | * @param ProductStream $stream |
||
| 643 | * @param ProductModel $article |
||
| 644 | * @throws \Doctrine\DBAL\DBALException |
||
| 645 | */ |
||
| 646 | private function addProductToStream(ProductStream $stream, ProductModel $article) |
||
| 655 | |||
| 656 | /** |
||
| 657 | * Set detail purchase price with plain SQL |
||
| 658 | * Entity usage throws exception when error handlers are disabled |
||
| 659 | * |
||
| 660 | * @param ProductModel $article |
||
| 661 | * @param DetailModel $detail |
||
| 662 | * @param Product $product |
||
| 663 | * @throws \Doctrine\DBAL\DBALException |
||
| 664 | */ |
||
| 665 | private function setPrice(ProductModel $article, DetailModel $detail, Product $product) |
||
| 697 | |||
| 698 | /** |
||
| 699 | * @param ProductModel $article |
||
| 700 | * @param DetailModel $detail |
||
| 701 | * @param array $priceRanges |
||
| 702 | * @param Group $group |
||
| 703 | * @throws \Doctrine\DBAL\ConnectionException |
||
| 704 | * @throws \Exception |
||
| 705 | */ |
||
| 706 | private function setPriceRange(ProductModel $article, DetailModel $detail, array $priceRanges, Group $group) |
||
| 742 | |||
| 743 | /** |
||
| 744 | * Adds translation record for given article |
||
| 745 | * |
||
| 746 | * @param ProductModel $article |
||
| 747 | * @param Product $sdkProduct |
||
| 748 | */ |
||
| 749 | private function addArticleTranslations(ProductModel $article, Product $sdkProduct) |
||
| 764 | |||
| 765 | /** |
||
| 766 | * dsadsa |
||
| 767 | * @return \Shopware\Components\Model\ModelRepository |
||
| 768 | */ |
||
| 769 | private function getLocaleRepository() |
||
| 777 | |||
| 778 | private function getShopRepository() |
||
| 786 | |||
| 787 | /** |
||
| 788 | * Delete product or product variant with given shopId and sourceId. |
||
| 789 | * |
||
| 790 | * Only the combination of both identifies a product uniquely. Do NOT |
||
| 791 | * delete products just by their sourceId. |
||
| 792 | * |
||
| 793 | * You might receive delete requests for products, which are not available |
||
| 794 | * in your shop. Just ignore them. |
||
| 795 | * |
||
| 796 | * @param string $shopId |
||
| 797 | * @param string $sourceId |
||
| 798 | * @return void |
||
| 799 | */ |
||
| 800 | public function delete($shopId, $sourceId) |
||
| 812 | |||
| 813 | /** |
||
| 814 | * @param DetailModel $detailModel |
||
| 815 | */ |
||
| 816 | private function deleteDetail(DetailModel $detailModel) |
||
| 869 | |||
| 870 | /** |
||
| 871 | * Get array of update info for the known fields |
||
| 872 | * |
||
| 873 | * @param $model |
||
| 874 | * @param $detail |
||
| 875 | * @param $attribute |
||
| 876 | * @param $product |
||
| 877 | * @return array |
||
| 878 | */ |
||
| 879 | public function getUpdateFields($model, $detail, $attribute, $product) |
||
| 909 | |||
| 910 | /** |
||
| 911 | * Determine if a given field has changed |
||
| 912 | * |
||
| 913 | * @param $field |
||
| 914 | * @param ProductModel $model |
||
| 915 | * @param DetailModel $detail |
||
| 916 | * @param Product $product |
||
| 917 | * @return bool |
||
| 918 | */ |
||
| 919 | public function hasFieldChanged($field, ProductModel $model, DetailModel $detail, Product $product) |
||
| 947 | |||
| 948 | /** |
||
| 949 | * Helper method to determine if a given $fields may/must be updated. |
||
| 950 | * This method will check for the model->id in order to determine, if it is a new entity. Therefore |
||
| 951 | * this method cannot be used after the model in question was already flushed. |
||
| 952 | * |
||
| 953 | * @param $field |
||
| 954 | * @param $model ProductModel |
||
| 955 | * @param $attribute ConnectAttribute |
||
| 956 | * @throws \RuntimeException |
||
| 957 | * @return bool|null |
||
| 958 | */ |
||
| 959 | public function isFieldUpdateAllowed($field, ProductModel $model, ConnectAttribute $attribute) |
||
| 995 | |||
| 996 | /** |
||
| 997 | * Read product attributes mapping and set to shopware attribute model |
||
| 998 | * |
||
| 999 | * @param AttributeModel $detailAttribute |
||
| 1000 | * @param Product $product |
||
| 1001 | * @return AttributeModel |
||
| 1002 | */ |
||
| 1003 | private function applyMarketplaceAttributes(AttributeModel $detailAttribute, Product $product) |
||
| 1018 | |||
| 1019 | /** |
||
| 1020 | * @param $vendor |
||
| 1021 | * @return Supplier |
||
| 1022 | */ |
||
| 1023 | private function createSupplier($vendor) |
||
| 1051 | |||
| 1052 | /** |
||
| 1053 | * Set detail purchase price with plain SQL |
||
| 1054 | * Entity usage throws exception when error handlers are disabled |
||
| 1055 | * |
||
| 1056 | * @param DetailModel $detail |
||
| 1057 | * @param float $purchasePrice |
||
| 1058 | * @param Group $defaultGroup |
||
| 1059 | * @throws \Doctrine\DBAL\DBALException |
||
| 1060 | */ |
||
| 1061 | private function setPurchasePrice(DetailModel $detail, $purchasePrice, Group $defaultGroup) |
||
| 1089 | |||
| 1090 | public function update($shopId, $sourceId, ProductUpdate $product) |
||
| 1142 | |||
| 1143 | public function changeAvailability($shopId, $sourceId, $availability) |
||
| 1167 | |||
| 1168 | /** |
||
| 1169 | * @inheritDoc |
||
| 1170 | */ |
||
| 1171 | public function makeMainVariant($shopId, $sourceId, $groupId) |
||
| 1204 | |||
| 1205 | /** |
||
| 1206 | * @param Product $product |
||
| 1207 | * @param ProductModel $model |
||
| 1208 | */ |
||
| 1209 | private function saveVat(Product $product, ProductModel $model) |
||
| 1227 | } |
||
| 1228 |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.