Skip to content

Commit e8fc753

Browse files
authored
Merge pull request #32 from Vendic/master
Cleaned up Magento 2 branch
2 parents e524e08 + 572a153 commit e8fc753

16 files changed

+236
-203
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.php_cs.cache
2+
*~

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
All notable changes to this project will be documented in this file.
3+
4+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6+
7+
## 1.1.0 - 20-12-2019
8+
### Changed
9+
- [#4](https://github.com/Vendic/EAVCleaner/pull/4) Added non interactive mode support [@boehsermoe](https://github.com/boehsermoe)
10+
11+
## 1.0.4 - 12-09-2019
12+
### Changed
13+
- [#5](https://github.com/Vendic/EAVCleaner/pull/5) Refactored command `eav:media:remove-unused`

app/code/EAVCleaner/Console/Command/CleanUpAttributesAndValuesWithoutParentCommand.php renamed to Console/Command/CleanUpAttributesAndValuesWithoutParentCommand.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
<?php
2-
namespace Hackaton\EAVCleaner\Console\Command;
2+
namespace Hackathon\EAVCleaner\Console\Command;
33

44
use Symfony\Component\Console\Command\Command;
55
use Symfony\Component\Console\Input\InputInterface;
66
use Symfony\Component\Console\Output\OutputInterface;
77
use Symfony\Component\Console\Question\ConfirmationQuestion;
88

9-
10-
119
class CleanUpAttributesAndValuesWithoutParentCommand extends Command
1210
{
13-
14-
var $questionHelper;
11+
public $questionHelper;
1512

1613
/**
1714
* Init command
@@ -38,7 +35,7 @@ public function execute(InputInterface $input, OutputInterface $output)
3835
{
3936
$isDryRun = $input->getOption('dry-run');
4037

41-
if(!$isDryRun) {
38+
if (!$isDryRun && $input->isInteractive()) {
4239
$output->writeln('WARNING: this is not a dry run. If you want to do a dry-run, add --dry-run.');
4340
$question = new ConfirmationQuestion('Are you sure you want to continue? [No] ', false);
4441

@@ -54,7 +51,7 @@ public function execute(InputInterface $input, OutputInterface $output)
5451
$db = $resConnection->getConnection();
5552
$types = array('varchar', 'int', 'decimal', 'text', 'datetime');
5653
$entityTypeCodes = array($db->getTableName('catalog_product'), $db->getTableName('catalog_category'), $db->getTableName('customer'), $db->getTableName('customer_address'));
57-
foreach($entityTypeCodes as $code) {
54+
foreach ($entityTypeCodes as $code) {
5855
$entityType = $objectManager->get('Magento\Eav\Model\Entity\Type')
5956
->getCollection()
6057
->addFieldToFilter('code', $code);
@@ -73,8 +70,6 @@ public function execute(InputInterface $input, OutputInterface $output)
7370
. " FROM `$eavTable` where entity_type_id = " . $entityType->getEntityTypeId() . ")");
7471
}
7572
}
76-
7773
}
7874
}
79-
80-
}
75+
}

app/code/EAVCleaner/Console/Command/RemoveUnusedAttributesCommand.php renamed to Console/Command/RemoveUnusedAttributesCommand.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?php
2-
namespace Hackaton\EAVCleaner\Console\Command;
2+
namespace Hackathon\EAVCleaner\Console\Command;
33

44
use Symfony\Component\Console\Command\Command;
55
use Symfony\Component\Console\Input\InputInterface;
@@ -30,9 +30,8 @@ protected function configure()
3030
*/
3131
public function execute(InputInterface $input, OutputInterface $output)
3232
{
33-
3433
$isDryRun = $input->getOption('dry-run');
35-
if (!$isDryRun) {
34+
if (!$isDryRun && $input->isInteractive()) {
3635
$output->writeln('WARNING: this is not a dry run. If you want to do a dry-run, add --dry-run.');
3736
$question = new ConfirmationQuestion('Are you sure you want to continue? [No] ', false);
3837
$this->questionHelper = $this->getHelper('question');
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
3+
namespace Hackathon\EAVCleaner\Console\Command;
4+
5+
use Magento\Framework\App\ResourceConnection;
6+
use Magento\Framework\Filesystem;
7+
use Symfony\Component\Console\Command\Command;
8+
use Symfony\Component\Console\Input\InputInterface;
9+
use Symfony\Component\Console\Output\OutputInterface;
10+
use Symfony\Component\Console\Question\ConfirmationQuestion;
11+
use Symfony\Component\Console\Input\InputOption;
12+
use Magento\Framework\App\Filesystem\DirectoryList;
13+
14+
/**
15+
* Class RemoveUnusedMediaCommand
16+
* @package Hackathon\EAVCleaner\Console\Command
17+
*/
18+
class RemoveUnusedMediaCommand extends Command
19+
{
20+
/**
21+
* @var ResourceConnection
22+
*/
23+
protected $resourceConnection;
24+
/**
25+
* @var Filesystem
26+
*/
27+
protected $filesystem;
28+
29+
public function __construct(
30+
Filesystem $filesystem,
31+
ResourceConnection $resourceConnection,
32+
string $name = null
33+
) {
34+
parent::__construct($name);
35+
$this->resourceConnection = $resourceConnection;
36+
$this->filesystem = $filesystem;
37+
}
38+
39+
/**
40+
* Init command
41+
*/
42+
protected function configure()
43+
{
44+
$this
45+
->setName('eav:media:remove-unused')
46+
->setDescription('Remove unused product images')
47+
->addOption('dry-run');
48+
}
49+
50+
public function execute(InputInterface $input, OutputInterface $output) : void
51+
{
52+
$fileSize = 0;
53+
$countFiles = 0;
54+
$isDryRun = $input->getOption('dry-run');
55+
56+
if (!$isDryRun && $input->isInteractive()) {
57+
$output->writeln(
58+
'<comment>WARNING: this is not a dry run. If you want to do a dry-run, add --dry-run.</comment>'
59+
);
60+
$question = new ConfirmationQuestion('<comment>Are you sure you want to continue? [No]</comment>', false);
61+
if (!$this->getHelper('question')->ask($input, $output, $question)) {
62+
return;
63+
}
64+
}
65+
66+
$imageDir = $this->getImageDir();
67+
$connection = $this->resourceConnection->getConnection('core_read');
68+
$mediaGalleryTable = $connection->getTableName(
69+
'catalog_product_entity_media_gallery'
70+
);
71+
72+
$directoryIterator = new \RecursiveDirectoryIterator($imageDir);
73+
74+
foreach (new \RecursiveIteratorIterator($directoryIterator) as $file) {
75+
76+
// Cached path guard
77+
if ($this->isInCachePath($file)) {
78+
continue;
79+
}
80+
81+
// Directory guard
82+
if (is_dir($file)) {
83+
continue;
84+
}
85+
86+
// Filepath guard
87+
$filePath = str_replace($imageDir, "", $file);
88+
if (empty($filePath)) {
89+
continue;
90+
}
91+
92+
$imageFound = $connection->fetchOne(
93+
'SELECT value FROM ' . $mediaGalleryTable . ' WHERE value = ?', array($filePath)
94+
);
95+
if ($imageFound) {
96+
continue;
97+
}
98+
99+
$fileSize += filesize($file);
100+
$countFiles++;
101+
if (!$isDryRun) {
102+
unlink($file);
103+
$output->writeln('## REMOVING: ' . $filePath . ' ##');
104+
} else {
105+
$output->writeln('## WOULD REMOVE: ' . $filePath . ' ##');
106+
}
107+
}
108+
109+
$this->printResult($output, $isDryRun, $countFiles, $fileSize);
110+
}
111+
112+
private function printResult(OutputInterface $output, $isDryRun, int $countFiles, int $filesize): void
113+
{
114+
$actionName = 'Deleted';
115+
if ($isDryRun) {
116+
$actionName = 'Would delete';
117+
}
118+
$fileSizeInMB = number_format($filesize / 1024 / 1024, '2');
119+
120+
$output->writeln("<info>{$actionName} {$countFiles} unused images. {$fileSizeInMB} MB</info>");
121+
}
122+
123+
private function getImageDir(): string
124+
{
125+
$directory = $this->filesystem->getDirectoryRead(DirectoryList::MEDIA);
126+
return $directory->getAbsolutePath() . DIRECTORY_SEPARATOR . 'catalog' . DIRECTORY_SEPARATOR . 'product';
127+
}
128+
129+
130+
private function isInCachePath(?string $file): bool
131+
{
132+
return strpos($file, "/cache") !== false;
133+
}
134+
}

app/code/EAVCleaner/Console/Command/RestoreUseDefaultConfigValueCommand.php renamed to Console/Command/RestoreUseDefaultConfigValueCommand.php

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
<?php
2-
namespace Hackaton\EAVCleaner\Console\Command;
2+
namespace Hackathon\EAVCleaner\Console\Command;
33

44
use Symfony\Component\Console\Command\Command;
55
use Symfony\Component\Console\Input\InputInterface;
66
use Symfony\Component\Console\Output\OutputInterface;
77
use Symfony\Component\Console\Question\ConfirmationQuestion;
88

9-
10-
119
class RestoreUseDefaultConfigValueCommand extends Command
1210
{
13-
14-
var $questionHelper;
11+
public $questionHelper;
1512

1613
/**
1714
* Init command
@@ -38,7 +35,7 @@ public function execute(InputInterface $input, OutputInterface $output)
3835
{
3936
$isDryRun = $input->getOption('dry-run');
4037

41-
if(!$isDryRun) {
38+
if (!$isDryRun && $input->isInteractive()) {
4239
$output->writeln('WARNING: this is not a dry run. If you want to do a dry-run, add --dry-run.');
4340
$question = new ConfirmationQuestion('Are you sure you want to continue? [No] ', false);
4441

@@ -56,19 +53,16 @@ public function execute(InputInterface $input, OutputInterface $output)
5653
$resConnection = $objectManager->get('Magento\Framework\App\ResourceConnection');
5754
$db = $resConnection->getConnection();
5855
$configData = $db->fetchAll('SELECT DISTINCT path, value FROM ' . $db->getTableName('core_config_data') . ' WHERE scope_id = 0');
59-
foreach($configData as $config) {
56+
foreach ($configData as $config) {
6057
$count = $db->fetchOne('SELECT COUNT(*) FROM ' . $db->getTableName('core_config_data') .' WHERE path = ? AND value = ?', array($config['path'], $config['value']));
61-
if($count > 1) {
58+
if ($count > 1) {
6259
$output->writeln('Config path ' . $config['path'] . ' with value ' . $config['value']. ' has ' . $count . ' values; deleting non-default values');
63-
if(!$isDryRun) {
60+
if (!$isDryRun) {
6461
$db->query('DELETE FROM ' . $db->getTableName('core_config_data') . ' WHERE path = ? AND value = ? AND scope_id != ?', array($config['path'], $config['value'], 0));
6562
}
6663
$removedConfigValues += ($count-1);
6764
}
6865
}
6966
$output->writeln('Removed ' . $removedConfigValues . ' values from core_config_data table.');
70-
71-
7267
}
73-
74-
}
68+
}

app/code/EAVCleaner/Console/Command/RestoreUseDefaultValueCommand.php renamed to Console/Command/RestoreUseDefaultValueCommand.php

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
<?php
2-
namespace Hackaton\EAVCleaner\Console\Command;
2+
namespace Hackathon\EAVCleaner\Console\Command;
33

44
use Symfony\Component\Console\Command\Command;
55
use Symfony\Component\Console\Input\InputInterface;
66
use Symfony\Component\Console\Output\OutputInterface;
77
use Symfony\Component\Console\Question\ConfirmationQuestion;
88

9-
10-
119
class RestoreUseDefaultValueCommand extends Command
1210
{
13-
14-
var $questionHelper;
11+
public $questionHelper;
1512

1613
/**
1714
* Init command
@@ -38,7 +35,7 @@ public function execute(InputInterface $input, OutputInterface $output)
3835
{
3936
$isDryRun = $input->getOption('dry-run');
4037

41-
if(!$isDryRun) {
38+
if (!$isDryRun && $input->isInteractive()) {
4239
$output->writeln('WARNING: this is not a dry run. If you want to do a dry-run, add --dry-run.');
4340
$question = new ConfirmationQuestion('Are you sure you want to continue? [No] ', false);
4441

@@ -63,7 +60,8 @@ public function execute(InputInterface $input, OutputInterface $output)
6360

6461
foreach ($rows as $row) {
6562
// Select the global value if it's the same as the non-global value
66-
$results = $db->fetchAll('SELECT * FROM ' . $fullTableName
63+
$results = $db->fetchAll(
64+
'SELECT * FROM ' . $fullTableName
6765
. ' WHERE attribute_id = ? AND store_id = ? AND entity_id = ? AND value = ?',
6866
array($row['attribute_id'], 0, $row['entity_id'], $row['value'])
6967
);
@@ -72,11 +70,14 @@ public function execute(InputInterface $input, OutputInterface $output)
7270
foreach ($results as $result) {
7371
if (!$isDryRun) {
7472
// Remove the non-global value
75-
$db->query('DELETE FROM ' . $fullTableName . ' WHERE value_id = ?', $row['value_id']
73+
$db->query(
74+
'DELETE FROM ' . $fullTableName . ' WHERE value_id = ?',
75+
$row['value_id']
7676
);
7777
}
7878

79-
$output->writeln('Deleting value ' . $row['value_id'] . ' "' . $row['value'] .'" in favor of ' . $result['value_id']
79+
$output->writeln(
80+
'Deleting value ' . $row['value_id'] . ' "' . $row['value'] .'" in favor of ' . $result['value_id']
8081
. ' for attribute ' . $row['attribute_id'] . ' in table ' . $fullTableName
8182
);
8283
if (!isset($counts[$row['attribute_id']])) {
@@ -87,28 +88,29 @@ public function execute(InputInterface $input, OutputInterface $output)
8788
}
8889
}
8990

90-
$nullValues = $db->fetchOne('SELECT COUNT(*) FROM ' . $fullTableName
91-
. ' WHERE store_id = ? AND value IS NULL', array($row['store_id'])
91+
$nullValues = $db->fetchOne(
92+
'SELECT COUNT(*) FROM ' . $fullTableName
93+
. ' WHERE store_id = ? AND value IS NULL',
94+
array($row['store_id'])
9295
);
9396

9497
if (!$isDryRun && $nullValues > 0) {
9598
$output->writeln("Deleting " . $nullValues ." NULL value(s) from " . $fullTableName);
9699
// Remove all non-global null values
97-
$db->query('DELETE FROM ' . $fullTableName
98-
. ' WHERE store_id = ? AND value IS NULL', array($row['store_id'])
100+
$db->query(
101+
'DELETE FROM ' . $fullTableName
102+
. ' WHERE store_id = ? AND value IS NULL',
103+
array($row['store_id'])
99104
);
100105
}
101106
}
102107

103108

104109
if (count($counts)) {
105110
$output->writeln('Done');
106-
}
107-
else {
111+
} else {
108112
$output->writeln('There were no attribute values to clean up');
109113
}
110-
111114
}
112115
}
113-
114-
}
116+
}

0 commit comments

Comments
 (0)