packthub_ebook_integration-1.0.0/src/Controller/ProductsDashboard.php
src/Controller/ProductsDashboard.php
<?php
namespace Drupal\packt\Controller;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\node\Entity\Node;
use Drupal\packt\Plugin\EbookDefinition;
use Drupal\packt\Plugin\EbookNodeProcessor;
use Drupal\packt\Plugin\Products;
use Drupal\packt\Plugin\ProductsAssets;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerInterface;
class ProductsDashboard extends ControllerBase {
/**
* {@inheritdoc}
*/
public function __construct(
protected readonly KillSwitch $killSwitch,
protected readonly RendererInterface $renderer,
ConfigFactoryInterface $config_factory
) {
$this->configFactory = $config_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container):
ProductsDashboard|static {
return new static(
$container->get('page_cache_kill_switch'),
$container->get('renderer'),
$container->get('config.factory'),
);
}
public function products(Request $request): array {
$this->killSwitch->trigger();
$pagesTotal = $this->totalPages();
$page = $request->get('page', 0);
// Let's check in the cache for this page
$cacheFactory = \Drupal::cache();
$cacheId = 'packt_page_products_'.$page;
// To retrieve the cached array:
$products = $cacheFactory->get($cacheId)->data ?? NULL;
if(empty($products)) {
// Lets get products
$prod = new Products();
$prod->setLimit(21);
$prod->setPage((int) $page);
$prod->setFilter('product_type', '=', 'book');
$products = $prod->getProducts(all: false);
$products = $this->processDetails($products, (int) $page);
}
$url = Url::fromRoute('packt.products_Search')->toString();
$urlCreate = Url::fromRoute('packt.products_ebook')->toString();
$loading = \Drupal::moduleHandler()->getModule('packt')->getPath();
$loading = $loading . "/assets/images/loading.gif";
$loading = \Drupal::service('file_url_generator')
->generateAbsoluteString($loading);
$create = \Drupal::moduleHandler()->getModule('packt')->getPath();
$create = $create . "/assets/images/creating.gif";
$create = \Drupal::service('file_url_generator')
->generateAbsoluteString($create);
return [
'#theme' => 'packt_products_dashboard',
'#title' => 'Dashboard',
'#content' => ['products' => $products,
'total'=>count($products),
'url'=>$url,
'icon'=>$loading,
'create' => $create,
'create_url' => $urlCreate,
'total_page' => $pagesTotal
],
'#attached' => [
'library' => [
'packt/manager_assets',
],
],
];
}
private function processDetails(array $products, int $page = 0): array {
$details = [];
foreach ($products as $product) {
$pid = $product['product_id'] ?? null;
if(!empty($pid)) {
$pDetails = new Products();
$pDetails->setProductID($pid);
$productInfo = $pDetails->getProducts();
$assets = new ProductsAssets();
$assets->setProduct($pid);
$png = [];
foreach ($productInfo['files'] as $file) {
if($file['distribution_type'] === 'cover_image') {
$png = $file;
break;
}
}
$thumbnail = null;
$defaultImage = null;
$noImage = false;
if($png) {
$filename = explode('.', $png['file_name'] ?? "");
if(!empty($filename[0])) {
$assets->setFileName($filename[0]);
$ext = end($filename);
$file = $assets->getAssets();
if(!empty($file['data'])) {
$thumbnail = "data:image/$ext;base64,".base64_encode($file['data']);
}else {
$noImage = true;
}
}
}
if($noImage || empty($png)) {
$module = \Drupal::moduleHandler()->getModule('packt')->getPath();
$defaultImage = $module . "/assets/images/book_coming_soon.png";
$defaultImage = \Drupal::service('file_url_generator')
->generateAbsoluteString($defaultImage);
}
$details[] = [
'product_name' => $productInfo['product_information']['title'] ?? '',
'product_id' => $productInfo['product_id'] ?? null,
'description' => $productInfo['product_information']['meta_description'] ?? null,
'date' => (new \DateTime($productInfo['metadata']['publication_date'] ?? 'now'))->format('d F, Y'),
'author' => $productInfo['contributors'][0]['firstname'] ?? null,
'type' => ucfirst($productInfo['product_type']) ?? null,
'thumbnail' => $thumbnail ?? $defaultImage,
];
}
}
// Lets cache this results
// Get the cache factory from the container
$cacheFactory = \Drupal::cache();
$cacheId = 'packt_page_products_'.$page;
// Store the array in the cache
$cacheFactory->set($cacheId, $details, CacheBackendInterface::CACHE_PERMANENT);
return $details;
}
public function productsSearch(Request $request): JsonResponse {
$this->killSwitch->trigger();
$limit = $request->get('limit');
$type = $request->get('type');
$title = $request->get('title');
$page = $request->get('page');
$orderBy = $request->get('orderby');
$buildUp = new Products();
if(!empty($title)) {
$buildUp->setFilter('title', '=',$title);
}
if(!empty($type)) {
$buildUp->setFilter('product_type', '=', $type);
}
if(!empty($page)) {
$buildUp->setPage((int) $page);
}
if(!empty($limit)) {
$buildUp->setLimit((int) $limit);
}
if(!empty($orderBy)) {
$buildUp->setOrderBy($orderBy);
}
$products = $buildUp->getProducts(all: false);
if(!empty($products)) {
$products = $this->processDetails($products, 0);
}
else {
return (new JsonResponse([],404));
}
$results = $this->createCards($products);
return (new JsonResponse(['results'=>$results, 'total'=>count($products)],200));
}
private function createCards(array $products):string {
$rendered_output = [
'#theme' => 'packt_products_search',
'#title' => NULL,
'#content' => ['products' => $products],
'#attached' => [
'library' => [
'packt/manager_assets',
],
],
];
// Render the HTML output using the renderer service.
return $this->renderer->renderRoot($rendered_output);
}
public function prepareNodeCreation(Request $request): JsonResponse {
// Get JSON data from the request.
$jsonData = json_decode($request->getContent(), TRUE);
$product = $jsonData['product'] ?? $request->get('product');
if(!empty($product)) {
$ebooks = new EbookNodeProcessor(explode(',', $product));
if($ebooks->attemptFieldsMapping()) {
$data = $ebooks->getMappedDataReady();
$message = $ebooks->getMessages();
$cacheId = random_int(100, 1000);
$cacheFactory = \Drupal::cache();
$cacheFactory->set($cacheId, $data, CacheBackendInterface::CACHE_PERMANENT);
$save = Url::fromRoute('packt.ebook_action',['action'=>'save','id'=>$cacheId])->toString();
$delete = Url::fromRoute('packt.ebook_action',['action'=>'delete','id'=>$cacheId])->toString();
return (new JsonResponse(['results'=> $message, 'save' => $save, 'delete'=>$delete], 200));
}
else {
$url = Url::fromRoute('packt.ebook_configure')->toString();
return (new JsonResponse(['results'=> "Content Type not provided, please configure content type <a href='$url'>here</a> for storing ebooks"], 200));
}
}
return (new JsonResponse(['results'=>'Product id (s) not provided'], 404));
}
public function finishingCreations(Request $request): array {
$this->killSwitch->trigger();
$cacheId = $request->get('id');
$action = $request->get('action');
$cacheFactory = \Drupal::cache();
$nodes = $cacheFactory->get($cacheId)->data ?? NULL;
if($action === 'save') {
if(!empty($nodes)) {
foreach ($nodes as $node) {
if($node instanceof Node) {
$node->save();
\Drupal::messenger()->addMessage('Created ebook, '. $node->getTitle());
}
}
$url = Url::fromRoute('packt.products')->toString();
$cacheFactory->delete($cacheId);
(new RedirectResponse($url))->send();
}
}
if($action === 'delete') {
$configuration = packt_ebook_maps();
if($configuration) {
$contentType = $configuration['content_type'];
unset($configuration['content_type']);
$fields = array_keys($configuration);
$ebook = new EbookDefinition();
$fieldInfo = $ebook->contentFieldDefinitions($contentType);
foreach ($fieldInfo as $item) {
if(in_array($item['id'], $fields) && ($item['type'] === 'image' || $item['type'] === 'file_managed' || $item['type'] === 'file')) {
// Lets look for node fid
foreach ($nodes as $node) {
if($node instanceof Node) {
$fid = $node->get($item['id'])->getValue()[0]['target_id'] ?? null;
if(!empty($fid)) {
$file = File::load($fid);
$filename = $file->getFilename();
if($file instanceof File) {
$file->delete();
\Drupal::messenger()->addMessage("Ebook related file removed ($filename)");
}
}
}
}
}
}
$cacheFactory->delete($cacheId);
\Drupal::messenger()->addMessage("Ebook creation cancelled successfully");
$url = Url::fromRoute('packt.products')->toString();
$cacheFactory->delete($cacheId);
(new RedirectResponse($url))->send();
}
}
return ['#markup' => 'Something went wrong'];
}
public function totalPages(): int {
$cacheFactory = \Drupal::cache();
$cacheId = 'packt_page_products_meta';
// To retrieve the cached array:
$meta = $cacheFactory->get($cacheId)->data ?? NULL;
if(!empty($meta)) {
return $meta;
}
$pr = new Products();
$pr->setLimit(1);
$pr->setFilter('product_type', '=', 'book');
$product =$pr->getProducts();
if(!empty($product) && $product['last_page']) {
// Store the array in the cache
$cacheFactory->set($cacheId, $product['last_page'], CacheBackendInterface::CACHE_PERMANENT);
return $product['last_page'];
}
return 100;
}
}
