parent
ebc82153bd
commit
5799a52c6e
@ -0,0 +1,58 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Chamilo\CoreBundle\Controller\Api; |
||||||
|
|
||||||
|
use Chamilo\CoreBundle\Entity\SocialPost; |
||||||
|
use Chamilo\CoreBundle\Entity\SocialPostAttachment; |
||||||
|
use Chamilo\CoreBundle\Entity\User; |
||||||
|
use Chamilo\CoreBundle\Repository\Node\SocialPostAttachmentRepository; |
||||||
|
use Doctrine\ORM\EntityManager; |
||||||
|
use Exception; |
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile; |
||||||
|
use Symfony\Component\HttpFoundation\Request; |
||||||
|
use Symfony\Component\Security\Core\Security; |
||||||
|
|
||||||
|
class CreateSocialPostAttachmentAction extends BaseResourceFileAction |
||||||
|
{ |
||||||
|
/** |
||||||
|
* @throws Exception |
||||||
|
*/ |
||||||
|
public function __invoke(Request $request, SocialPostAttachmentRepository $repo, EntityManager $em, Security $security): SocialPostAttachment |
||||||
|
{ |
||||||
|
/** @var UploadedFile $uploadedFile */ |
||||||
|
$uploadedFile = $request->files->get('file'); |
||||||
|
$socialPostId = $request->request->get('messageId'); |
||||||
|
|
||||||
|
if (!$uploadedFile instanceof UploadedFile) { |
||||||
|
throw new \Exception('No file uploaded'); |
||||||
|
} |
||||||
|
|
||||||
|
$socialPost = $em->getRepository(SocialPost::class)->find($socialPostId); |
||||||
|
if (!$socialPost) { |
||||||
|
throw new \Exception('No social post found'); |
||||||
|
} |
||||||
|
|
||||||
|
/** @var User $currentUser */ |
||||||
|
$currentUser = $security->getUser(); |
||||||
|
$attachment = new SocialPostAttachment(); |
||||||
|
$attachment->setSocialPost($socialPost); |
||||||
|
$attachment->setPath(uniqid('social_post', true)); |
||||||
|
$attachment->setFilename($uploadedFile->getClientOriginalName()); |
||||||
|
$attachment->setSize($uploadedFile->getSize()); |
||||||
|
$attachment->setInsertUserId($currentUser->getId()); |
||||||
|
$attachment->setInsertDateTime(new \DateTime('now', new \DateTimeZone('UTC'))); |
||||||
|
$attachment->setParent($currentUser); |
||||||
|
$attachment->addUserLink($currentUser); |
||||||
|
|
||||||
|
$em->persist($attachment); |
||||||
|
$em->flush(); |
||||||
|
|
||||||
|
$repo->addFile($attachment, $uploadedFile); |
||||||
|
|
||||||
|
return $attachment; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Chamilo\CoreBundle\Controller\Api; |
||||||
|
|
||||||
|
use Chamilo\CoreBundle\Entity\SocialPost; |
||||||
|
use Chamilo\CoreBundle\Entity\SocialPostAttachment; |
||||||
|
use Chamilo\CoreBundle\Repository\Node\SocialPostAttachmentRepository; |
||||||
|
use Doctrine\ORM\EntityManager; |
||||||
|
use Doctrine\ORM\EntityManagerInterface; |
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse; |
||||||
|
use Symfony\Component\Security\Core\Security; |
||||||
|
|
||||||
|
class SocialPostAttachmentsController extends BaseResourceFileAction |
||||||
|
{ |
||||||
|
|
||||||
|
public function __invoke(SocialPost $socialPost, EntityManager $em, Security $security, SocialPostAttachmentRepository $attachmentRepo): JsonResponse |
||||||
|
{ |
||||||
|
$attachments = $em->getRepository(SocialPostAttachment::class)->findBy(['socialPost' => $socialPost->getId()]); |
||||||
|
|
||||||
|
if (!$attachments) { |
||||||
|
return new JsonResponse(['error' => 'No attachments found for this post'], JsonResponse::HTTP_NOT_FOUND); |
||||||
|
} |
||||||
|
|
||||||
|
$attachmentsInfo = []; |
||||||
|
foreach ($attachments as $attachment) { |
||||||
|
$attachmentsInfo[] = [ |
||||||
|
'id' => $attachment->getId(), |
||||||
|
'filename' => $attachment->getFilename(), |
||||||
|
'path' => $attachmentRepo->getResourceFileUrl($attachment), |
||||||
|
'size' => $attachment->getSize(), |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
return new JsonResponse($attachmentsInfo, JsonResponse::HTTP_OK); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,192 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
namespace Chamilo\CoreBundle\Entity; |
||||||
|
|
||||||
|
use ApiPlatform\Metadata\ApiResource; |
||||||
|
use ApiPlatform\Metadata\Get; |
||||||
|
use ApiPlatform\Metadata\GetCollection; |
||||||
|
use ApiPlatform\Metadata\Post; |
||||||
|
use Chamilo\CoreBundle\Controller\Api\CreateSocialPostAttachmentAction; |
||||||
|
use Chamilo\CoreBundle\Repository\Node\SocialPostAttachmentRepository; |
||||||
|
use DateTime; |
||||||
|
use Doctrine\ORM\Mapping as ORM; |
||||||
|
use Stringable; |
||||||
|
|
||||||
|
#[ApiResource( |
||||||
|
types: ['http://schema.org/MediaObject'], |
||||||
|
operations: [ |
||||||
|
new Get(), |
||||||
|
new GetCollection(), |
||||||
|
new Post( |
||||||
|
controller: CreateSocialPostAttachmentAction::class, |
||||||
|
openapiContext: [ |
||||||
|
'requestBody' => [ |
||||||
|
'content' => [ |
||||||
|
'multipart/form-data' => [ |
||||||
|
'schema' => [ |
||||||
|
'type' => 'object', |
||||||
|
'properties' => [ |
||||||
|
'file' => [ |
||||||
|
'type' => 'string', |
||||||
|
'format' => 'binary', |
||||||
|
], |
||||||
|
'messageId' => [ |
||||||
|
'type' => 'integer', |
||||||
|
], |
||||||
|
], |
||||||
|
], |
||||||
|
], |
||||||
|
], |
||||||
|
], |
||||||
|
], |
||||||
|
security: 'is_granted(\'ROLE_USER\')', |
||||||
|
validationContext: [ |
||||||
|
'groups' => [ |
||||||
|
'Default', |
||||||
|
'message_attachment:create', |
||||||
|
], |
||||||
|
], |
||||||
|
deserialize: false |
||||||
|
), |
||||||
|
], |
||||||
|
normalizationContext: [ |
||||||
|
'groups' => ['message:read'], |
||||||
|
], |
||||||
|
)] |
||||||
|
#[ORM\Table(name: 'social_post_attachments')] |
||||||
|
#[ORM\Entity(repositoryClass: SocialPostAttachmentRepository::class)] |
||||||
|
class SocialPostAttachment extends AbstractResource implements ResourceInterface, Stringable |
||||||
|
{ |
||||||
|
#[ORM\Column(name: 'id', type: 'integer')] |
||||||
|
#[ORM\Id] |
||||||
|
#[ORM\GeneratedValue] |
||||||
|
protected ?int $id = null; |
||||||
|
|
||||||
|
#[ORM\ManyToOne(targetEntity: \Chamilo\CoreBundle\Entity\SocialPost::class)] |
||||||
|
#[ORM\JoinColumn(name: 'social_post_id', referencedColumnName: 'id', onDelete: 'CASCADE')] |
||||||
|
protected SocialPost $socialPost; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'path', type: 'string', length: 255, nullable: false)] |
||||||
|
protected string $path; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'filename', type: 'text', nullable: false)] |
||||||
|
protected string $filename; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'size', type: 'integer')] |
||||||
|
protected int $size; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'sys_insert_user_id', type: 'integer')] |
||||||
|
protected int $insertUserId; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'sys_insert_datetime', type: 'datetime')] |
||||||
|
protected DateTime $insertDateTime; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'sys_lastedit_user_id', type: 'integer', nullable: true, unique: false)] |
||||||
|
protected ?int $lastEditUserId = null; |
||||||
|
|
||||||
|
#[ORM\Column(name: 'sys_lastedit_datetime', type: 'datetime', nullable: true, unique: false)] |
||||||
|
protected ?DateTime $lastEditDateTime = null; |
||||||
|
|
||||||
|
public function __toString(): string |
||||||
|
{ |
||||||
|
return $this->getFilename(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return int |
||||||
|
*/ |
||||||
|
public function getId() |
||||||
|
{ |
||||||
|
return $this->id; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function getPath() |
||||||
|
{ |
||||||
|
return $this->path; |
||||||
|
} |
||||||
|
|
||||||
|
public function setPath(string $path): self |
||||||
|
{ |
||||||
|
$this->path = $path; |
||||||
|
|
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return string |
||||||
|
*/ |
||||||
|
public function getFilename() |
||||||
|
{ |
||||||
|
return $this->filename; |
||||||
|
} |
||||||
|
|
||||||
|
public function setFilename(string $filename): self |
||||||
|
{ |
||||||
|
$this->filename = $filename; |
||||||
|
|
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @return int |
||||||
|
*/ |
||||||
|
public function getSize() |
||||||
|
{ |
||||||
|
return $this->size; |
||||||
|
} |
||||||
|
|
||||||
|
public function setSize(int $size): self |
||||||
|
{ |
||||||
|
$this->size = $size; |
||||||
|
|
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
public function getSocialPost(): SocialPost |
||||||
|
{ |
||||||
|
return $this->socialPost; |
||||||
|
} |
||||||
|
|
||||||
|
public function setSocialPost(SocialPost $socialPost): self |
||||||
|
{ |
||||||
|
$this->socialPost = $socialPost; |
||||||
|
|
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
public function getResourceName(): string |
||||||
|
{ |
||||||
|
return $this->getFilename(); |
||||||
|
} |
||||||
|
|
||||||
|
public function setResourceName(string $name) |
||||||
|
{ |
||||||
|
return $this->setFilename($name); |
||||||
|
} |
||||||
|
|
||||||
|
public function getResourceIdentifier(): int |
||||||
|
{ |
||||||
|
return $this->getId(); |
||||||
|
} |
||||||
|
|
||||||
|
public function setInsertUserId(int $insertUserId): self |
||||||
|
{ |
||||||
|
$this->insertUserId = $insertUserId; |
||||||
|
|
||||||
|
return $this; |
||||||
|
} |
||||||
|
|
||||||
|
public function setInsertDateTime(DateTime $insertDateTime): self |
||||||
|
{ |
||||||
|
$this->insertDateTime = $insertDateTime; |
||||||
|
|
||||||
|
return $this; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
namespace Chamilo\CoreBundle\Migrations\Schema\V200; |
||||||
|
|
||||||
|
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; |
||||||
|
use Doctrine\DBAL\Schema\Schema; |
||||||
|
|
||||||
|
class Version20231026221100 extends AbstractMigrationChamilo |
||||||
|
{ |
||||||
|
public function getDescription(): string |
||||||
|
{ |
||||||
|
return 'Add table social_post_attachments'; |
||||||
|
} |
||||||
|
|
||||||
|
public function up(Schema $schema): void |
||||||
|
{ |
||||||
|
if (false === $schema->hasTable('social_post_attachments')) { |
||||||
|
$this->addSql("CREATE TABLE social_post_attachments (id INT AUTO_INCREMENT NOT NULL, social_post_id BIGINT DEFAULT NULL, resource_node_id BIGINT DEFAULT NULL, path VARCHAR(255) NOT NULL, filename LONGTEXT NOT NULL, size INT NOT NULL, sys_insert_user_id INT NOT NULL, sys_insert_datetime DATETIME NOT NULL COMMENT '(DC2Type:datetime)', sys_lastedit_user_id INT DEFAULT NULL, sys_lastedit_datetime DATETIME DEFAULT NULL COMMENT '(DC2Type:datetime)', INDEX IDX_DF2A8F34C4F2D6B1 (social_post_id), UNIQUE INDEX UNIQ_DF2A8F341BAD783F (resource_node_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB ROW_FORMAT = DYNAMIC;"); |
||||||
|
$this->addSql("ALTER TABLE social_post_attachments ADD CONSTRAINT FK_DF2A8F34C4F2D6B1 FOREIGN KEY (social_post_id) REFERENCES social_post (id) ON DELETE CASCADE;"); |
||||||
|
$this->addSql("ALTER TABLE social_post_attachments ADD CONSTRAINT FK_DF2A8F341BAD783F FOREIGN KEY (resource_node_id) REFERENCES resource_node (id) ON DELETE CASCADE;"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,116 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
namespace Chamilo\CoreBundle\Migrations\Schema\V200; |
||||||
|
|
||||||
|
use Chamilo\CoreBundle\Entity\SocialPost; |
||||||
|
use Chamilo\CoreBundle\Entity\SocialPostAttachment; |
||||||
|
use Chamilo\CoreBundle\Migrations\AbstractMigrationChamilo; |
||||||
|
use Chamilo\CoreBundle\Repository\Node\SocialPostAttachmentRepository; |
||||||
|
use Chamilo\CoreBundle\Repository\Node\UserRepository; |
||||||
|
use DirectoryIterator; |
||||||
|
use Doctrine\DBAL\Connection; |
||||||
|
use Doctrine\DBAL\Schema\Schema; |
||||||
|
use Symfony\Component\HttpFoundation\File\UploadedFile; |
||||||
|
|
||||||
|
final class Version20231026231100 extends AbstractMigrationChamilo |
||||||
|
{ |
||||||
|
public function getDescription(): string |
||||||
|
{ |
||||||
|
return 'Migrate message_attachments to social_post_attachments'; |
||||||
|
} |
||||||
|
|
||||||
|
public function up(Schema $schema): void |
||||||
|
{ |
||||||
|
$container = $this->getContainer(); |
||||||
|
$em = $this->getEntityManager(); |
||||||
|
/** @var Connection $connection */ |
||||||
|
$connection = $em->getConnection(); |
||||||
|
|
||||||
|
$kernel = $container->get('kernel'); |
||||||
|
$rootPath = $kernel->getProjectDir(); |
||||||
|
|
||||||
|
$repo = $container->get(SocialPostAttachmentRepository::class); |
||||||
|
$userRepo = $container->get(UserRepository::class); |
||||||
|
$admin = $this->getAdmin(); |
||||||
|
|
||||||
|
$sub = $em->createQueryBuilder(); |
||||||
|
$sub->select('sp.id') |
||||||
|
->from('Chamilo\CoreBundle\Entity\SocialPost', 'sp'); |
||||||
|
|
||||||
|
$qb = $em->createQueryBuilder(); |
||||||
|
$qb->select('ma') |
||||||
|
->from('Chamilo\CoreBundle\Entity\MessageAttachment', 'ma') |
||||||
|
->where($qb->expr()->in('ma.message', $sub->getDQL())); |
||||||
|
|
||||||
|
$query = $qb->getQuery(); |
||||||
|
$messageAttachments = $query->getResult(); |
||||||
|
|
||||||
|
foreach ($messageAttachments as $attachment) { |
||||||
|
$message = $attachment->getMessage(); |
||||||
|
if ($message) { |
||||||
|
$messageId = $message->getId(); |
||||||
|
$filename = $attachment->getFilename(); |
||||||
|
$rootDir = $rootPath.'/app/upload/users'; |
||||||
|
$targetFile = $attachment->getPath(); |
||||||
|
$foundFilePath = $this->findFileRecursively($rootDir, $targetFile); |
||||||
|
|
||||||
|
if ($foundFilePath) { |
||||||
|
echo "Archivo encontrado en: " . $foundFilePath; |
||||||
|
|
||||||
|
$mimeType = mime_content_type($foundFilePath); |
||||||
|
$uploadFile = new UploadedFile($foundFilePath, $filename, $mimeType, null, true); |
||||||
|
|
||||||
|
$socialPost = $em->getRepository(SocialPost::class)->find($messageId); |
||||||
|
|
||||||
|
$attachment = new SocialPostAttachment(); |
||||||
|
$attachment->setSocialPost($socialPost); |
||||||
|
$attachment->setPath(uniqid('social_post', true)); |
||||||
|
$attachment->setFilename($uploadFile->getClientOriginalName()); |
||||||
|
$attachment->setSize($uploadFile->getSize()); |
||||||
|
$attachment->setInsertUserId($admin->getId()); |
||||||
|
$attachment->setInsertDateTime(new \DateTime('now', new \DateTimeZone('UTC'))); |
||||||
|
$attachment->setParent($admin); |
||||||
|
$attachment->addUserLink($admin); |
||||||
|
$attachment->setCreator($admin); |
||||||
|
|
||||||
|
$em->persist($attachment); |
||||||
|
$em->flush(); |
||||||
|
|
||||||
|
$repo->addFile($attachment, $uploadFile); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private function findFileRecursively(string $directory, string $targetFile): ?string |
||||||
|
{ |
||||||
|
if (!is_dir($directory)) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
foreach (new DirectoryIterator($directory) as $fileInfo) { |
||||||
|
if ($fileInfo->isDot()) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
$filePath = $fileInfo->getPathname(); |
||||||
|
|
||||||
|
if ($fileInfo->isDir()) { |
||||||
|
$result = $this->findFileRecursively($filePath, $targetFile); |
||||||
|
if ($result !== null) { |
||||||
|
return $result; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (str_contains($fileInfo->getFilename(), $targetFile)) { |
||||||
|
return $filePath; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,19 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
/* For licensing terms, see /license.txt */ |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Chamilo\CoreBundle\Repository\Node; |
||||||
|
|
||||||
|
use Chamilo\CoreBundle\Entity\SocialPostAttachment; |
||||||
|
use Chamilo\CoreBundle\Repository\ResourceRepository; |
||||||
|
use Doctrine\Persistence\ManagerRegistry; |
||||||
|
|
||||||
|
class SocialPostAttachmentRepository extends ResourceRepository |
||||||
|
{ |
||||||
|
public function __construct(ManagerRegistry $registry) |
||||||
|
{ |
||||||
|
parent::__construct($registry, SocialPostAttachment::class); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue