Actualización

This commit is contained in:
Xes
2025-04-10 12:36:07 +02:00
parent 1da7c3f3b9
commit 4aff98e77b
3147 changed files with 320647 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
<?php
/* For license terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\TopLinks\Repository;
use Chamilo\CoreBundle\Entity\Course;
use Chamilo\CourseBundle\Entity\CTool;
use Chamilo\PluginBundle\Entity\TopLinks\TopLink;
use Chamilo\PluginBundle\Entity\TopLinks\TopLinkRelTool;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
/**
* Class TopLinkRelToolRepository.
*
* @package Chamilo\PluginBundle\Entity\TopLinks\Repository
*/
class TopLinkRelToolRepository extends EntityRepository
{
public function findInCourse(Course $course)
{
$qb = $this->createQueryBuilder('tlrt');
return $qb
->innerJoin('tlrt.tool', 'tool', Join::WITH)
->where($qb->expr()->eq('tool.cId', ':course'))
->setParameter('course', $course)
->getQuery()
->getResult();
}
public function updateTools(TopLink $link)
{
$subQb = $this->createQueryBuilder('tlrt');
$subQb
->select('tool.iid')
->innerJoin('tlrt.tool', 'tool', Join::WITH)
->where($subQb->expr()->eq('tlrt.link', ':link'))
->setParameter('link', $link);
$linkTools = $subQb->getQuery()->getArrayResult();
$qb = $this->_em->createQueryBuilder();
$qb
->update(CTool::class, 'tool')
->set('tool.name', ':link_name')
->set('tool.target', ':link_target')
->where(
$qb->expr()->in('tool.iid', ':tools')
)
->setParameter('link_name', $link->getTitle())
->setParameter('link_target', $link->getTarget())
->setParameter('tools', array_column($linkTools, 'iid'))
->getQuery()
->execute();
}
public function getMissingCoursesForTool(int $linkId)
{
$qb = $this->_em->createQueryBuilder();
$subQb = $this->_em->createQueryBuilder();
$subQb
->select('t.cId')
->from(CTool::class, 't')
->innerJoin(TopLinkRelTool::class, 'tlrt', Join::WITH, $subQb->expr()->eq('t.iid', 'tlrt.tool'))
->where($subQb->expr()->eq('tlrt.link', ':link_id'));
return $qb
->select('c')
->from(Course::class, 'c')
->where($qb->expr()->notIn('c.id', $subQb->getDQL()))
->setParameter('link_id', $linkId)
->getQuery()
->getResult();
}
}

View File

@@ -0,0 +1,26 @@
<?php
/* For license terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\TopLinks\Repository;
use Doctrine\ORM\EntityRepository;
/**
* Class TopLinkRepository.
*
* @package Chamilo\PluginBundle\Entity\TopLinks
*/
class TopLinkRepository extends EntityRepository
{
public function all($offset, $limit, $column, $direction): array
{
$orderBy = ['title' => $direction];
if (1 == $column) {
$orderBy = ['url' => $direction];
}
return parent::findBy([], $orderBy, $limit, $offset);
}
}

View File

@@ -0,0 +1,137 @@
<?php
/* For license terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\TopLinks;
use Chamilo\CourseBundle\Entity\CTool;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* Class TopLink.
*
* @package Chamilo\PluginBundle\Entity\TopLinks
*
* @ORM\Table(name="toplinks_link")
* @ORM\Entity(repositoryClass="Chamilo\PluginBundle\Entity\TopLinks\Repository\TopLinkRepository")
*/
class TopLink
{
/**
* @var int
*
* @ORM\Column(type="integer", name="id")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="title", type="string")
*/
private $title;
/**
* @var string
*
* @ORM\Column(name="url", type="text")
*/
private $url;
/**
* @var string
*
* @ORM\Column(name="target", type="string", length=10, options={"default":"_blank"})
*/
private $target;
/**
* @var string|null
*
* @ORM\Column(name="icon", type="string", nullable=true)
*/
private $icon;
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\OneToMany(targetEntity="Chamilo\PluginBundle\Entity\TopLinks\TopLinkRelTool", mappedBy="link", orphanRemoval=true, cascade={"persist", "remove"})
*/
private $tools;
public function __construct()
{
$this->target = '_blank';
$this->icon = null;
$this->tools = new ArrayCollection();
}
public function getId(): int
{
return $this->id;
}
public function getTitle(): string
{
return $this->title;
}
public function setTitle(string $title): TopLink
{
$this->title = $title;
return $this;
}
public function getUrl(): string
{
return $this->url;
}
public function setUrl(string $url): TopLink
{
$this->url = $url;
return $this;
}
public function getTarget(): string
{
return $this->target;
}
public function setTarget(string $target): TopLink
{
$this->target = $target;
return $this;
}
public function getIcon(): ?string
{
return $this->icon;
}
public function setIcon(string $icon = null): TopLink
{
$this->icon = $icon;
return $this;
}
/**
* @return \Doctrine\Common\Collections\Collection
*/
public function getTools()
{
return $this->tools;
}
public function addTool(CTool $tool)
{
$linkTool = new TopLinkRelTool();
$linkTool
->setTool($tool)
->setLink($this);
$this->tools->add($linkTool);
}
}

View File

@@ -0,0 +1,84 @@
<?php
/* For license terms, see /license.txt */
namespace Chamilo\PluginBundle\Entity\TopLinks;
use Chamilo\CourseBundle\Entity\CTool;
use Doctrine\ORM\Mapping as ORM;
/**
* Class TopLinkRelTool.
*
* @package Chamilo\PluginBundle\Entity\TopLinks
*
* @ORM\Table(name="toplinks_link_rel_tool")
* @ORM\Entity(repositoryClass="Chamilo\PluginBundle\Entity\TopLinks\Repository\TopLinkRelToolRepository")
*/
class TopLinkRelTool
{
/**
* @var int
*
* @ORM\Column(type="integer", name="id")
* @ORM\Id()
* @ORM\GeneratedValue()
*/
private $id;
/**
* @var \Chamilo\PluginBundle\Entity\TopLinks\TopLink
*
* @ORM\ManyToOne(targetEntity="Chamilo\PluginBundle\Entity\TopLinks\TopLink", inversedBy="tools")
* @ORM\JoinColumn(name="link_id", referencedColumnName="id")
*/
private $link;
/**
* @var \Chamilo\CourseBundle\Entity\CTool
*
* @ORM\OneToOne(targetEntity="Chamilo\CourseBundle\Entity\CTool", cascade={"persist", "remove"})
* @ORM\JoinColumn(name="tool_id", referencedColumnName="iid", nullable=true, onDelete="CASCADE")
*/
private $tool;
public function getId(): int
{
return $this->id;
}
public function setId(int $id): TopLinkRelTool
{
$this->id = $id;
return $this;
}
/**
* @return \Chamilo\PluginBundle\Entity\TopLinks\TopLink
*/
public function getLink(): TopLink
{
return $this->link;
}
/**
* @param \Chamilo\PluginBundle\Entity\TopLinks\TopLink $link
*/
public function setLink(TopLink $link): TopLinkRelTool
{
$this->link = $link;
return $this;
}
public function getTool(): CTool
{
return $this->tool;
}
public function setTool(CTool $tool): TopLinkRelTool
{
$this->tool = $tool;
return $this;
}
}

View File

@@ -0,0 +1,40 @@
<?php
/* For licensing terms, see /license.txt */
use Chamilo\PluginBundle\Entity\TopLinks\TopLink;
/**
* Class TopLinksCreateCourseHookObserver.
*/
class TopLinksCreateCourseHookObserver extends HookObserver implements HookCreateCourseObserverInterface
{
/**
* XApiCreateCourseHookObserver constructor.
*/
protected function __construct()
{
parent::__construct('plugin/toplinks/src/TopLinksPlugin.php', 'toplinks');
}
public function hookCreateCourse(HookCreateCourseEventInterface $hook): int
{
$data = $hook->getEventData();
$type = $data['type'];
$courseInfo = $data['course_info'];
$plugin = TopLinksPlugin::create();
$em = Database::getManager();
$linkRepo = $em->getRepository(TopLink::class);
if (HOOK_EVENT_TYPE_POST == $type) {
foreach ($linkRepo->findAll() as $link) {
$plugin->addToolInCourse($courseInfo['real_id'], $link);
}
}
return (int) $courseInfo['real_id'];
}
}

View File

@@ -0,0 +1,148 @@
<?php
/* For license terms, see /license.txt */
namespace Chamilo\PluginBundle\TopLinks\Form;
use Chamilo\PluginBundle\Entity\TopLinks\TopLink;
use FormValidator;
use Image;
use Security;
use Symfony\Component\Filesystem\Filesystem;
/**
* Class LinkForm.
*
* @package Chamilo\PluginBundle\TopLinks\Form
*/
class LinkForm extends FormValidator
{
/**
* @var TopLink
*/
private $link;
/**
* LinkForm constructor.
*/
public function __construct(TopLink $link = null)
{
$this->link = $link;
$actionParams = [
'action' => 'add',
'sec_token' => Security::get_existing_token(),
];
if ($this->link) {
$actionParams['action'] = 'edit';
$actionParams['link'] = $this->link->getId();
}
$action = api_get_self().'?'.http_build_query($actionParams);
parent::__construct('frm_link', 'post', $action, '');
}
public function validate(): bool
{
return parent::validate() && Security::check_token('get');
}
public function exportValues($elementList = null)
{
Security::clear_token();
return parent::exportValues($elementList);
}
public function createElements()
{
global $htmlHeadXtra;
$htmlHeadXtra[] = api_get_css_asset('cropper/dist/cropper.min.css');
$htmlHeadXtra[] = api_get_asset('cropper/dist/cropper.min.js');
$this->addText('title', get_lang('LinkName'));
$this->addUrl('url', 'URL');
$this->addRule('url', get_lang('GiveURL'), 'url');
$this->addSelect(
'target',
[
get_lang('LinkTarget'),
get_lang('AddTargetOfLinkOnHomepage'),
],
[
'_blank' => get_lang('LinkOpenBlank'),
'_self' => get_lang('LinkOpenSelf'),
]
);
$this->addFile(
'picture',
[
$this->link ? get_lang('UpdateImage') : get_lang('AddImage'),
get_lang('OnlyImagesAllowed'),
],
[
'id' => 'picture',
'class' => 'picture-form',
'crop_image' => true,
'crop_ratio' => '1 / 1',
'accept' => 'image/*',
]
);
$allowedPictureTypes = api_get_supported_image_extensions(false);
$this->addRule(
'picture',
get_lang('OnlyImagesAllowed').' ('.implode(', ', $allowedPictureTypes).')',
'filetype',
$allowedPictureTypes
);
$this->addButtonSave(get_lang('SaveLink'), 'submitLink');
}
public function returnForm()
{
$defaults = [];
if ($this->link) {
$defaults['title'] = $this->link->getTitle();
$defaults['url'] = $this->link->getUrl();
$defaults['target'] = $this->link->getTarget();
}
$this->setDefaults($defaults);
return parent::returnForm(); // TODO: Change the autogenerated stub
}
public function setLink(TopLink $link): LinkForm
{
$this->link = $link;
return $this;
}
public function saveImage(): ?string
{
$pictureCropResult = $this->exportValue('picture_crop_result');
if (empty($pictureCropResult)) {
return null;
}
$extension = pathinfo($_FILES['picture']['name'], PATHINFO_EXTENSION);
$newFilename = md5($this->link->getId()).".$extension";
$directoryName = api_get_path(SYS_UPLOAD_PATH).'plugins/toplinks';
$fs = new Filesystem();
$fs->mkdir($directoryName, api_get_permissions_for_new_directories());
$image = new Image($_FILES['picture']['tmp_name']);
$image->crop($pictureCropResult);
$image->resize(ICON_SIZE_BIG);
$image->send_image("$directoryName/$newFilename");
return $newFilename;
}
}

View File

@@ -0,0 +1,136 @@
<?php
/* For license terms, see /license.txt */
use Chamilo\PluginBundle\Entity\TopLinks\TopLink;
use Chamilo\PluginBundle\Entity\TopLinks\TopLinkRelTool;
use Doctrine\ORM\Tools\SchemaTool;
/**
* Class TopLinksPlugin.
*/
class TopLinksPlugin extends Plugin implements HookPluginInterface
{
/**
* TopLinksPlugin constructor.
*/
protected function __construct()
{
$settings = [
];
parent::__construct(
'0.1',
'Angel Fernando Quiroz Campos <angel.quiroz@beeznest.com>',
$settings
);
}
/**
* @return \TopLinksPlugin
*/
public static function create(): TopLinksPlugin
{
static $result = null;
return $result ? $result : $result = new self();
}
/**
* {@inheritdoc}
*/
public function getAdminUrl()
{
$webPath = api_get_path(WEB_PLUGIN_PATH).$this->get_name();
return "$webPath/admin.php";
}
public function addToolInCourse(int $courseId, TopLink $link)
{
// The $link param is set to "../plugin" as a hack to link correctly to the plugin URL in course tool.
// Otherwise, the link en the course tool will link to "/main/" URL.
$tool = $this->createLinkToCourseTool(
$link->getTitle(),
$courseId,
'external_link.png',
'../plugin/toplinks/start.php?'.http_build_query(['link' => $link->getId()]),
0,
'authoring'
);
if (null === $tool) {
return;
}
$tool->setTarget($link->getTarget());
$link->addTool($tool);
$em = Database::getManager();
$em->persist($link);
$em->flush();
}
public function install()
{
$em = Database::getManager();
$schemaManager = $em->getConnection()->getSchemaManager();
$tableReferences = [
'toplinks_link' => $em->getClassMetadata(TopLink::class),
'toplinks_link_rel_tool' => $em->getClassMetadata(TopLinkRelTool::class),
];
$tablesExists = $schemaManager->tablesExist(array_keys($tableReferences));
if ($tablesExists) {
return;
}
$schemaTool = new SchemaTool($em);
$schemaTool->createSchema(array_values($tableReferences));
$this->installHook();
}
public function installHook(): int
{
$createCourseObserver = TopLinksCreateCourseHookObserver::create();
HookCreateCourse::create()->attach($createCourseObserver);
return 1;
}
public function uninstall()
{
$em = Database::getManager();
$tableReferences = [
'toplinks_link' => $em->getClassMetadata(TopLink::class),
'toplinks_link_rel_tool' => $em->getClassMetadata(TopLinkRelTool::class),
];
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema(array_values($tableReferences));
$this->uninstallHook();
$this->deleteCourseTools();
}
public function uninstallHook(): int
{
$createCourseObserver = TopLinksCreateCourseHookObserver::create();
HookCreateCourse::create()->detach($createCourseObserver);
return 1;
}
private function deleteCourseTools()
{
Database::getManager()
->createQuery('DELETE FROM ChamiloCourseBundle:CTool t WHERE t.category = :category AND t.link LIKE :link')
->execute(['category' => 'authoring', 'link' => '../plugin/toplinks/start.php%']);
}
}