Example #1
0
 public function __invoke($records)
 {
     $data = ['totals' => [], 'group_by' => $this->search->group_by, 'group_by_attribute_key' => $this->search->group_by_attribute_key, 'timeline_attribute' => $this->search->timeline_attribute];
     if (count($records)) {
         // Grab just label and total from db results
         if ($this->search->timeline) {
             $data['totals'] = $this->formatTimelineTotals($records);
             $data['time_interval'] = $this->search->getFilter('timeline_interval', 86400);
         } else {
             $data['totals'] = $this->formatTotals($records);
         }
     }
     return $data;
 }
Example #2
0
 public function setSearchParams(SearchData $search)
 {
     $this->search_query = $this->selectQuery();
     $sorting = $search->getSorting();
     if (!empty($sorting['orderby'])) {
         $this->search_query->order_by($this->getTable() . '.' . $sorting['orderby'], Arr::get($sorting, 'order'));
     }
     if (!empty($sorting['offset'])) {
         $this->search_query->offset($sorting['offset']);
     }
     if (!empty($sorting['limit'])) {
         $this->search_query->limit($sorting['limit']);
     }
     // apply the unique conditions of the search
     $this->setSearchConditions($search);
 }
Example #3
0
 /**
  * Get filter parameters as search data.
  *
  * @return SearchData
  */
 protected function getSearch()
 {
     $fields = $this->repo->getSearchFields();
     $paging = $this->getPagingFields();
     $filters = $this->getFilters(array_merge($fields, array_keys($paging)));
     $this->search->setFilters(array_merge($paging, $filters));
     $this->search->setSortingKeys(array_keys($paging));
     return $this->search;
 }
Example #4
0
 public function setSearchParams(SearchData $search)
 {
     // Overriding so we can alter sorting logic
     // @todo make it easier to override just sorting
     $this->search_query = $this->selectQuery();
     $sorting = $search->getSorting();
     // Always return featured sets first
     // @todo make this optional
     $this->search_query->order_by('sets.featured', 'DESC');
     if (!empty($sorting['orderby'])) {
         $this->search_query->order_by($this->getTable() . '.' . $sorting['orderby'], Arr::get($sorting, 'order'));
     }
     if (!empty($sorting['offset'])) {
         $this->search_query->offset($sorting['offset']);
     }
     if (!empty($sorting['limit'])) {
         $this->search_query->limit($sorting['limit']);
     }
     // apply the unique conditions of the search
     $this->setSearchConditions($search);
 }
Example #5
0
 protected function setSearchConditions(SearchData $search)
 {
     if ($search->include_types) {
         if (is_array($search->include_types)) {
             $this->include_value_types = $search->include_types;
         } else {
             $this->include_value_types = explode(',', $search->include_types);
         }
     }
     if ($search->include_attributes) {
         if (is_array($search->include_attributes)) {
             $this->include_attributes = $search->include_attributes;
         } else {
             $this->include_attributes = explode(',', $search->include_attributes);
         }
     }
     $query = $this->search_query;
     $table = $this->getTable();
     $status = $search->getFilter('status', 'published');
     if ($status !== 'all') {
         $query->where("{$table}.status", '=', $status);
     }
     foreach (['type', 'locale', 'slug'] as $key) {
         if ($search->{$key}) {
             $query->where("{$table}.{$key}", '=', $search->{$key});
         }
     }
     // If user = me, replace with current user id
     if ($search->user === 'me') {
         $search->user = $this->getUserId();
     }
     foreach (['user', 'parent', 'form'] as $key) {
         if (isset($search->{$key})) {
             // Make sure we have an array
             if (!is_array($search->{$key})) {
                 $search->{$key} = explode(',', $search->{$key});
             }
             // Special case: 'none' looks for null
             if (in_array('none', $search->{$key})) {
                 $query->and_where_open()->where("{$table}.{$key}_id", 'IS', NULL)->or_where("{$table}.{$key}_id", 'IN', $search->{$key})->and_where_close();
             } else {
                 $query->where("{$table}.{$key}_id", 'IN', $search->{$key});
             }
         }
     }
     if ($search->q) {
         // search terms are all wrapped as a series of OR conditions
         $query->and_where_open();
         // searching in title / content
         $query->where("{$table}.title", 'LIKE', "%{$search->q}%")->or_where("{$table}.content", 'LIKE', "%{$search->q}%");
         if (is_numeric($search->q)) {
             // if `q` is numeric, could be searching for a specific id
             $query->or_where('id', '=', $search->q);
         }
         $query->and_where_close();
     }
     if ($search->id) {
         //searching for specific post id, used for single post in set searches
         $query->where('id', '=', $search->id);
     }
     // date chcks
     if ($search->created_after) {
         $created_after = strtotime($search->created_after);
         $query->where("{$table}.created", '>=', $created_after);
     }
     if ($search->created_before) {
         $created_before = strtotime($search->created_before);
         $query->where("{$table}.created", '<=', $created_before);
     }
     if ($search->updated_after) {
         $updated_after = strtotime($search->updated_after);
         $query->where("{$table}.updated", '>=', $updated_after);
     }
     if ($search->updated_before) {
         $updated_before = strtotime($search->updated_before);
         $query->where("{$table}.updated", '<=', $updated_before);
     }
     // Bounding box search
     // Create geometry from bbox (or create bbox from center & radius)
     $bounding_box = null;
     if ($search->bbox) {
         $bounding_box = $this->createBoundingBoxFromCSV($search->bbox);
     } else {
         if ($search->center_point && $search->within_km) {
             $bounding_box = $this->createBoundingBoxFromCenter($search->center_point, $search->within_km);
         }
     }
     if ($bounding_box) {
         $query->join([$this->getBoundingBoxSubquery($bounding_box), 'Filter_BBox'], 'INNER')->on('posts.id', '=', 'Filter_BBox.post_id');
     }
     if ($search->current_stage) {
         $stages = $search->current_stage;
         if (!is_array($stages)) {
             $stages = explode(',', $stages);
         }
         /**
          * Here be dragons
          * The purpose of this query is to return the set of posts which
          * have current stage X. In this case, current stage X is actually the
          * the stage the post has NOT yet completed - which is the stage with.
          * the lowest priority.
          * For example:
          * If I have 3 stages for a given Post Type, I am on stage 1 if
          * I have completed no stages and I am on stage 3 if I have completed
          * stages 1 and 2.
          * If I have completed stages 1 and 3, I am on stage 2 as stages are considered
          * to be sequential
          */
         /**
          * This query is responsible for returning all the
          * stages for a given post id, where the stage has been completed.
          * This is used to check which stages the Post has not yet completed
          */
         $stages_posts = DB::select('form_stage_id')->from('form_stages_posts')->where('post_id', '=', DB::expr('posts.id'))->and_where('completed', '=', '1');
         /**
          * This query returns the IDs for the stages that we are filtering by
          */
         $forms_sub = DB::select('form_stages.form_id')->from('form_stages')->where('form_stages.id', 'IN', $stages);
         /**
          * This is the master query, it collects all the posts
          * missing stages that we are filtering by.
          */
         $sub = DB::select(array('posts.id', 'p_id'), array('form_stages.id', 'fs_id'), 'priority', 'posts.form_id', 'forms.id')->from('posts')->join('forms')->on('posts.form_id', '=', 'forms.id')->on('forms.id', 'IN', $forms_sub)->join('form_stages')->on('form_stages.form_id', 'IN', $forms_sub)->on('form_stages.id', 'NOT IN', $stages_posts)->group_by('p_id')->having('form_stages.id', 'IN', $stages)->order_by('priority');
         //This step wraps the query and returns only the posts ids without the extra data such as form, stage or priority
         $posts_sub = DB::select('p_id')->from(array($sub, 'sub'));
         $query->where('posts.id', 'IN', $posts_sub);
     }
     // Filter by tag
     if ($search->tags) {
         if (isset($search->tags['any'])) {
             $tags = $search->tags['any'];
             if (!is_array($tags)) {
                 $tags = explode(',', $tags);
             }
             $query->join('posts_tags')->on('posts.id', '=', 'posts_tags.post_id')->where('tag_id', 'IN', $tags);
         } elseif (isset($search->tags['all'])) {
             $tags = $search->tags['all'];
             if (!is_array($tags)) {
                 $tags = explode(',', $tags);
             }
             foreach ($tags as $tag) {
                 $sub = DB::select('post_id')->from('posts_tags')->where('tag_id', '=', $tag);
                 $query->where('posts.id', 'IN', $sub);
             }
         } else {
             $tags = $search->tags;
             if (!is_array($tags)) {
                 $tags = explode(',', $tags);
             }
             $query->join('posts_tags')->on('posts.id', '=', 'posts_tags.post_id')->where('tag_id', 'IN', $tags);
         }
     }
     // Filter by set
     if ($search->set) {
         $set = $search->set;
         if (!is_array($set)) {
             $set = explode(',', $set);
         }
         $query->join('posts_sets', 'INNER')->on('posts.id', '=', 'posts_sets.post_id')->where('posts_sets.set_id', 'IN', $set);
     }
     // Attributes
     if ($search->values) {
         foreach ($search->values as $key => $value) {
             $attribute = $this->form_attribute_repo->getByKey($key);
             $sub = $this->post_value_factory->getRepo($attribute->type)->getValueQuery($attribute->id, $value);
             $query->join([$sub, 'Filter_' . ucfirst($key)], 'INNER')->on('posts.id', '=', 'Filter_' . ucfirst($key) . '.post_id');
         }
     }
     $user = $this->getUser();
     // If there's no logged in user, or the user isn't admin
     // restrict our search to make sure we still return SOME results
     // they are allowed to see
     if (!$user->id) {
         $query->where("{$table}.status", '=', 'published');
     } elseif ($user->role !== 'admin') {
         $query->and_where_open()->where("{$table}.status", '=', 'published')->or_where("{$table}.user_id", '=', $user->id)->and_where_close();
     }
 }
Example #6
0
 /**
  * Get the paging parameters for the current collection request from input data.
  * @param  Ushahidi\SearchData $input
  * @return Array  [limit, offset, order, orderby, curr, next, prev]
  */
 protected function _get_paging_for_input(SearchData $input)
 {
     $params = $input->getSortingParams();
     $prev_params = $next_params = $params;
     $next_params['offset'] = $params['offset'] + $params['limit'];
     $prev_params['offset'] = $params['offset'] - $params['limit'];
     $prev_params['offset'] = $prev_params['offset'] > 0 ? $prev_params['offset'] : 0;
     $curr = URL::site($this->request->uri() . URL::query($params), $this->request);
     $next = URL::site($this->request->uri() . URL::query($next_params), $this->request);
     $prev = URL::site($this->request->uri() . URL::query($prev_params), $this->request);
     return array('limit' => $input->limit, 'offset' => $input->offset, 'order' => $input->order, 'orderby' => $input->orderby, 'curr' => $curr, 'next' => $next, 'prev' => $prev);
 }
Example #7
0
 protected function setSearchConditions(SearchData $search)
 {
     if ($search->include_types) {
         if (is_array($search->include_types)) {
             $this->include_value_types = $search->include_types;
         } else {
             $this->include_value_types = explode(',', $search->include_types);
         }
     }
     if ($search->include_attributes) {
         if (is_array($search->include_attributes)) {
             $this->include_attributes = $search->include_attributes;
         } else {
             $this->include_attributes = explode(',', $search->include_attributes);
         }
     }
     $query = $this->search_query;
     $table = $this->getTable();
     $status = $search->getFilter('status', 'published');
     if ($status !== 'all') {
         $query->where("{$table}.status", '=', $status);
     }
     foreach (['type', 'locale', 'slug'] as $key) {
         if ($search->{$key}) {
             $query->where("{$table}.{$key}", '=', $search->{$key});
         }
     }
     // If user = me, replace with current user id
     if ($search->user === 'me') {
         $search->user = $this->getUserId();
     }
     foreach (['user', 'parent', 'form'] as $key) {
         if (isset($search->{$key})) {
             // Special case: empty search string looks for null
             if (empty($search->{$key})) {
                 $query->where("{$table}.{$key}_id", "IS", NULL);
             } else {
                 // Make sure we have an array
                 if (!is_array($search->{$key})) {
                     $search->{$key} = explode(',', $search->{$key});
                 }
                 $query->where("{$table}.{$key}_id", 'IN', $search->{$key});
             }
         }
     }
     if ($search->q) {
         // search terms are all wrapped as a series of OR conditions
         $query->and_where_open();
         // searching in title / content
         $query->where("{$table}.title", 'LIKE', "%{$search->q}%")->or_where("{$table}.content", 'LIKE', "%{$search->q}%");
         if (is_numeric($search->q)) {
             // if `q` is numeric, could be searching for a specific id
             $query->or_where('id', '=', $search->q);
         }
         $query->and_where_close();
     }
     if ($search->id) {
         //searching for specific post id, used for single post in set searches
         $query->where('id', '=', $search->id);
     }
     // date chcks
     if ($search->created_after) {
         $created_after = strtotime($search->created_after);
         $query->where("{$table}.created", '>=', $created_after);
     }
     if ($search->created_before) {
         $created_before = strtotime($search->created_before);
         $query->where("{$table}.created", '<=', $created_before);
     }
     if ($search->updated_after) {
         $updated_after = strtotime($search->updated_after);
         $query->where("{$table}.updated", '>=', $updated_after);
     }
     if ($search->updated_before) {
         $updated_before = strtotime($search->updated_before);
         $query->where("{$table}.updated", '<=', $updated_before);
     }
     // Bounding box search
     // Create geometry from bbox (or create bbox from center & radius)
     $bounding_box = null;
     if ($search->bbox) {
         $bounding_box = $this->createBoundingBoxFromCSV($search->bbox);
     } else {
         if ($search->center_point && $search->within_km) {
             $bounding_box = $this->createBoundingBoxFromCenter($search->center_point, $search->within_km);
         }
     }
     if ($bounding_box) {
         $query->join([$this->getBoundingBoxSubquery($bounding_box), 'Filter_BBox'], 'INNER')->on('posts.id', '=', 'Filter_BBox.post_id');
     }
     // Filter by tag
     if ($search->tags) {
         if (isset($search->tags['any'])) {
             $tags = $search->tags['any'];
             if (!is_array($tags)) {
                 $tags = explode(',', $tags);
             }
             $query->join('posts_tags')->on('posts.id', '=', 'posts_tags.post_id')->where('tag_id', 'IN', $tags);
         } elseif (isset($search->tags['all'])) {
             $tags = $search->tags['all'];
             if (!is_array($tags)) {
                 $tags = explode(',', $tags);
             }
             foreach ($tags as $tag) {
                 $sub = DB::select('post_id')->from('posts_tags')->where('tag_id', '=', $tag);
                 $query->where('posts.id', 'IN', $sub);
             }
         } else {
             $tags = $search->tags;
             if (!is_array($tags)) {
                 $tags = explode(',', $tags);
             }
             $query->join('posts_tags')->on('posts.id', '=', 'posts_tags.post_id')->where('tag_id', 'IN', $tags);
         }
     }
     // Filter by set
     if ($search->set) {
         $query->join('posts_sets', 'INNER')->on('posts.id', '=', 'posts_sets.post_id')->where('posts_sets.set_id', '=', $search->set);
     }
     // Attributes
     if ($search->values) {
         foreach ($search->values as $key => $value) {
             $attribute = $this->form_attribute_repo->getByKey($key);
             $sub = $this->post_value_factory->getRepo($attribute->type)->getValueQuery($attribute->id, $value);
             $query->join([$sub, 'Filter_' . ucfirst($key)], 'INNER')->on('posts.id', '=', 'Filter_' . ucfirst($key) . '.post_id');
         }
     }
 }