Example #1
0
 public function getMatchingArtifacts(PFUser $user, Project $project, array $tracker_ids, Tracker_Hierarchy $hierarchy, Tracker_CrossSearch_Query $query, $excluded_artifact_ids = array())
 {
     $shared_fields = $this->shared_field_factory->getSharedFields($query->getSharedFields());
     $semantic_fields = $query->getSemanticCriteria();
     $artifacts_info = $this->dao->searchMatchingArtifacts($user, $project->getId(), $query, $tracker_ids, $shared_fields, $semantic_fields, $this->artifact_link_field_ids_for_column_display, $excluded_artifact_ids);
     return $this->result_sorter->buildTreeWithMissingChildren($user, $artifacts_info, $excluded_artifact_ids);
 }
Example #2
0
 public function itIsNotEmptyWhenThereIsASharedFieldSelected()
 {
     $shared_fields_criteria = array(1084 => array('values' => array(0 => '1080')));
     $query = new Tracker_CrossSearch_Query($shared_fields_criteria, array(), array());
     $this->assertFalse($query->isEmpty());
 }
Example #3
0
 /**
  * Monstro query 
  * 
  * @param User $user
  * @param unknown_type $group_id
  * @param Tracker_CrossSearch_Query $query
  * @param array $tracker_ids
  * @param array $shared_fields
  * @param array $semantic_fields
  * @param array $artifact_link_field_ids_for_column_display
  * @param array $excluded_artifact_ids
  */
 public function searchMatchingArtifacts(User $user, $group_id, Tracker_CrossSearch_Query $query, array $tracker_ids, array $shared_fields, array $semantic_fields, array $artifact_link_field_ids_for_column_display, array $excluded_artifact_ids = array())
 {
     $report_dao = new Tracker_ReportDao();
     $report_dao->logStart(__METHOD__, json_encode(array('user' => $user->getUserName(), 'project' => $group_id, 'query' => $query->toArrayOfDoom(), 'trackers' => array_values($tracker_ids))));
     $is_super_user = $user->isSuperUser();
     $ugroups = $user->getUgroups($group_id, array());
     $quoted_ugroups = $this->da->quoteSmartImplode(',', $ugroups);
     $quoted_tracker_ids = $this->da->quoteSmartImplode(',', $tracker_ids);
     $excluded_artifact_ids = $this->da->quoteSmartImplode(',', $excluded_artifact_ids);
     $shared_fields_constraints = $this->getSharedFieldsSqlFragment($shared_fields);
     $title_constraint = $this->getTitleSqlFragment($this->getSemanticFieldCriteria($semantic_fields, 'title'));
     $status_constraint = $this->getStatusSqlFragment($this->getSemanticFieldCriteria($semantic_fields, 'status'));
     $tracker_constraint = $tracker_ids ? " AND   artifact.tracker_id IN ({$quoted_tracker_ids}) " : "";
     $artifact_ids_list = $query->listArtifactIds();
     $artifact_link_constraints = '';
     if (count($artifact_ids_list)) {
         $artifact_ids_list = $this->da->quoteSmartImplode(',', $artifact_ids_list);
         $artifacts_fields = $this->getArtifactLinkFields($artifact_ids_list, $is_super_user, $quoted_ugroups);
         $artifact_link_constraints = $this->getArtifactLinkSearchSqlFragment($artifacts_fields);
     }
     $artifact_link_columns_select = $this->getArtifactLinkSelects($artifact_link_field_ids_for_column_display);
     $artifact_link_columns_join = $this->getArtifactLinkColumns($artifact_link_field_ids_for_column_display, $is_super_user, $quoted_ugroups);
     $artifact_permissions = $report_dao->getSqlFragmentForArtifactPermissions($user->isSuperUser(), $user->getUgroups($group_id, array()));
     $artifact_permissions_join = $artifact_permissions['from'];
     $artifact_permissions_where = $artifact_permissions['where'];
     $tracker_semantic_title_join = $this->getTrackerSemanticTitleJoin($is_super_user, $quoted_ugroups);
     $tracker_semantic_status_join = $this->getTrackerSemanticStatusJoin($is_super_user, $quoted_ugroups);
     $from = " FROM tracker_artifact AS artifact\n                   INNER JOIN tracker_changeset AS c ON (artifact.last_changeset_id = c.id) \n                   {$shared_fields_constraints} \n                   {$artifact_link_constraints} \n                   {$tracker_semantic_title_join} \n                   {$tracker_semantic_status_join} \n                   {$artifact_permissions_join} ";
     $where = " WHERE 1 {$artifact_permissions_where} {$title_constraint} {$status_constraint} ";
     $permissions_manager = PermissionsManager::instance();
     $tracker_factory = TrackerFactory::instance();
     $sqls = array();
     foreach ($tracker_ids as $tracker_id) {
         // {{{ This is a big copy 'n paste from Tracker_Report::getMatchingIdsInDb.
         //     TODO:
         //          instead of building a big query with plenty of unions,
         //          call getMatchingIdsInDb foreach tracker involved in the
         //          crosssearch query. As getMatchingIdsInDb returns the
         //          tuple (artifact_ids, matching_ids) -- where ids are
         //          comma separated --, we will have to do the join in php
         //          by concatenating strings.
         //          Example:
         //              $artifact_ids = $changeset_ids = '';
         //              foreach ($trackers as $tracker) {
         //                  merge($artifact_ids, $changeset_ids, report->getMatchingIdsInDb(..., $tracker, ...));
         //              }
         //              crosssearch->retrieveColumns($artifact_ids, $changeset_ids)
         //
         //          And if we are feeling lucky, we can also move the
         //              reportdao->searchMatchingIds in searchdao since it make more sense.
         //
         //          Possible caveat:
         //              - 1 big sql query full of unions is really slower
         //                than n small queries?
         $instances = array('artifact_type' => $tracker_id);
         $ugroups = $user->getUgroups($group_id, $instances);
         $static_ugroups = $user->getStaticUgroups($group_id);
         $dynamic_ugroups = $user->getDynamicUgroups($group_id, $instances);
         $permissions = $permissions_manager->getPermissionsAndUgroupsByObjectid($tracker_id, $ugroups);
         $subwhere = " {$where} AND artifact.tracker_id = {$tracker_id} ";
         $tracker = $tracker_factory->getTrackerById($tracker_id);
         $contributor_field = $tracker->getContributorField();
         $contributor_field_id = $contributor_field ? $contributor_field->getId() : null;
         // }}}
         $sqls = array_merge($sqls, $report_dao->getSqlFragmentsAccordinglyToTrackerPermissions($user->isSuperUser(), $from, $subwhere, $group_id, $tracker_id, $permissions, $ugroups, $static_ugroups, $dynamic_ugroups, $contributor_field_id));
     }
     array_filter($sqls);
     if (count($sqls) == 0) {
         $results = new DataAccessResultEmpty();
     } else {
         $union = implode(' UNION ', $sqls);
         $sql = "SET SESSION group_concat_max_len = 134217728";
         $this->retrieve($sql);
         $sql = "\n            SELECT artifact.id,\n                   artifact.last_changeset_id,\n                   CVT.value                                AS title,\n                   artifact.tracker_id,\n                   GROUP_CONCAT(CVAL.artifact_id) AS artifactlinks\n                   {$artifact_link_columns_select}\n                   \n            FROM       tracker_artifact  AS artifact\n            INNER JOIN tracker_artifact_priority ON (tracker_artifact_priority.curr_id = artifact.id)\n            INNER JOIN ( {$union} ) AS R ON (R.id = artifact.id)\n            INNER JOIN tracker_changeset AS c ON (R.last_changeset_id = c.id)\n\n            -- shared_fields_constraints\n            \n            -- artifact_link_constraints\n\n            {$tracker_semantic_title_join}\n\n            LEFT JOIN (\n                           tracker_changeset_value_artifactlink AS CVAL\n                INNER JOIN tracker_changeset_value              AS CV2 ON (CV2.id = CVAL.changeset_value_id) \n            \n            ) ON CV2.changeset_id = artifact.last_changeset_id\n\n            {$artifact_link_columns_join}\n            -- artifact_permissions_join\n        \n            WHERE 1\n            -- artifact_permissions_where\n                    {$tracker_constraint}\n            -- title_constraint\n            -- status_constraint\n            ";
         if ($excluded_artifact_ids != '') {
             $sql .= "\n                  AND artifact.id NOT IN ({$excluded_artifact_ids}) ";
         }
         $sql .= "\n                GROUP BY artifact.id\n                ORDER BY tracker_artifact_priority.rank\n            ";
         $results = $this->retrieve($sql);
     }
     $nb_matching = count($results);
     $report_dao->logEnd(__METHOD__, $nb_matching);
     return $results;
 }
Example #4
0
 public function getArtifactLinkCriteria(User $user, Tracker_Report $report, Tracker_CrossSearch_Query $cross_search_query)
 {
     $criteria = array();
     $allowed_artifact_ids = array();
     foreach ($this->planning_trackers as $tracker) {
         $tracker_id = $tracker->getId();
         $tracker_artifacts = Tracker_ArtifactFactory::instance()->getArtifactsByTrackerIdUserCanView($user, $tracker_id);
         // TODO: far from being perfect, anyway we should not modify query but
         //       we should only use criteria in the whole stack
         foreach ($tracker_artifacts as $artifact) {
             $allowed_artifact_ids[$artifact->getId()] = true;
         }
         $tracker_artifacts = $cross_search_query->setSelectedArtifacts($tracker_id, $tracker_artifacts);
         $field = new Tracker_CrossSearch_ArtifactReportField($tracker, $tracker_artifacts);
         $criteria[] = $this->buildCriteria($report, $field);
     }
     $cross_search_query->purgeArtifactIdsNotInList($allowed_artifact_ids);
     return $criteria;
 }