Example #1
0
	private function _calculateRelevancy(){
		// Lowercase it.
		$query       = strtolower($this->query);
		// Convert this string to latin.
		$query       = \Core\str_to_latin($query);
		// Skip punctuation.
		$query       = preg_replace('/[^a-z0-9 ]/', '', $query);
		// Split out words.
		$parts       = explode(' ', $query);

		$ignore = Helper::GetSkipWords();
		foreach($parts as $k => $word){
			// Skip blank words.
			if(!$word){
				unset($parts[$k]);
				continue;
			}
			// Unset any to-be-skipped word.
			if(in_array($word, $ignore)){
				unset($parts[$k]);
				continue;
			}
		}

		// All query words in the result mean 100% relevancy.
		$size = sizeof($parts);
		if(!$size){
			$this->relevancy = 0;
			return;
		}

		$wordweight = 100 / $size;
		// And each word has 3 parts to it.
		$wordweight /= 3;

		$rel = 0.0;

		$str = explode(' ', $this->_model->get('search_index_str'));
		$pri = explode(' ', $this->_model->get('search_index_pri'));
		$sec = explode(' ', $this->_model->get('search_index_sec'));

		foreach($parts as $word){
			$it = new DoubleMetaPhone($word);

			if(in_array($word, $str)){
				// Exact matches here get an automatic boost!
				$rel += ($wordweight * 3);
			}
			else{
				foreach($str as $w){
					if(strpos($w, $word) !== false){
						// If a partial match is located, add a fraction of the word weight, (since it wasn't a complete match).
						$rel += $wordweight * (strlen($word) / strlen($w));
						break;
					}
				}
			}

			if(in_array($it->primary, $pri)) $rel += $wordweight;
			if(in_array($it->secondary, $sec)) $rel += $wordweight;
		}

		$this->relevancy = min($rel, 100);
	}
Example #2
0
	/**
	 * Perform a model search on the records of this Model.
	 *
	 * @param string $query The base query to search
	 * @param array $where  Any additional where parameters to add onto the factory
	 *
	 * @return array An array of ModelResult objects.
	 */
	public static function Search($query, $where = []){
		$ret = [];

		// If this object does not support searching, simply return an empty array.
		$ref = new ReflectionClass(get_called_class());

		if(!$ref->getProperty('HasSearch')->getValue()){
			return $ret;
		}

		$fac = new ModelFactory(get_called_class());

		if(sizeof($where)){
			$fac->where($where);
		}

		if($ref->getProperty('HasDeleted')->getValue()){
			$fac->where('deleted = 0');
		}

		$fac->where(\Core\Search\Helper::GetWhereClause($query));
		foreach($fac->get() as $m){
			/** @var Model $m */
			$sr = new \Core\Search\ModelResult($query, $m);

			// This may happen since the where clause can be a little open-ended.
			if($sr->relevancy < 1) continue;
			$sr->title = $m->getLabel();
			$sr->link  = $m->get('baseurl');

			$ret[] = $sr;
		}

		// Sort the results before returning them.
		// Because otherwise, what's the point of a search algorithm?!?
		usort($ret, function($a, $b) {
			/** @var $a Core\Search\ModelResult */
			/** @var $b Core\Search\ModelResult */
			return $a->relevancy < $b->relevancy;
		});

		return $ret;
	}
Example #3
0
 /**
  * View controller for a blog article listing page.
  * This will only display articles under this same blog.
  *
  * @param BlogModel $blog
  */
 private function _viewBlog(BlogModel $blog)
 {
     $view = $this->getView();
     $page = $blog->getLink('Page');
     $request = $this->getPageRequest();
     $manager = \Core\user()->checkAccess('p:/blog/manage_all');
     $editor = \Core\user()->checkAccess($blog->get('manage_articles_permission ')) || $manager;
     $viewer = \Core\user()->checkAccess($blog->get('access')) || $editor;
     // Get the latest published article's update date.  This will be used for the blog updated timestamp.
     // (This doesn't have a whole lot of benefit above the ModelFactory, simply illustrating a different way to query data).
     $latest = \Core\Datamodel\Dataset::Init()->select('*')->table('page')->where('parenturl = ' . $blog->get('baseurl'))->where('published_status = published')->order('published DESC')->limit(1)->current();
     $filters = new FilterForm();
     $filters->haspagination = true;
     // Allow different type of requests to come in here.
     switch ($request->ctype) {
         case 'application/atom+xml':
             $view->templatename = 'pages/blog/view-blog.atom.tpl';
             $view->contenttype = $request->ctype;
             $view->mastertemplate = false;
             $filters->setLimit(200);
             break;
         case 'application/rss+xml':
             $view->templatename = 'pages/blog/view-blog.rss.tpl';
             $view->contenttype = $request->ctype;
             $view->mastertemplate = false;
             $filters->setLimit(200);
             break;
         default:
             $view->templatename = 'pages/blog/view-blog.tpl';
             $filters->setLimit(20);
             break;
     }
     $filters->load($this->getPageRequest());
     $factory = new ModelFactory('PageModel');
     if ($request->getParameter('q')) {
         $query = $request->getParameter('q');
         $factory->where(\Core\Search\Helper::GetWhereClause($request->getParameter('q')));
     } else {
         $query = null;
     }
     $factory->where('parenturl = ' . $blog->get('baseurl'));
     $factory->order('published DESC');
     if (!$editor) {
         // Limit these to published articles.
         $factory->where('published_status = published');
         // And where the published date is >= now.
         $factory->where('published <= ' . CoreDateTime::Now('U', Time::TIMEZONE_GMT));
     }
     $filters->applyToFactory($factory);
     $articles = $factory->get();
     $view->mode = View::MODE_PAGEORAJAX;
     $view->assign('blog', $blog);
     $view->assign('articles', $articles);
     $view->assign('page', $page);
     $view->assign('filters', $filters);
     $view->assign('canonical_url', \Core\resolve_link($blog->get('baseurl')));
     $view->assign('last_updated', $latest ? $latest['updated'] : 0);
     $view->assign('servername', SERVERNAME_NOSSL);
     $view->assign('editor', $editor);
     $view->assign('add_article_link', '/content/create?page_template=blog-article.tpl&parenturl=' . $blog->get('baseurl'));
     // Add the extra view types for this page
     $view->addHead('<link rel="alternate" type="application/atom+xml" title="' . $page->get('title') . ' Atom Feed" href="' . \Core\resolve_link($blog->get('baseurl')) . '.atom"/>');
     $view->addHead('<link rel="alternate" type="application/rss+xml" title="' . $page->get('title') . ' RSS Feed" href="' . \Core\resolve_link($blog->get('baseurl')) . '.rss"/>');
     if ($editor) {
         if ($blog->get('type') == 'remote') {
             $view->addControl('Import Feed', '/blog/import/' . $blog->get('id'), 'exchange');
         } else {
             $view->addControl('Add Article', '/content/create?page_template=blog-article.tpl&parenturl=' . $blog->get('baseurl'), 'add');
         }
     }
     if ($manager) {
         $view->addControl('Edit Blog', '/blog/update/' . $blog->get('id'), 'edit');
         $view->addControl('All Articles', '/admin/pages/?filter[parenturl]=' . $blog->get('baseurl'), 'tasks');
     }
     $view->addControl('RSS Feed', \Core\resolve_link($blog->get('baseurl')) . '.rss', 'rss');
     //$view->addControl('Atom Feed', \Core\resolve_link($blog->get('baseurl')) . '.atom', 'rss');
 }