1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace AppBundle\Command; |
4
|
|
|
|
5
|
|
|
use Doctrine\ORM\EntityManager; |
6
|
|
|
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; |
7
|
|
|
use Symfony\Component\Console\Input\InputInterface; |
8
|
|
|
use Symfony\Component\Console\Output\OutputInterface; |
9
|
|
|
use Symfony\Component\PropertyAccess\PropertyAccessor; |
10
|
|
|
use Sonata\MediaBundle\Entity\BaseMedia as SonataEntityMedia; |
11
|
|
|
|
12
|
|
|
class RemoveBrokenMediaObjectsCommand extends ContainerAwareCommand |
|
|
|
|
13
|
|
|
{ |
14
|
|
|
protected function configure() |
15
|
|
|
{ |
16
|
|
|
$this |
17
|
|
|
->setName('app:remove-image') |
18
|
|
|
->setDescription('Remove image that not relation to media') |
19
|
|
|
; |
20
|
|
|
} |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @param InputInterface $input |
24
|
|
|
* @param OutputInterface $output |
25
|
|
|
* @return int|null|void |
26
|
|
|
*/ |
27
|
|
|
protected function execute(InputInterface $input, OutputInterface $output) |
28
|
|
|
{ |
29
|
|
|
$mediaManager = $this->getContainer()->get('sonata.media.manager.media'); |
30
|
|
|
|
31
|
|
|
$associatedMediaMappings = $this->getAssociationMediaMappings(); |
32
|
|
|
|
33
|
|
|
$associatedMediaObjects = $this->getAssociatedMediaObjects($associatedMediaMappings); |
34
|
|
|
$associatedMediaObjectsIds = array_map(function (SonataEntityMedia $media) { |
35
|
|
|
return $media->getId(); |
36
|
|
|
}, $associatedMediaObjects); |
37
|
|
|
|
38
|
|
|
foreach ($mediaManager->findAll() as $media) { |
39
|
|
|
if (false == in_array($media->getId(), $associatedMediaObjectsIds)) { |
|
|
|
|
40
|
|
|
$output->writeln(sprintf('Removed media with id "%s"', $media->getId())); |
41
|
|
|
$mediaManager->delete($media); |
42
|
|
|
} |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
$output->writeln('Deleted media without reference object was successful'); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @param array $associationMappings |
50
|
|
|
* @return array |
51
|
|
|
*/ |
52
|
|
|
protected function getAssociatedMediaObjects(array $associationMappings) |
53
|
|
|
{ |
54
|
|
|
/** @var EntityManager $em */ |
55
|
|
|
$em = $this->getContainer()->get('doctrine')->getManager(); |
56
|
|
|
|
57
|
|
|
if ($em->getFilters()->isEnabled('softdeleteable')) { |
58
|
|
|
$em->getFilters()->disable('softdeleteable'); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
$accessor = new PropertyAccessor(); |
62
|
|
|
|
63
|
|
|
$mediaObjects = []; |
64
|
|
|
|
65
|
|
|
foreach ($associationMappings as $repositoryName => $properties) { |
66
|
|
|
foreach ($properties as $property) { |
67
|
|
|
$objects = $em->getRepository($repositoryName)->findAll(); |
68
|
|
|
|
69
|
|
|
foreach ($objects as $object) { |
70
|
|
|
if (!is_null($accessor->getValue($object, $property))) { |
71
|
|
|
$mediaObjects[] = $accessor->getValue($object, $property); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
} |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
return $mediaObjects; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @return array associationMappings[className][propertyName][metadata] |
82
|
|
|
*/ |
83
|
|
|
protected function getAssociationMediaMappings() |
84
|
|
|
{ |
85
|
|
|
$appClassMetadata = $this |
86
|
|
|
->getContainer() |
87
|
|
|
->get('sonata.media.manager.media') |
88
|
|
|
->getEntityManager() |
89
|
|
|
->getMetadataFactory() |
90
|
|
|
->getAllMetadata() |
91
|
|
|
; |
92
|
|
|
|
93
|
|
|
$mediaAssociationMappings = []; |
94
|
|
|
|
95
|
|
|
foreach ($appClassMetadata as $classMetadata) { |
96
|
|
|
foreach ($classMetadata->associationMappings as $propertyName => $associationMapping) { |
97
|
|
|
if ('App\Entity\Media' == $associationMapping['targetEntity']) { |
98
|
|
|
$mediaAssociationMappings[$classMetadata->name][] = $propertyName; |
99
|
|
|
} |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
return $mediaAssociationMappings; |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
|
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.