vendor/uvdesk/support-center-bundle/Controller/Website.php line 165

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\SupportCenterBundle\Controller;
  3. use Doctrine\Common\Collections\Criteria;
  4. use Webkul\UVDesk\SupportCenterBundle\Form;
  5. use Symfony\Component\HttpFoundation\Request;
  6. use Symfony\Component\HttpFoundation\Response;
  7. use Symfony\Component\HttpFoundation\ParameterBag;
  8. use Webkul\UVDesk\SupportCenterBundle\Entity\Article;
  9. use Webkul\UVDesk\SupportCenterBundle\Entity\Solutions;
  10. use Symfony\Bundle\FrameworkBundle\Controller\Controller;
  11. use Webkul\UVDesk\SupportCenterBundle\Entity\ArticleViewLog;
  12. use Webkul\UVDesk\SupportCenterBundle\Entity\SolutionCategory;
  13. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  14. use Webkul\UVDesk\SupportCenterBundle\Entity\KnowledgebaseWebsite;
  15. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Website as CoreWebsite;
  16. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  17. use Symfony\Component\Security\Core\Security;
  18. use Webkul\UVDesk\CoreFrameworkBundle\Entity\User;
  19. use Doctrine\ORM\EntityManagerInterface;
  20. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportRole;
  21. use Webkul\UVDesk\CoreFrameworkBundle\Entity\UserInstance;
  22. use Symfony\Component\HttpFoundation\RequestStack;
  23. use Symfony\Component\EventDispatcher\GenericEvent;
  24. use Symfony\Component\DependencyInjection\ContainerInterface;
  25. use Webkul\UVDesk\CoreFrameworkBundle\Workflow\Events as CoreWorkflowEvents;
  26. use Symfony\Component\Routing\Annotation\Route;
  27. use Symfony\Component\HttpFoundation\JsonResponse;
  28. class Website extends Controller
  29. {
  30.     private $visibility = ['public'];
  31.     private $limit 5;
  32.     private $company;
  33.     private function isKnowledgebaseActive()
  34.     {
  35.         $entityManager $this->getDoctrine()->getManager();
  36.         $website $entityManager->getRepository(CoreWebsite::class)->findOneByCode('knowledgebase');
  37.         if (!empty($website)) {
  38.             $knowledgebaseWebsite $entityManager->getRepository(KnowledgebaseWebsite::class)->findOneBy(['website' => $website->getId(), 'status' => true]);
  39.             if (!empty($knowledgebaseWebsite) && true == $knowledgebaseWebsite->getIsActive()) {
  40.                 return true;
  41.             }
  42.         }
  43.         throw new NotFoundHttpException('Page Not Found');
  44.     }
  45.     public function home(Request $request)
  46.     {
  47.         $user=$this->get('user.service')->getSessionUser();
  48.         if(!$user){
  49.            return new Response($this->container->get('twig')->render('@UVDeskSupportCenter//Knowledgebase//login.html.twig', [
  50.             ]));
  51.         }
  52.         
  53.         $this->isKnowledgebaseActive();
  54.         $parameterBag = [
  55.             'visibility' => 'public',
  56.             'sort' => 'id',
  57.             'direction' => 'desc'
  58.         ];
  59.         $articleRepository $this->getDoctrine()->getRepository('UVDeskSupportCenterBundle:Article');
  60.         $solutionRepository $this->getDoctrine()->getRepository('UVDeskSupportCenterBundle:Solutions');
  61.         $twigResponse = [
  62.             'searchDisable' => false,
  63.             'popArticles' => $articleRepository->getPopularTranslatedArticles($request->getLocale()),
  64.             'solutions' => $solutionRepository->getAllSolutions(new ParameterBag($parameterBag), $this->container'a', [1]),
  65.         ];
  66.         $newResult = [];
  67.        
  68.         foreach ($twigResponse['solutions'] as $key => $result) {
  69.             $newResult[] = [
  70.                 'id' => $result->getId(),
  71.                 'name' => $result->getName(),
  72.                 'description' => $result->getDescription(),
  73.                 'visibility' => $result->getVisibility(),
  74.                 'solutionImage' => ($result->getSolutionImage() == null) ? '' $result->getSolutionImage(),
  75.                 'categoriesCount' => $solutionRepository->getCategoriesCountBySolution($result->getId()),
  76.                 'categories' => $solutionRepository->getCategoriesWithCountBySolution($result->getId()),
  77.                 'articleCount' => $solutionRepository->getArticlesCountBySolution($result->getId()),
  78.             ];
  79.         }
  80.         $twigResponse['solutions']['results'] = $newResult;
  81.         $twigResponse['solutions']['categories'] = array_map(function($category) use ($articleRepository) {
  82.             $parameterBag = [
  83.                 'categoryId' => $category['id'],
  84.                 'status' => 1,
  85.                 'sort' => 'id',
  86.                 'limit'=>10,
  87.                 'direction' => 'desc'
  88.             ];
  89.             $article =  $articleRepository->getAllArticles(new ParameterBag($parameterBag), $this->container'a.id, a.name, a.slug, a.stared');
  90.              
  91.             return [
  92.                 'id' => $category['id'],
  93.                 'name' => $category['name'],
  94.                 'description' => $category['description'],
  95.                 'articles' => $article
  96.             ];
  97.         }, $solutionRepository->getAllCategories(102));
  98.         
  99.         $filterArray = ['id' => 5];
  100.         $solution $this->getDoctrine()
  101.             ->getRepository('UVDeskSupportCenterBundle:Solutions')
  102.             ->findOneBy($filterArray);
  103.         $parameterBag = [
  104.             'solutionId' => $solution->getId(),
  105.             'status' => 1,
  106.             'sort' => 'id',
  107.             'direction' => 'desc'
  108.         ];
  109.         $articles $this->getDoctrine()
  110.             ->getRepository('UVDeskSupportCenterBundle:Article')
  111.             ->getAllArticles(new ParameterBag($parameterBag), $this->container'a.id, a.name, a.slug, a.stared');
  112.         $twigResponse['articles'] = array_reverse($articles);
  113.         return $this->render('@UVDeskSupportCenter//Knowledgebase//index.html.twig'$twigResponse);
  114.     }
  115.     public function listCategories(Request $request)
  116.     {
  117.         $this->isKnowledgebaseActive();
  118.         $solutionRepository $this->getDoctrine()->getRepository('UVDeskSupportCenterBundle:Solutions');
  119.         $categoryCollection $solutionRepository->getAllCategories(104);
  120.         
  121.         return $this->render('@UVDeskSupportCenter/Knowledgebase/categoryListing.html.twig', [
  122.             'categories' => $categoryCollection,
  123.             'categoryCount' => count($categoryCollection),
  124.         ]);
  125.     }
  126.     public function changePass($email,$pass)
  127.     {   
  128.         try{
  129.             $entityManager $this->getDoctrine()->getManager();
  130.             $user $entityManager->getRepository('UVDeskCoreFrameworkBundle:User')->findOneByEmail($email) ?: new User();
  131.             $encodedPassword $this->container->get('security.password_encoder')->encodePassword($user$pass);
  132.             $user->setPassword($encodedPassword);
  133.             $entityManager->persist($user);
  134.             $entityManager->flush();
  135.             return $this->render('@UVDeskSupportCenter/Knowledgebase/json.html.twig', ['return'=>'ok']);
  136.         }catch(Exception $e){
  137.             return $this->render('@UVDeskSupportCenter/Knowledgebase/json.html.twig', ['return'=>$es]);
  138.         }
  139.     }
  140.     public function viewFolder(Request $request)
  141.     {
  142.         //////////////
  143.         //colocar sesion
  144.         /////////////
  145.         
  146.         $this->isKnowledgebaseActive();
  147.         
  148.         if(!$request->attributes->get('solution'))
  149.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  150.         $filterArray = ['id' => $request->attributes->get('solution')];
  151.         $solution $this->getDoctrine()
  152.                     ->getRepository('UVDeskSupportCenterBundle:Solutions')
  153.                     ->findOneBy($filterArray);
  154.         if(!$solution)
  155.             $this->noResultFound();
  156.         $sesion=null;
  157.         if($this->get('user.service')->getSessionUser()!=null)
  158.             $sesion=true;
  159.         $breadcrumbs = [
  160.             [
  161.                 'label' => $this->get('translator')->trans('Support Center'),
  162.                 'url' => $this->generateUrl('helpdesk_knowledgebase'),
  163.                   'sesion'=> $sesion
  164.             ],
  165.             [
  166.                 'label' => $solution->getName(),
  167.                 'url' => '#',
  168.                   'sesion'=> $sesion
  169.             ],
  170.         ];
  171.         $testArray = [1234];
  172.         foreach ($testArray as $test) {
  173.             $categories[] = [
  174.                 'id' => $test,
  175.                 'name' => $test " name",
  176.                 'articleCount' => $test " articleCount",
  177.             ];
  178.         }
  179.         return $this->render('@UVDeskSupportCenter//Knowledgebase//folder.html.twig', [
  180.             'folder' => $solution,
  181.             'categoryCount' => $this->getDoctrine()
  182.                 ->getRepository('UVDeskSupportCenterBundle:Solutions')
  183.                 ->getCategoriesCountBySolution($solution->getId()),
  184.             'categories' => $this->getDoctrine()
  185.                 ->getRepository('UVDeskSupportCenterBundle:Solutions')
  186.                 ->getCategoriesWithCountBySolution($solution->getId()),
  187.             'breadcrumbs' => $breadcrumbs
  188.         ]);
  189.     }
  190. //////////aca////
  191.     public function viewFolderArticle(Request $request)
  192.     {
  193.         $this->isKnowledgebaseActive();
  194.         if(!$request->attributes->get('solution'))
  195.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  196.         $filterArray = ['id' => $request->attributes->get('solution')];
  197.         $solution $this->getDoctrine()
  198.                     ->getRepository('UVDeskSupportCenterBundle:Solutions')
  199.                     ->findOneBy($filterArray);
  200.         if(!$solution)
  201.             $this->noResultFound();
  202.         $sesion=null;
  203.         if($this->get('user.service')->getSessionUser()!=null)
  204.             $sesion=true;
  205.         $breadcrumbs = [
  206.             [
  207.                 'label' => $this->get('translator')->trans('Support Center'),
  208.                 'url' => $this->generateUrl('helpdesk_knowledgebase'),
  209.                 'sesion'=>$sesion
  210.             ],
  211.             [
  212.                 'label' => $solution->getName(),
  213.                 'url' => '#',
  214.                  'sesion'=>$sesion
  215.             ],
  216.         ];
  217.         $parameterBag = [
  218.             'solutionId' => $solution->getId(),
  219.             'status' => 1,
  220.             'sort' => 'id',
  221.             'direction' => 'desc'
  222.         ];
  223.         $article_data = [
  224.             'folder' => $solution,
  225.             'articlesCount' => $this->getDoctrine()
  226.                 ->getRepository('UVDeskSupportCenterBundle:Solutions')
  227.                 ->getArticlesCountBySolution($solution->getId(), [1]),
  228.             'articles' => $this->getDoctrine()
  229.                 ->getRepository('UVDeskSupportCenterBundle:Article')
  230.                 ->getAllArticles(new ParameterBag($parameterBag), $this->container'a.id, a.name, a.slug, a.stared'),
  231.             'breadcrumbs' => $breadcrumbs,
  232.         ];
  233.         return $this->render('@UVDeskSupportCenter/Knowledgebase/folderArticle.html.twig'$article_data);
  234.     }
  235.     public function viewCategory(Request $request)
  236.     {
  237.         $this->isKnowledgebaseActive();
  238.         if(!$request->attributes->get('category'))
  239.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  240.         $filterArray = array(
  241.                             'id' => $request->attributes->get('category'),
  242.                             'status' => 1,
  243.                         );
  244.        
  245.         $category $this->getDoctrine()
  246.                     ->getRepository('UVDeskSupportCenterBundle:SolutionCategory')
  247.                     ->findOneBy($filterArray);
  248.     
  249.         if(!$category)
  250.             $this->noResultFound();
  251.           $sesion=null;
  252.         if($this->get('user.service')->getSessionUser()!=null)
  253.             $sesion=true;
  254.         
  255.         $breadcrumbs = [
  256.             [ 'label' => $this->get('translator')->trans('Support Center'),'url' => $this->generateUrl('helpdesk_knowledgebase'),'sesion'=>$sesion ],
  257.             [ 'label' => $category->getName(),'url' => '#','sesion'=>$sesion ],
  258.         ];
  259.         
  260.         $parameterBag = [
  261.             'categoryId' => $category->getId(),
  262.             'status' => 1,
  263.             'sort' => 'id',
  264.             'direction' => 'desc'
  265.         ];
  266.         $category_data=  array(
  267.             'category' => $category,
  268.             'articlesCount' => $this->getDoctrine()
  269.                             ->getRepository('UVDeskSupportCenterBundle:SolutionCategory')
  270.                             ->getArticlesCountByCategory($category->getId(), [1]),
  271.             'articles' => $this->getDoctrine()
  272.                         ->getRepository('UVDeskSupportCenterBundle:Article')
  273.                         ->getAllArticles(new ParameterBag($parameterBag), $this->container'a.id, a.name, a.slug, a.stared'),
  274.             'breadcrumbs' => $breadcrumbs
  275.         );
  276.         return $this->render('@UVDeskSupportCenter/Knowledgebase/category.html.twig',$category_data);
  277.     }
  278.    
  279.     public function viewArticle(Request $request)
  280.     {
  281.         $this->isKnowledgebaseActive();
  282.        
  283.         if (!$request->attributes->get('article') && !$request->attributes->get('slug')) {
  284.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  285.         }
  286.         $entityManager $this->getDoctrine()->getManager();
  287.         $user $this->get('user.service')->getCurrentUser();
  288.         $articleRepository $entityManager->getRepository('UVDeskSupportCenterBundle:Article');
  289.         if ($request->attributes->get('article')) {
  290.             $article $articleRepository->findOneBy(['status' => 1'id' => $request->attributes->get('article')]);
  291.         } else {
  292.             $article $articleRepository->findOneBy(['status' => 1,'slug' => $request->attributes->get('slug')]);
  293.         }
  294.        
  295.         if (empty($article)) {
  296.             $this->noResultFound();
  297.         }
  298.         $article->setViewed((int) $article->getViewed() + 1);
  299.         
  300.         // Log article view
  301.         $articleViewLog = new ArticleViewLog();
  302.         $articleViewLog->setUser(($user != null && $user != 'anon.') ? $user null);
  303.         
  304.         $articleViewLog->setArticle($article);
  305.         $articleViewLog->setViewedAt(new \DateTime('now'));
  306.         $entityManager->persist($article);
  307.         $entityManager->persist($articleViewLog);
  308.         $entityManager->flush();
  309.         
  310.         // Get article feedbacks
  311.         $feedbacks = ['enabled' => false'submitted' => false'article' => $articleRepository->getArticleFeedbacks($article)];
  312.         if (!empty($user) && $user != 'anon.') {
  313.             $feedbacks['enabled'] = true;
  314.             if (!empty($feedbacks['article']['collection']) && in_array($user->getId(), array_column($feedbacks['article']['collection'], 'user'))) {
  315.                 $feedbacks['submitted'] = true;
  316.             }
  317.         }
  318.           $sesion=null;
  319.         if($this->get('user.service')->getSessionUser()!=null)
  320.             $sesion=true;
  321.         // @TODO: App popular articles
  322.         $article_details = [
  323.             'article' => $article,
  324.             'breadcrumbs' => [
  325.                 ['label' => $this->get('translator')->trans('Support Center'), 'url' => $this->generateUrl('helpdesk_knowledgebase'),'sesion'=>$sesion],
  326.                 ['label' => $article->getName(), 'url' => '#','sesion'=>$sesion]
  327.             ],
  328.             'dateAdded' => $this->get('user.service')->convertToTimezone($article->getDateAdded()),
  329.             'articleTags' => $articleRepository->getTagsByArticle($article->getId()),
  330.             'articleAuthor' => $articleRepository->getArticleAuthorDetails($article->getId()),
  331.             'relatedArticles' => $articleRepository->getAllRelatedyByArticle(['locale' => $request->getLocale(), 'articleId' => $article->getId()], [1]),
  332.             'popArticles'  => $articleRepository->getPopularTranslatedArticles($request->getLocale())
  333.         ];
  334.      
  335.         return $this->render('@UVDeskSupportCenter/Knowledgebase/article.html.twig',$article_details);
  336.     }
  337.     public function searchKnowledgebase(Request $request)
  338.     {
  339.         $this->isKnowledgebaseActive();
  340.         $searchQuery $request->query->get('s');
  341.         if (empty($searchQuery)) {
  342.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  343.         }
  344.         $articleCollection $this->getDoctrine()->getRepository('UVDeskSupportCenterBundle:Article')->getArticleBySearch($request);
  345.         return $this->render('@UVDeskSupportCenter/Knowledgebase/search.html.twig', [
  346.             'search' => $searchQuery,
  347.             'articles' => $articleCollection,
  348.         ]);
  349.     }
  350.     public function viewTaggedResources(Request $request)
  351.     {
  352.         $this->isKnowledgebaseActive();
  353.         $tagQuery $request->attributes->get('tag');
  354.         if (empty($tagQuery)) {
  355.             return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  356.         }
  357.         $tagLabel $request->attributes->get('name');
  358.         $articleCollection $this->getDoctrine()->getRepository('UVDeskSupportCenterBundle:Article')->getArticleByTags([$tagLabel]);
  359.          $sesion=null;
  360.         if($this->get('user.service')->getSessionUser()!=null)
  361.             $sesion=true;
  362.         return $this->render('@UVDeskSupportCenter/Knowledgebase/search.html.twig', [
  363.             'articles' => $articleCollection,
  364.             'search' => $tagLabel,
  365.             'breadcrumbs' => [
  366.                 ['label' => $this->get('translator')->trans('Support Center'), 'url' => $this->generateUrl('helpdesk_knowledgebase'),'sesion'=>$sesion],
  367.                 ['label' => $tagLabel'url' => '#','sesion'=>$sesion],
  368.             ],
  369.         ]);
  370.     }
  371.     public function rateArticle($articleIdRequest $request)
  372.     {
  373.         $this->isKnowledgebaseActive();
  374.         // @TODO: Refactor
  375.             
  376.         // if ($request->getMethod() != 'POST') {
  377.         //     return $this->redirect($this->generateUrl('helpdesk_knowledgebase'));
  378.         // }
  379.         // $company = $this->getCompany();
  380.         // $user = $this->container->get('user.service')->getCurrentUser();
  381.         $response = ['code' => 404'content' => ['alertClass' => 'danger''alertMessage' => 'An unexpected error occurred. Please try again later.']];
  382.         // if (!empty($user) && $user != 'anon.') {
  383.         //     $entityManager = $this->getDoctrine()->getEntityManager();
  384.         //     $article = $entityManager->getRepository('WebkulSupportCenterBundle:Article')->findOneBy(['id' => $articleId, 'companyId' => $company->getId()]);
  385.         //     if (!empty($article)) {
  386.         //         $providedFeedback = $request->request->get('feedback');
  387.         //         if (!empty($providedFeedback) && in_array(strtolower($providedFeedback), ['positive', 'neagtive'])) {
  388.         //             $isArticleHelpful = ('positive' == strtolower($providedFeedback)) ? true : false;
  389.         //             $articleFeedback = $entityManager->getRepository('WebkulSupportCenterBundle:ArticleFeedback')->findOneBy(['article' => $article, 'ratedCustomer' => $user]);
  390.         //             $response = ['code' => 200, 'content' => ['alertClass' => 'success', 'alertMessage' => 'Feedback saved successfully.']];
  391.         //             if (empty($articleFeedback)) {
  392.         //                 $articleFeedback = new \Webkul\SupportCenterBundle\Entity\ArticleFeedback();
  393.         //                 // $articleBadge->setDescription('');
  394.         //                 $articleFeedback->setIsHelpful($isArticleHelpful);
  395.         //                 $articleFeedback->setArticle($article);
  396.         //                 $articleFeedback->setRatedCustomer($user);
  397.         //                 $articleFeedback->setCreatedAt(new \DateTime('now'));
  398.         //             } else {
  399.         //                 $articleFeedback->setIsHelpful($isArticleHelpful);
  400.         //                 $response['content']['alertMessage'] = 'Feedback updated successfully.';
  401.         //             }
  402.         //             $entityManager->persist($articleFeedback);
  403.         //             $entityManager->flush();
  404.         //         } else {
  405.         //             $response['content']['alertMessage'] = 'Invalid feedback provided.';
  406.         //         }
  407.         //     } else {
  408.         //         $response['content']['alertMessage'] = 'Article not found.';
  409.         //     }
  410.         // } else {
  411.         //     $response['content']['alertMessage'] = 'You need to login to your account before can perform this action.';
  412.         // }
  413.         return new Response(json_encode($response['content']), $response['code'], ['Content-Type: application/json']);
  414.     }
  415.     /**
  416.      * @Route("/api/knowledgebase/documents", name="helpdesk_knowledgebase_documents_api", methods={"GET", "OPTIONS"})
  417.      */
  418.     public function getKnowledgebaseDocuments(Request $request)
  419.     {
  420.         $this->isKnowledgebaseActive();
  421.         
  422.         $entityManager $this->getDoctrine()->getManager();
  423.         $articleRepository $entityManager->getRepository('UVDeskSupportCenterBundle:Article');
  424.         
  425.         // Obtener todos los artículos activos
  426.         $query $entityManager->createQueryBuilder()
  427.             ->select('a')
  428.             ->from('UVDeskSupportCenterBundle:Article''a')
  429.             ->where('a.status = :status')
  430.             ->setParameter('status'1);
  431.             
  432.         // Ejecutar la consulta para obtener todos los artículos
  433.         $articles $query->getQuery()->getResult();
  434.         
  435.         // Formatear los resultados
  436.         $documents = [];
  437.         $searchQuery $request->query->get('search');
  438.         $searchPerformed = !empty($searchQuery);
  439.         
  440.         foreach ($articles as $article) {
  441.             // Obtener el contenido del artículo
  442.             $content $article->getContent();
  443.             
  444.             // Inicializar variables
  445.             $documentName 'TEC' $article->getId() . ' - ' $article->getName();
  446.             $documentUrl null;
  447.             $linkText '';
  448.             $includeDocument true;
  449.             
  450.             // Información de depuración
  451.             $contentDebug = [
  452.                 'articleId' => $article->getId(),
  453.                 'hasContent' => !empty($content),
  454.                 'contentLength' => !empty($content) ? strlen($content) : 0,
  455.             ];
  456.             
  457.             // Buscar enlaces .pdf en el contenido
  458.             if (!empty($content)) {
  459.                 // Vista previa del contenido
  460.                 $contentPreview substr($content0300) . (strlen($content) > 300 '...' '');
  461.                 $contentDebug['contentPreview'] = $contentPreview;
  462.                 
  463.                 // Contar menciones de PDF y enlaces
  464.                 $contentDebug['pdfMentions'] = substr_count(strtolower($content), '.pdf');
  465.                 $contentDebug['linkMentions'] = substr_count(strtolower($content), 'href=');
  466.                 
  467.                 // Buscar enlaces dentro de etiquetas <a href>
  468.                 preg_match_all('/<a\s+[^>]*href=["\']([^"\']+)["\'][^>]*>([^<]+)<\/a>/i'$content$matches);
  469.                 
  470.                 if (!empty($matches[1])) {
  471.                     // Filtrar solo los enlaces relevantes (PDF o softguardtv.com o otros recursos)
  472.                     $relevantLinks = [];
  473.                     $relevantTexts = [];
  474.                     
  475.                     foreach ($matches[1] as $index => $link) {
  476.                         // Aceptar si es un PDF o contiene softguardtv.com o knowledge
  477.                         if (preg_match('/\.pdf$/i'$link) || 
  478.                             strpos($link'softguardtv.com') !== false || 
  479.                             strpos($link'knowledge') !== false ||
  480.                             strpos($link'courses') !== false ||
  481.                             strpos($link'lectures') !== false) {
  482.                             $relevantLinks[] = $link;
  483.                             $relevantTexts[] = $matches[2][$index] ?? '';
  484.                         }
  485.                     }
  486.                     
  487.                     // Guardar enlaces y textos relevantes
  488.                     if (!empty($relevantLinks)) {
  489.                         $contentDebug['foundLinks'] = $relevantLinks;
  490.                         $contentDebug['linkTexts'] = $relevantTexts;
  491.                         
  492.                         // Usar el primer enlace encontrado
  493.                         $documentUrl $relevantLinks[0];
  494.                         $linkText = !empty($relevantTexts[0]) ? trim($relevantTexts[0]) : '';
  495.                         
  496.                         // Usar texto del enlace como nombre
  497.                         if (!empty($linkText)) {
  498.                             $documentName $linkText;
  499.                         }
  500.                     }
  501.                 } else {
  502.                     // Búsqueda alternativa para URLs
  503.                     preg_match_all('/(https?:\/\/[^\s"\'<>]+)/i'$content$altMatches);
  504.                     
  505.                     if (!empty($altMatches[0])) {
  506.                         // Filtrar enlaces relevantes
  507.                         $relevantLinks = [];
  508.                         foreach ($altMatches[0] as $link) {
  509.                             if (preg_match('/\.pdf$/i'$link) || 
  510.                                 strpos($link'softguardtv.com') !== false || 
  511.                                 strpos($link'knowledge') !== false ||
  512.                                 strpos($link'courses') !== false ||
  513.                                 strpos($link'lectures') !== false) {
  514.                                 $relevantLinks[] = $link;
  515.                             }
  516.                         }
  517.                         
  518.                         if (!empty($relevantLinks)) {
  519.                             $contentDebug['foundLinks'] = $relevantLinks;
  520.                             $documentUrl $relevantLinks[0];
  521.                         }
  522.                     }
  523.                 }
  524.                 
  525.                 // Si se está realizando una búsqueda, verificar si el término está en el contenido
  526.                 if ($searchPerformed) {
  527.                     // Buscar en el contenido completo (incluye texto y enlaces)
  528.                     $includeDocument = (
  529.                         stripos($content$searchQuery) !== false || 
  530.                         stripos($documentName$searchQuery) !== false || 
  531.                         (!empty($documentUrl) && stripos($documentUrl$searchQuery) !== false) ||
  532.                         (!empty($linkText) && stripos($linkText$searchQuery) !== false)
  533.                     );
  534.                     
  535.                     $contentDebug['searchPerformed'] = true;
  536.                     $contentDebug['searchTerm'] = $searchQuery;
  537.                     $contentDebug['matchFound'] = $includeDocument;
  538.                 }
  539.             }
  540.             
  541.             // Si no se encontró URL, usar formato estándar
  542.             if (empty($documentUrl)) {
  543.                 $baseDocumentName $article->getName();
  544.                 $documentUrl 'https://softguard.com/knowledge/TEC' $article->getId() . '_' $baseDocumentName '.pdf';
  545.                 $contentDebug['usingFallbackUrl'] = true;
  546.             }
  547.             
  548.             // Solo incluir el documento si pasa los filtros de búsqueda
  549.             if ($includeDocument) {
  550.                 $documents[] = [
  551.                     'id' => $article->getId(),
  552.                     'name' => $documentName,
  553.                     'url' => $documentUrl,
  554.                     'views' => $article->getViewed(),
  555.                     'dateAdded' => $article->getDateAdded() ? $article->getDateAdded()->format('Y-m-d H:i:s') : null,
  556.                     'contentDebug' => $contentDebug
  557.                 ];
  558.             }
  559.         }
  560.         
  561.         // Ordenar por popularidad (vistas)
  562.         usort($documents, function($a$b) {
  563.             return $b['views'] - $a['views'];
  564.         });
  565.         
  566.         // Devolver respuesta JSON
  567.         return new JsonResponse([
  568.             'success' => true,
  569.             'documents' => $documents,
  570.             'totalFound' => count($documents),
  571.             'searchQuery' => $searchQuery
  572.         ]);
  573.     }
  574.     /**
  575.      * Función auxiliar para convertir texto en un slug
  576.      */
  577.     private function slugify($text)
  578.     {
  579.         // Reemplazar espacios con guiones bajos
  580.         $text str_replace(' ''_'$text);
  581.         // Eliminar caracteres especiales
  582.         $text preg_replace('/[^A-Za-z0-9\-_]/'''$text);
  583.         // Convertir a minúsculas
  584.         return strtolower($text);
  585.     }
  586. }