/** * Searches the content and returns an array that is built as needed by the search module. * * @param string $searchTerm * * @return array */ public function searchResultsForSearchModule($searchTerm) { $em = \Env::get('cx')->getDb()->getEntityManager(); $pageRepo = $em->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Page'); // only list results in case the associated page of the module is active $page = $pageRepo->findOneBy(array('module' => 'MediaDir', 'lang' => FRONTEND_LANG_ID, 'type' => \Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION)); //If page is not exists or page is inactive then return empty result if (!$page || !$page->isActive()) { return array(); } //get the config site values \Cx\Core\Setting\Controller\Setting::init('Config', 'site', 'Yaml'); $coreListProtectedPages = \Cx\Core\Setting\Controller\Setting::getValue('coreListProtectedPages', 'Config'); $searchVisibleContentOnly = \Cx\Core\Setting\Controller\Setting::getValue('searchVisibleContentOnly', 'Config'); //get the config otherConfigurations value \Cx\Core\Setting\Controller\Setting::init('Config', 'otherConfigurations', 'Yaml'); $searchDescriptionLength = \Cx\Core\Setting\Controller\Setting::getValue('searchDescriptionLength', 'Config'); $hasPageAccess = true; $isNotVisible = $searchVisibleContentOnly == 'on' && !$page->isVisible(); if ($coreListProtectedPages == 'off' && $page->isFrontendProtected()) { $hasPageAccess = \Permission::checkAccess($page->getFrontendAccessId(), 'dynamic', true); } //If the page is invisible and frontend access is denied then return empty result if ($isNotVisible || !$hasPageAccess) { return array(); } //get the media directory entry by the search term $entries = new \Cx\Modules\MediaDir\Controller\MediaDirectoryEntry($this->moduleName); $entries->getEntries(null, null, null, $searchTerm); //if no entries found then return empty result if (empty($entries->arrEntries)) { return array(); } $results = array(); $formEntries = array(); $defaultEntries = null; $objForm = new \Cx\Modules\MediaDir\Controller\MediaDirectoryForm(null, $this->moduleName); $numOfEntries = intval($entries->arrSettings['settingsPagingNumEntries']); foreach ($entries->arrEntries as $entry) { $pageUrlResult = null; $entryForm = $objForm->arrForms[$entry['entryFormId']]; //Get the entry's link url //check the entry's form detail view exists if not, //check the entry's form overview exists if not, //check the default overview exists if not, dont show the corresponding entry in entry switch (true) { case $entries->checkPageCmd('detail' . $entry['entryFormId']): $pageUrlResult = \Cx\Core\Routing\Url::fromModuleAndCmd($entries->moduleName, 'detail' . $entry['entryFormId'], FRONTEND_LANG_ID, array('eid' => $entry['entryId'])); break; case $pageCmdExists = $entries->checkPageCmd($entryForm['formCmd']): case $entries->checkPageCmd(''): if ($pageCmdExists && !isset($formEntries[$entryForm['formCmd']])) { $formEntries[$entryForm['formCmd']] = new \Cx\Modules\MediaDir\Controller\MediaDirectoryEntry($entries->moduleName); $formEntries[$entryForm['formCmd']]->getEntries(null, null, null, null, null, null, 1, null, 'n', null, null, $entryForm['formId']); } if (!$pageCmdExists && !isset($defaultEntries)) { $defaultEntries = new \Cx\Modules\MediaDir\Controller\MediaDirectoryEntry($entries->moduleName); $defaultEntries->getEntries(); } //get entry's form overview / default page paging position $entriesPerPage = $numOfEntries; if ($pageCmdExists) { $entriesPerPage = !empty($entryForm['formEntriesPerPage']) ? $entryForm['formEntriesPerPage'] : $numOfEntries; } $pageCmd = $pageCmdExists ? $entryForm['formCmd'] : ''; $entryKeys = $pageCmdExists ? array_keys($formEntries[$entryForm['formCmd']]->arrEntries) : array_keys($defaultEntries->arrEntries); $entryPos = array_search($entry['entryId'], $entryKeys); $position = floor($entryPos / $entriesPerPage); $pageUrlResult = \Cx\Core\Routing\Url::fromModuleAndCmd($entries->moduleName, $pageCmd, FRONTEND_LANG_ID, array('pos' => $position * $entriesPerPage)); break; default: break; } //If page url is empty then dont show it in the result if (!$pageUrlResult) { continue; } //Get the search results title and content from the form context field 'title' and 'content' $title = current($entry['entryFields']); $content = ''; $objInputfields = new MediaDirectoryInputfield($entry['entryFormId'], false, $entry['entryTranslationStatus'], $this->moduleName); $inputFields = $objInputfields->getInputfields(); foreach ($inputFields as $arrInputfield) { $contextType = isset($arrInputfield['context_type']) ? $arrInputfield['context_type'] : ''; if (!in_array($contextType, array('title', 'content'))) { continue; } $strType = isset($arrInputfield['type_name']) ? $arrInputfield['type_name'] : ''; $strInputfieldClass = "\\Cx\\Modules\\MediaDir\\Model\\Entity\\MediaDirectoryInputfield" . ucfirst($strType); try { $objInputfield = safeNew($strInputfieldClass, $this->moduleName); $arrTranslationStatus = contrexx_input2int($arrInputfield['type_multi_lang']) == 1 ? $entry['entryTranslationStatus'] : null; $arrInputfieldContent = $objInputfield->getContent($entry['entryId'], $arrInputfield, $arrTranslationStatus); if (\Cx\Core\Core\Controller\Cx::instanciate()->getMode() == \Cx\Core\Core\Controller\Cx::MODE_FRONTEND && \Cx\Core\Setting\Controller\Setting::getValue('blockStatus', 'Config')) { $arrInputfieldContent[$this->moduleLangVar . '_INPUTFIELD_VALUE'] = preg_replace('/\\[\\[(BLOCK_[A-Z0-9_-]+)\\]\\]/', '{\\1}', $arrInputfieldContent[$this->moduleLangVar . '_INPUTFIELD_VALUE']); \Cx\Modules\Block\Controller\Block::setBlocks($arrInputfieldContent[$this->moduleLangVar . '_INPUTFIELD_VALUE'], \Cx\Core\Core\Controller\Cx::instanciate()->getPage()); } } catch (\Exception $e) { \DBG::log($e->getMessage()); continue; } $inputFieldValue = $arrInputfieldContent[$this->moduleConstVar . '_INPUTFIELD_VALUE']; if (empty($inputFieldValue)) { continue; } if ($contextType == 'title') { $title = $inputFieldValue; } elseif ($contextType == 'content') { $content = \Cx\Core_Modules\Search\Controller\Search::shortenSearchContent($inputFieldValue, $searchDescriptionLength); } } $results[] = array('Score' => 100, 'Title' => html_entity_decode(contrexx_strip_tags($title), ENT_QUOTES, CONTREXX_CHARSET), 'Content' => $content, 'Link' => $pageUrlResult->toString()); } return $results; }
/** * Returns search results * * The entries in the array returned contain the following indices: * 'Score': The matching score ([0..100]) * 'Title': The object or content title * 'Content': The content * 'Link': The link to the (detailed) view of the result * 'Date': The change date, optional * Mind that the date is not available for all types of results. * Note that the $term parameter is not currently used, but may be useful * i.e. for hilighting matches in the results. * @author Christian Wehrli <*****@*****.**> * @param string $query The query * @param string $module_var The module (empty for core/content?) * @param string $cmd_var The cmd (or empty) * @param string $pagevar The ID parameter name for referencing * found objects in the URL * @param string $term The search term * @return array The search results array */ public function getResultArray($query, $module, $command, $pagevar, $term, $parseSearchData = null) { global $_ARRAYLANG; $page = $this->getAccessablePage($module, $command); if (!$page) { return array(); } $pagePath = $page->getPath(); $objDatabase = \Env::get('db'); $objResult = $objDatabase->Execute($query); if (!$objResult || $objResult->EOF) { return array(); } $config = \Env::get('config'); $max_length = intval($config['searchDescriptionLength']); $arraySearchResults = array(); while (!$objResult->EOF) { if (is_callable($pagevar)) { $temp_pagelink = $pagevar($pagePath, $objResult->fields); } else { $temp_pagelink = $pagePath . '?' . $pagevar . $objResult->fields['id']; } if (is_callable($parseSearchData)) { $parseSearchData($objResult->fields); } $content = isset($objResult->fields['content']) ? trim($objResult->fields['content']) : ''; $content = \Cx\Core_Modules\Search\Controller\Search::shortenSearchContent($content, $max_length); $score = $objResult->fields['score']; $scorePercent = $score >= 1 ? 100 : intval($score * 100); //TODO: Muss noch geändert werden, sobald das Ranking bei News funktioniert $scorePercent = $score == 0 ? 25 : $scorePercent; $date = empty($objResult->fields['date']) ? NULL : $objResult->fields['date']; $searchtitle = empty($objResult->fields['title']) ? $_ARRAYLANG['TXT_UNTITLED'] : $objResult->fields['title']; $arraySearchResults[] = array('Score' => $scorePercent, 'Title' => $searchtitle, 'Content' => $content, 'Link' => $temp_pagelink, 'Date' => $date); $objResult->MoveNext(); } return $arraySearchResults; }
/** * Searches the content and returns an array that is built as needed by the search module. * * Please do not use this anywhere else, write a search method with proper results instead. Ideally, this * method would then be invoked by searchResultsForSearchModule(). * * @param string $string the string to match against. * @return array ( * 'Score' => int * 'Title' => string * 'Content' => string * 'Link' => string * ) */ public function searchResultsForSearchModule($string, $license) { if ($string == '') { return array(); } //TODO: use MATCH AGAINST for score // Doctrine can be extended as mentioned in http://groups.google.com/group/doctrine-user/browse_thread/thread/69d1f293e8000a27 //TODO: shorten content in query rather than in php $qb = $this->em->createQueryBuilder(); $qb->add('select', 'p')->add('from', 'Cx\\Core\\ContentManager\\Model\\Entity\\Page p')->add('where', $qb->expr()->andx($qb->expr()->eq('p.lang', FRONTEND_LANG_ID), $qb->expr()->orx($qb->expr()->like('p.content', ':searchString'), $qb->expr()->like('p.content', ':searchStringEscaped'), $qb->expr()->like('p.title', ':searchString')), $qb->expr()->orX('p.module = \'\'', 'p.module IS NULL', $qb->expr()->in('p.module', $license->getLegalFrontendComponentsList()))))->setParameter('searchString', '%' . $string . '%')->setParameter('searchStringEscaped', '%' . contrexx_raw2xhtml($string) . '%'); $pages = $qb->getQuery()->getResult(); $config = \Env::get('config'); $results = array(); foreach ($pages as $page) { $isNotVisible = $config['searchVisibleContentOnly'] == 'on' && !$page->isVisible(); $hasPageAccess = true; if ($config['coreListProtectedPages'] == 'off' && $page->isFrontendProtected()) { $hasPageAccess = \Permission::checkAccess($page->getFrontendAccessId(), 'dynamic', true); } if (!$page->isActive() || $isNotVisible || !$hasPageAccess) { continue; } // TODO: Add proper score with MATCH () AGAINST () or similar $results[] = array('Score' => 100, 'Title' => $page->getTitle(), 'Content' => \Cx\Core_Modules\Search\Controller\Search::shortenSearchContent($page->getContent(), $config['searchDescriptionLength']), 'Link' => $this->getPath($page)); } return $results; }
/** * Returns search results * * The entries in the array returned contain the following indices: * 'Score': The matching score ([0..100]) * 'Title': The object or content title * 'Content': The content * 'Link': The link to the (detailed) view of the result * 'Date': The change date, optional * Mind that the date is not available for all types of results. * Note that the $term parameter is not currently used, but may be useful * i.e. for hilighting matches in the results. * @author Christian Wehrli <*****@*****.**> * @param string $query The query * @param string $module_var The module (empty for core/content?) * @param string $cmd_var The cmd (or empty) * @param string $pagevar The ID parameter name for referencing * found objects in the URL * @param string $term The search term * @return array The search results array */ public static function getResultArray($query, $module, $command, $pagevar, $term, $parseSearchData = null) { global $_ARRAYLANG; $pageRepo = \Env::get('em')->getRepository('Cx\\Core\\ContentManager\\Model\\Entity\\Page'); $criteria = array('module' => $module, 'lang' => FRONTEND_LANG_ID, 'type' => \Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION); if (!empty($command)) { $criteria['cmd'] = $command; } // only list results in case the associated page of the module is active $page = $pageRepo->findOneBy($criteria); if (!$page || !$page->isActive()) { return array(); } // don't list results in case the user doesn't have sufficient rights to access the page // and the option to list only unprotected pages is set (coreListProtectedPages) $hasPageAccess = true; $config = \Env::get('config'); if ($config['coreListProtectedPages'] == 'off' && $page->isFrontendProtected()) { $hasPageAccess = \Permission::checkAccess($page->getFrontendAccessId(), 'dynamic', true); } if (!$hasPageAccess) { return array(); } // In case we are handling the search result of a module ($module is not empty), // we have to check if we are allowed to list the results even when the associated module // page is invisible. // We don't have to check for regular pages ($module is empty) here, because they // are handled by an other method than this one. if ($config['searchVisibleContentOnly'] == 'on' && !empty($module)) { if (!$page->isVisible()) { // If $command is set, then this would indicate that we have // checked the visibility of the detail view page of the module. // Those pages are almost always invisible. // Therefore, we shall make the decision if we are allowed to list // the results based on the visibility of the main module page // (empty $command). if (!empty($command)) { $mainModulePage = $pageRepo->findOneBy(array('module' => $module, 'lang' => FRONTEND_LANG_ID, 'type' => \Cx\Core\ContentManager\Model\Entity\Page::TYPE_APPLICATION, 'cmd' => '')); if (!$mainModulePage || !$mainModulePage->isActive() || !$mainModulePage->isVisible()) { // main module page is also invisible return array(); } } else { // page is invisible return array(); } } } $pagePath = $pageRepo->getPath($page); $objDatabase = \Env::get('db'); $objResult = $objDatabase->Execute($query); if (!$objResult || $objResult->EOF) { return array(); } $max_length = intval($config['searchDescriptionLength']); $arraySearchResults = array(); while (!$objResult->EOF) { if (is_callable($pagevar)) { $temp_pagelink = $pagevar($pagePath, $objResult->fields); } else { $temp_pagelink = $pagePath . '?' . $pagevar . $objResult->fields['id']; } if (is_callable($parseSearchData)) { $parseSearchData($objResult->fields); } $content = isset($objResult->fields['content']) ? trim($objResult->fields['content']) : ''; $content = \Cx\Core_Modules\Search\Controller\Search::shortenSearchContent($content, $max_length); $score = $objResult->fields['score']; $scorePercent = $score >= 1 ? 100 : intval($score * 100); //TODO: Muss noch geändert werden, sobald das Ranking bei News funktioniert $scorePercent = $score == 0 ? 25 : $scorePercent; $date = empty($objResult->fields['date']) ? NULL : $objResult->fields['date']; $searchtitle = empty($objResult->fields['title']) ? $_ARRAYLANG['TXT_UNTITLED'] : $objResult->fields['title']; $arraySearchResults[] = array('Score' => $scorePercent, 'Title' => $searchtitle, 'Content' => $content, 'Link' => $temp_pagelink, 'Date' => $date); $objResult->MoveNext(); } return $arraySearchResults; }