File entity added. Post and Comment entities now has $files property. New migration. New FileFactory.
This commit is contained in:
parent
a1b982d891
commit
f919740524
51
app/DoctrineMigrations/Version20160325001415.php
Normal file
51
app/DoctrineMigrations/Version20160325001415.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Application\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
class Version20160325001415 extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||||
|
|
||||||
|
$this->addSql('CREATE SEQUENCE posts.files_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||||
|
$this->addSql('CREATE TABLE posts.comments_files (comment_id INT NOT NULL, file_id INT NOT NULL, PRIMARY KEY(comment_id, file_id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_D0F69329F8697D13 ON posts.comments_files (comment_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_D0F6932993CB796C ON posts.comments_files (file_id)');
|
||||||
|
$this->addSql('CREATE TABLE posts.posts_files (post_id VARCHAR(16) NOT NULL, file_id INT NOT NULL, PRIMARY KEY(post_id, file_id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_D799EBF04B89032C ON posts.posts_files (post_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_D799EBF093CB796C ON posts.posts_files (file_id)');
|
||||||
|
$this->addSql('CREATE TABLE posts.files (id INT NOT NULL, remoteUrl VARCHAR(128) NOT NULL, PRIMARY KEY(id))');
|
||||||
|
$this->addSql('CREATE UNIQUE INDEX UNIQ_744CC52C80445AEA ON posts.files (remoteUrl)');
|
||||||
|
$this->addSql('ALTER TABLE posts.comments_files ADD CONSTRAINT FK_D0F69329F8697D13 FOREIGN KEY (comment_id) REFERENCES posts.comments (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE posts.comments_files ADD CONSTRAINT FK_D0F6932993CB796C FOREIGN KEY (file_id) REFERENCES posts.files (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE posts.posts_files ADD CONSTRAINT FK_D799EBF04B89032C FOREIGN KEY (post_id) REFERENCES posts.posts (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE posts.posts_files ADD CONSTRAINT FK_D799EBF093CB796C FOREIGN KEY (file_id) REFERENCES posts.files (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function down(Schema $schema)
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||||
|
|
||||||
|
$this->addSql('ALTER TABLE posts.comments_files DROP CONSTRAINT FK_D0F6932993CB796C');
|
||||||
|
$this->addSql('ALTER TABLE posts.posts_files DROP CONSTRAINT FK_D799EBF093CB796C');
|
||||||
|
$this->addSql('DROP SEQUENCE posts.files_id_seq CASCADE');
|
||||||
|
$this->addSql('DROP TABLE posts.comments_files');
|
||||||
|
$this->addSql('DROP TABLE posts.posts_files');
|
||||||
|
$this->addSql('DROP TABLE posts.files');
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,14 @@ class Post
|
||||||
*/
|
*/
|
||||||
private $tags;
|
private $tags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string[]
|
||||||
|
*
|
||||||
|
* @JMSS\SerializedName("files")
|
||||||
|
* @JMSS\Type("array<string>")
|
||||||
|
*/
|
||||||
|
private $files;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var User
|
* @var User
|
||||||
*
|
*
|
||||||
|
@ -104,6 +112,26 @@ class Post
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function getFiles()
|
||||||
|
{
|
||||||
|
return $this->files;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $files
|
||||||
|
*
|
||||||
|
* @return Post
|
||||||
|
*/
|
||||||
|
public function setFiles($files)
|
||||||
|
{
|
||||||
|
$this->files = $files;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return User
|
* @return User
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -76,6 +76,17 @@ class Comment
|
||||||
*/
|
*/
|
||||||
private $author;
|
private $author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var File[]|ArrayCollection
|
||||||
|
*
|
||||||
|
* @ORM\ManyToMany(targetEntity="Skobkin\Bundle\PointToolsBundle\Entity\Blogs\File", fetch="EXTRA_LAZY", cascade={"persist"})
|
||||||
|
* @ORM\JoinTable(name="posts.comments_files", schema="posts",
|
||||||
|
* joinColumns={@ORM\JoinColumn(name="comment_id")},
|
||||||
|
* inverseJoinColumns={@ORM\JoinColumn(name="file_id")}
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
private $files;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Comment|null
|
* @var Comment|null
|
||||||
*
|
*
|
||||||
|
@ -94,6 +105,7 @@ class Comment
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
$this->files = new ArrayCollection();
|
||||||
$this->children = new ArrayCollection();
|
$this->children = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +259,39 @@ class Comment
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add files
|
||||||
|
*
|
||||||
|
* @param File $files
|
||||||
|
* @return Comment
|
||||||
|
*/
|
||||||
|
public function addFile(File $files)
|
||||||
|
{
|
||||||
|
$this->files[] = $files;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove files
|
||||||
|
*
|
||||||
|
* @param File $files
|
||||||
|
*/
|
||||||
|
public function removeFile(File $files)
|
||||||
|
{
|
||||||
|
$this->files->removeElement($files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get files
|
||||||
|
*
|
||||||
|
* @return File[]|ArrayCollection
|
||||||
|
*/
|
||||||
|
public function getFiles()
|
||||||
|
{
|
||||||
|
return $this->files;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Comment
|
* @return Comment
|
||||||
*/
|
*/
|
||||||
|
|
69
src/Skobkin/Bundle/PointToolsBundle/Entity/Blogs/File.php
Normal file
69
src/Skobkin/Bundle/PointToolsBundle/Entity/Blogs/File.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Entity\Blogs;
|
||||||
|
|
||||||
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File
|
||||||
|
*
|
||||||
|
* @ORM\Table(name="posts.files", schema="posts")
|
||||||
|
* @ORM\Entity(repositoryClass="Skobkin\Bundle\PointToolsBundle\Repository\Blogs\FileRepository")
|
||||||
|
*/
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var integer
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="id", type="integer")
|
||||||
|
* @ORM\Id
|
||||||
|
* @ORM\GeneratedValue(strategy="AUTO")
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*
|
||||||
|
* @ORM\Column(name="remoteUrl", type="string", length=128, unique=true)
|
||||||
|
*/
|
||||||
|
private $remoteUrl;
|
||||||
|
|
||||||
|
|
||||||
|
public function __construct($remoteUrl = null)
|
||||||
|
{
|
||||||
|
$this->remoteUrl = $remoteUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get id
|
||||||
|
*
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
public function getId()
|
||||||
|
{
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set remoteUrl
|
||||||
|
*
|
||||||
|
* @param string $remoteUrl
|
||||||
|
* @return File
|
||||||
|
*/
|
||||||
|
public function setRemoteUrl($remoteUrl)
|
||||||
|
{
|
||||||
|
$this->remoteUrl = $remoteUrl;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get remoteUrl
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getRemoteUrl()
|
||||||
|
{
|
||||||
|
return $this->remoteUrl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -79,6 +79,17 @@ class Post
|
||||||
*/
|
*/
|
||||||
private $author;
|
private $author;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var File[]|ArrayCollection
|
||||||
|
*
|
||||||
|
* @ORM\ManyToMany(targetEntity="Skobkin\Bundle\PointToolsBundle\Entity\Blogs\File", fetch="EXTRA_LAZY", cascade={"persist"})
|
||||||
|
* @ORM\JoinTable(name="posts.posts_files", schema="posts",
|
||||||
|
* joinColumns={@ORM\JoinColumn(name="post_id")},
|
||||||
|
* inverseJoinColumns={@ORM\JoinColumn(name="file_id")}
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
private $files;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Tag[]|ArrayCollection
|
* @var Tag[]|ArrayCollection
|
||||||
*
|
*
|
||||||
|
@ -102,6 +113,7 @@ class Post
|
||||||
{
|
{
|
||||||
$this->id = $id;
|
$this->id = $id;
|
||||||
|
|
||||||
|
$this->files = new ArrayCollection();
|
||||||
$this->postTags = new ArrayCollection();
|
$this->postTags = new ArrayCollection();
|
||||||
$this->comments = new ArrayCollection();
|
$this->comments = new ArrayCollection();
|
||||||
}
|
}
|
||||||
|
@ -219,6 +231,39 @@ class Post
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add files
|
||||||
|
*
|
||||||
|
* @param File $files
|
||||||
|
* @return Post
|
||||||
|
*/
|
||||||
|
public function addFile(File $files)
|
||||||
|
{
|
||||||
|
$this->files[] = $files;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove files
|
||||||
|
*
|
||||||
|
* @param File $files
|
||||||
|
*/
|
||||||
|
public function removeFile(File $files)
|
||||||
|
{
|
||||||
|
$this->files->removeElement($files);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get files
|
||||||
|
*
|
||||||
|
* @return File[]|ArrayCollection
|
||||||
|
*/
|
||||||
|
public function getFiles()
|
||||||
|
{
|
||||||
|
return $this->files;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add post tags
|
* Add post tags
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Repository\Blogs;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
|
||||||
|
class FileRepository extends EntityRepository
|
||||||
|
{
|
||||||
|
}
|
|
@ -37,6 +37,17 @@ services:
|
||||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\TagFactory
|
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\TagFactory
|
||||||
arguments: [ @logger, @doctrine.orm.entity_manager ]
|
arguments: [ @logger, @doctrine.orm.entity_manager ]
|
||||||
|
|
||||||
|
skobkin__point_tools.service_factory.file_factory:
|
||||||
|
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\FileFactory
|
||||||
|
arguments: [ @logger, @doctrine.orm.entity_manager ]
|
||||||
|
|
||||||
skobkin__point_tools.service_factory.post_factory:
|
skobkin__point_tools.service_factory.post_factory:
|
||||||
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\PostFactory
|
class: Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs\PostFactory
|
||||||
arguments: [ @logger, @doctrine.orm.entity_manager, @skobkin__point_tools.service_factory.user_factory, @skobkin__point_tools.service_factory.comment_factory, @skobkin__point_tools.service_factory.tag_factory ]
|
arguments:
|
||||||
|
- @logger
|
||||||
|
- @doctrine.orm.entity_manager
|
||||||
|
- @skobkin__point_tools.service_factory.user_factory
|
||||||
|
- @skobkin__point_tools.service_factory.file_factory
|
||||||
|
- @skobkin__point_tools.service_factory.comment_factory
|
||||||
|
- @skobkin__point_tools.service_factory.tag_factory
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Service\Factory\Blogs;
|
||||||
|
|
||||||
|
use Doctrine\ORM\EntityManager;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Entity\Blogs\File;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Service\Exceptions\InvalidResponseException;
|
||||||
|
|
||||||
|
|
||||||
|
class FileFactory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var EntityManager
|
||||||
|
*/
|
||||||
|
private $em;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var LoggerInterface
|
||||||
|
*/
|
||||||
|
private $log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var EntityRepository
|
||||||
|
*/
|
||||||
|
private $fileRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param EntityManager $em
|
||||||
|
*/
|
||||||
|
public function __construct(LoggerInterface $log, EntityManagerInterface $em)
|
||||||
|
{
|
||||||
|
$this->log = $log;
|
||||||
|
$this->em = $em;
|
||||||
|
$this->fileRepository = $em->getRepository('SkobkinPointToolsBundle:Blogs\File');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $urlStrings
|
||||||
|
*
|
||||||
|
* @return File[]
|
||||||
|
*/
|
||||||
|
public function createFromUrlsArray(array $urlStrings)
|
||||||
|
{
|
||||||
|
$files = [];
|
||||||
|
|
||||||
|
foreach ($urlStrings as $url) {
|
||||||
|
try {
|
||||||
|
$file = $this->createFromUrl($url);
|
||||||
|
$files[] = $file;
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->log->error('Error while creating file from DTO', ['file' => $url, 'message' => $e->getMessage()]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $url
|
||||||
|
*
|
||||||
|
* @return File
|
||||||
|
* @throws InvalidResponseException
|
||||||
|
*/
|
||||||
|
public function createFromUrl($url)
|
||||||
|
{
|
||||||
|
$this->validateData($url);
|
||||||
|
|
||||||
|
// Replacing HTTP with HTTPS
|
||||||
|
$url = str_replace('http://', 'https://', $url);
|
||||||
|
|
||||||
|
if (null === ($file = $this->fileRepository->findOneBy(['remoteUrl' => $url]))) {
|
||||||
|
// Creating new file
|
||||||
|
$file = new File($url);
|
||||||
|
$this->em->persist($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->em->flush($file);
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $data
|
||||||
|
*
|
||||||
|
* @throws InvalidResponseException
|
||||||
|
*/
|
||||||
|
private function validateData($data)
|
||||||
|
{
|
||||||
|
if (!is_string($data)) {
|
||||||
|
// @todo Change exception
|
||||||
|
throw new InvalidResponseException('File data must be a string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -39,6 +39,11 @@ class PostFactory
|
||||||
*/
|
*/
|
||||||
private $userFactory;
|
private $userFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FileFactory
|
||||||
|
*/
|
||||||
|
private $fileFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var CommentFactory
|
* @var CommentFactory
|
||||||
*/
|
*/
|
||||||
|
@ -52,10 +57,11 @@ class PostFactory
|
||||||
/**
|
/**
|
||||||
* @param EntityManager $em
|
* @param EntityManager $em
|
||||||
*/
|
*/
|
||||||
public function __construct(LoggerInterface $log, EntityManagerInterface $em, UserFactory $userFactory, CommentFactory $commentFactory, TagFactory $tagFactory)
|
public function __construct(LoggerInterface $log, EntityManagerInterface $em, UserFactory $userFactory, FileFactory $fileFactory, CommentFactory $commentFactory, TagFactory $tagFactory)
|
||||||
{
|
{
|
||||||
$this->log = $log;
|
$this->log = $log;
|
||||||
$this->userFactory = $userFactory;
|
$this->userFactory = $userFactory;
|
||||||
|
$this->fileFactory = $fileFactory;
|
||||||
$this->commentFactory = $commentFactory;
|
$this->commentFactory = $commentFactory;
|
||||||
$this->tagFactory = $tagFactory;
|
$this->tagFactory = $tagFactory;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
|
@ -140,6 +146,7 @@ class PostFactory
|
||||||
;
|
;
|
||||||
|
|
||||||
$this->updatePostTags($post, $postData->getPost()->getTags());
|
$this->updatePostTags($post, $postData->getPost()->getTags());
|
||||||
|
$this->updatePostFiles($post, $postData->getPost()->getFiles());
|
||||||
|
|
||||||
$this->em->flush($post);
|
$this->em->flush($post);
|
||||||
|
|
||||||
|
@ -190,6 +197,29 @@ class PostFactory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Post $post
|
||||||
|
* @param array $urls
|
||||||
|
*/
|
||||||
|
private function updatePostFiles(Post $post, array $urls)
|
||||||
|
{
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function validateMetaPost(MetaPost $post)
|
private function validateMetaPost(MetaPost $post)
|
||||||
{
|
{
|
||||||
if (!$post->getPost()->getId()) {
|
if (!$post->getPost()->getId()) {
|
||||||
|
|
Loading…
Reference in a new issue