1: <?php
2: namespace TIC\ListBundle\Command;
3:
4: use Doctrine\ORM\EntityManager;
5: use Doctrine\ORM\Exception\NotSupported;
6: use Doctrine\Persistence\ManagerRegistry;
7: use Symfony\Component\Yaml\Yaml;
8: use TIC\CoreBundle\Base\TICCommand as BaseCommand;
9:
10: use Symfony\Component\Console\Input\InputOption;
11: use Symfony\Component\Console\Input\InputArgument;
12: use Symfony\Component\Console\Input\InputInterface;
13: use Symfony\Component\Console\Output\OutputInterface;
14:
15: use TIC\ListBundle\Entity\ListInfo;
16: use TIC\ListBundle\Entity\ListItem;
17:
18: /**
19: * Commande d'importation de liste administrable (à partir de fichiers YAML ou JSON).
20: */
21: class ImportListCommand extends BaseCommand {
22:
23: use \TIC\DormBundle\Traits\ManagerTrait;
24:
25: /**
26: * {@inheritdoc}
27: */
28: protected function configure(): void
29: {
30: parent::configure();
31: $this
32: ->setDescription("Commande d'importation de liste administrable (à partir de fichiers YAML ou JSON).")
33: ->addArgument('path', InputArgument::REQUIRED, "Fichier ou dossier à charger")
34: ->addOption('empty', null, InputOption::VALUE_NONE, "Vide les éléments d'une liste existante")
35: ->addOption('update', null, InputOption::VALUE_NONE, "Modification des éléments déjà existant")
36: ;
37: }
38:
39: /**
40: * {@inheritdoc}
41: * @throws NotSupported
42: */
43: protected function execute(InputInterface $input, OutputInterface $output): int
44: {
45: $source = $input->getArgument('path');
46: if (! file_exists($source)) {
47: $this->io->error("File or folder '$source' does not exists!");
48: exit;
49: }
50:
51: // traitement des fichiers INI indiqués
52: foreach ($this->getSources($source) as $path => $format) {
53:
54: // lecture des données à importer depuis le fichier
55: switch ($format) {
56: case 'json': $data = json_decode(file_get_contents($path), true); break;
57: case 'yaml': $data = Yaml::parse(file_get_contents($path)); break;
58: default : $data = null;
59: }
60: if (! is_array($data)) {
61: $this->io->error("File '$path' does not contain list informations!");
62: continue;
63: }
64:
65: // analyse du contenu des données importées
66: if (isset($data['ref'])) $ref = $data['ref'];
67: $nbItems = isset($data['items']) ? count($data['items']) : null;
68: $this->io->section("Importing list: $ref (" . (($nbItems === null) ? 'no' : $nbItems) . " elements)");
69:
70: // récupération ou création de la liste
71: $list = $this->getRepo('ListInfo')->find($ref);
72: if ($list) {
73: $this->io->note("List '$ref' already exists.");
74: } else {
75: $list = new ListInfo(0, $ref);
76: $this->io->success("List '$ref' created.");
77: }
78:
79: // si la liste existe et contient déjà des noeuds...
80: if ($nbItems !== null && $list->countItems()) {
81: // suppression des nœuds existant (avec l'option "empty")
82: if ($input->getOption('empty')) {
83: $this->io->warning("List '$ref' is not empty: removing existing items!");
84: foreach ($list->getItems() as $item) $list->removeItem($item);
85: }
86: // ou échec de l'import (sauf avec l'option "update")
87: elseif (! $input->getOption('update')) {
88: $this->io->error("List '$ref' contains items: use 'empty' or 'update' option!");
89: exit;
90: }
91: }
92:
93: // ajout/mise à jour des infos et éléments depuis les données importées
94: $list->import($data);
95:
96: // fin de la boucle en mode test (pas de commit)
97: if ($this->test) {
98: $this->io->note("TEST mode: no commit.");
99: # dump($list);
100: continue;
101: }
102:
103: // enregistrement dans la base de données
104: $this->em->persist($list);
105: $this->em->flush();
106: $this->io->success("Import done.");
107: }
108:
109: return true;
110: }
111:
112:
113: /**
114: *
115: */
116: protected function getSources($path) {
117: $this->io->section("Scanning source: $path");
118:
119: $files = array();
120: if (is_dir($path)) foreach (scandir($path) as $name) {
121: $file = $path . '/' . $name;
122: if (! is_file($file)) continue;
123: if (preg_match('/^.+\.(ya?ml|json)$/i', $name, $m)) $files[ $file ] = $m[1];
124: }
125: elseif (is_file($path)) {
126: $name = basename( $path );
127: if (preg_match('/^.+\.(ya?ml|json)$/', $name, $m)) $files[ $path ] = $m[1];
128: }
129:
130: if ($this->out->isVeryVerbose()) $this->io->listing(array_keys($files));
131: return $files;
132: }
133:
134:
135: }
136: