Complex classes like Tracker_Report 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 Tracker_Report, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 26 | class Tracker_Report extends Error implements Tracker_Dispatchable_Interface { |
||
| 27 | |||
| 28 | const ACTION_SAVE = 'report-save'; |
||
| 29 | const ACTION_SAVEAS = 'report-saveas'; |
||
| 30 | const ACTION_REPLACE = 'report-replace'; |
||
| 31 | const ACTION_DELETE = 'report-delete'; |
||
| 32 | const ACTION_SCOPE = 'report-scope'; |
||
| 33 | const ACTION_DEFAULT = 'report-default'; |
||
| 34 | const ACTION_CLEANSESSION = 'clean-session'; |
||
| 35 | const TYPE_CRITERIA = 'criteria'; |
||
| 36 | const TYPE_TABLE = 'table'; |
||
| 37 | |||
| 38 | public $id; |
||
| 39 | public $name; |
||
| 40 | public $description; |
||
| 41 | public $current_renderer_id; |
||
| 42 | public $parent_report_id; |
||
| 43 | public $user_id; |
||
| 44 | public $group_id; |
||
| 45 | public $is_default; |
||
| 46 | public $tracker_id; |
||
| 47 | public $is_query_displayed; |
||
| 48 | public $updated_by; |
||
| 49 | public $updated_at; |
||
| 50 | |||
| 51 | public $renderers; |
||
| 52 | public $criteria; |
||
| 53 | |||
| 54 | /** |
||
| 55 | * Constructor |
||
| 56 | * |
||
| 57 | * @param int $id The id of the report |
||
| 58 | * @param string $name The name of the report |
||
| 59 | * @param string $description The description of the report |
||
| 60 | * @param int $current_renderer_id The current Renderer id to display |
||
| 61 | * @param int $parent_report_id The parent report if this report is temporary (null else) |
||
| 62 | * @param int $user_id The owner of the report (null if scope = project) |
||
| 63 | * @param bool $is_default true if the report is the default one |
||
| 64 | * @param int $tracker_id The id of the tracker to which this Tracker_Report is associated. |
||
| 65 | */ |
||
| 66 | function __construct($id, $name, $description, $current_renderer_id, $parent_report_id, $user_id, $is_default, $tracker_id, $is_query_displayed, $updated_by, $updated_at) { |
||
| 67 | parent::__construct(); |
||
| 68 | $this->id = $id; |
||
| 69 | $this->name = $name; |
||
| 70 | $this->description = $description; |
||
| 71 | $this->current_renderer_id = $current_renderer_id; |
||
| 72 | $this->parent_report_id = $parent_report_id; |
||
| 73 | $this->user_id = $user_id; |
||
| 74 | $this->is_default = $is_default; |
||
| 75 | $this->tracker_id = $tracker_id; |
||
| 76 | $this->is_query_displayed = $is_query_displayed; |
||
| 77 | $this->updated_by = $updated_by; |
||
| 78 | $this->updated_at = $updated_at; |
||
| 79 | } |
||
| 80 | |||
| 81 | public function setProjectId($id) { |
||
| 84 | |||
| 85 | protected function getProjectId() { |
||
| 86 | if (!$this->group_id) { |
||
| 87 | $this->group_id = $this->tracker->getGroupId(); |
||
| 88 | } |
||
| 89 | return $this->group_id; |
||
| 90 | } |
||
| 91 | |||
| 92 | public function registerInSession() { |
||
| 95 | |||
| 96 | protected function getCriteriaDao() { |
||
| 99 | |||
| 100 | /** @return Tracker_Report_Criteria[] */ |
||
| 101 | public function getCriteria() { |
||
| 102 | $session_criteria = null; |
||
| 103 | if (isset($this->report_session)) { |
||
| 104 | $session_criteria = &$this->report_session->getCriteria(); |
||
| 105 | } |
||
| 106 | |||
| 107 | $this->criteria = array(); |
||
| 108 | $ff = $this->getFormElementFactory(); |
||
| 109 | //there is previously stored |
||
| 110 | if ($session_criteria) { |
||
| 111 | $rank = 0; |
||
| 112 | foreach ($session_criteria as $key => $value) { |
||
| 113 | if ($value['is_removed'] == 0) { |
||
| 114 | $is_advanced = isset($value['is_advanced']) ? $value['is_advanced'] : 0 ; |
||
| 115 | if ($formElement = $ff->getUsedFormElementById($key)) { |
||
| 116 | if ($formElement->userCanRead()) { |
||
| 117 | $formElement->setCriteriaValue( (!empty($value['value']) ? $value['value']: ''), $this->id ) ; |
||
| 118 | $this->criteria[$key] = new Tracker_Report_Criteria( |
||
| 119 | 0, |
||
| 120 | $this, |
||
| 121 | $formElement, |
||
| 122 | $rank, |
||
| 123 | $is_advanced |
||
| 124 | ); |
||
| 125 | $rank++; |
||
| 126 | } |
||
| 127 | } |
||
| 128 | } |
||
| 129 | } |
||
| 130 | } else { |
||
| 131 | //retrieve data from database |
||
| 132 | foreach($this->getCriteriaDao()->searchByReportId($this->id) as $row) { |
||
|
|
|||
| 133 | if ($formElement = $ff->getFormElementFieldById($row['field_id'])) { |
||
| 134 | if ($formElement->userCanRead()) { |
||
| 135 | $this->criteria[$row['field_id']] = new Tracker_Report_Criteria( |
||
| 136 | $row['id'], |
||
| 137 | $this, |
||
| 138 | $formElement, |
||
| 139 | $row['rank'], |
||
| 140 | $row['is_advanced'] |
||
| 141 | ); |
||
| 142 | $criterion_value = $formElement->getCriteriaValue($this->criteria[$row['field_id']]); |
||
| 143 | $criterion_opts['is_advanced'] = $row['is_advanced']; |
||
| 144 | if (isset($this->report_session)) { |
||
| 145 | $this->report_session->storeCriterion($row['field_id'], $criterion_value, $criterion_opts ); |
||
| 146 | } |
||
| 147 | } |
||
| 148 | } |
||
| 149 | } |
||
| 150 | } |
||
| 151 | return $this->criteria; |
||
| 152 | } |
||
| 153 | |||
| 154 | public function getCriteriaFromDb() { |
||
| 173 | |||
| 174 | public function getFormElementFactory() { |
||
| 177 | /** |
||
| 178 | * Sets or adds a criterion to the global report search criteria list |
||
| 179 | * @param integer $field_id criterion id to be added or set |
||
| 180 | * @return Tracker_Report_Criteria |
||
| 181 | * @TODO refactor : must be renamed after addCriterion, and return the current criterion |
||
| 182 | */ |
||
| 183 | protected function setCriteria($field_id) { |
||
| 184 | $ff = $this->getFormElementFactory(); |
||
| 185 | $formElement = $ff->getFormElementById($field_id); |
||
| 186 | $this->criteria[$field_id] = new Tracker_Report_Criteria( |
||
| 187 | 0, |
||
| 188 | $this, |
||
| 189 | $formElement, |
||
| 190 | 0, |
||
| 191 | 0 |
||
| 192 | ); |
||
| 193 | return $this->criteria[$field_id]; |
||
| 194 | } |
||
| 195 | |||
| 196 | protected $current_user; |
||
| 197 | protected function getCurrentUser() { |
||
| 198 | if (!$this->current_user) { |
||
| 199 | $this->current_user = UserManager::instance()->getCurrentUser(); |
||
| 200 | } |
||
| 201 | return $this->current_user; |
||
| 202 | } |
||
| 203 | |||
| 204 | protected $permissions_manager; |
||
| 205 | private function getPermissionsManager() { |
||
| 206 | if (!$this->permissions_manager) { |
||
| 207 | $this->permissions_manager = PermissionsManager::instance(); |
||
| 208 | } |
||
| 209 | return $this->permissions_manager; |
||
| 210 | } |
||
| 211 | |||
| 212 | protected $matching_ids; |
||
| 213 | public function getMatchingIds($request = null, $use_data_from_db = false) { |
||
| 214 | if (!$this->matching_ids) { |
||
| 215 | $user = $this->getCurrentUser(); |
||
| 216 | if ($use_data_from_db) { |
||
| 217 | $criteria = $this->getCriteriaFromDb(); |
||
| 218 | } else { |
||
| 219 | $criteria = $this->getCriteria(); |
||
| 220 | } |
||
| 221 | $this->matching_ids = $this->getMatchingIdsInDb($this->getDao(), $this->getPermissionsManager(), $this->getTracker(), $user, $criteria); |
||
| 222 | |||
| 223 | $additional_criteria = $this->getAdditionalCriteria(); |
||
| 224 | $result = array(); |
||
| 225 | $search_performed = false; |
||
| 226 | EventManager::instance()->processEvent( |
||
| 227 | TRACKER_EVENT_REPORT_PROCESS_ADDITIONAL_QUERY, |
||
| 228 | array( |
||
| 229 | 'request' => $request, |
||
| 230 | 'result' => &$result, |
||
| 231 | 'search_performed' => &$search_performed, |
||
| 232 | 'tracker' => $this->getTracker(), |
||
| 233 | 'additional_criteria' => $additional_criteria, |
||
| 234 | 'user' => $user, |
||
| 235 | 'form_element_factory' => $this->getFormElementFactory() |
||
| 236 | ) |
||
| 237 | ); |
||
| 238 | if ($search_performed) { |
||
| 239 | $joiner = new Tracker_Report_ResultJoiner(); |
||
| 240 | |||
| 241 | $this->matching_ids = $this->implodeMatchingIds( |
||
| 242 | $joiner->joinResults( |
||
| 243 | $this->getLastChangesetIdByArtifactId($this->matching_ids), |
||
| 244 | $result |
||
| 245 | ) |
||
| 246 | ); |
||
| 247 | } |
||
| 248 | } |
||
| 249 | |||
| 250 | return $this->matching_ids; |
||
| 251 | } |
||
| 252 | |||
| 253 | /** |
||
| 254 | * Given the output of getMatchingIds() which returns an array containing 'artifacts ids' and 'Last changeset ids' |
||
| 255 | * as two strings with comma separated values, this method would format such output to an array with artifactIds in keys |
||
| 256 | * and last changeset ids in values. |
||
| 257 | * @see Tracker_Report::getMatchingIds() for usage |
||
| 258 | * |
||
| 259 | * @return Array |
||
| 260 | */ |
||
| 261 | private function getLastChangesetIdByArtifactId($matching_ids) { |
||
| 262 | $artifact_ids = explode(',', $matching_ids['id']); |
||
| 263 | $last_changeset_ids = explode(',', $matching_ids['last_changeset_id']); |
||
| 264 | |||
| 265 | $formatted_matching_ids = array(); |
||
| 266 | foreach ($artifact_ids as $key => $artifactId) { |
||
| 267 | $formatted_matching_ids[$artifactId] = $last_changeset_ids[$key]; |
||
| 268 | } |
||
| 269 | return $formatted_matching_ids; |
||
| 270 | } |
||
| 271 | |||
| 272 | /** |
||
| 273 | * This method is the opposite of getLastChangesetIdByArtifactId(). |
||
| 274 | * Given an array with artifactIds in keys and lastChangesetIds on values it would return and array with two elements of type string |
||
| 275 | * the first contains comma separated "artifactIds" and the second contains comma separated "lastChangesetIds". |
||
| 276 | * @see Tracker_Report::getMatchingIds() for usage |
||
| 277 | * |
||
| 278 | * @param Array $formattedMatchingIds Matching Id's that will get converted in that format |
||
| 279 | * |
||
| 280 | * @return Array |
||
| 281 | */ |
||
| 282 | private function implodeMatchingIds($formattedMatchingIds) { |
||
| 297 | |||
| 298 | protected function getMatchingIdsInDb(DataAccessObject $dao, PermissionsManager $permissionManager, Tracker $tracker, PFUser $user, array $criteria) { |
||
| 299 | $dump_criteria = array(); |
||
| 300 | foreach ($criteria as $c) { |
||
| 301 | $dump_criteria[$c->field->getName()] = $c->field->getCriteriaValue($c); |
||
| 302 | } |
||
| 303 | $dao->logStart(__METHOD__, json_encode(array( |
||
| 304 | 'user' => $user->getUserName(), |
||
| 305 | 'project' => $tracker->getGroupId(), |
||
| 306 | 'query' => $dump_criteria, |
||
| 307 | 'trackers' => array($tracker->getId()), |
||
| 308 | ))); |
||
| 309 | |||
| 310 | $matching_ids = array(); |
||
| 311 | |||
| 312 | $group_id = $tracker->getGroupId(); |
||
| 313 | $permissions = $permissionManager->getPermissionsAndUgroupsByObjectid($tracker->getId()); |
||
| 314 | $contributor_field = $tracker->getContributorField(); |
||
| 315 | $contributor_field_id = $contributor_field ? $contributor_field->getId() : null; |
||
| 316 | |||
| 317 | $additional_from = array(); |
||
| 318 | $additional_where = array(); |
||
| 319 | foreach($criteria as $c) { |
||
| 320 | if ($f = $c->getFrom()) { |
||
| 321 | $additional_from[] = $f; |
||
| 322 | } |
||
| 323 | |||
| 324 | if ($w = $c->getWhere()) { |
||
| 325 | $additional_where[] = $w; |
||
| 326 | } |
||
| 327 | } |
||
| 328 | $matching_ids['id'] = ''; |
||
| 329 | $matching_ids['last_changeset_id'] = ''; |
||
| 330 | $matching_ids_result = $dao->searchMatchingIds($group_id, $tracker->getId(), $additional_from, $additional_where, $user, $permissions, $contributor_field_id); |
||
| 331 | if ($matching_ids_result) { |
||
| 332 | $matching_ids = $matching_ids_result->getRow(); |
||
| 333 | if ($matching_ids) { |
||
| 334 | if (substr($matching_ids['id'], -1) === ',') { |
||
| 335 | $matching_ids['id'] = substr($matching_ids['id'], 0, -1); |
||
| 336 | } |
||
| 337 | if (substr($matching_ids['last_changeset_id'], -1) === ',') { |
||
| 338 | $matching_ids['last_changeset_id'] = substr($matching_ids['last_changeset_id'], 0, -1); |
||
| 339 | } |
||
| 340 | } |
||
| 341 | } |
||
| 342 | |||
| 343 | $nb_matching = $matching_ids['id'] ? substr_count($matching_ids['id'], ',') + 1 : 0; |
||
| 344 | $dao->logEnd(__METHOD__, $nb_matching); |
||
| 345 | |||
| 346 | return $matching_ids; |
||
| 347 | } |
||
| 348 | |||
| 349 | /** |
||
| 350 | * @return boolean true if the report has been modified since the last checkout |
||
| 351 | */ |
||
| 352 | public function isObsolete() { |
||
| 355 | |||
| 356 | /** |
||
| 357 | * @return string html the user who has modified the report. Or false if the report has not been modified |
||
| 358 | */ |
||
| 359 | public function getLastUpdaterUserName() { |
||
| 360 | if ($this->isObsolete()) { |
||
| 361 | return UserHelper::instance()->getLinkOnUserFromUserId($this->updated_by); |
||
| 362 | } |
||
| 363 | return ''; |
||
| 364 | } |
||
| 365 | |||
| 366 | protected function displayHeader(Tracker_IFetchTrackerSwitcher $layout, $request, $current_user, $report_can_be_modified) { |
||
| 367 | $header_builder = new Tracker_Report_HeaderRenderer( |
||
| 368 | Tracker_ReportFactory::instance(), |
||
| 369 | Codendi_HTMLPurifier::instance(), |
||
| 370 | $this->getTemplateRenderer() |
||
| 371 | ); |
||
| 372 | $header_builder->displayHeader($layout, $request, $current_user, $this, $report_can_be_modified); |
||
| 373 | } |
||
| 374 | |||
| 375 | public function nbPublicReport($reports) { |
||
| 376 | $i = 0; |
||
| 377 | foreach ($reports as $report) { |
||
| 378 | if ($report->user_id == null) { |
||
| 379 | $i++; |
||
| 380 | } |
||
| 381 | } |
||
| 382 | return $i; |
||
| 383 | } |
||
| 384 | |||
| 385 | public function fetchDisplayQuery(array $criteria, array $additional_criteria, $report_can_be_modified, PFUser $current_user) { |
||
| 386 | $hp = Codendi_HTMLPurifier::instance(); |
||
| 387 | |||
| 388 | $html = ''; |
||
| 389 | $html .= '<div id="tracker_report_query" data-report-id="'.$this->id.'">'; |
||
| 390 | $html .= '<form action="" method="POST" id="tracker_report_query_form">'; |
||
| 391 | $html .= '<input type="hidden" name="report" value="' . $this->id . '" />'; |
||
| 392 | $id = 'tracker_report_query_' . $this->id; |
||
| 393 | $html .= '<h4 class="backlog-planning-search-title ' . Toggler::getClassname($id, $this->is_query_displayed ? true : false) . '" id="' . $id . '">'; |
||
| 394 | |||
| 395 | // Query title |
||
| 396 | $html .= $GLOBALS['Language']->getText('plugin_tracker_report', 'search').'</h4>'; |
||
| 397 | $used = array(); |
||
| 398 | $criteria_fetched = array(); |
||
| 399 | foreach ($criteria as $criterion) { |
||
| 400 | if ($criterion->field->isUsed()) { |
||
| 401 | $li = '<li id="tracker_report_crit_' . $criterion->field->getId() . '">'; |
||
| 402 | if ($current_user->isAnonymous()) { |
||
| 403 | $li .= $criterion->fetchWithoutExpandFunctionnality(); |
||
| 404 | } else { |
||
| 405 | $li .= $criterion->fetch(); |
||
| 406 | } |
||
| 407 | $li .= '</li>'; |
||
| 408 | $criteria_fetched[] = $li; |
||
| 409 | $used[$criterion->field->getId()] = $criterion->field; |
||
| 410 | } |
||
| 411 | } |
||
| 412 | if ($report_can_be_modified && ! $current_user->isAnonymous()) { |
||
| 413 | $html .= '<div class="pull-right">'; |
||
| 414 | $html .= $this->getAddCriteriaDropdown($used); |
||
| 415 | $html .= '</div>'; |
||
| 416 | } |
||
| 417 | |||
| 418 | $array_of_html_criteria = array(); |
||
| 419 | EventManager::instance()->processEvent( |
||
| 420 | TRACKER_EVENT_REPORT_DISPLAY_ADDITIONAL_CRITERIA, |
||
| 421 | array( |
||
| 422 | 'array_of_html_criteria' => &$array_of_html_criteria, |
||
| 423 | 'tracker' => $this->getTracker(), |
||
| 424 | 'additional_criteria' => $additional_criteria, |
||
| 425 | 'user' => $current_user, |
||
| 426 | ) |
||
| 427 | ); |
||
| 428 | foreach ($array_of_html_criteria as $additional_criteria) { |
||
| 429 | $criteria_fetched[] = '<li>'. $additional_criteria .'</li>'; |
||
| 430 | } |
||
| 431 | $html .= '<ul id="tracker_query">' . implode('', $criteria_fetched).'</ul>'; |
||
| 432 | |||
| 433 | $html .= '<div align="center">'; |
||
| 434 | $html .= '<button type="submit" name="tracker_query_submit" class="btn btn-primary">'; |
||
| 435 | $html .= '<i class="icon-search"></i> '; |
||
| 436 | $html .= $GLOBALS['Language']->getText('global', 'btn_search'); |
||
| 437 | $html .= '</button>'; |
||
| 438 | $html .= '</div>'; |
||
| 439 | $html .= '</form>'; |
||
| 440 | $html .= '</div>'; |
||
| 441 | return $html; |
||
| 442 | } |
||
| 443 | |||
| 444 | private function getAddCriteriaDropdown($used) { |
||
| 445 | $add_criteria_presenter = new Templating_Presenter_ButtonDropdownsMini( |
||
| 446 | 'tracker_report_add_criteria_dropdown', |
||
| 447 | $GLOBALS['Language']->getText('plugin_tracker_report', 'toggle_criteria'), |
||
| 448 | $this->getFieldsAsDropdownOptions('tracker_report_add_criterion', $used, self::TYPE_CRITERIA) |
||
| 449 | ); |
||
| 450 | $add_criteria_presenter->setIcon('icon-eye-close'); |
||
| 451 | |||
| 452 | return $this->getTemplateRenderer()->renderToString('button_dropdowns', $add_criteria_presenter); |
||
| 453 | } |
||
| 454 | |||
| 455 | public function getFieldsAsDropdownOptions($id_prefix, array $used, $dropdown_type) { |
||
| 456 | $fields_for_criteria = array(); |
||
| 457 | $fields_for_sort = array(); |
||
| 458 | |||
| 459 | foreach($this->getFormElementFactory()->getFields($this->getTracker()) as $field) { |
||
| 460 | if ($dropdown_type === self::TYPE_CRITERIA && ! $field->canBeUsedAsReportCriterion()) { |
||
| 461 | continue; |
||
| 462 | } |
||
| 463 | |||
| 464 | if ($field->userCanRead() && $field->isUsed()) { |
||
| 465 | $fields_for_criteria[$field->getId()] = $field; |
||
| 466 | $fields_for_sort[$field->getId()] = strtolower($field->getLabel()); |
||
| 467 | } |
||
| 468 | } |
||
| 469 | asort($fields_for_sort); |
||
| 470 | $criteria_options = array(); |
||
| 471 | foreach ($fields_for_sort as $id => $nop) { |
||
| 472 | $option = new Templating_Presenter_ButtonDropdownsOption( |
||
| 473 | $id_prefix.'_'.$id, |
||
| 474 | $fields_for_criteria[$id]->getLabel(), |
||
| 475 | isset($used[$id]), |
||
| 476 | '#' |
||
| 477 | ); |
||
| 478 | $option->setLiParameters( |
||
| 479 | array( |
||
| 480 | 'data-field-id' => $id, |
||
| 481 | 'data-field-is-used' => intval(isset($used[$id])), |
||
| 482 | ) |
||
| 483 | ); |
||
| 484 | $criteria_options[] = $option; |
||
| 485 | } |
||
| 486 | return $criteria_options; |
||
| 487 | } |
||
| 488 | |||
| 489 | public function getTemplateRenderer() { |
||
| 490 | return TemplateRendererFactory::build()->getRenderer( |
||
| 491 | array( |
||
| 492 | TRACKER_TEMPLATE_DIR.'/report', |
||
| 493 | ForgeConfig::get('codendi_dir').'/src/templates/common' |
||
| 494 | ) |
||
| 495 | ); |
||
| 496 | } |
||
| 497 | |||
| 498 | public function display(Tracker_IDisplayTrackerLayout $layout, $request, $current_user) { |
||
| 670 | |||
| 671 | public function getRenderers() { |
||
| 674 | |||
| 675 | protected function orderRenderersByRank($renderers) { |
||
| 676 | $array_rank = array(); |
||
| 677 | foreach($renderers as $field_id => $properties) { |
||
| 678 | $array_rank[$field_id] = $properties->rank; |
||
| 679 | } |
||
| 680 | asort($array_rank); |
||
| 681 | $renderers_sort = array(); |
||
| 682 | foreach ($array_rank as $id => $rank) { |
||
| 683 | $renderers_sort[$id] = $renderers[$id]; |
||
| 684 | } |
||
| 685 | return $renderers_sort; |
||
| 686 | } |
||
| 687 | |||
| 688 | protected function getRendererFactory() { |
||
| 691 | |||
| 692 | protected function _fetchAddCriteria($used) { |
||
| 709 | |||
| 710 | /** |
||
| 711 | * Say if the report is public |
||
| 712 | * |
||
| 713 | * @return bool |
||
| 714 | */ |
||
| 715 | public function isPublic() { |
||
| 718 | |||
| 719 | /** |
||
| 720 | * Only owners of a report can update it. |
||
| 721 | * owner = report->user_id |
||
| 722 | * or if null, owner = tracker admin or site admins |
||
| 723 | * @param PFUser $user the user who wants to update the report |
||
| 724 | * @return boolean |
||
| 725 | */ |
||
| 726 | public function userCanUpdate($user) { |
||
| 738 | |||
| 739 | private function isBelongingToATracker() { |
||
| 742 | |||
| 743 | protected $tracker; |
||
| 744 | public function getTracker() { |
||
| 745 | if (!$this->tracker) { |
||
| 746 | $this->tracker = TrackerFactory::instance()->getTrackerById($this->tracker_id); |
||
| 747 | } |
||
| 748 | return $this->tracker; |
||
| 749 | } |
||
| 750 | |||
| 751 | public function setTracker(Tracker $tracker) { |
||
| 755 | |||
| 756 | /** |
||
| 757 | * hide or show the criteria |
||
| 758 | */ |
||
| 759 | public function toggleQueryDisplay() { |
||
| 763 | |||
| 764 | /** |
||
| 765 | * Remove a formElement from criteria |
||
| 766 | * @param int $formElement_id the formElement used for the criteria |
||
| 767 | */ |
||
| 768 | public function removeCriteria($formElement_id) { |
||
| 769 | $criteria = $this->getCriteria(); |
||
| 770 | if (isset($criteria[$formElement_id])) { |
||
| 771 | if ($this->getCriteriaDao()->delete($this->id, $formElement_id)) { |
||
| 772 | $criteria[$formElement_id]->delete(); |
||
| 773 | unset($criteria[$formElement_id]); |
||
| 774 | } |
||
| 775 | } |
||
| 776 | return $this; |
||
| 777 | } |
||
| 778 | |||
| 779 | /** |
||
| 780 | * Add a criteria |
||
| 781 | * |
||
| 782 | * @param Tracker_Report_Criteria the formElement used for the criteria |
||
| 783 | * |
||
| 784 | * @return int the id of the new criteria |
||
| 785 | */ |
||
| 786 | public function addCriteria( Tracker_Report_Criteria $criteria ) { |
||
| 790 | |||
| 791 | public function deleteAllCriteria() { |
||
| 794 | |||
| 795 | /** |
||
| 796 | * Toggle the state 'is_advanced' of a criteria |
||
| 797 | * @param int $formElement_id the formElement used for the criteria |
||
| 798 | */ |
||
| 799 | public function toggleAdvancedCriterion($formElement_id) { |
||
| 800 | $advanced = 1; |
||
| 801 | $session_criterion = $this->report_session->getCriterion($formElement_id); |
||
| 802 | if ( !empty($session_criterion['is_advanced']) ) { |
||
| 803 | $advanced = 0; |
||
| 804 | } |
||
| 805 | $this->report_session->updateCriterion($formElement_id, '', array('is_advanced'=>$advanced)); |
||
| 806 | return $this; |
||
| 807 | } |
||
| 808 | |||
| 809 | /** |
||
| 810 | * Store the criteria value |
||
| 811 | * NOTICE : if a criterion does not exist it is not created |
||
| 812 | * @param array $criteria_values |
||
| 813 | */ |
||
| 814 | public function updateCriteriaValues($criteria_values) { |
||
| 825 | |||
| 826 | public function updateAdditionalCriteriaValues($additional_criteria_values) { |
||
| 827 | foreach($additional_criteria_values as $key => $new_value) { |
||
| 828 | $additional_criterion = new Tracker_Report_AdditionalCriterion($key, $new_value); |
||
| 829 | $this->report_session->storeAdditionalCriterion($additional_criterion); |
||
| 830 | } |
||
| 831 | } |
||
| 832 | |||
| 833 | /** |
||
| 834 | * Process the request for the specified renderer |
||
| 835 | * @param int $renderer_id |
||
| 836 | * @param Request $request |
||
| 837 | * @return ReportRenderer |
||
| 838 | */ |
||
| 839 | public function processRendererRequest($renderer_id, Tracker_IDisplayTrackerLayout $layout, $request, $current_user, $store_in_session = true) { |
||
| 840 | $rrf = Tracker_Report_RendererFactory::instance(); |
||
| 841 | if ($renderer = $rrf->getReportRendererByReportAndId($this, $renderer_id, $store_in_session)) { |
||
| 842 | $renderer->process($layout, $request, $current_user); |
||
| 843 | } |
||
| 844 | } |
||
| 845 | |||
| 846 | /** |
||
| 847 | * Delete a renderer from the report |
||
| 848 | * @param mixed the renderer to remove (Tracker_Report_Renderer or the id as int) |
||
| 849 | */ |
||
| 850 | public function deleteRenderer($renderer) { |
||
| 851 | $rrf = Tracker_Report_RendererFactory::instance(); |
||
| 852 | if (!is_a($renderer, 'Tracker_Report_Renderer')) { |
||
| 853 | $renderer_id = (int)$renderer; |
||
| 854 | $renderer = $rrf->getReportRendererByReportAndId($this, $renderer_id); |
||
| 855 | } |
||
| 856 | if ($renderer) { |
||
| 857 | $renderer_id = $renderer->id; |
||
| 858 | $renderer->delete(); |
||
| 859 | $rrf->delete($renderer_id); |
||
| 860 | } |
||
| 861 | return $this; |
||
| 862 | } |
||
| 863 | |||
| 864 | /** |
||
| 865 | * Move a renderer at a specific position |
||
| 866 | * |
||
| 867 | * @param mixed $renderer the renderer to remove (Tracker_Report_Renderer or the id as int) |
||
| 868 | * @param int $position the new position |
||
| 869 | */ |
||
| 870 | public function moveRenderer($renderer, $position) { |
||
| 871 | $rrf = Tracker_Report_RendererFactory::instance(); |
||
| 872 | if (!is_a($renderer, 'Tracker_Report_Renderer')) { |
||
| 873 | $renderer_id = (int)$renderer; |
||
| 874 | $renderer = $rrf->getReportRendererByReportAndId($this, $renderer_id); |
||
| 875 | } |
||
| 876 | if ($renderer) { |
||
| 877 | $rrf->move($renderer->id, $this, $position); |
||
| 878 | } |
||
| 879 | return $this; |
||
| 880 | } |
||
| 881 | |||
| 882 | /** |
||
| 883 | * Add a new renderer to the report |
||
| 884 | * |
||
| 885 | * @param string $name |
||
| 886 | * @param string $description |
||
| 887 | * |
||
| 888 | * @return int the id of the new renderer |
||
| 889 | */ |
||
| 890 | public function addRenderer($name, $description, $type) { |
||
| 894 | |||
| 895 | public function addRendererInSession($name, $description, $type) { |
||
| 899 | |||
| 900 | |||
| 901 | public function process(Tracker_IDisplayTrackerLayout $layout, $request, $current_user) { |
||
| 902 | if ($this->isObsolete()) { |
||
| 903 | header('X-Codendi-Tracker-Report-IsObsolete: '. $this->getLastUpdaterUserName()); |
||
| 904 | } |
||
| 905 | $hp = Codendi_HTMLPurifier::instance(); |
||
| 906 | $tracker = $this->getTracker(); |
||
| 907 | |||
| 908 | if ($request->exist('tracker') && $request->get('tracker') != $tracker->getId()) { |
||
| 909 | $GLOBALS['Response']->addFeedback( |
||
| 910 | Feedback::ERROR, |
||
| 911 | $GLOBALS['Language']->getText('plugin_tracker_admin', 'invalid_request') |
||
| 912 | ); |
||
| 913 | |||
| 914 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 915 | 'tracker' => $tracker->getId() |
||
| 916 | ))); |
||
| 917 | } |
||
| 918 | |||
| 919 | switch ($request->get('func')) { |
||
| 920 | case 'display-masschange-form': |
||
| 921 | if ($tracker->userIsAdmin($current_user)) { |
||
| 922 | $masschange_aids = array(); |
||
| 923 | $renderer_table = $request->get('renderer_table'); |
||
| 924 | |||
| 925 | if ( !empty($renderer_table['masschange_checked']) ) { |
||
| 926 | $masschange_aids = $request->get('masschange_aids'); |
||
| 927 | } else if (!empty($renderer_table['masschange_all'])) { |
||
| 928 | $masschange_aids = $request->get('masschange_aids_all'); |
||
| 929 | } |
||
| 930 | |||
| 931 | if( empty($masschange_aids) ) { |
||
| 932 | $GLOBALS['Response']->addFeedback('error', $GLOBALS['Language']->getText('plugin_tracker_masschange_detail', 'no_items_selected')); |
||
| 933 | $GLOBALS['Response']->redirect(TRACKER_BASE_URL.'/?tracker='. $tracker->getId()); |
||
| 934 | } |
||
| 935 | $tracker->displayMasschangeForm($layout, $masschange_aids); |
||
| 936 | } else { |
||
| 937 | $GLOBALS['Response']->addFeedback('error', $GLOBALS['Language']->getText('plugin_tracker_admin', 'access_denied')); |
||
| 938 | $GLOBALS['Response']->redirect(TRACKER_BASE_URL.'/?tracker='. $tracker->getId()); |
||
| 939 | } |
||
| 940 | break; |
||
| 941 | case 'update-masschange-aids': |
||
| 942 | $masschange_updater = new Tracker_MasschangeUpdater($tracker, $this); |
||
| 943 | $masschange_updater->updateArtifacts($current_user, $request); |
||
| 944 | break; |
||
| 945 | case 'remove-criteria': |
||
| 946 | if ($request->get('field') && ! $current_user->isAnonymous()) { |
||
| 947 | $this->report_session->removeCriterion($request->get('field')); |
||
| 948 | $this->report_session->setHasChanged(); |
||
| 949 | } |
||
| 950 | break; |
||
| 951 | case 'add-criteria': |
||
| 952 | if ($request->get('field') && ! $current_user->isAnonymous()) { |
||
| 953 | //TODO: make sure that the formElement exists and the user can read it |
||
| 954 | if ($request->isAjax()) { |
||
| 955 | $criteria = $this->getCriteria(); |
||
| 956 | $field_id = $request->get('field'); |
||
| 957 | $this->setCriteria($field_id); |
||
| 958 | $this->report_session->storeCriterion($field_id, '', array('is_advanced'=>0)); |
||
| 959 | $this->report_session->setHasChanged(); |
||
| 960 | echo $this->criteria[$field_id]->fetch(); |
||
| 961 | } |
||
| 962 | } |
||
| 963 | break; |
||
| 964 | case 'toggle-advanced': |
||
| 965 | if ($request->get('field') && ! $current_user->isAnonymous()) { |
||
| 966 | $this->toggleAdvancedCriterion($request->get('field')); |
||
| 967 | $this->report_session->setHasChanged(); |
||
| 968 | if ($request->isAjax()) { |
||
| 969 | $criteria = $this->getCriteria(); |
||
| 970 | if (isset($criteria[$request->get('field')])) { |
||
| 971 | echo $criteria[$request->get('field')]->fetch(); |
||
| 972 | } |
||
| 973 | } |
||
| 974 | } |
||
| 975 | break; |
||
| 976 | case self::ACTION_CLEANSESSION: |
||
| 977 | $this->report_session->clean(); |
||
| 978 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 979 | 'tracker' => $this->tracker_id |
||
| 980 | ))); |
||
| 981 | break; |
||
| 982 | case 'renderer': |
||
| 983 | if ($request->get('renderer')) { |
||
| 984 | $store_in_session = true; |
||
| 985 | if ($request->exist('store_in_session')) { |
||
| 986 | $store_in_session = (bool)$request->get('store_in_session'); |
||
| 987 | } |
||
| 988 | $this->processRendererRequest($request->get('renderer'), $layout, $request, $current_user, $store_in_session); |
||
| 989 | } |
||
| 990 | break; |
||
| 991 | case 'rename-renderer': |
||
| 992 | if ($request->get('new_name') == '') { |
||
| 993 | $GLOBALS['Response']->addFeedback('error', $GLOBALS['Language']->getText('plugin_tracker_report','renderer_name_mandatory')); |
||
| 994 | } else if (! $current_user->isAnonymous() && (int)$request->get('renderer') && trim($request->get('new_name'))) { |
||
| 995 | $this->report_session->renameRenderer((int)$request->get('renderer'), trim($request->get('new_name')), trim($request->get('new_description'))); |
||
| 996 | $this->report_session->setHasChanged(); |
||
| 997 | } |
||
| 998 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 999 | 'report' => $this->id |
||
| 1000 | ))); |
||
| 1001 | break; |
||
| 1002 | case 'delete-renderer': |
||
| 1003 | if (! $current_user->isAnonymous() && (int)$request->get('renderer')) { |
||
| 1004 | $this->report_session->removeRenderer((int)$request->get('renderer')); |
||
| 1005 | $this->report_session->setHasChanged(); |
||
| 1006 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1007 | 'report' => $this->id |
||
| 1008 | ))); |
||
| 1009 | } |
||
| 1010 | break; |
||
| 1011 | case 'move-renderer': |
||
| 1012 | if (! $current_user->isAnonymous() && (int)$request->get('renderer')) { |
||
| 1013 | if ($request->isAjax()) { |
||
| 1014 | $this->report_session->moveRenderer($request->get('tracker_report_renderers')); |
||
| 1015 | $this->report_session->setHasChanged(); |
||
| 1016 | } else { |
||
| 1017 | if ( $request->get('move-renderer-direction')) { |
||
| 1018 | $this->moveRenderer((int)$request->get('renderer'), $request->get('move-renderer-direction')); |
||
| 1019 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1020 | 'report' => $this->id |
||
| 1021 | ))); |
||
| 1022 | } |
||
| 1023 | } |
||
| 1024 | } |
||
| 1025 | break; |
||
| 1026 | case 'add-renderer': |
||
| 1027 | $new_name = trim($request->get('new_name')); |
||
| 1028 | $new_description = trim($request->get('new_description')); |
||
| 1029 | $new_type = trim($request->get('new_type')); |
||
| 1030 | if (! $current_user->isAnonymous() && $new_name) { |
||
| 1031 | $new_renderer_id = $this->addRendererInSession($new_name, $new_description, $new_type); |
||
| 1032 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1033 | 'report' => $this->id, |
||
| 1034 | 'renderer' => $new_renderer_id ? $new_renderer_id : '' |
||
| 1035 | ))); |
||
| 1036 | } |
||
| 1037 | break; |
||
| 1038 | case self::ACTION_SAVE: |
||
| 1039 | Tracker_ReportFactory::instance()->save($this); |
||
| 1040 | $this->saveCriteria(); |
||
| 1041 | $this->saveAdditionalCriteria(); |
||
| 1042 | $this->saveRenderers(); |
||
| 1043 | //Clean session |
||
| 1044 | $this->report_session->cleanNamespace(); |
||
| 1045 | |||
| 1046 | $GLOBALS['Response']->addFeedback('info', '<a href="?report='. $this->id .'">'. $hp->purify($this->name, CODENDI_PURIFIER_CONVERT_HTML) .'</a> has been saved.', CODENDI_PURIFIER_DISABLED); |
||
| 1047 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1048 | 'report' => $this->id |
||
| 1049 | ))); |
||
| 1050 | break; |
||
| 1051 | case self::ACTION_SAVEAS: |
||
| 1052 | $redirect_to_report_id = $this->id; |
||
| 1053 | $report_copy_name = trim($request->get('report_copy_name')); |
||
| 1054 | if ($report_copy_name) { |
||
| 1055 | $new_report = Tracker_ReportFactory::instance()->duplicateReportSkeleton($this, $this->tracker_id, $current_user->getId()); |
||
| 1056 | //Set the name |
||
| 1057 | $new_report->name = $report_copy_name; |
||
| 1058 | //The new report is individual |
||
| 1059 | $new_report->user_id = $current_user->getId(); |
||
| 1060 | Tracker_ReportFactory::instance()->save($new_report); |
||
| 1061 | $GLOBALS['Response']->addFeedback('info', '<a href="?report='. $new_report->id .'">'. $hp->purify($new_report->name, CODENDI_PURIFIER_CONVERT_HTML) .'</a> has been created.', CODENDI_PURIFIER_DISABLED); |
||
| 1062 | $redirect_to_report_id = $new_report->id; |
||
| 1063 | //copy parent tracker session content |
||
| 1064 | $this->report_session->copy($this->id, $redirect_to_report_id); |
||
| 1065 | //clean current session namespace |
||
| 1066 | $this->report_session->cleanNamespace(); |
||
| 1067 | //save session content into db |
||
| 1068 | $new_report->saveCriteria(); |
||
| 1069 | $new_report->saveAdditionalCriteria(); |
||
| 1070 | $new_report->saveRenderers(); |
||
| 1071 | $new_report->report_session->cleanNamespace(); |
||
| 1072 | } else { |
||
| 1073 | $GLOBALS['Response']->addFeedback('error', 'Invalid copy name', CODENDI_PURIFIER_DISABLED); |
||
| 1074 | } |
||
| 1075 | |||
| 1076 | |||
| 1077 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1078 | 'report' => $redirect_to_report_id |
||
| 1079 | ))); |
||
| 1080 | break; |
||
| 1081 | case self::ACTION_DELETE: |
||
| 1082 | $this->delete(); |
||
| 1083 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1084 | 'tracker' => $this->tracker_id |
||
| 1085 | ))); |
||
| 1086 | break; |
||
| 1087 | case self::ACTION_SCOPE: |
||
| 1088 | if ($this->getTracker()->userIsAdmin($current_user) && (!$this->user_id || $this->user_id == $current_user->getId())) { |
||
| 1089 | if ($request->exist('report_scope_public')) { |
||
| 1090 | $old_user_id = $this->user_id; |
||
| 1091 | if ($request->get('report_scope_public') && $this->user_id == $current_user->getId()) { |
||
| 1092 | $this->user_id = null; |
||
| 1093 | } else if (!$request->get('report_scope_public') && !$this->user_id) { |
||
| 1094 | $this->user_id = $current_user->getId(); |
||
| 1095 | } |
||
| 1096 | if ($this->user_id != $old_user_id) { |
||
| 1097 | Tracker_ReportFactory::instance()->save($this); |
||
| 1098 | } |
||
| 1099 | } |
||
| 1100 | } |
||
| 1101 | case self::ACTION_DEFAULT: |
||
| 1102 | if ($this->getTracker()->userIsAdmin($current_user)) { |
||
| 1103 | if ($request->exist('report_default')) { |
||
| 1104 | $old_user_id = $this->user_id; |
||
| 1105 | if ($request->get('report_default')) { |
||
| 1106 | $this->is_default = '1'; |
||
| 1107 | } else { |
||
| 1108 | $this->is_default = '0'; |
||
| 1109 | } |
||
| 1110 | } |
||
| 1111 | $this->setDefaultReport(); |
||
| 1112 | $GLOBALS['Response']->redirect('?'. http_build_query(array( |
||
| 1113 | 'report' => $this->id |
||
| 1114 | ))); |
||
| 1115 | break; |
||
| 1116 | } |
||
| 1117 | default: |
||
| 1118 | if ($request->exist('tracker_query_submit')) { |
||
| 1119 | $criteria_values = $request->get('criteria'); |
||
| 1120 | if (!empty($criteria_values)) { |
||
| 1121 | $this->updateCriteriaValues($criteria_values); |
||
| 1122 | } |
||
| 1123 | |||
| 1124 | $additional_criteria_values = $request->get('additional_criteria'); |
||
| 1125 | if (!empty($additional_criteria_values)) { |
||
| 1126 | $this->updateAdditionalCriteriaValues($additional_criteria_values); |
||
| 1127 | } |
||
| 1128 | |||
| 1129 | $this->report_session->setHasChanged(); |
||
| 1130 | } |
||
| 1131 | $this->display($layout, $request, $current_user); |
||
| 1132 | break; |
||
| 1133 | } |
||
| 1134 | } |
||
| 1135 | |||
| 1136 | public function setDefaultReport() { |
||
| 1137 | $default_report = Tracker_ReportFactory::instance()->getDefaultReportByTrackerId($this->tracker_id); |
||
| 1138 | if ($default_report) { |
||
| 1139 | $default_report->is_default = '0'; |
||
| 1140 | Tracker_ReportFactory::instance()->save($default_report); |
||
| 1141 | } |
||
| 1142 | Tracker_ReportFactory::instance()->save($this); |
||
| 1143 | |||
| 1144 | } |
||
| 1145 | /** |
||
| 1146 | * NOTICE: make sure you are in the correct session namespace |
||
| 1147 | */ |
||
| 1148 | public function saveCriteria() { |
||
| 1149 | //populate $this->criteria |
||
| 1150 | $this->getCriteria(); |
||
| 1151 | //Delete criteria value |
||
| 1152 | foreach($this->criteria as $c) { |
||
| 1153 | if ($c->field->getCriteriaValue($c)) { |
||
| 1154 | $c->field->delete($c->id); |
||
| 1155 | } |
||
| 1156 | } |
||
| 1157 | //Delete criteria in the db |
||
| 1158 | $this->deleteAllCriteria(); |
||
| 1159 | |||
| 1160 | $session_criteria = $this->report_session->getCriteria(); |
||
| 1161 | if (is_array($session_criteria)) { |
||
| 1162 | foreach($session_criteria as $key=>$session_criterion) { |
||
| 1163 | if ( !empty($session_criterion['is_removed'])) { |
||
| 1164 | continue; |
||
| 1165 | } |
||
| 1166 | |||
| 1167 | if (isset($this->criteria[$key])) { |
||
| 1168 | $c = $this->criteria[$key]; |
||
| 1169 | $id = $this->addCriteria($c); |
||
| 1170 | $c->setId($id); |
||
| 1171 | $c->updateValue($session_criterion['value']); |
||
| 1172 | } |
||
| 1173 | } |
||
| 1174 | } |
||
| 1175 | } |
||
| 1176 | |||
| 1177 | public function saveAdditionalCriteria() { |
||
| 1178 | $additional_criteria = $this->getAdditionalCriteria(); |
||
| 1179 | EventManager::instance()->processEvent( |
||
| 1180 | TRACKER_EVENT_REPORT_SAVE_ADDITIONAL_CRITERIA, |
||
| 1181 | array( |
||
| 1182 | 'additional_criteria' => $additional_criteria, |
||
| 1183 | 'report' => $this, |
||
| 1184 | ) |
||
| 1185 | ); |
||
| 1186 | } |
||
| 1187 | |||
| 1188 | /** |
||
| 1189 | * Save report renderers |
||
| 1190 | * NOTICE: make sure you are in the correct session namespace |
||
| 1191 | * |
||
| 1192 | * @return void |
||
| 1193 | */ |
||
| 1194 | public function saveRenderers() { |
||
| 1195 | $rrf = Tracker_Report_RendererFactory::instance(); |
||
| 1196 | |||
| 1197 | //Get the renderers in the session and in the db |
||
| 1198 | $renderers_session = $this->getRenderers(); |
||
| 1199 | $renderers_db = $rrf->getReportRenderersByReportFromDb($this); |
||
| 1200 | |||
| 1201 | //Delete renderers in db if they are deleted in the session |
||
| 1202 | foreach ($renderers_db as $renderer_db_key => $renderer_db) { |
||
| 1203 | if ( ! isset($renderers_session[$renderer_db_key]) ) { |
||
| 1204 | $this->deleteRenderer($renderer_db_key); |
||
| 1205 | } |
||
| 1206 | } |
||
| 1207 | |||
| 1208 | //Create or update renderers in db |
||
| 1209 | if(is_array($renderers_session)) { |
||
| 1210 | foreach ($renderers_session as $renderer_key => $renderer) { |
||
| 1211 | if( ! isset($renderers_db[$renderer_key]) ) { |
||
| 1212 | // this is a new renderer |
||
| 1213 | $renderer->create(); |
||
| 1214 | } else { |
||
| 1215 | // this is an old renderer |
||
| 1216 | $rrf->save($renderer); |
||
| 1217 | $renderer->update(); |
||
| 1218 | } |
||
| 1219 | } |
||
| 1220 | } |
||
| 1221 | } |
||
| 1222 | |||
| 1223 | /** |
||
| 1224 | * Delete the report and its renderers |
||
| 1225 | */ |
||
| 1226 | protected function delete() { |
||
| 1227 | //Delete user preferences |
||
| 1228 | $dao = new UserPreferencesDao(); |
||
| 1229 | $dao->deleteByPreferenceNameAndValue('tracker_'. $this->tracker_id .'_last_report', $this->id); |
||
| 1230 | |||
| 1231 | //Delete criteria |
||
| 1232 | foreach($this->getCriteria() as $criteria) { |
||
| 1233 | $this->removeCriteria($criteria->field->id); |
||
| 1234 | } |
||
| 1235 | |||
| 1236 | //Delete renderers |
||
| 1237 | foreach($this->getRenderers() as $renderer) { |
||
| 1238 | $this->deleteRenderer($renderer); |
||
| 1239 | } |
||
| 1240 | |||
| 1241 | //clean session |
||
| 1242 | $this->report_session->cleanNamespace(); |
||
| 1243 | |||
| 1244 | //Delete me |
||
| 1245 | return Tracker_ReportFactory::instance()->delete($this->id); |
||
| 1246 | } |
||
| 1247 | |||
| 1248 | public function duplicate($from_report, $formElement_mapping) { |
||
| 1249 | //Duplicate criteria |
||
| 1250 | Tracker_Report_CriteriaFactory::instance()->duplicate($from_report, $this, $formElement_mapping); |
||
| 1251 | |||
| 1252 | //Duplicate renderers |
||
| 1253 | Tracker_Report_RendererFactory::instance()->duplicate($from_report, $this, $formElement_mapping); |
||
| 1254 | } |
||
| 1255 | |||
| 1256 | /** |
||
| 1257 | * Transforms Report into a SimpleXMLElement |
||
| 1258 | * |
||
| 1259 | * @param SimpleXMLElement $root the node to which the Report is attached (passed by reference) |
||
| 1260 | */ |
||
| 1261 | public function exportToXml(SimpleXMLElement $roott, $xmlMapping) { |
||
| 1262 | $root = $roott->addChild('report'); |
||
| 1263 | // if old ids are important, modify code here |
||
| 1264 | if (false) { |
||
| 1265 | $root->addAttribute('id', $this->id); |
||
| 1266 | $root->addAttribute('tracker_id', $this->tracker_id); |
||
| 1267 | $root->addAttribute('current_renderer_id', $this->current_renderer_id); |
||
| 1268 | $root->addAttribute('user_id', $this->user_id); |
||
| 1269 | $root->addAttribute('parent_report_id', $this->parent_report_id); |
||
| 1270 | } |
||
| 1271 | // only add if different from default values |
||
| 1272 | if (!$this->is_default) { |
||
| 1273 | $root->addAttribute('is_default', $this->is_default); |
||
| 1274 | } |
||
| 1275 | if (!$this->is_query_displayed) { |
||
| 1276 | $root->addAttribute('is_query_displayed', $this->is_query_displayed); |
||
| 1277 | } |
||
| 1278 | $root->addChild('name', $this->name); |
||
| 1279 | // only add if not empty |
||
| 1280 | if ($this->description) { |
||
| 1281 | $root->addChild('description', $this->description); |
||
| 1282 | } |
||
| 1283 | $child = $root->addChild('criterias'); |
||
| 1284 | foreach($this->getCriteria() as $criteria) { |
||
| 1285 | if ($criteria->field->isUsed()) { |
||
| 1286 | $grandchild = $child->addChild('criteria'); |
||
| 1287 | $criteria->exportToXML($grandchild, $xmlMapping); |
||
| 1288 | } |
||
| 1289 | } |
||
| 1290 | $child = $root->addChild('renderers'); |
||
| 1291 | foreach($this->getRenderers() as $renderer) { |
||
| 1292 | $grandchild = $child->addChild('renderer'); |
||
| 1293 | $renderer->exportToXML($grandchild, $xmlMapping); |
||
| 1294 | } |
||
| 1295 | } |
||
| 1296 | |||
| 1297 | /** |
||
| 1298 | * Convert the current report to its SOAP representation |
||
| 1299 | * |
||
| 1300 | * @return Array |
||
| 1301 | */ |
||
| 1302 | public function exportToSoap() { |
||
| 1303 | return array( |
||
| 1304 | 'id' => (int)$this->id, |
||
| 1305 | 'name' => (string)$this->name, |
||
| 1306 | 'description' => (string)$this->description, |
||
| 1307 | 'user_id' => (int)$this->user_id, |
||
| 1308 | 'is_default' => (bool)$this->is_default, |
||
| 1309 | ); |
||
| 1310 | } |
||
| 1311 | |||
| 1312 | protected $dao; |
||
| 1313 | /** |
||
| 1314 | * @return Tracker_ReportDao |
||
| 1315 | */ |
||
| 1316 | public function getDao() { |
||
| 1317 | if (!$this->dao) { |
||
| 1318 | $this->dao = new Tracker_ReportDao(); |
||
| 1319 | } |
||
| 1320 | return $this->dao; |
||
| 1321 | } |
||
| 1322 | |||
| 1323 | public function getId() { |
||
| 1326 | |||
| 1327 | public function getName() { |
||
| 1330 | |||
| 1331 | public function getAdditionalCriteria() { |
||
| 1332 | $session_additional_criteria = null; |
||
| 1333 | if (isset($this->report_session)) { |
||
| 1334 | $session_additional_criteria = &$this->report_session->getAdditionalCriteria(); |
||
| 1335 | } |
||
| 1336 | |||
| 1337 | $additional_criteria = array(); |
||
| 1338 | if ($session_additional_criteria) { |
||
| 1339 | foreach ($session_additional_criteria as $key => $additional_criterion_value) { |
||
| 1340 | $additional_criterion = new Tracker_Report_AdditionalCriterion($key, $additional_criterion_value['value']); |
||
| 1341 | $additional_criteria[$key] = $additional_criterion; |
||
| 1342 | } |
||
| 1343 | } else { |
||
| 1344 | $additional_criteria_values = array(); |
||
| 1345 | EventManager::instance()->processEvent( |
||
| 1346 | TRACKER_EVENT_REPORT_LOAD_ADDITIONAL_CRITERIA, |
||
| 1347 | array( |
||
| 1348 | 'additional_criteria_values' => &$additional_criteria_values, |
||
| 1349 | 'report' => $this, |
||
| 1350 | ) |
||
| 1351 | ); |
||
| 1352 | foreach ($additional_criteria_values as $key => $additional_criterion_value) { |
||
| 1353 | $additional_criterion = new Tracker_Report_AdditionalCriterion($key, $additional_criterion_value['value']); |
||
| 1354 | $additional_criteria[$key] = $additional_criterion; |
||
| 1355 | if (isset($this->report_session)) { |
||
| 1356 | $this->report_session->storeAdditionalCriterion($additional_criterion); |
||
| 1357 | } |
||
| 1358 | } |
||
| 1359 | } |
||
| 1360 | |||
| 1361 | return $additional_criteria; |
||
| 1362 | } |
||
| 1363 | |||
| 1364 | private function fetchUpdateRendererForm(Tracker_Report_Renderer $renderer) { |
||
| 1365 | $hp = Codendi_HTMLPurifier::instance(); |
||
| 1398 | |||
| 1399 | private function fetchAddRendererForm($current_renderer) { |
||
| 1438 | } |
||
| 1439 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.