Complex classes like ArtifactReport often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ArtifactReport, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 69 | class ArtifactReport extends Error { |
||
| 70 | |||
| 71 | // The report id |
||
| 72 | var $report_id; |
||
| 73 | |||
| 74 | // The group artifact id (artifact type) |
||
| 75 | var $group_artifact_id; |
||
| 76 | |||
| 77 | // The fields used by this report (array) |
||
| 78 | var $fields; |
||
| 79 | |||
| 80 | // Name of this report |
||
| 81 | var $name; |
||
| 82 | |||
| 83 | // Description of this report |
||
| 84 | var $description; |
||
| 85 | |||
| 86 | // Scope of this report ('S': system, 'P': project) |
||
| 87 | var $scope; |
||
| 88 | |||
| 89 | // Is this default report |
||
| 90 | var $is_default; |
||
| 91 | |||
| 92 | /** |
||
| 93 | * Constructor. |
||
| 94 | * |
||
| 95 | * @param report_id |
||
| 96 | * @param atid: the artifact type id |
||
| 97 | * |
||
| 98 | * @return boolean success. |
||
| 99 | */ |
||
| 100 | function ArtifactReport($report_id,$atid) { |
||
| 101 | // Error constructor |
||
| 102 | $this->Error(); |
||
| 103 | $this->group_artifact_id = $atid; |
||
| 104 | $this->fields = array(); |
||
| 105 | |||
| 106 | if ( !$this->fetchData($report_id,$atid) ) { |
||
| 107 | return false; |
||
| 108 | } |
||
| 109 | |||
| 110 | return true; |
||
| 111 | } |
||
| 112 | |||
| 113 | function getReportId() { |
||
| 116 | |||
| 117 | /** |
||
| 118 | * recreate - use this to reset a Report in the database. |
||
| 119 | * |
||
| 120 | * @param string The report name. |
||
| 121 | * @param string The report description. |
||
| 122 | * @return true on success, false on failure. |
||
| 123 | */ |
||
| 124 | function recreate($user_id,$name,$description,$scope,$is_default) { |
||
| 125 | global $ath,$Language; |
||
| 126 | /* |
||
| 127 | $perm = $ath->Group->getPermissionFromId( $user_id); |
||
| 128 | |||
| 129 | if (!$perm || !is_object($perm) || !$perm->isArtifactAdmin()) { |
||
| 130 | $this->setError('ArtifactReport: Permission Denied'); |
||
| 131 | return false; |
||
| 132 | } |
||
| 133 | */ |
||
| 134 | |||
| 135 | if (!$name || !$description ||!$scope) { |
||
| 136 | $this->setError('ArtifactReport: '.$Language->getText('tracker_common_report','name_requ')); |
||
| 137 | echo 'ArtifactReport: '.$Language->getText('tracker_common_report','name_requ'); |
||
| 138 | return false; |
||
| 139 | } |
||
| 140 | |||
| 141 | $group_id = $ath->Group->getID(); |
||
| 142 | |||
| 143 | |||
| 144 | // first delete any report field entries for this report |
||
| 145 | $res = db_query("DELETE FROM artifact_report_field WHERE report_id=". db_ei($this->report_id) ); |
||
| 146 | |||
| 147 | $res = db_query("UPDATE artifact_report |
||
| 148 | SET user_id='" . db_ei($user_id) . "',name='". db_es($name) ."', description='". db_es($description) ."',scope='". db_es($scope) ."',is_default='".db_es($is_default)."' |
||
| 149 | WHERE report_id=". db_ei($this->report_id) ); |
||
| 150 | |||
| 151 | // set other reports as not default report |
||
| 152 | if ($is_default ==1 ) { |
||
| 153 | $res = db_query("UPDATE artifact_report SET is_default=0 WHERE report_id <>".db_ei($this->report_id)." AND group_artifact_id=".db_ei($this->group_artifact_id)); |
||
| 154 | } |
||
| 155 | $this->user_id = $user_id; |
||
| 156 | $this->name = $name; |
||
| 157 | $this->description = $description; |
||
| 158 | $this->scope = $scope; |
||
| 159 | $this->is_default = $is_default; |
||
| 160 | $this->fields = array(); |
||
| 161 | return true; |
||
| 162 | } |
||
| 163 | |||
| 164 | /** |
||
| 165 | * delete - use this to remove a Report from the database. |
||
| 166 | * |
||
| 167 | * @return true on success, false on failure. |
||
| 168 | */ |
||
| 169 | function delete() { |
||
| 170 | global $ath; |
||
| 171 | |||
| 172 | // first delete any report field entries for this report |
||
| 173 | $res = db_query("DELETE FROM artifact_report_field WHERE report_id=". db_ei($this->report_id) ); |
||
| 174 | |||
| 175 | // then delete the report entry item |
||
| 176 | $res = db_query("DELETE FROM artifact_report WHERE report_id=". db_ei($this->report_id) ); |
||
| 177 | |||
| 178 | $this->name = ''; |
||
| 179 | $this->description = ''; |
||
| 180 | $this->scope = ''; |
||
| 181 | $this->is_default = ''; |
||
| 182 | $this->fields = array(); |
||
| 183 | return true; |
||
| 184 | } |
||
| 185 | |||
| 186 | /** |
||
| 187 | * updateDefaultReport - use this to set the report to default |
||
| 188 | * @return true on success false on failure |
||
| 189 | */ |
||
| 190 | |||
| 191 | function updateDefaultReport() { |
||
| 192 | if ($GLOBALS['ath']->userIsAdmin()) { |
||
| 193 | db_query("UPDATE artifact_report SET is_default=1 WHERE report_id =".db_ei($this->report_id)." AND group_artifact_id=".db_ei($this->group_artifact_id)); |
||
| 194 | db_query("UPDATE artifact_report SET is_default=0 WHERE report_id <>".db_ei($this->report_id)." AND group_artifact_id=".db_ei($this->group_artifact_id)); |
||
| 195 | return true; |
||
| 196 | } |
||
| 197 | return false; |
||
| 198 | } |
||
| 199 | |||
| 200 | /** |
||
| 201 | * create - use this to create a new Report in the database. |
||
| 202 | * |
||
| 203 | * @param string The report name. |
||
| 204 | * @param string The report description. |
||
| 205 | * @return id on success, false on failure. |
||
| 206 | */ |
||
| 207 | function create($user_id,$name,$description,$scope,$is_default) { |
||
| 208 | global $ath,$Language; |
||
| 209 | /*$perm = $ath->Group->getPermissionFromId( $user_id); |
||
| 210 | |||
| 211 | if (!$perm || !is_object($perm) || !$perm->isArtifactAdmin()) { |
||
| 212 | $this->setError('ArtifactReport: Permission Denied'); |
||
| 213 | return false; |
||
| 214 | } |
||
| 215 | */ |
||
| 216 | if (!$name || !$description ||!$scope) { |
||
| 217 | $this->setError('ArtifactReport: '.$Language->getText('tracker_common_report','name_requ')); |
||
| 218 | return false; |
||
| 219 | } |
||
| 220 | |||
| 221 | $group_id = $ath->Group->getID(); |
||
| 222 | $atid=$ath->getID(); |
||
| 223 | |||
| 224 | $sql = 'INSERT INTO artifact_report (group_artifact_id,user_id,name,description,scope,is_default) '. |
||
| 225 | "VALUES ('". db_ei($atid) ."','". db_ei($user_id) ."','". db_es($name) ."',". |
||
| 226 | "'". db_es($description) ."','". db_es($scope) ."','".db_ei($is_default)."')"; |
||
| 227 | //echo $sql; |
||
| 228 | |||
| 229 | $res = db_query($sql); |
||
| 230 | |||
| 231 | $report_id = db_insertid($res, 'artifact_report', 'report_id'); |
||
| 232 | if (($is_default == 1) && ($report_id)) { |
||
| 233 | db_query("UPDATE artifact_report SET is_default=0 WHERE report_id <>".db_ei($report_id)." AND group_artifact_id=".db_ei($this->group_artifact_id)); |
||
| 234 | } |
||
| 235 | if (!$res || !$report_id) { |
||
| 236 | $this->setError('ArtifactReport: '.db_error()); |
||
| 237 | return false; |
||
| 238 | } else { |
||
| 239 | $this->report_id = $report_id; |
||
| 240 | $this->description = $description; |
||
| 241 | $this->name = $name; |
||
| 242 | $this->scope = $scope; |
||
| 243 | $this->is_default = $is_default; |
||
| 244 | |||
| 245 | $this->fields = array(); |
||
| 246 | return true; |
||
| 247 | } |
||
| 248 | } |
||
| 249 | |||
| 250 | function add_report_field($field_name,$show_on_query,$show_on_result,$place_query,$place_result,$col_width) { |
||
| 251 | $sql = 'INSERT INTO artifact_report_field (report_id, field_name,'. |
||
| 252 | 'show_on_query,show_on_result,place_query,place_result,col_width) VALUES '; |
||
| 253 | |||
| 254 | $sql .= "(". db_ei($this->report_id) .",'". db_es($field_name) ."',". db_ei($show_on_query) .",". db_ei($show_on_result) .",". |
||
| 255 | db_ei($place_query, CODENDI_DB_NULL) .",". db_ei($place_result, CODENDI_DB_NULL) .",". db_ei($col_width, CODENDI_DB_NULL) .")"; |
||
| 256 | //echo $sql.'<br>'; |
||
| 257 | $res = db_query($sql); |
||
| 258 | if ($res) { |
||
| 259 | return true; |
||
| 260 | } else { |
||
| 261 | return false; |
||
| 262 | } |
||
| 263 | } |
||
| 264 | |||
| 265 | function toggleFieldColumnUsage($field_name) { |
||
| 266 | $sql = "UPDATE artifact_report_field |
||
| 267 | SET show_on_result = 1 - show_on_result |
||
| 268 | WHERE report_id = ". db_ei($this->report_id) ." |
||
| 269 | AND field_name = '". db_es($field_name) ."'"; |
||
| 270 | db_query($sql); |
||
| 271 | } |
||
| 272 | function toggleFieldQueryUsage($field_name) { |
||
| 273 | $sql = "UPDATE artifact_report_field |
||
| 274 | SET show_on_query = 1 - show_on_query |
||
| 275 | WHERE report_id = ". db_ei($this->report_id) ." |
||
| 276 | AND field_name = '". db_es($field_name) ."'"; |
||
| 277 | db_query($sql); |
||
| 278 | } |
||
| 279 | /** |
||
| 280 | * fetchData - re-fetch the data for this ArtifactReport from the database. |
||
| 281 | * |
||
| 282 | * @param int The report ID. |
||
| 283 | * @return boolean success. |
||
| 284 | */ |
||
| 285 | function fetchData($report_id) { |
||
| 286 | global $Language; |
||
| 287 | |||
| 288 | // Read the report infos |
||
| 289 | $sql = "SELECT * FROM artifact_report ". |
||
| 290 | "WHERE report_id=". db_ei($report_id) ; |
||
| 291 | //echo $sql.'<br>'; |
||
| 292 | $res=db_query($sql); |
||
| 293 | if (!$res || db_numrows($res) < 1) { |
||
| 294 | $this->setError('ArtifactReport: '.$Language->getText('tracker_common_report','not_found')); |
||
| 295 | return false; |
||
| 296 | } |
||
| 297 | $data_array = db_fetch_array($res); |
||
| 298 | $this->name = $data_array['name']; |
||
| 299 | $this->description = $data_array['description']; |
||
| 300 | $this->scope = $data_array['scope']; |
||
| 301 | $this->is_default = $data_array['is_default']; |
||
| 302 | $this->report_id = $report_id; |
||
| 303 | |||
| 304 | // Read the fields infos |
||
| 305 | $res=db_query("SELECT * FROM artifact_report_field ". |
||
| 306 | "WHERE report_id=". db_ei($report_id) ); |
||
| 307 | if (!$res || db_numrows($res) < 1) { |
||
| 308 | $this->setError('ArtifactReport:fetchData'); |
||
| 309 | return false; |
||
| 310 | } |
||
| 311 | |||
| 312 | // Store the fields in $this->fields |
||
| 313 | $this->fields=array(); |
||
| 314 | $i=0; |
||
| 315 | while ($field_array = db_fetch_array($res)) { |
||
| 316 | // ArtifactReportField inherits from ArtifactField |
||
| 317 | // So we need to retreive ArtifactField values |
||
| 318 | $this->fields[$field_array['field_name']] = new ArtifactReportField(); |
||
| 319 | $obj = $this->fields[$field_array['field_name']]; |
||
| 320 | $obj->fetchData($this->group_artifact_id,$field_array['field_name']); |
||
| 321 | $obj->setReportFieldsFromArray($field_array); |
||
| 322 | $this->fields[$field_array['field_name']] = $obj; |
||
| 323 | $i++; |
||
| 324 | } |
||
| 325 | return true; |
||
| 326 | } |
||
| 327 | |||
| 328 | /** |
||
| 329 | * Retrieve the artifact report list order by scope |
||
| 330 | * |
||
| 331 | * @param group_artifact_id: the artifact type |
||
| 332 | * |
||
| 333 | * @return array |
||
| 334 | */ |
||
| 335 | function getReports($group_artifact_id, $user_id) { |
||
| 336 | |||
| 337 | // If user is unknown then get only project-wide and system wide reports |
||
| 338 | // else get personal reports in addition project-wide and system wide. |
||
| 339 | $sql = 'SELECT report_id,name,description,scope,is_default FROM artifact_report WHERE '; |
||
| 340 | if (!$user_id || ($user_id == 100)) { |
||
| 341 | $sql .= "(group_artifact_id=". db_ei($group_artifact_id) ." AND scope='P') OR scope='S' ". |
||
| 342 | 'ORDER BY report_id'; |
||
| 343 | } else { |
||
| 344 | $sql .= "(group_artifact_id=". db_ei($group_artifact_id) ." AND (user_id=". db_ei($user_id) ." OR scope='P')) OR ". |
||
| 345 | "scope='S' ORDER BY scope,report_id"; |
||
| 346 | } |
||
| 347 | //echo "DBG sql report = $sql"; |
||
| 348 | return db_query($sql); |
||
| 349 | } |
||
| 350 | |||
| 351 | /** |
||
| 352 | * Return the field list used for the query report |
||
| 353 | * |
||
| 354 | * @return array |
||
| 355 | */ |
||
| 356 | function getQueryFields() { |
||
| 357 | $query_fields = array(); |
||
| 358 | |||
| 359 | if ( count($this->fields) == 0 ) return $query_fields; |
||
| 360 | |||
| 361 | reset($this->fields); |
||
| 362 | |||
| 363 | while (list($key,$field) = each($this->fields) ) { |
||
| 364 | if ( ($field->isShowOnQuery())&&($field->isUsed())) { |
||
| 365 | if ($field->userCanRead($GLOBALS['group_id'], $this->group_artifact_id)) { |
||
| 366 | $query_fields[$key] = $field; |
||
| 367 | } |
||
| 368 | } |
||
| 369 | } |
||
| 370 | |||
| 371 | uasort($query_fields,'cmp_place_query'); |
||
| 372 | return $query_fields; |
||
| 373 | } |
||
| 374 | |||
| 375 | /** |
||
| 376 | * Return the field list used to display the report |
||
| 377 | * |
||
| 378 | * @return array |
||
| 379 | */ |
||
| 380 | function getResultFields() { |
||
| 381 | $result_fields = array(); |
||
| 382 | |||
| 383 | if ( count($this->fields) == 0 ) return $result_fields; |
||
| 384 | |||
| 385 | reset($this->fields); |
||
| 386 | |||
| 387 | while (list($key,$field) = each($this->fields) ) { |
||
| 388 | if ( ($field->isShowOnResult())&&($field->isUsed()) ) { |
||
| 389 | if ($field->userCanRead($GLOBALS['group_id'], $this->group_artifact_id)) { |
||
| 390 | $result_fields[$key] = $field; |
||
| 391 | } |
||
| 392 | } |
||
| 393 | } |
||
| 394 | |||
| 395 | uasort($result_fields,'cmp_place_result'); |
||
| 396 | return $result_fields; |
||
| 397 | } |
||
| 398 | |||
| 399 | /** |
||
| 400 | * Return all the fields list used for the report |
||
| 401 | * |
||
| 402 | * @return array |
||
| 403 | */ |
||
| 404 | function getSortedFields() { |
||
| 421 | |||
| 422 | /** |
||
| 423 | * Return the field list used to display the report (SelectBox or MultiBox type) |
||
| 424 | * |
||
| 425 | * @return array |
||
| 426 | */ |
||
| 427 | function getSingleMultiBoxFields() { |
||
| 428 | $result_fields = array(); |
||
| 429 | |||
| 430 | if ( count($this->fields) == 0 ) return $result_fields; |
||
| 431 | |||
| 432 | reset($this->fields); |
||
| 433 | |||
| 434 | while (list($key,$field) = each($this->fields) ) { |
||
| 435 | if ( ($field->isShowOnResult())&&($field->getUseIt() == 1)&&($field->isMultiSelectBox()||$field->isSelectBox()) ) { |
||
| 436 | $result_fields[$key] = $field; |
||
| 437 | } |
||
| 438 | } |
||
| 439 | |||
| 440 | return $result_fields; |
||
| 441 | } |
||
| 442 | |||
| 443 | /** |
||
| 444 | * |
||
| 445 | * @param aids: the list (array) of artifact ids that match the query given in $prefs |
||
| 446 | * Returns the number of rows for the current query, filtered with permissions |
||
| 447 | * |
||
| 448 | * |
||
| 449 | * @return int |
||
| 450 | */ |
||
| 451 | function selectReportItems($prefs,$morder,$advsrch,&$aids) { |
||
| 452 | global $ath; |
||
| 453 | $this->getQueryElements($prefs,$advsrch,$from,$where); |
||
| 454 | |||
| 455 | $um = UserManager::instance(); |
||
| 456 | $u = $um->getCurrentUser(); |
||
| 457 | $instances = array('artifact_type' => $this->group_artifact_id); |
||
| 458 | $group_id = $ath->Group->getID(); |
||
| 459 | $ugroups = $u->getUgroups($group_id, $instances); |
||
| 460 | |||
| 461 | $pm =& PermissionsManager::instance(); |
||
| 462 | $permissions = $pm->getPermissionsAndUgroupsByObjectid($this->group_artifact_id); |
||
| 463 | |||
| 464 | if(!$u->isSuperUser() && !$u->isTrackerAdmin($group_id,$this->group_artifact_id)) { |
||
| 465 | //artifact permissions |
||
| 466 | $from .= " LEFT JOIN permissions |
||
| 467 | ON (permissions.object_id = CONVERT(a.artifact_id USING utf8) |
||
| 468 | AND |
||
| 469 | permissions.permission_type = 'TRACKER_ARTIFACT_ACCESS') "; |
||
| 470 | $where .= " AND (a.use_artifact_permissions = 0 |
||
| 471 | OR |
||
| 472 | ( |
||
| 473 | permissions.ugroup_id IN (". implode(',', $ugroups) .") |
||
| 474 | ) |
||
| 475 | ) "; |
||
| 476 | |||
| 477 | } |
||
| 478 | |||
| 479 | $aids = array(); |
||
| 480 | //Does the user member of at least one group which has ACCESS_FULL ? |
||
| 481 | if ($u->isSuperUser() || $u->isTrackerAdmin($group_id,$this->group_artifact_id) || (isset($permissions['TRACKER_ACCESS_FULL']) && count(array_intersect($ugroups, $permissions['TRACKER_ACCESS_FULL'])) > 0)) { |
||
| 482 | |||
| 483 | $sql = "SELECT a.artifact_id ". |
||
| 484 | $from." ". |
||
| 485 | $where. |
||
| 486 | ""; |
||
| 487 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 488 | } else { |
||
| 489 | |||
| 490 | $static_ugroups = $u->getStaticUgroups($group_id); |
||
| 491 | $dynamic_ugroups = $u->getDynamicUgroups($group_id, $instances); |
||
| 492 | //Does the user member of at least one group which has ACCESS_SUBMITTER ? |
||
| 493 | if (isset($permissions['TRACKER_ACCESS_SUBMITTER']) && count(array_intersect($ugroups, $permissions['TRACKER_ACCESS_SUBMITTER'])) > 0) { |
||
| 494 | // {{{ The static ugroups |
||
| 495 | if (count(array_intersect($static_ugroups, $permissions['TRACKER_ACCESS_SUBMITTER'])) > 0) { |
||
| 496 | $sql = "SELECT a.artifact_id ". |
||
| 497 | $from." , ugroup_user uu ". |
||
| 498 | $where. |
||
| 499 | " AND a.submitted_by = uu.user_id ". |
||
| 500 | " AND uu.ugroup_id IN (". db_es(implode(', ', $static_ugroups)).") ". |
||
| 501 | ""; |
||
| 502 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 503 | } |
||
| 504 | // }}} |
||
| 505 | |||
| 506 | // {{{ tracker_admins |
||
| 507 | if (in_array($GLOBALS['UGROUP_TRACKER_ADMIN'], $dynamic_ugroups) && |
||
| 508 | in_array($GLOBALS['UGROUP_TRACKER_ADMIN'], $permissions['TRACKER_ACCESS_SUBMITTER'])) |
||
| 509 | { |
||
| 510 | $sql = "SELECT a.artifact_id ". |
||
| 511 | $from." , artifact_perm p ". |
||
| 512 | $where. |
||
| 513 | " AND a.submitted_by = p.user_id ". |
||
| 514 | " AND p.group_artifact_id = ". db_ei($this->group_artifact_id) ." ". |
||
| 515 | " AND p.perm_level >= 2 ". |
||
| 516 | ""; |
||
| 517 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 518 | } |
||
| 519 | //}}} |
||
| 520 | // {{{ project_members |
||
| 521 | if (in_array($GLOBALS['UGROUP_PROJECT_MEMBERS'], $dynamic_ugroups) && |
||
| 522 | in_array($GLOBALS['UGROUP_PROJECT_MEMBERS'], $permissions['TRACKER_ACCESS_SUBMITTER'])) |
||
| 523 | { |
||
| 524 | $sql = "SELECT a.artifact_id ". |
||
| 525 | $from." , user_group ug ". |
||
| 526 | $where. |
||
| 527 | " AND a.submitted_by = ug.user_id ". |
||
| 528 | " AND ug.group_id = ". db_ei($GLOBALS['group_id']) ." ". |
||
| 529 | ""; |
||
| 530 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 531 | } |
||
| 532 | //}}} |
||
| 533 | // {{{ project_admins |
||
| 534 | if (in_array($GLOBALS['UGROUP_PROJECT_ADMIN'], $dynamic_ugroups) && |
||
| 535 | in_array($GLOBALS['UGROUP_PROJECT_ADMIN'], $permissions['TRACKER_ACCESS_SUBMITTER'])) |
||
| 536 | { |
||
| 537 | $sql = "SELECT a.artifact_id ". |
||
| 538 | $from." , user_group ug ". |
||
| 539 | $where. |
||
| 540 | " AND a.submitted_by = ug.user_id ". |
||
| 541 | " AND ug.group_id = ". db_ei($GLOBALS['group_id']) ." ". |
||
| 542 | " AND ug.admin_flags = 'A' ". |
||
| 543 | ""; |
||
| 544 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 545 | } |
||
| 546 | //}}} |
||
| 547 | } |
||
| 548 | |||
| 549 | //Does the user member of at least one group which has ACCESS_ASSIGNEE ? |
||
| 550 | if (isset($permissions['TRACKER_ACCESS_ASSIGNEE']) && count(array_intersect($ugroups, $permissions['TRACKER_ACCESS_ASSIGNEE'])) > 0) { |
||
| 551 | |||
| 552 | //Get only once the field_id of assigned_to/multi_assigned_to |
||
| 553 | $field_dao = new ArtifactFieldDao(CodendiDataAccess::instance()); |
||
| 554 | $dar =& $field_dao->searchAssignedToFieldIdByArtifactTypeId($this->group_artifact_id); |
||
| 555 | $assigned_to = array(); |
||
| 556 | while ($row = $dar->getRow()) { |
||
| 557 | $assigned_to[] = $row['field_id']; |
||
| 558 | } |
||
| 559 | if (count($assigned_to) > 0) { |
||
| 560 | // {{{ The static ugroups |
||
| 561 | if (count(array_intersect($static_ugroups, $permissions['TRACKER_ACCESS_ASSIGNEE'])) > 0) { |
||
| 562 | $sql = "SELECT a.artifact_id ". |
||
| 563 | $from." , artifact_field_value afv, ugroup_user uu ". |
||
| 564 | $where. |
||
| 565 | " AND a.artifact_id = afv.artifact_id ". |
||
| 566 | " AND afv.field_id IN (". db_es(implode(', ', $assigned_to)) .") ". |
||
| 567 | " AND afv.valueInt = uu.user_id ". |
||
| 568 | " AND uu.ugroup_id IN (". db_es(implode(', ', $static_ugroups)) .") ". |
||
| 569 | ""; |
||
| 570 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 571 | } |
||
| 572 | // }}} |
||
| 573 | |||
| 574 | // {{{ tracker_admins |
||
| 575 | if (in_array($GLOBALS['UGROUP_TRACKER_ADMIN'], $dynamic_ugroups) && |
||
| 576 | in_array($GLOBALS['UGROUP_TRACKER_ADMIN'], $permissions['TRACKER_ACCESS_ASSIGNEE'])) |
||
| 577 | { |
||
| 578 | $sql = "SELECT a.artifact_id ". |
||
| 579 | $from." , artifact_field_value afv, artifact_perm p ". |
||
| 580 | $where. |
||
| 581 | " AND a.artifact_id = afv.artifact_id ". |
||
| 582 | " AND afv.field_id IN (". db_es(implode(', ', $assigned_to)) .") ". |
||
| 583 | " AND afv.valueInt = p.user_id ". |
||
| 584 | " AND p.group_artifact_id = ". db_ei($this->group_artifact_id) ." ". |
||
| 585 | " AND p.perm_level >= 2 ". |
||
| 586 | ""; |
||
| 587 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 588 | } |
||
| 589 | //}}} |
||
| 590 | // {{{ project_members |
||
| 591 | if (in_array($GLOBALS['UGROUP_PROJECT_MEMBERS'], $dynamic_ugroups) && |
||
| 592 | in_array($GLOBALS['UGROUP_PROJECT_MEMBERS'], $permissions['TRACKER_ACCESS_ASSIGNEE'])) |
||
| 593 | { |
||
| 594 | $sql = "SELECT a.artifact_id ". |
||
| 595 | $from." , artifact_field_value afv, user_group ug ". |
||
| 596 | $where. |
||
| 597 | " AND a.artifact_id = afv.artifact_id ". |
||
| 598 | " AND afv.field_id IN (". db_es(implode(', ', $assigned_to)) .") ". |
||
| 599 | " AND afv.valueInt = ug.user_id ". |
||
| 600 | " AND ug.group_id = ". db_ei($GLOBALS['group_id']) ." ". |
||
| 601 | ""; |
||
| 602 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 603 | } |
||
| 604 | //}}} |
||
| 605 | // {{{ project_admins |
||
| 606 | if (in_array($GLOBALS['UGROUP_PROJECT_ADMIN'], $dynamic_ugroups) && |
||
| 607 | in_array($GLOBALS['UGROUP_PROJECT_ADMIN'], $permissions['TRACKER_ACCESS_ASSIGNEE'])) |
||
| 608 | { |
||
| 609 | $sql = "SELECT a.artifact_id ". |
||
| 610 | $from." , artifact_field_value afv, user_group ug ". |
||
| 611 | $where. |
||
| 612 | " AND a.artifact_id = afv.artifact_id ". |
||
| 613 | " AND afv.field_id IN (". db_es(implode(', ', $assigned_to)) .") ". |
||
| 614 | " AND afv.valueInt = ug.user_id ". |
||
| 615 | " AND ug.group_id = ". db_ei($GLOBALS['group_id']) ." ". |
||
| 616 | " AND ug.admin_flags = 'A' ". |
||
| 617 | ""; |
||
| 618 | $aids = array_merge($aids, $this->_ExecuteQueryForSelectReportItems($sql)); |
||
| 619 | } |
||
| 620 | //}}} |
||
| 621 | } |
||
| 622 | } |
||
| 623 | } |
||
| 624 | $aids = array_unique($aids); |
||
| 625 | return count($aids); |
||
| 626 | } |
||
| 627 | |||
| 628 | function _ExecuteQueryForSelectReportItems($sql) { |
||
| 629 | $ret = array(); |
||
| 630 | $res = db_query($sql); |
||
| 631 | while ($arr = db_fetch_array($res)) { |
||
| 632 | $ret[] = $arr['artifact_id']; |
||
| 633 | } |
||
| 634 | return $ret; |
||
| 635 | } |
||
| 636 | |||
| 637 | /** |
||
| 638 | * Return all the fields list used for the report |
||
| 639 | * |
||
| 640 | * @return string |
||
| 641 | */ |
||
| 642 | function createQueryReport($prefs,$morder,$advsrch,$offset,$chunksz,$aids) { |
||
| 643 | |||
| 644 | $this->getResultQueryElements($prefs,$morder,$advsrch,$aids,$select,$from,$where,$order_by); |
||
| 645 | $limit =""; |
||
| 646 | // Final query |
||
| 647 | if ($offset != 0 || $chunksz != 0) { |
||
| 648 | // there is no limit only in case where offset==0 and chunksz==0, in any other case, there is a limit |
||
| 649 | $limit = " LIMIT ". db_ei($offset) .",". db_ei($chunksz) ; |
||
| 650 | } |
||
| 651 | |||
| 652 | //We need group by due to multi assign-to. However, the performances with big trackers are really bad. |
||
| 653 | $sql = $select." ".$from." ".$where." GROUP BY artifact_id ".$order_by.$limit; |
||
| 654 | //echo "<DBG> query=".$sql."<br>"; |
||
| 655 | |||
| 656 | return $sql; |
||
| 657 | |||
| 658 | } |
||
| 659 | |||
| 660 | /** |
||
| 661 | * Return if the value is ANY |
||
| 662 | * |
||
| 663 | * The ANY value is 0. The simple fact that |
||
| 664 | * ANY (0) is one of the value means it is Any even if there are |
||
| 665 | * other non zero values in the array |
||
| 666 | * |
||
| 667 | * @return boolean |
||
| 668 | */ |
||
| 669 | function isvarany($var) { |
||
| 682 | |||
| 683 | |||
| 684 | /** |
||
| 685 | * Return the value to find for a field, for the current query |
||
| 686 | * |
||
| 687 | * @param field: the field object |
||
| 688 | * @param prefs: field values array (HTTP GET variable) |
||
| 689 | * @param field_value: the field name |
||
| 690 | * @param advsrch: advance search or simple search |
||
| 691 | * @param notany: is true if the value of the field is not "Any" |
||
| 692 | * |
||
| 693 | * @return string |
||
| 694 | */ |
||
| 695 | function getValuesWhereClause($field,$prefs,$field_name,$advsrch,&$notany) { |
||
| 696 | $notany=true; |
||
| 697 | $where = ''; |
||
| 698 | |||
| 699 | //echo $field_name."->prefs[".$field->getName()."]=".$prefs[$field->getName()][0]."<br>"; |
||
| 700 | if (($field->isSelectBox()||$field->isMultiSelectBox()) && (isset($prefs[$field->getName()]) && !$this->isvarany($prefs[$field->getName()])) ) { |
||
| 701 | |||
| 702 | // Only select box criteria to where clause if argument is not ANY |
||
| 703 | return " AND ".$field_name." IN (". db_es(implode(",",$prefs[$field->getName()])) .") "; |
||
| 704 | |||
| 705 | } else if ( $field->isDateField() && ( |
||
| 706 | ((isset($prefs[$field->getName()]) && $prefs[$field->getName()][0]) || |
||
| 707 | (isset($prefs[$field->getName().'_end']) && $prefs[$field->getName().'_end'][0])))) { |
||
| 708 | // transform a date field into a unix time and use <, > or = |
||
| 709 | list($time,$ok) = util_date_to_unixtime($prefs[$field->getName()][0]); |
||
| 710 | |||
| 711 | if ($advsrch) { |
||
| 712 | list($time_end,$ok_end) = util_date_to_unixtime($prefs[$field->getName().'_end'][0]); |
||
|
|
|||
| 713 | if ($ok) { |
||
| 714 | list($year,$month,$day) = util_date_explode($prefs[$field->getName()][0]); |
||
| 715 | $time_after = mktime(0, 0, 0, $month, $day, $year); |
||
| 716 | $where .= " AND ".$field_name." >= ".$time_after; |
||
| 717 | } |
||
| 718 | |||
| 719 | if ($ok_end) { |
||
| 720 | list($year,$month,$day) = util_date_explode($prefs[$field->getName().'_end'][0]); |
||
| 721 | $time_before = mktime(23, 59, 59, $month, $day, $year); |
||
| 722 | $where .= " AND ". $field_name." <= ".$time_before; |
||
| 723 | } |
||
| 724 | |||
| 725 | |||
| 726 | } else { |
||
| 727 | |||
| 728 | if(isset($prefs[$field->getName()][1])) { |
||
| 729 | $operator = $prefs[$field->getName()][1]; |
||
| 730 | }else { |
||
| 731 | $operator = $prefs[$field->getName().'_op'][0]; |
||
| 732 | } |
||
| 733 | |||
| 734 | // '=' means that day between 00:00 and 23:59 |
||
| 735 | if ($operator == '=') { |
||
| 736 | list($year,$month,$day) = util_date_explode($prefs[$field->getName()][0]); |
||
| 737 | $time_end = mktime(23, 59, 59, $month, $day, $year); |
||
| 738 | $where = " AND ".$field_name." >= ".$time." AND ".$field_name." <= ".$time_end; |
||
| 739 | } else if ($operator == '>') { |
||
| 740 | list($year,$month,$day) = util_date_explode($prefs[$field->getName()][0]); |
||
| 741 | $time_after = mktime(0, 0, 0, $month, $day+1, $year); |
||
| 742 | $where = " AND ".$field_name." ".$operator."=".$time_after; |
||
| 743 | } else if ($operator == '<') { |
||
| 744 | list($year,$month,$day) = util_date_explode($prefs[$field->getName()][0]); |
||
| 745 | $time_before = mktime(23, 59, 59, $month, $day-1, $year); |
||
| 746 | $where = " AND ".$field_name." ".$operator."=".$time_before; |
||
| 747 | } |
||
| 748 | } |
||
| 749 | |||
| 750 | // Always exclude undefined dates (0) |
||
| 751 | $where .= " AND ".$field_name." <> 0 "; |
||
| 752 | |||
| 753 | return $where; |
||
| 754 | |||
| 755 | } else if ( ($field->isTextField() || $field->isTextArea()) |
||
| 756 | && isset($prefs[$field->getName()][0]) && $prefs[$field->getName()][0]) { |
||
| 757 | |||
| 758 | // It's a text field accept. Process INT or TEXT,VARCHAR fields differently |
||
| 759 | return " AND ".$field->buildMatchExpression($field_name,$prefs[$field->getName()][0]); |
||
| 760 | } |
||
| 761 | $notany = false; |
||
| 762 | } |
||
| 763 | |||
| 764 | /** |
||
| 765 | * Return the fields for the order by statement, for the current query |
||
| 766 | * |
||
| 767 | * @return array |
||
| 768 | */ |
||
| 769 | function getFieldsOrder($morder) { |
||
| 770 | |||
| 771 | global $art_field_fact; |
||
| 772 | |||
| 773 | $fields_order = array(); |
||
| 774 | |||
| 775 | $arr = explode(',',$morder); |
||
| 776 | while (list(,$attr) = each($arr)) { |
||
| 777 | $key = substr($attr,0,(strlen($attr)-1)); |
||
| 778 | if (isset($this->fields[$key]) && $this->fields[$key]->isUsed() && ('severity' == $key || $this->fields[$key]->isShowOnResult())) { |
||
| 779 | preg_match("/\s*([^<>]*)([<>]*)/", $attr,$match); |
||
| 780 | list(,$mattr,$mdir) = $match; |
||
| 781 | //echo "<br>DBG \$mattr=$mattr,\$mdir=$mdir"; |
||
| 782 | if ( ($mdir == '>') || (!isset($mdir)) ) { |
||
| 783 | $fields_order[$mattr] = "ASC"; |
||
| 784 | } else { |
||
| 785 | $fields_order[$mattr] = "DESC"; |
||
| 786 | } |
||
| 787 | } |
||
| 788 | } |
||
| 789 | |||
| 790 | return $fields_order; |
||
| 791 | |||
| 792 | } |
||
| 793 | |||
| 794 | /** |
||
| 795 | * Return the different elements for building the current query |
||
| 796 | * |
||
| 797 | * @param countonly: specifies whether the query is only used to count the number of |
||
| 798 | * queried artifacts. If we only want to count, we don't need to |
||
| 799 | * build a huge join for fields that are not determining the serach |
||
| 800 | * result |
||
| 801 | * @param aids: the artifact ids that have been calculated in a former select and that |
||
| 802 | * correspond to the query given in prefs. By using the aids we do not need |
||
| 803 | * to use the query constraints on the different artifact fields => lesser |
||
| 804 | * tables to JOIN |
||
| 805 | * @param select: the select value |
||
| 806 | * @param from: the from value |
||
| 807 | * @param where: the where value |
||
| 808 | * @param order_by: the order by value |
||
| 809 | * |
||
| 810 | * @return void |
||
| 811 | */ |
||
| 812 | function getQueryElements($prefs,$advsrch,&$from,&$where) { |
||
| 813 | global $art_field_fact; |
||
| 814 | // |
||
| 815 | // NOTICE |
||
| 816 | // |
||
| 817 | // We can't use left join because the performs are very bad. |
||
| 818 | // Take care: Big organisations (like FT) adore having many, many fields in their trackers |
||
| 819 | // So the restriction to this: all fields used in the query must have a value. |
||
| 820 | // That involves artifact creation or artifact admin (add a field) must create |
||
| 821 | // empty records with default values for fields which haven't a value (from the user). |
||
| 822 | // |
||
| 823 | /* The query must be something like this : |
||
| 824 | FROM artifact a |
||
| 825 | JOIN artifact_field_value v1 ON (v1.artifact_id=a.artifact_id) |
||
| 826 | JOIN artifact_field_value v2 ON (v2.artifact_id=a.artifact_id) |
||
| 827 | JOIN artifact_field_value v3 ON (v2.artifact_id=a.artifact_id) |
||
| 828 | JOIN user u3 ON (v3.valueInt = u3.user_id) |
||
| 829 | JOIN user u |
||
| 830 | WHERE a.group_artifact_id = 100 and |
||
| 831 | v1.field_id=101 and |
||
| 832 | v2.field_id=103 and |
||
| 833 | v3.field_id=104 and |
||
| 834 | a.submitted_by = u.user_id |
||
| 835 | |||
| 836 | */ |
||
| 837 | |||
| 838 | // Get the fields sorted by the result order |
||
| 839 | $fields = $this->getSortedFields(); |
||
| 840 | |||
| 841 | $count = 1; |
||
| 842 | $status_id_ok = 0; |
||
| 843 | $assigned_to_ok = 0; |
||
| 844 | $multi_assigned_to_ok = 0; |
||
| 845 | |||
| 846 | |||
| 847 | $from = "FROM artifact a"; |
||
| 848 | $where = "WHERE a.group_artifact_id = ". db_ei($this->group_artifact_id) ; |
||
| 849 | |||
| 850 | |||
| 851 | |||
| 852 | while (list($key,$field) = each($fields) ) { |
||
| 853 | |||
| 854 | //echo $field->getName()."-".$field->getID()."<br>"; |
||
| 855 | |||
| 856 | if ($field->isShowOnQuery()) { |
||
| 857 | // If the field is a standard field ie the value is stored directly into the artifact table (severity, artifact_id, ...) |
||
| 858 | if ( $field->isStandardField()) { |
||
| 859 | $where .= $this->getValuesWhereClause($field,$prefs,"a.".$field->getName(),$advsrch,$notany); |
||
| 860 | |||
| 861 | if ($field->getName() == "status_id") $status_id_ok = 1; |
||
| 862 | } else { |
||
| 863 | |||
| 864 | // The field value is stored into the artifact_field_value table |
||
| 865 | // So we need to add a new join |
||
| 866 | $where .= $this->getValuesWhereClause($field,$prefs,"v".$count.".".$field->getValueFieldName(),$advsrch,$notany); |
||
| 867 | |||
| 868 | if ($notany) { |
||
| 869 | $from .= " JOIN artifact_field_value v".$count." ON (v".$count.".artifact_id=a.artifact_id". |
||
| 870 | " and v".$count.".field_id=". db_ei($field->getID()) .")"; |
||
| 871 | |||
| 872 | $count++; |
||
| 873 | } |
||
| 874 | |||
| 875 | // special case for assigned_to/multi_assigned_to fields or status_id field that can also be set |
||
| 876 | // in prefs through My or Open link but which are not necessarily in the ShowOnQuery fields of this report |
||
| 877 | if ($field->getName() == "assigned_to") $assigned_to_ok = 1; |
||
| 878 | else if ($field->getName() == "multi_assigned_to") $multi_assigned_to_ok = 1; |
||
| 879 | } |
||
| 880 | } |
||
| 881 | } |
||
| 882 | |||
| 883 | if (isset($prefs['assigned_to']) && !$assigned_to_ok) { |
||
| 884 | $field = $art_field_fact->getFieldFromName('assigned_to'); |
||
| 885 | if ($field) { |
||
| 886 | $where .= $this->getValuesWhereClause($field,$prefs,"v".$count.".".$field->getValueFieldName(),$advsrch,$notany); |
||
| 887 | |||
| 888 | if ($notany) { |
||
| 889 | $from .= " JOIN artifact_field_value v".$count." ON (v".$count.".artifact_id=a.artifact_id". |
||
| 890 | " and v".$count.".field_id=". db_ei($field->getID()) .")"; |
||
| 891 | |||
| 892 | $count++; |
||
| 893 | } |
||
| 894 | } |
||
| 895 | } else if (isset($prefs['multi_assigned_to']) && !$multi_assigned_to_ok) { |
||
| 896 | $field = $art_field_fact->getFieldFromName('multi_assigned_to'); |
||
| 897 | if ($field) { |
||
| 898 | $where .= $this->getValuesWhereClause($field,$prefs,"v".$count.".".$field->getValueFieldName(),$advsrch,$notany); |
||
| 899 | |||
| 900 | if ($notany) { |
||
| 901 | $from .= " JOIN artifact_field_value v".$count." ON (v".$count.".artifact_id=a.artifact_id". |
||
| 902 | " and v".$count.".field_id=". db_ei($field->getID()) .")"; |
||
| 903 | |||
| 904 | $count++; |
||
| 905 | } |
||
| 906 | } |
||
| 907 | } |
||
| 908 | if (isset($prefs['status_id']) && !$status_id_ok) { |
||
| 909 | $field = $art_field_fact->getFieldFromName('status_id'); |
||
| 910 | if ($field) { |
||
| 911 | $where .= $this->getValuesWhereClause($field,$prefs,"a.".$field->getName(),$advsrch,$notany); |
||
| 912 | } |
||
| 913 | } |
||
| 914 | } |
||
| 915 | |||
| 916 | |||
| 917 | /** |
||
| 918 | * Return the different elements for building the current query |
||
| 919 | * |
||
| 920 | * @param aids: the artifact ids that have been calculated in a former select and that |
||
| 921 | * correspond to the query given in prefs. By using the aids we do not need |
||
| 922 | * to use the query constraints on the different artifact fields => lesser |
||
| 923 | * tables to JOIN |
||
| 924 | * @param select: the select value |
||
| 925 | * @param from: the from value |
||
| 926 | * @param where: the where value |
||
| 927 | * @param order_by: the order by value |
||
| 928 | * |
||
| 929 | * @return void |
||
| 930 | */ |
||
| 931 | function getResultQueryElements($prefs,$morder,$advsrch,$aids=false,&$select,&$from,&$where,&$order_by) { |
||
| 1113 | |||
| 1114 | |||
| 1115 | /** |
||
| 1116 | * Return the query result in a multi array |
||
| 1117 | * For SelectBox or MultiBox, we retreive the label value |
||
| 1118 | * |
||
| 1119 | * @param query: the SQL query |
||
| 1120 | * |
||
| 1121 | * @return array |
||
| 1122 | */ |
||
| 1123 | function getResultQueryReport($query) { |
||
| 1124 | |||
| 1125 | $fields_sb = $this->getSingleMultiBoxFields(); |
||
| 1126 | |||
| 1127 | $result = db_query($query); |
||
| 1128 | $res = array(); |
||
| 1129 | for($i=0;$i<db_numrows($result);$i++) { |
||
| 1130 | $res[$i] = db_fetch_array($result); |
||
| 1131 | if ( $res[$i]['artifact_id'] ) { |
||
| 1132 | reset($fields_sb); |
||
| 1133 | while (list($field_name,$field) = each($fields_sb)) { |
||
| 1134 | $values = array(); |
||
| 1135 | if ( $field->isStandardField() ) { |
||
| 1136 | $values[] = $res[$i][$field_name]; |
||
| 1137 | } else { |
||
| 1138 | $values = $field->getValues($res[$i]['artifact_id']); |
||
| 1139 | } |
||
| 1140 | |||
| 1141 | $label_values = $field->getLabelValues($this->group_artifact_id,$values); |
||
| 1142 | $res[$i][$field_name] = join(", ",$label_values); |
||
| 1143 | } |
||
| 1144 | |||
| 1145 | } |
||
| 1146 | } |
||
| 1147 | |||
| 1148 | return $res; |
||
| 1149 | } |
||
| 1150 | |||
| 1151 | // getters for the ArtifactReport class |
||
| 1152 | |||
| 1153 | /** |
||
| 1154 | * getID - get this ArtifactReportID. |
||
| 1155 | * |
||
| 1156 | * @return int The report_id #. |
||
| 1157 | */ |
||
| 1158 | |||
| 1159 | function getID() { |
||
| 1162 | |||
| 1163 | /** |
||
| 1164 | * getArtifactTypeID - get this ArtifactTypeID. |
||
| 1165 | * |
||
| 1166 | * @return int The group_artifact_id #. |
||
| 1167 | */ |
||
| 1168 | |||
| 1169 | function getArtifactTypeID() { |
||
| 1172 | |||
| 1173 | /** |
||
| 1174 | * getName - get Name of this report. |
||
| 1175 | * |
||
| 1176 | * @return string The report name. |
||
| 1177 | */ |
||
| 1178 | |||
| 1179 | function getName() { |
||
| 1182 | |||
| 1183 | /** |
||
| 1184 | * getDescription - get Description of this report. |
||
| 1185 | * |
||
| 1186 | * @return string The report description. |
||
| 1187 | */ |
||
| 1188 | function getDescription() { |
||
| 1191 | |||
| 1192 | /** |
||
| 1193 | * getScope - get Scope of this report. |
||
| 1194 | * |
||
| 1195 | * @return string The report scope ('S': system, 'P': project). |
||
| 1196 | */ |
||
| 1197 | function getScope() { |
||
| 1200 | |||
| 1201 | /** |
||
| 1202 | * is_default - get is_default value |
||
| 1203 | * |
||
| 1204 | * @return string The default report value. |
||
| 1205 | */ |
||
| 1206 | function isDefault() { |
||
| 1209 | } |
||
| 1210 | |||
| 1211 | ?> |
||
| 1212 |
This checks looks for assignemnts to variables using the
list(...)function, where not all assigned variables are subsequently used.Consider the following code example.
Only the variables
$aand$care used. There was no need to assign$b.Instead, the list call could have been.