<?php
namespace Webkul\UVDesk\CoreFrameworkBundle\Dashboard;
use Symfony\Component\Routing\RouterInterface;
use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService;
use Webkul\UVDesk\CoreFrameworkBundle\Framework\ExtendableComponentInterface;
use Webkul\UVDesk\CoreFrameworkBundle\Dashboard\Segments\HomepageSectionInterface;
use Webkul\UVDesk\CoreFrameworkBundle\Dashboard\Segments\HomepageSectionItemInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class HomepageTemplate implements ExtendableComponentInterface
{
CONST SECTION_TEMPLATE = '<div class="uv-brick"><div class="uv-brick-head"><h6>[[ TITLE ]]</h6><p>[[ DESCRIPTION ]]</p></div><div class="uv-brick-section">[[ COLLECTION ]]</div></div>';
CONST SECTION_ITEM_TEMPLATE = '<a href="[[ PATH ]]"><div class="uv-brick-container"><div class="uv-brick-icon">[[ SVG ]]</div><p>[[ TITLE ]]</p></div></a>';
private $sections = [];
private $sectionItems = [];
private $isOrganized = false;
public function __construct(RouterInterface $router, UserService $userService, TranslatorInterface $translator)
{
$this->router = $router;
$this->userService = $userService;
$this->translator = $translator;
}
public function appendSection(HomepageSectionInterface $section, $tags = [])
{
$this->sections[] = $section;
}
public function appendSectionItem(HomepageSectionItemInterface $sectionItem, $tags = [])
{
$this->sectionItems[] = $sectionItem;
}
private function organizeCollection()
{
$references = [];
// Sort segments alphabetically
usort($this->sections, function($section_1, $section_2) {
return strcasecmp($section_1::getTitle(), $section_2::getTitle());
});
// @TODO: Refactor!!!
$findSectionByName = function(&$array, $name) {
for ($i = 0; $i < count($array); $i++) {
if (strtolower($array[$i]::getTitle()) === $name) {
return array($i, $array[$i]);
}
}
};
// re-inserting users section
$users_sec = $findSectionByName($this->sections, "users");
array_splice($this->sections, $users_sec[0], 1);
array_splice($this->sections, $findSectionByName($this->sections, "knowledgebase")[0] + 1, 0, [$users_sec[1]]);
usort($this->sectionItems, function($item_1, $item_2) {
return strcasecmp($item_1::getTitle(), $item_2::getTitle());
});
// Maintain array references
foreach ($this->sections as $reference => $section) {
$references[get_class($section)] = $reference;
}
// Iteratively add child segments to their respective parent segments
foreach ($this->sectionItems as $sectionItem) {
if (!array_key_exists($sectionItem::getSectionReferenceId(), $references)) {
continue;
// @TODO: Handle exception
throw new \Exception("No dashboard section [" . $sectionItem::getSectionReferenceId() . "] found for section item " . $sectionItem::getTitle() . " [" . get_class($sectionItem) . "].");
}
$this->sections[$references[$sectionItem::getSectionReferenceId()]]->appendItem($sectionItem);
}
$this->isOrganized = true;
}
private function isSegmentAccessible($segment)
{
if ($segment::getRoles() != null) {
$is_accessible = false;
foreach ($segment::getRoles() as $accessRole) {
if ($this->userService->isAccessAuthorized($accessRole)) {
$is_accessible = true;
break;
}
}
return $is_accessible;
}
return true;
}
private function getAccessibleSegments()
{
$whitelist = [];
// Filter segments based on user credentials
foreach ($this->sections as $segment) {
if (false == $this->isSegmentAccessible($segment)) {
continue;
}
foreach ($segment->getItemCollection() as $childSegment) {
if (false == $this->isSegmentAccessible($childSegment)) {
continue;
}
$whitelist[get_class($segment)][] = get_class($childSegment);
}
}
return $whitelist;
}
public function render()
{
if (false == $this->isOrganized) {
$this->organizeCollection();
}
$html = '';
$whitelist = $this->getAccessibleSegments();
// Render user accessible segments
foreach ($this->sections as $segment) {
if (empty($whitelist[get_class($segment)])) {
continue;
}
$sectionHtml = '';
$references = $whitelist[get_class($segment)];
foreach ($segment->getItemCollection() as $childSegment) {
if (!in_array(get_class($childSegment), $references)) {
continue;
}
$sectionHtml .= strtr(self::SECTION_ITEM_TEMPLATE, [
'[[ SVG ]]' => $childSegment::getIcon(),
'[[ TITLE ]]' => $this->translator->trans($childSegment::getTitle()),
'[[ PATH ]]' => $this->router->generate($childSegment::getRouteName()),
]);
}
$html .= strtr(self::SECTION_TEMPLATE, [
'[[ TITLE ]]' => $this->translator->trans($segment::getTitle()),
'[[ DESCRIPTION ]]' => $this->translator->trans($segment::getDescription()),
'[[ COLLECTION ]]' => $sectionHtml,
]);
}
return $html;
}
}