em = $em; $this->postRepository = $postRepository; $this->userFactory = $userFactory; $this->fileFactory = $fileFactory; $this->commentFactory = $commentFactory; $this->tagFactory = $tagFactory; } /** * Creates posts and return status of new insertions * * @todo refactor * * @throws InvalidResponseException */ public function createFromPageDTO(PostsPage $page): bool { $posts = []; $hasNew = false; foreach ((array) $page->getPosts() as $postData) { try { if (null === $this->postRepository->find($postData->getPost()->getId())) { $hasNew = true; } $post = $this->findOrCreateFromDTOWithTagsAndFiles($postData); $posts[] = $post; } catch (\Exception $e) { $this->logger->error('Error while processing post DTO', [ 'post_id' => $postData->getPost()->getId(), 'exception' => get_class($e), 'message' => $e->getMessage(), 'file' => $e->getFile(), 'line' => $e->getLine(), ]); } } foreach ($posts as $post) { if ($this->em->getUnitOfWork()->isScheduledForInsert($post)) { $hasNew = true; } } return $hasNew; } /** * @todo Implement full post processing with comments * * @throws InvalidDataException */ public function findOrCreateFromDTOWithTagsAndFiles(MetaPost $metaPost): Post { if (!$metaPost->isValid()) { throw new InvalidDataException('Invalid post data'); } $postData = $metaPost->getPost(); try { $author = $this->userFactory->findOrCreateFromDTO($metaPost->getPost()->getAuthor()); } catch (\Exception $e) { $this->logger->error('Error while creating user from DTO'); throw $e; } $post = $this->findOrCreateFromDto($postData, $author); try { $this->updatePostTags($post, $postData->getTags() ?: []); } catch (\Exception $e) { $this->logger->error('Error while updating post tags'); throw $e; } try { $this->updatePostFiles($post, $postData->getFiles() ?: []); } catch (\Exception $e) { $this->logger->error('Error while updating post files'); throw $e; } return $post; } private function findOrCreateFromDto(PostDTO $postData, User $author): Post { if (null === ($post = $this->postRepository->find($postData->getId()))) { // Creating new post $post = new Post( $postData->getId(), $author, new \DateTime($postData->getCreated()), $postData->getType() ?: Post::TYPE_POST ); $this->postRepository->add($post); } $post ->setText($postData->getText()) ->setPrivate($postData->getPrivate()) ; return $post; } /** * @param Post $post * @param string[] $tagsStrings */ private function updatePostTags(Post $post, array $tagsStrings): void { $tags = $this->tagFactory->createFromStringsArray($tagsStrings); // Hashing tags strings $tagStringsHash = []; foreach ($tagsStrings as $tagsString) { $tagStringsHash[mb_strtolower($tagsString)] = $tagsString; } // Hashing current post tags $newTagsHash = []; foreach ($tags as $tag) { $newTagsHash[mb_strtolower($tag->getText())] = $tag; } // Hashing old post tags (from DB) $oldTagsHash = []; foreach ($post->getPostTags() as $postTag) { $oldTagsHash[mb_strtolower($postTag->getOriginalTagText())] = $postTag; } // Adding missing tags foreach ($tags as $tag) { if (!array_key_exists(mb_strtolower($tag->getText()), $oldTagsHash)) { $tmpPostTag = (new PostTag($tag)) ->setText($tagStringsHash[mb_strtolower($tag->getText())]) ; $post->addPostTag($tmpPostTag); } } // Removing deleted tags foreach ($post->getPostTags() as $postTag) { if (!array_key_exists(mb_strtolower($postTag->getOriginalTagText()), $newTagsHash)) { $post->removePostTag($postTag); } } } /** * @param Post $post * @param array $urls */ private function updatePostFiles(Post $post, array $urls): void { $files = $this->fileFactory->createFromUrlsArray($urls); // Adding missing files foreach ($files as $file) { if (!$post->getFiles()->contains($file)) { $post->addFile($file); } } // Removing deleted files foreach ($post->getFiles() as $file) { if (!in_array($file, $files, true)) { $post->removeFile($file); } } } }