You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

131 lines
3.4 KiB

  1. <?php
  2. namespace App\Service;
  3. /*
  4. * Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19. * 02110-1301, USA.
  20. */
  21. use App\Entity\Bucket;
  22. use App\Entity\Feed;
  23. use Doctrine\ORM\EntityManagerInterface;
  24. use SimpleXMLElement;
  25. use Symfony\Component\String\Slugger\SluggerInterface;
  26. class OpmlImporter
  27. {
  28. /**
  29. * @var SluggerInterface
  30. */
  31. private $slugger;
  32. /**
  33. * @var EntityManagerInterface
  34. */
  35. private $entityManager;
  36. public function __construct(
  37. SluggerInterface $slugger,
  38. EntityManagerInterface $entityManager
  39. ) {
  40. $this->slugger = $slugger;
  41. $this->entityManager = $entityManager;
  42. }
  43. public function importFromFile(string $filePath): void
  44. {
  45. $opml = new SimpleXMLElement(file_get_contents($filePath));
  46. // TODO: Trigger event
  47. foreach ($opml->body->outline as $outline) {
  48. $this->importOutline($outline);
  49. }
  50. $this->entityManager->flush();
  51. }
  52. public function isBucket(SimpleXMLElement $outline): bool
  53. {
  54. return is_null($outline['type'])
  55. && (
  56. isset($outline['text'])
  57. || isset($outline['title'])
  58. )
  59. ;
  60. }
  61. public function isFeed(SimpleXMLElement $outline): bool
  62. {
  63. return isset($outline['type'])
  64. && $outline['type']->__toString() === 'rss'
  65. && isset($outline['xmlUrl'])
  66. ;
  67. }
  68. private function importOutline(SimpleXMLElement $outline, Bucket $bucket = null): void
  69. {
  70. if ($this->isBucket($outline)) {
  71. $this->importBucket($outline);
  72. return;
  73. }
  74. if ($this->isFeed($outline)) {
  75. $this->importFeed($outline, $bucket);
  76. return;
  77. }
  78. }
  79. private function importBucket(SimpleXMLElement $outline): void
  80. {
  81. $title = $outline['title'] ?? $outline['text'];
  82. // Check whether bucket already exists.
  83. $bucket = new Bucket(
  84. $title,
  85. strtolower($this->slugger->slug($title))
  86. );
  87. // TODO: Trigger event
  88. $this->entityManager->persist($bucket);
  89. foreach ($outline->outline as $subOutline) {
  90. $this->importOutline($subOutline, $bucket);
  91. }
  92. }
  93. private function importFeed(SimpleXMLElement $outline, Bucket $bucket = null): void
  94. {
  95. $title = $outline['title'] ?? $outline['text'];
  96. $feed = new Feed(
  97. $title,
  98. strtolower($this->slugger->slug($title)),
  99. $outline['xmlUrl'],
  100. $bucket,
  101. $outline['htmlUrl'] ?? ''
  102. );
  103. // TODO: Trigger event
  104. $this->entityManager->persist($feed);
  105. }
  106. }