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

Commit

Permalink
Merge pull request #24 from grayloon/stable-version
Browse files Browse the repository at this point in the history
Inline Commands for API sync operations, cleanup command
  • Loading branch information
ahinkle authored Apr 8, 2021
2 parents a161d35 + 786a69f commit 07f0feb
Show file tree
Hide file tree
Showing 9 changed files with 245 additions and 55 deletions.
38 changes: 38 additions & 0 deletions src/Console/MagentoCleanAttributesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Grayloon\MagentoStorage\Console;

use Grayloon\MagentoStorage\Models\MagentoCustomAttribute;
use Illuminate\Console\Command;

class MagentoCleanAttributesCommand extends Command
{
protected $signature = 'magento:clean';

protected $description = 'Cleans up the database by removing missing relationships.';

protected $deleted = 0;
protected $attributes;
protected $count;

public function handle()
{
$count = MagentoCustomAttribute::count();

$this->info('Checking ' . $count . ' custom attributes...');

$this->attributes = MagentoCustomAttribute::with('attributable')
->cursor();

$this->withProgressBar($this->attributes, function ($attribute) {
if (! $attribute->attributable) {
$attribute->delete();

$this->deleted++;
}
});

$this->newLine();
$this->info($this->deleted . ' attributes with missing attributable relationships removed.');
}
}
88 changes: 66 additions & 22 deletions src/Console/SyncMagentoCategoriesCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,78 @@

namespace Grayloon\MagentoStorage\Console;

use Grayloon\MagentoStorage\Jobs\SyncMagentoCategories;
use Grayloon\Magento\Magento;
use Grayloon\MagentoStorage\Jobs\SyncMagentoCategoriesBatch;
use Grayloon\MagentoStorage\Models\MagentoCategory;
use Grayloon\MagentoStorage\Support\MagentoCategories;
use Illuminate\Console\Command;

class SyncMagentoCategoriesCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'magento:sync-categories';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Imports the category data from the Magneto 2 API';

/**
* Execute the console command.
*
* @return int
*/
protected $signature = 'magento:sync-categories {--queue : Whether the job should be queued}';

protected $description = 'Sync the categories in Magento with your application.';

protected $bar;
protected $count;
protected $pages;
protected $pageSize = 50;

public function handle()
{
SyncMagentoCategories::dispatch();
$this->info('Retrieving categories from Magento...');

$this->count = (new MagentoCategories())->count();
$this->info($this->count . ' categories found.');

$this->bar = $this->output
->createProgressBar($this->count);
$this->pages = ceil(($this->count / $this->pageSize) + 1);

return ($this->option('queue'))
? $this->processViaQueue()
: $this->processViaCommand();
}

protected function processViaQueue()
{
for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
SyncMagentoCategoriesBatch::dispatch($this->pageSize, $currentPage);
}

$this->info('Queued job to sync Magento categories.');
}

protected function processViaCommand()
{
if (env('MAGENTO_DEFAULT_CATEGORY')) {
$this->newLine();
$this->info('Looks like we have a root category of "'. env('MAGENTO_DEFAULT_CATEGORY') .'" configured in your env.');
$this->info('We will only sync those categories associated with ID "'. env('MAGENTO_DEFAULT_CATEGORY') .'".');
$this->info('Existing non-associated categories will be removed.');
}

$this->newLine();
$this->bar->start();

for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
$categories = (new Magento())->api('categories')
->all($this->pageSize, $currentPage)
->json();

foreach ($categories['items'] as $category) {
try {
(new MagentoCategories())->updateCategory($category);
} catch (\Exception $e) {
//
}
$this->bar->advance();
}
}

$this->info('Successfully launched job to import magento categories.');
$this->bar->finish();
$this->newLine();
$this->newLine();
$this->info(MagentoCategory::count() . ' categories synced from the Magento instance to your application.');
}
}
101 changes: 79 additions & 22 deletions src/Console/SyncMagentoProductsCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,91 @@

namespace Grayloon\MagentoStorage\Console;

use Grayloon\MagentoStorage\Jobs\SyncMagentoProducts;
use Grayloon\Magento\Magento;
use Grayloon\MagentoStorage\Events\MagentoProductSynced;
use Grayloon\MagentoStorage\Jobs\SyncMagentoProductsBatch;
use Grayloon\MagentoStorage\Models\MagentoProduct;
use Grayloon\MagentoStorage\Support\MagentoProducts;
use Illuminate\Console\Command;

class SyncMagentoProductsCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'magento:sync-products';

/**
* The console command description.
*
* @var string
*/
protected $description = 'Imports the product data from the Magneto 2 API';

/**
* Execute the console command.
*
* @return int
*/
protected $signature = 'magento:sync-products {--queue : Whether the job should be queued}';

protected $description = 'Sync the products in Magento with your application.';

protected $bar;
protected $count;
protected $pages;
protected $pageSize = 100;

public function handle()
{
SyncMagentoProducts::dispatch();
$this->info('Retrieving products from Magento...');

$this->count = (new MagentoProducts())->count();
$this->info($this->count . ' products found.');

$this->bar = $this->output
->createProgressBar($this->count);
$this->pages = ceil(($this->count / $this->pageSize) + 1);

return ($this->option('queue'))
? $this->processViaQueue()
: $this->processViaCommand();
}

protected function processViaQueue()
{
for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
SyncMagentoProductsBatch::dispatch($this->pageSize, $currentPage);
}

$this->info('Queued job to sync Magento products.');
}

protected function processViaCommand()
{
if (config('magento.store_code')) {
$this->newLine();
$this->info('Default Store Code: "'. config('magento.store_code') .'" is configured in your env.');
$this->info('We will only sync those products associated with "'. config('magento.store_code') .'".');
$this->info('Existing non-associated products will be removed.');
}

$this->newLine();
$this->bar->start();

for ($currentPage = 1; $this->pages > $currentPage; $currentPage++) {
$products = (new Magento())->api('products')
->all($this->pageSize, $currentPage)
->json();

foreach ($products['items'] as $product) {
try {
$apiProduct = (new Magento())->api('products')
->show($product['sku'])
->json();

if (in_array(config('magento.default_store_id'), ($apiProduct)['extension_attributes']['website_ids'])) {
$product = (new MagentoProducts())->updateOrCreateProduct($apiProduct);

event(new MagentoProductSynced($product));
} else {
// product doesnt exist in given website
return (new MagentoProducts())->deleteIfExists($this->sku);
}
} catch (\Exception $e) {
//
}

$this->bar->advance();
}
}

$this->info('Successfully launched job to import magento products.');
$this->bar->finish();
$this->newLine();
$this->newLine();
$this->info(MagentoProduct::count() . ' products synced from the Magento instance to your application.');
}
}
1 change: 0 additions & 1 deletion src/Jobs/WaitForLinkedProductSku.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Grayloon\MagentoStorage\Jobs;

use Exception;
use Grayloon\Magento\Magento;
use Grayloon\MagentoStorage\Models\MagentoProduct;
use Grayloon\MagentoStorage\Support\MagentoProducts;
Expand Down
1 change: 1 addition & 0 deletions src/MagentoStorageServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public function register()
Console\SyncMagentoProductCategoriesCommand::class,
Console\SyncMagentoCustomAttributeTypesCommand::class,
Console\SyncMagentoWebsitesCommand::class,
Console\MagentoCleanAttributesCommand::class,
]);
}
}
8 changes: 5 additions & 3 deletions src/Support/MagentoCategories.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ public function updateCategories($categories)
}

foreach ($categories as $apiCategory) {
if ($this->validCategory($apiCategory)) {
$this->updateCategory($apiCategory);
}
$this->updateCategory($apiCategory);
}

return $this;
Expand Down Expand Up @@ -110,6 +108,10 @@ protected function downloadCategoryImage($customAttributes, $category)
*/
public function updateCategory($apiCategory)
{
if (! $this->validCategory($apiCategory)) {
return;
}

$category = MagentoCategory::updateOrCreate(['id' => $apiCategory['id']], [
'name' => $apiCategory['name'],
'slug' => $this->findAttributeByKey('url_path', $apiCategory['custom_attributes']),
Expand Down
37 changes: 37 additions & 0 deletions tests/Console/MagentoCleanAttributesCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Grayloon\MagentoStorage\Tests\Console;

use Grayloon\MagentoStorage\Database\Factories\MagentoCustomAttributeFactory;
use Grayloon\MagentoStorage\Database\Factories\MagentoProductFactory;
use Grayloon\MagentoStorage\Models\MagentoCustomAttribute;
use Grayloon\MagentoStorage\Models\MagentoProduct;
use Grayloon\MagentoStorage\Tests\TestCase;

class MagentoCleanAttributesCommandTest extends TestCase
{
public function test_it_removes_missing_relational_custom_attributes()
{
$attribute = MagentoCustomAttributeFactory::new()->create([
'attributable_type' => MagentoProduct::class,
'attributable_id' => 123,
]);

$this->artisan('magento:clean');

$this->assertDeleted($attribute);
}

public function test_it_keeps_relational_match_custom_attribute()
{
$product = MagentoProductFactory::new()->create();
$attribute = MagentoCustomAttributeFactory::new()->create([
'attributable_type' => MagentoProduct::class,
'attributable_id' => $product->id,
]);

$this->artisan('magento:clean');

$this->assertEquals(1, MagentoCustomAttribute::count());
}
}
14 changes: 10 additions & 4 deletions tests/Console/SyncMagentoCategoriesCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@

namespace Grayloon\MagentoStorage\Tests\Console;

use Grayloon\MagentoStorage\Jobs\SyncMagentoCategories;
use Grayloon\MagentoStorage\Jobs\SyncMagentoCategoriesBatch;
use Grayloon\MagentoStorage\Tests\TestCase;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Queue;

class SyncMagentoCategoriesCommandTest extends TestCase
{
public function test_magento_categories_command_fires_product_job()
{
Queue::fake();
Http::fake(function ($request) {
return Http::response([
'total_count' => 1,
], 200);
});

$this->artisan('magento:sync-categories --queue');

$this->artisan('magento:sync-categories');

Queue::assertPushed(SyncMagentoCategories::class);
Queue::assertPushed(SyncMagentoCategoriesBatch::class);
}
}
12 changes: 9 additions & 3 deletions tests/Console/SyncMagentoProductsCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@

namespace Grayloon\MagentoStorage\Tests\Console;

use Grayloon\MagentoStorage\Jobs\SyncMagentoProducts;
use Grayloon\MagentoStorage\Jobs\SyncMagentoProductsBatch;
use Grayloon\MagentoStorage\Tests\TestCase;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Queue;

class SyncMagentoProductsCommandTest extends TestCase
{
public function test_magento_products_command_fires_product_job()
{
Queue::fake();
Http::fake(function ($request) {
return Http::response([
'total_count' => 1,
], 200);
});

$this->artisan('magento:sync-products');
$this->artisan('magento:sync-products --queue');

Queue::assertPushed(SyncMagentoProducts::class);
Queue::assertPushed(SyncMagentoProductsBatch::class);
}
}

0 comments on commit 07f0feb

Please sign in to comment.