public static function getFilterFieldValue($filter, $name)
 {
     $field = $filter[$name];
     $value = $field->getValue();
     $types = $filter->getFields();
     $type = $types[$field->getName()];
     switch ($type) {
         case 'Enum':
             return $value;
         case 'Boolean':
             return aBlogToolkit::getValueForId($field, $value);
         case 'ForeignKey':
         case 'ManyKey':
             if (is_array($value)) {
                 $values = array();
                 foreach ($value as $v) {
                     $values[] = aBlogToolkit::getValueForId($field, $v);
                 }
             } else {
                 $values = aBlogToolkit::getValueForId($field, $value);
             }
             return $values;
         case 'Text':
         case 'Number':
             return $value['text'];
     }
 }
 public function preExecute()
 {
     parent::preExecute();
     $request = $this->getRequest();
     $this->info = aBlogToolkit::filterForEngine($this->getFilterForEngineParams());
     if (sfConfig::get('app_aBlog_use_bundled_assets', true)) {
         $this->getResponse()->addJavascript('/apostropheBlogPlugin/js/aBlog.js');
     }
 }
 public function executeSearch(sfWebRequest $request)
 {
     return aBlogToolkit::searchBody($this, '@a_blog_redirect', 'aBlogPost', null, $request);
 }
Example #4
0
 public function preExecute()
 {
     parent::preExecute();
     $request = $this->getRequest();
     $this->info = aBlogToolkit::filterForEngine($this->getFilterForEngineParams());
 }
 public static function searchBody($action, $slugMatch, $modelClass, $categories, sfWebRequest $request)
 {
     $now = date('YmdHis');
     // create the array of pages matching the query
     $ajax = false;
     if ($request->hasParameter('term')) {
         $ajax = true;
         $q = $request->getParameter('term');
         // Wildcarding is better for autocomplete
         $q .= '*';
     } else {
         $q = $request->getParameter('q');
         if ($request->hasParameter('x')) {
             // We sometimes like to use input type="image" for presentation reasons, but it generates
             // ugly x and y parameters with click coordinates. Get rid of those and come back. Keep
             // all the other stuff
             return $action->redirect(sfContext::getInstance()->getController()->genUrl(aUrl::addParams($request->getParameter('module') . '/' . $request->getParameter('action'), array('q' => $q, 'cat' => $request->getParameter('cat'), 'tag' => $request->getParameter('tag'), 'year' => $request->getParameter('year'), 'month' => $request->getParameter('month'), 'day' => $request->getParameter('day')))));
         }
     }
     $key = strtolower(trim($q));
     $key = preg_replace('/\\s+/', ' ', $key);
     $replacements = sfConfig::get('app_a_search_refinements', array());
     if (isset($replacements[$key])) {
         $q = $replacements[$key];
     }
     try {
         $q = "({$q}) AND slug:{$slugMatch}";
         $values = aZendSearch::searchLuceneWithValues(Doctrine::getTable('aPage'), $q, aTools::getUserCulture());
     } catch (Exception $e) {
         // Lucene search error. TODO: display it nicely if they are always safe things to display. For now: just don't crash
         $values = array();
     }
     $nvalues = array();
     // The truth is that Zend cannot do all of our filtering for us, especially
     // permissions-based. So we can do some other filtering as well, although it
     // would be bad not to have Zend take care of the really big cuts (if 99% are
     // not being prefiltered by Zend, and we have a Zend max results of 1000, then
     // we are reduced to working with a maximum of 10 real results).
     if ($request->hasParameter('cat')) {
         $categories = Doctrine::getTable('aCategory')->createQuery()->where('slug = ?', array($request->getParameter('cat')))->execute(array(), Doctrine::HYDRATE_ARRAY);
     }
     if (is_null($categories)) {
         $categoryIds = array();
     } else {
         $categoryIds = aArray::getIds($categories);
     }
     foreach ($values as $value) {
         if ($ajax && count($nvalues) >= sfConfig::get('app_aBlog_autocomplete_max', 10)) {
             break;
         }
         // 1.5: the names under which we store columns in Zend Lucene have changed to
         // avoid conflict with also indexing them
         $info = unserialize($value->info_stored);
         // Do a whole bunch of filtering that can't be easily done at the Lucene level.
         // This is not ideal because the 1000 results we consider might not meet the
         // criteria and some later set of results might. For 2.0 we need to find something
         // that fully merges text search and other criteria without complaint
         // The main performance killer isn't MySQL, it's Doctrine object hydration. Just keep it light
         if (count($categoryIds) && !count(Doctrine::getTable('aPage')->createQuery('p')->where('p.id = ?', $info['id'])->innerJoin('p.Categories c')->select('p.id, c.id')->andWhereIn('c.id', $categoryIds)->execute(array(), Doctrine::HYDRATE_NONE))) {
             continue;
         }
         if ($request->hasParameter('tag') && !count(Doctrine::getTable('Tagging')->createQuery('ta')->innerJoin('ta.Tag t WITH t.name = ?', $request->getParameter('tag'))->where('ta.taggable_model = ? AND ta.taggable_id = ?', array('aPage', $info['id']))->execute(array(), Doctrine::HYDRATE_NONE))) {
             continue;
         }
         // Filter search results chronologically. How to do this depends on whether
         // we're dealing with blog or events
         $year = sprintf("%04d", $request->getParameter('year'));
         $month = sprintf("%02d", $request->getParameter('month'));
         $day = sprintf("%02d", $request->getParameter('day'));
         // This if is gross and ought to be refactored by calling a method on
         // the actions class which is differently implemented by the two classes
         if (get_class($action) === 'aEventActions') {
             if ($day > 0) {
                 if (!aBlogToolkit::between("{$year}-{$month}-{$day}", $value->start_date, $value->end_date)) {
                     continue;
                 }
             } elseif ($month > 0) {
                 if (!aBlogToolkit::between("{$year}-{$month}", substr($value->start_date, 0, 7), substr($value->end_date, 0, 7))) {
                     continue;
                 }
             } elseif ($year > 0) {
                 if (!aBlogToolkit::between("{$year}", substr($value->start_date, 0, 4), substr($value->end_date, 0, 4))) {
                     continue;
                 }
             }
         } else {
             // We store this one real picky in a keyword so it's searchable at the lucene level
             if (preg_match('/^(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)/', $value->published_at, $matches)) {
                 list($dummy, $pyear, $pmonth, $pday) = $matches;
                 if ($year > 0) {
                     if ($pyear != $year) {
                         continue;
                     }
                 }
                 if ($month > 0) {
                     if ($pmonth != $month) {
                         continue;
                     }
                 }
                 if ($day > 0) {
                     if ($pday != $day) {
                         continue;
                     }
                 }
             }
         }
         // Regardless of the above if it ain't published yet we can't see it
         if ($value->published_at > $now) {
             continue;
         }
         if (!aPageTable::checkPrivilege('view', $info)) {
             continue;
         }
         $nvalue = $value;
         $nvalue->page_id = $info['id'];
         $nvalue->slug = $nvalue->slug_stored;
         $nvalue->title = $nvalue->title_stored;
         $nvalue->summary = $nvalue->summary_stored;
         // Virtual page slug is a named Symfony route, it wants search results to go there
         $nvalue->url = $action->getController()->genUrl($nvalue->slug, true);
         $nvalue->class = $modelClass;
         $nvalues[] = $nvalue;
     }
     $values = $nvalues;
     if ($ajax) {
         // We need the IDs of the blog posts, not their virtual pages
         $pageIds = array();
         foreach ($values as $value) {
             $pageIds[] = $value->page_id;
         }
         $action->results = array();
         if (count($pageIds)) {
             $infos = Doctrine::getTable($modelClass)->createQuery('p')->select('p.id, p.page_id, p.status')->whereIn('p.page_id', $pageIds)->fetchArray();
             // At this point, if we're an admin, we have some posts on our list that are not actually
             // useful to return as AJAX results because we only care about posts that are published when
             // we're building up a posts slot
             foreach ($infos as $info) {
                 if ($info['status'] !== 'published') {
                     continue;
                 }
                 $pageIdToPostId[$info['page_id']] = $info['id'];
             }
             foreach ($values as $value) {
                 if (isset($pageIdToPostId[$value->page_id])) {
                     // Titles are stored as entity-escaped HTML text, so decode to meet
                     // the expectations of autocomplete
                     $action->results[] = array('label' => html_entity_decode($value->title, ENT_COMPAT, 'UTF-8'), 'value' => $pageIdToPostId[$value->page_id]);
                 }
             }
         }
         return 'Autocomplete';
     }
     $action->pager = new aArrayPager(null, sfConfig::get('app_a_search_results_per_page', 10));
     $action->pager->setResultArray($values);
     $action->pager->setPage($request->getParameter('page', 1));
     $action->pager->init();
     $action->pagerUrl = "aBlog/search?" . http_build_query(array("q" => $q));
     // setTitle takes care of escaping things
     $action->getResponse()->setTitle(aTools::getOptionI18n('title_prefix') . 'Search for ' . $q . aTools::getOptionI18n('title_suffix'));
     $action->results = $action->pager->getResults();
 }