Skip to content
This repository was archived by the owner on Oct 27, 2022. It is now read-only.

Commit 07f0feb

Browse files
authored
Merge pull request #24 from grayloon/stable-version
Inline Commands for API sync operations, cleanup command
2 parents a161d35 + 786a69f commit 07f0feb

9 files changed

+245
-55
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Grayloon\MagentoStorage\Console;
4+
5+
use Grayloon\MagentoStorage\Models\MagentoCustomAttribute;
6+
use Illuminate\Console\Command;
7+
8+
class MagentoCleanAttributesCommand extends Command
9+
{
10+
protected $signature = 'magento:clean';
11+
12+
protected $description = 'Cleans up the database by removing missing relationships.';
13+
14+
protected $deleted = 0;
15+
protected $attributes;
16+
protected $count;
17+
18+
public function handle()
19+
{
20+
$count = MagentoCustomAttribute::count();
21+
22+
$this->info('Checking ' . $count . ' custom attributes...');
23+
24+
$this->attributes = MagentoCustomAttribute::with('attributable')
25+
->cursor();
26+
27+
$this->withProgressBar($this->attributes, function ($attribute) {
28+
if (! $attribute->attributable) {
29+
$attribute->delete();
30+
31+
$this->deleted++;
32+
}
33+
});
34+
35+
$this->newLine();
36+
$this->info($this->deleted . ' attributes with missing attributable relationships removed.');
37+
}
38+
}

src/Console/SyncMagentoCategoriesCommand.php

Lines changed: 66 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,78 @@
22

33
namespace Grayloon\MagentoStorage\Console;
44

5-
use Grayloon\MagentoStorage\Jobs\SyncMagentoCategories;
5+
use Grayloon\Magento\Magento;
6+
use Grayloon\MagentoStorage\Jobs\SyncMagentoCategoriesBatch;
7+
use Grayloon\MagentoStorage\Models\MagentoCategory;
8+
use Grayloon\MagentoStorage\Support\MagentoCategories;
69
use Illuminate\Console\Command;
710

811
class SyncMagentoCategoriesCommand extends Command
912
{
10-
/**
11-
* The name and signature of the console command.
12-
*
13-
* @var string
14-
*/
15-
protected $signature = 'magento:sync-categories';
16-
17-
/**
18-
* The console command description.
19-
*
20-
* @var string
21-
*/
22-
protected $description = 'Imports the category data from the Magneto 2 API';
23-
24-
/**
25-
* Execute the console command.
26-
*
27-
* @return int
28-
*/
13+
protected $signature = 'magento:sync-categories {--queue : Whether the job should be queued}';
14+
15+
protected $description = 'Sync the categories in Magento with your application.';
16+
17+
protected $bar;
18+
protected $count;
19+
protected $pages;
20+
protected $pageSize = 50;
21+
2922
public function handle()
3023
{
31-
SyncMagentoCategories::dispatch();
24+
$this->info('Retrieving categories from Magento...');
25+
26+
$this->count = (new MagentoCategories())->count();
27+
$this->info($this->count . ' categories found.');
28+
29+
$this->bar = $this->output
30+
->createProgressBar($this->count);
31+
$this->pages = ceil(($this->count / $this->pageSize) + 1);
32+
33+
return ($this->option('queue'))
34+
? $this->processViaQueue()
35+
: $this->processViaCommand();
36+
}
37+
38+
protected function processViaQueue()
39+
{
40+
for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
41+
SyncMagentoCategoriesBatch::dispatch($this->pageSize, $currentPage);
42+
}
43+
44+
$this->info('Queued job to sync Magento categories.');
45+
}
46+
47+
protected function processViaCommand()
48+
{
49+
if (env('MAGENTO_DEFAULT_CATEGORY')) {
50+
$this->newLine();
51+
$this->info('Looks like we have a root category of "'. env('MAGENTO_DEFAULT_CATEGORY') .'" configured in your env.');
52+
$this->info('We will only sync those categories associated with ID "'. env('MAGENTO_DEFAULT_CATEGORY') .'".');
53+
$this->info('Existing non-associated categories will be removed.');
54+
}
55+
56+
$this->newLine();
57+
$this->bar->start();
58+
59+
for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
60+
$categories = (new Magento())->api('categories')
61+
->all($this->pageSize, $currentPage)
62+
->json();
63+
64+
foreach ($categories['items'] as $category) {
65+
try {
66+
(new MagentoCategories())->updateCategory($category);
67+
} catch (\Exception $e) {
68+
//
69+
}
70+
$this->bar->advance();
71+
}
72+
}
3273

33-
$this->info('Successfully launched job to import magento categories.');
74+
$this->bar->finish();
75+
$this->newLine();
76+
$this->newLine();
77+
$this->info(MagentoCategory::count() . ' categories synced from the Magento instance to your application.');
3478
}
3579
}

src/Console/SyncMagentoProductsCommand.php

Lines changed: 79 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,91 @@
22

33
namespace Grayloon\MagentoStorage\Console;
44

5-
use Grayloon\MagentoStorage\Jobs\SyncMagentoProducts;
5+
use Grayloon\Magento\Magento;
6+
use Grayloon\MagentoStorage\Events\MagentoProductSynced;
7+
use Grayloon\MagentoStorage\Jobs\SyncMagentoProductsBatch;
8+
use Grayloon\MagentoStorage\Models\MagentoProduct;
9+
use Grayloon\MagentoStorage\Support\MagentoProducts;
610
use Illuminate\Console\Command;
711

812
class SyncMagentoProductsCommand extends Command
913
{
10-
/**
11-
* The name and signature of the console command.
12-
*
13-
* @var string
14-
*/
15-
protected $signature = 'magento:sync-products';
16-
17-
/**
18-
* The console command description.
19-
*
20-
* @var string
21-
*/
22-
protected $description = 'Imports the product data from the Magneto 2 API';
23-
24-
/**
25-
* Execute the console command.
26-
*
27-
* @return int
28-
*/
14+
protected $signature = 'magento:sync-products {--queue : Whether the job should be queued}';
15+
16+
protected $description = 'Sync the products in Magento with your application.';
17+
18+
protected $bar;
19+
protected $count;
20+
protected $pages;
21+
protected $pageSize = 100;
22+
2923
public function handle()
3024
{
31-
SyncMagentoProducts::dispatch();
25+
$this->info('Retrieving products from Magento...');
26+
27+
$this->count = (new MagentoProducts())->count();
28+
$this->info($this->count . ' products found.');
29+
30+
$this->bar = $this->output
31+
->createProgressBar($this->count);
32+
$this->pages = ceil(($this->count / $this->pageSize) + 1);
33+
34+
return ($this->option('queue'))
35+
? $this->processViaQueue()
36+
: $this->processViaCommand();
37+
}
38+
39+
protected function processViaQueue()
40+
{
41+
for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
42+
SyncMagentoProductsBatch::dispatch($this->pageSize, $currentPage);
43+
}
44+
45+
$this->info('Queued job to sync Magento products.');
46+
}
47+
48+
protected function processViaCommand()
49+
{
50+
if (config('magento.store_code')) {
51+
$this->newLine();
52+
$this->info('Default Store Code: "'. config('magento.store_code') .'" is configured in your env.');
53+
$this->info('We will only sync those products associated with "'. config('magento.store_code') .'".');
54+
$this->info('Existing non-associated products will be removed.');
55+
}
56+
57+
$this->newLine();
58+
$this->bar->start();
59+
60+
for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
61+
$products = (new Magento())->api('products')
62+
->all($this->pageSize, $currentPage)
63+
->json();
64+
65+
foreach ($products['items'] as $product) {
66+
try {
67+
$apiProduct = (new Magento())->api('products')
68+
->show($product['sku'])
69+
->json();
70+
71+
if (in_array(config('magento.default_store_id'), ($apiProduct)['extension_attributes']['website_ids'])) {
72+
$product = (new MagentoProducts())->updateOrCreateProduct($apiProduct);
73+
74+
event(new MagentoProductSynced($product));
75+
} else {
76+
// product doesnt exist in given website
77+
return (new MagentoProducts())->deleteIfExists($this->sku);
78+
}
79+
} catch (\Exception $e) {
80+
//
81+
}
82+
83+
$this->bar->advance();
84+
}
85+
}
3286

33-
$this->info('Successfully launched job to import magento products.');
87+
$this->bar->finish();
88+
$this->newLine();
89+
$this->newLine();
90+
$this->info(MagentoProduct::count() . ' products synced from the Magento instance to your application.');
3491
}
3592
}

src/Jobs/WaitForLinkedProductSku.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Grayloon\MagentoStorage\Jobs;
44

5-
use Exception;
65
use Grayloon\Magento\Magento;
76
use Grayloon\MagentoStorage\Models\MagentoProduct;
87
use Grayloon\MagentoStorage\Support\MagentoProducts;

src/MagentoStorageServiceProvider.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public function register()
8383
Console\SyncMagentoProductCategoriesCommand::class,
8484
Console\SyncMagentoCustomAttributeTypesCommand::class,
8585
Console\SyncMagentoWebsitesCommand::class,
86+
Console\MagentoCleanAttributesCommand::class,
8687
]);
8788
}
8889
}

src/Support/MagentoCategories.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,7 @@ public function updateCategories($categories)
3838
}
3939

4040
foreach ($categories as $apiCategory) {
41-
if ($this->validCategory($apiCategory)) {
42-
$this->updateCategory($apiCategory);
43-
}
41+
$this->updateCategory($apiCategory);
4442
}
4543

4644
return $this;
@@ -110,6 +108,10 @@ protected function downloadCategoryImage($customAttributes, $category)
110108
*/
111109
public function updateCategory($apiCategory)
112110
{
111+
if (! $this->validCategory($apiCategory)) {
112+
return;
113+
}
114+
113115
$category = MagentoCategory::updateOrCreate(['id' => $apiCategory['id']], [
114116
'name' => $apiCategory['name'],
115117
'slug' => $this->findAttributeByKey('url_path', $apiCategory['custom_attributes']),
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace Grayloon\MagentoStorage\Tests\Console;
4+
5+
use Grayloon\MagentoStorage\Database\Factories\MagentoCustomAttributeFactory;
6+
use Grayloon\MagentoStorage\Database\Factories\MagentoProductFactory;
7+
use Grayloon\MagentoStorage\Models\MagentoCustomAttribute;
8+
use Grayloon\MagentoStorage\Models\MagentoProduct;
9+
use Grayloon\MagentoStorage\Tests\TestCase;
10+
11+
class MagentoCleanAttributesCommandTest extends TestCase
12+
{
13+
public function test_it_removes_missing_relational_custom_attributes()
14+
{
15+
$attribute = MagentoCustomAttributeFactory::new()->create([
16+
'attributable_type' => MagentoProduct::class,
17+
'attributable_id' => 123,
18+
]);
19+
20+
$this->artisan('magento:clean');
21+
22+
$this->assertDeleted($attribute);
23+
}
24+
25+
public function test_it_keeps_relational_match_custom_attribute()
26+
{
27+
$product = MagentoProductFactory::new()->create();
28+
$attribute = MagentoCustomAttributeFactory::new()->create([
29+
'attributable_type' => MagentoProduct::class,
30+
'attributable_id' => $product->id,
31+
]);
32+
33+
$this->artisan('magento:clean');
34+
35+
$this->assertEquals(1, MagentoCustomAttribute::count());
36+
}
37+
}

tests/Console/SyncMagentoCategoriesCommandTest.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,24 @@
22

33
namespace Grayloon\MagentoStorage\Tests\Console;
44

5-
use Grayloon\MagentoStorage\Jobs\SyncMagentoCategories;
5+
use Grayloon\MagentoStorage\Jobs\SyncMagentoCategoriesBatch;
66
use Grayloon\MagentoStorage\Tests\TestCase;
7+
use Illuminate\Support\Facades\Http;
78
use Illuminate\Support\Facades\Queue;
89

910
class SyncMagentoCategoriesCommandTest extends TestCase
1011
{
1112
public function test_magento_categories_command_fires_product_job()
1213
{
1314
Queue::fake();
15+
Http::fake(function ($request) {
16+
return Http::response([
17+
'total_count' => 1,
18+
], 200);
19+
});
20+
21+
$this->artisan('magento:sync-categories --queue');
1422

15-
$this->artisan('magento:sync-categories');
16-
17-
Queue::assertPushed(SyncMagentoCategories::class);
23+
Queue::assertPushed(SyncMagentoCategoriesBatch::class);
1824
}
1925
}

tests/Console/SyncMagentoProductsCommandTest.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,24 @@
22

33
namespace Grayloon\MagentoStorage\Tests\Console;
44

5-
use Grayloon\MagentoStorage\Jobs\SyncMagentoProducts;
5+
use Grayloon\MagentoStorage\Jobs\SyncMagentoProductsBatch;
66
use Grayloon\MagentoStorage\Tests\TestCase;
7+
use Illuminate\Support\Facades\Http;
78
use Illuminate\Support\Facades\Queue;
89

910
class SyncMagentoProductsCommandTest extends TestCase
1011
{
1112
public function test_magento_products_command_fires_product_job()
1213
{
1314
Queue::fake();
15+
Http::fake(function ($request) {
16+
return Http::response([
17+
'total_count' => 1,
18+
], 200);
19+
});
1420

15-
$this->artisan('magento:sync-products');
21+
$this->artisan('magento:sync-products --queue');
1622

17-
Queue::assertPushed(SyncMagentoProducts::class);
23+
Queue::assertPushed(SyncMagentoProductsBatch::class);
1824
}
1925
}

0 commit comments

Comments
 (0)