Example #1
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;
 }
 /**
  * Process the request
  * 
  * @param Tracker_IDisplayTrackerLayout  $layout          Displays the page header and footer
  * @param Codendi_Request                $request         The data coming from the user
  * @param User                           $current_user    The user who mades the request
  *
  * @return void
  */
 public function process(Tracker_IDisplayTrackerLayout $layout, $request, $current_user)
 {
     switch ($request->get('func')) {
         case 'fetch-artifacts':
             $read_only = false;
             $prefill_removed_values = array();
             $only_rows = true;
             $this_project_id = $this->getTracker()->getProject()->getGroupId();
             $hp = Codendi_HTMLPurifier::instance();
             $ugroups = $current_user->getUgroups($this_project_id, array());
             $ids = $request->get('ids');
             //2, 14, 15
             $tracker = array();
             $result = array();
             //We must retrieve the last changeset ids of each artifact id.
             $dao = new Tracker_ArtifactDao();
             foreach ($dao->searchLastChangesetIds($ids, $ugroups, $current_user->isSuperUser()) as $matching_ids) {
                 $tracker_id = $matching_ids['tracker_id'];
                 $tracker = $this->getTrackerFactory()->getTrackerById($tracker_id);
                 $project = $tracker->getProject();
                 if ($tracker->userCanView()) {
                     $trf = Tracker_ReportFactory::instance();
                     $report = $trf->getDefaultReportsByTrackerId($tracker->getId());
                     if ($report) {
                         $renderers = $report->getRenderers();
                         // looking for the first table renderer
                         foreach ($renderers as $renderer) {
                             if ($renderer->getType() === Tracker_Report_Renderer::TABLE) {
                                 $key = $this->id . '_' . $report->id . '_' . $renderer->getId();
                                 $result[$key] = $renderer->fetchAsArtifactLink($matching_ids, $this->getId(), $read_only, $prefill_removed_values, $only_rows);
                                 $head = '<div>';
                                 $project_name = '';
                                 if ($project->getGroupId() != $this_project_id) {
                                     $project_name = ' (<abbr title="' . $hp->purify($project->getPublicName(), CODENDI_PURIFIER_CONVERT_HTML) . '">';
                                     $project_name .= $hp->purify($project->getUnixName(), CODENDI_PURIFIER_CONVERT_HTML);
                                     $project_name .= '</abbr>)';
                                 }
                                 $head .= '<h2 class="tracker-form-element-artifactlink-tracker_' . $tracker->getId() . '">';
                                 $head .= $hp->purify($tracker->getName(), CODENDI_PURIFIER_CONVERT_HTML) . $project_name;
                                 $head .= '</h2>';
                                 //if ($artifact) {
                                 //    $title = $hp->purify('link a '. $tracker->getItemName(), CODENDI_PURIFIER_CONVERT_HTML);
                                 //    $head .= '<a href="'.TRACKER_BASE_URL.'/?tracker='.$tracker_id.'&func=new-artifact-link&id='.$artifact->getId().'" class="tracker-form-element-artifactlink-link-new-artifact">'. 'create a new '.$hp->purify($tracker->getItemName(), CODENDI_PURIFIER_CONVERT_HTML)  .'</a>';
                                 //}
                                 $result[$key]['head'] = $head . $result[$key]['head'];
                                 break;
                             }
                         }
                     }
                 }
             }
             if ($result) {
                 $head = array();
                 $rows = array();
                 foreach ($result as $key => $value) {
                     $head[$key] = $value["head"];
                     $rows[$key] = $value["rows"];
                 }
                 header('Content-type: application/json');
                 echo json_encode(array('head' => $head, 'rows' => $rows));
             }
             exit;
             break;
         case 'fetch-aggregates':
             $read_only = false;
             $prefill_removed_values = array();
             $only_rows = true;
             $only_one_column = false;
             $extracolumn = Tracker_Report_Renderer_Table::EXTRACOLUMN_UNLINK;
             $read_only = true;
             $use_data_from_db = false;
             $ugroups = $current_user->getUgroups($this->getTracker()->getGroupId(), array());
             $ids = $request->get('ids');
             //2, 14, 15
             $tracker = array();
             $json = array('tabs' => array());
             $dao = new Tracker_ArtifactDao();
             foreach ($dao->searchLastChangesetIds($ids, $ugroups, $current_user->isSuperUser()) as $matching_ids) {
                 $tracker_id = $matching_ids['tracker_id'];
                 $tracker = $this->getTrackerFactory()->getTrackerById($tracker_id);
                 $project = $tracker->getProject();
                 if ($tracker->userCanView()) {
                     $trf = Tracker_ReportFactory::instance();
                     $report = $trf->getDefaultReportsByTrackerId($tracker->getId());
                     if ($report) {
                         $renderers = $report->getRenderers();
                         // looking for the first table renderer
                         foreach ($renderers as $renderer) {
                             if ($renderer->getType() === Tracker_Report_Renderer::TABLE) {
                                 $key = $this->id . '_' . $report->id . '_' . $renderer->getId();
                                 $columns = $renderer->getTableColumns($only_one_column, $use_data_from_db);
                                 $extracted_fields = $renderer->extractFieldsFromColumns($columns);
                                 $json['tabs'][] = array('key' => $key, 'src' => $renderer->fetchAggregates($matching_ids, $extracolumn, $only_one_column, $columns, $extracted_fields, $use_data_from_db, $read_only));
                                 break;
                             }
                         }
                     }
                 }
             }
             header('Content-type: application/json');
             echo json_encode($json);
             exit;
             break;
         default:
             parent::process($layout, $request, $current_user);
             break;
     }
 }
Example #3
0
 protected function getMatchingIdsInDb(DataAccessObject $dao, PermissionsManager $permissionManager, Tracker $tracker, User $user, array $criteria)
 {
     $dump_criteria = array();
     foreach ($criteria as $c) {
         $dump_criteria[$c->field->getName()] = $c->field->getCriteriaValue($c);
     }
     $dao->logStart(__METHOD__, json_encode(array('user' => $user->getUserName(), 'project' => $tracker->getGroupId(), 'query' => $dump_criteria, 'trackers' => array($tracker->getId()))));
     $matching_ids = array();
     $group_id = $tracker->getGroupId();
     $instances = array('artifact_type' => $tracker->getId());
     $ugroups = $user->getUgroups($group_id, $instances);
     $static_ugroups = $user->getStaticUgroups($group_id);
     $dynamic_ugroups = $user->getDynamicUgroups($group_id, $instances);
     $permissions = $permissionManager->getPermissionsAndUgroupsByObjectid($tracker->getId());
     $contributor_field = $tracker->getContributorField();
     $contributor_field_id = $contributor_field ? $contributor_field->getId() : null;
     $additional_from = array();
     $additional_where = array();
     foreach ($criteria as $c) {
         if ($f = $c->getFrom()) {
             $additional_from[] = $f;
         }
         if ($w = $c->getWhere()) {
             $additional_where[] = $w;
         }
     }
     $matching_ids = $dao->searchMatchingIds($group_id, $tracker->getId(), $additional_from, $additional_where, $user->isSuperUser(), $permissions, $ugroups, $static_ugroups, $dynamic_ugroups, $contributor_field_id)->getRow();
     if ($matching_ids) {
         if (substr($matching_ids['id'], -1) === ',') {
             $matching_ids['id'] = substr($matching_ids['id'], 0, -1);
         }
         if (substr($matching_ids['last_changeset_id'], -1) === ',') {
             $matching_ids['last_changeset_id'] = substr($matching_ids['last_changeset_id'], 0, -1);
         }
     } else {
         $matching_ids['id'] = '';
         $matching_ids['last_changeset_id'] = '';
     }
     $nb_matching = $matching_ids['id'] ? substr_count($matching_ids['id'], ',') + 1 : 0;
     $dao->logEnd(__METHOD__, $nb_matching);
     return $matching_ids;
 }