This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Copyright (c) Enalean, 2012-2015. All Rights Reserved. |
||
4 | * |
||
5 | * This file is a part of Tuleap. |
||
6 | * |
||
7 | * Tuleap is free software; you can redistribute it and/or modify |
||
8 | * it under the terms of the GNU General Public License as published by |
||
9 | * the Free Software Foundation; either version 2 of the License, or |
||
10 | * (at your option) any later version. |
||
11 | * |
||
12 | * Tuleap is distributed in the hope that it will be useful, |
||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
15 | * GNU General Public License for more details. |
||
16 | * |
||
17 | * You should have received a copy of the GNU General Public License |
||
18 | * along with Tuleap. If not, see <http://www.gnu.org/licenses/>. |
||
19 | */ |
||
20 | |||
21 | require_once 'common/plugin/Plugin.class.php'; |
||
22 | require_once 'autoload.php'; |
||
23 | require_once 'constants.php'; |
||
24 | |||
25 | /** |
||
26 | * AgileDashboardPlugin |
||
27 | */ |
||
28 | class AgileDashboardPlugin extends Plugin { |
||
29 | |||
30 | const PLUGIN_NAME = 'agiledashboard'; |
||
31 | |||
32 | private $service; |
||
0 ignored issues
–
show
|
|||
33 | |||
34 | /** @var AgileDashboard_SequenceIdManager */ |
||
35 | private $sequence_id_manager; |
||
36 | |||
37 | /** |
||
38 | * Plugin constructor |
||
39 | */ |
||
40 | public function __construct($id) { |
||
41 | parent::__construct($id); |
||
42 | $this->setScope(self::SCOPE_PROJECT); |
||
43 | } |
||
44 | |||
45 | public function getHooksAndCallbacks() { |
||
46 | // Do not load the plugin if tracker is not installed & active |
||
47 | if (defined('TRACKER_BASE_URL')) { |
||
48 | require_once dirname(__FILE__) .'/../../tracker/include/autoload.php'; |
||
49 | $this->_addHook('cssfile', 'cssfile', false); |
||
50 | $this->_addHook('javascript_file'); |
||
51 | $this->_addHook(Event::COMBINED_SCRIPTS, 'combined_scripts', false); |
||
52 | $this->_addHook(TRACKER_EVENT_INCLUDE_CSS_FILE, 'tracker_event_include_css_file', false); |
||
53 | $this->_addHook(TRACKER_EVENT_TRACKERS_DUPLICATED, 'tracker_event_trackers_duplicated', false); |
||
54 | $this->_addHook(TRACKER_EVENT_BUILD_ARTIFACT_FORM_ACTION, 'tracker_event_build_artifact_form_action', false); |
||
55 | $this->_addHook(TRACKER_EVENT_ARTIFACT_ASSOCIATION_EDITED, 'tracker_event_artifact_association_edited', false); |
||
56 | $this->_addHook(TRACKER_EVENT_REDIRECT_AFTER_ARTIFACT_CREATION_OR_UPDATE, 'tracker_event_redirect_after_artifact_creation_or_update', false); |
||
57 | $this->_addHook(TRACKER_EVENT_ARTIFACT_PARENTS_SELECTOR, 'event_artifact_parents_selector', false); |
||
58 | $this->_addHook(TRACKER_EVENT_MANAGE_SEMANTICS, 'tracker_event_manage_semantics', false); |
||
59 | $this->_addHook(TRACKER_EVENT_SEMANTIC_FROM_XML, 'tracker_event_semantic_from_xml'); |
||
60 | $this->_addHook(TRACKER_EVENT_SOAP_SEMANTICS, 'tracker_event_soap_semantics'); |
||
61 | $this->addHook(TRACKER_EVENT_GET_SEMANTIC_FACTORIES); |
||
62 | $this->addHook('plugin_statistics_service_usage'); |
||
63 | $this->addHook(TRACKER_EVENT_REPORT_DISPLAY_ADDITIONAL_CRITERIA); |
||
64 | $this->addHook(TRACKER_EVENT_REPORT_PROCESS_ADDITIONAL_QUERY); |
||
65 | $this->addHook(TRACKER_EVENT_REPORT_SAVE_ADDITIONAL_CRITERIA); |
||
66 | $this->addHook(TRACKER_EVENT_REPORT_LOAD_ADDITIONAL_CRITERIA); |
||
67 | $this->addHook(TRACKER_EVENT_FIELD_AUGMENT_DATA_FOR_REPORT); |
||
68 | $this->addHook(TRACKER_USAGE); |
||
69 | $this->addHook(TRACKER_EVENT_TRACKERS_CANNOT_USE_IN_HIERARCHY); |
||
70 | $this->addHook(Event::SERVICE_ICON); |
||
71 | $this->addHook(Event::SERVICES_ALLOWED_FOR_PROJECT); |
||
72 | $this->_addHook('register_project_creation'); |
||
73 | |||
74 | $this->_addHook(Event::IMPORT_XML_PROJECT_CARDWALL_DONE); |
||
75 | $this->addHook(Event::REST_RESOURCES); |
||
76 | $this->addHook(Event::REST_RESOURCES_V2); |
||
77 | $this->addHook(Event::REST_PROJECT_ADDITIONAL_INFORMATIONS); |
||
78 | $this->addHook(Event::REST_PROJECT_AGILE_ENDPOINTS); |
||
79 | $this->addHook(Event::REST_GET_PROJECT_PLANNINGS); |
||
80 | $this->addHook(Event::REST_OPTIONS_PROJECT_PLANNINGS); |
||
81 | $this->addHook(Event::REST_PROJECT_RESOURCES); |
||
82 | $this->addHook(Event::REST_GET_PROJECT_MILESTONES); |
||
83 | $this->addHook(Event::REST_OPTIONS_PROJECT_MILESTONES); |
||
84 | $this->addHook(Event::REST_GET_PROJECT_BACKLOG); |
||
85 | $this->addHook(Event::REST_PUT_PROJECT_BACKLOG); |
||
86 | $this->addHook(Event::REST_PATCH_PROJECT_BACKLOG); |
||
87 | $this->addHook(Event::REST_OPTIONS_PROJECT_BACKLOG); |
||
88 | $this->addHook(Event::GET_PROJECTID_FROM_URL); |
||
89 | $this->addHook(ITEM_PRIORITY_CHANGE); |
||
90 | } |
||
91 | |||
92 | if (defined('CARDWALL_BASE_URL')) { |
||
93 | $this->addHook(CARDWALL_EVENT_USE_STANDARD_JAVASCRIPT,'cardwall_event_use_standard_javascript'); |
||
94 | } |
||
95 | |||
96 | return parent::getHooksAndCallbacks(); |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * @see Plugin::getDependencies() |
||
101 | */ |
||
102 | public function getDependencies() { |
||
103 | return array('tracker', 'cardwall'); |
||
104 | } |
||
105 | |||
106 | public function getServiceShortname() { |
||
107 | return 'plugin_agiledashboard'; |
||
108 | } |
||
109 | |||
110 | public function service_icon($params) { |
||
111 | $params['list_of_icon_unicodes'][$this->getServiceShortname()] = '\e80e'; |
||
112 | } |
||
113 | |||
114 | public function register_project_creation($params) { |
||
115 | $this->getConfigurationManager()->duplicate( |
||
116 | $params['group_id'], |
||
117 | $params['template_id'] |
||
118 | ); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * @return AgileDashboard_ConfigurationManager |
||
123 | */ |
||
124 | private function getConfigurationManager() { |
||
125 | return new AgileDashboard_ConfigurationManager( |
||
126 | new AgileDashboard_ConfigurationDao() |
||
127 | ); |
||
128 | } |
||
129 | |||
130 | public function cardwall_event_get_swimline_tracker($params) { |
||
131 | $planning_factory = $this->getPlanningFactory(); |
||
132 | if ($planning = $planning_factory->getPlanningByPlanningTracker($params['tracker'])) { |
||
133 | $params['backlog_trackers'] = $planning->getBacklogTrackers(); |
||
134 | } |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * @see TRACKER_EVENT_REPORT_DISPLAY_ADDITIONAL_CRITERIA |
||
139 | */ |
||
140 | public function tracker_event_report_display_additional_criteria($params) { |
||
141 | $backlog_tracker = $params['tracker']; |
||
142 | if (! $backlog_tracker) { |
||
143 | return; |
||
144 | } |
||
145 | |||
146 | $planning_factory = $this->getPlanningFactory(); |
||
147 | $user = $this->getCurrentUser(); |
||
148 | $provider = new AgileDashboard_Milestone_MilestoneReportCriterionProvider( |
||
149 | new AgileDashboard_Milestone_SelectedMilestoneProvider( |
||
150 | $params['additional_criteria'], |
||
151 | $this->getMilestoneFactory(), |
||
152 | $user, |
||
153 | $backlog_tracker->getProject() |
||
154 | ), |
||
155 | new AgileDashboard_Milestone_MilestoneReportCriterionOptionsProvider( |
||
156 | new AgileDashboard_Planning_NearestPlanningTrackerProvider($planning_factory), |
||
157 | new AgileDashboard_Milestone_MilestoneDao(), |
||
158 | Tracker_HierarchyFactory::instance(), |
||
159 | $planning_factory |
||
160 | ) |
||
161 | ); |
||
162 | $additional_criterion = $provider->getCriterion($backlog_tracker, $user); |
||
163 | |||
164 | if (! $additional_criterion) { |
||
0 ignored issues
–
show
The expression
$additional_criterion of type null|string is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
165 | return; |
||
166 | } |
||
167 | |||
168 | $params['array_of_html_criteria'][] = $additional_criterion; |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @see TRACKER_EVENT_REPORT_PROCESS_ADDITIONAL_QUERY |
||
173 | */ |
||
174 | public function tracker_event_report_process_additional_query($params) { |
||
175 | $backlog_tracker = $params['tracker']; |
||
176 | |||
177 | $user = $params['user']; |
||
178 | $project = $backlog_tracker->getProject(); |
||
179 | |||
180 | $milestone_provider = new AgileDashboard_Milestone_SelectedMilestoneProvider($params['additional_criteria'], $this->getMilestoneFactory(), $user, $project); |
||
181 | $milestone = $milestone_provider->getMilestone(); |
||
182 | |||
183 | if ($milestone) { |
||
184 | $provider = new AgileDashboard_BacklogItem_SubBacklogItemProvider(new Tracker_ArtifactDao(), $this->getBacklogStrategyFactory(), $this->getBacklogItemCollectionFactory()); |
||
185 | $params['result'][] = $provider->getMatchingIds($milestone, $backlog_tracker, $user); |
||
186 | $params['search_performed'] = true; |
||
187 | } |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * @see TRACKER_EVENT_REPORT_SAVE_ADDITIONAL_CRITERIA |
||
192 | */ |
||
193 | public function tracker_event_report_save_additional_criteria($params) { |
||
194 | $dao = new MilestoneReportCriterionDao(); |
||
195 | $project = $params['report']->getTracker()->getProject(); |
||
196 | $user = $this->getCurrentUser(); |
||
197 | |||
198 | $milestone_provider = new AgileDashboard_Milestone_SelectedMilestoneProvider($params['additional_criteria'], $this->getMilestoneFactory(), $user, $project); |
||
199 | |||
200 | if ($milestone_provider->getMilestone()) { |
||
201 | $dao->save($params['report']->getId(), $milestone_provider->getMilestoneId()); |
||
202 | } else { |
||
203 | $dao->delete($params['report']->getId()); |
||
204 | } |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * @see TRACKER_EVENT_REPORT_LOAD_ADDITIONAL_CRITERIA |
||
209 | */ |
||
210 | public function tracker_event_report_load_additional_criteria($params) { |
||
211 | $dao = new MilestoneReportCriterionDao(); |
||
212 | $report_id = $params['report']->getId(); |
||
213 | $field_name = AgileDashboard_Milestone_MilestoneReportCriterionProvider::FIELD_NAME; |
||
214 | |||
215 | $row = $dao->searchByReportId($report_id)->getRow(); |
||
216 | if ($row){ |
||
217 | $params['additional_criteria_values'][$field_name]['value'] = $row['milestone_id']; |
||
218 | } |
||
219 | } |
||
220 | |||
221 | public function event_artifact_parents_selector($params) { |
||
222 | $artifact_parents_selector = new Planning_ArtifactParentsSelector( |
||
223 | $this->getArtifactFactory(), |
||
224 | PlanningFactory::build(), |
||
225 | $this->getMilestoneFactory(), |
||
226 | $this->getHierarchyFactory() |
||
227 | ); |
||
228 | $event_listener = new Planning_ArtifactParentsSelectorEventListener($this->getArtifactFactory(), $artifact_parents_selector, HTTPRequest::instance()); |
||
229 | $event_listener->process($params); |
||
230 | } |
||
231 | |||
232 | public function tracker_event_include_css_file($params) { |
||
233 | $params['include_tracker_css_file'] = true; |
||
234 | } |
||
235 | |||
236 | public function tracker_event_trackers_duplicated($params) { |
||
237 | PlanningFactory::build()->duplicatePlannings( |
||
238 | $params['group_id'], |
||
239 | $params['tracker_mapping'], |
||
240 | $params['ugroups_mapping'] |
||
241 | ); |
||
242 | |||
243 | $this->getKanbanManager()->duplicateKanbans($params['tracker_mapping'], $params['field_mapping']); |
||
244 | } |
||
245 | |||
246 | public function tracker_event_redirect_after_artifact_creation_or_update($params) { |
||
247 | $params_extractor = new AgileDashboard_PaneRedirectionExtractor(); |
||
248 | $artifact_linker = new Planning_ArtifactLinker($this->getArtifactFactory(), PlanningFactory::build()); |
||
249 | $last_milestone_artifact = $artifact_linker->linkBacklogWithPlanningItems($params['request'], $params['artifact']); |
||
250 | $requested_planning = $params_extractor->extractParametersFromRequest($params['request']); |
||
251 | |||
252 | if ($requested_planning) { |
||
253 | $this->redirectOrAppend($params['request'], $params['artifact'], $params['redirect'], $requested_planning, $last_milestone_artifact); |
||
254 | } |
||
255 | } |
||
256 | |||
257 | public function tracker_usage($params) { |
||
258 | $tracker = $params['tracker']; |
||
259 | $tracker_id = $tracker->getId(); |
||
260 | |||
261 | $is_used_in_planning = PlanningFactory::build()->isTrackerIdUsedInAPlanning($tracker_id); |
||
262 | $is_used_in_backlog = PlanningFactory::build()->isTrackerUsedInBacklog($tracker_id); |
||
263 | $is_used_in_kanban = $this->getKanbanManager()->doesKanbanExistForTracker($tracker); |
||
264 | |||
265 | if ($is_used_in_planning || $is_used_in_backlog || $is_used_in_kanban) { |
||
266 | $result['can_be_deleted'] = false; |
||
267 | $result['message'] = 'Agile Dashboard'; |
||
268 | $params['result'] = $result; |
||
269 | } |
||
270 | |||
271 | } |
||
272 | |||
273 | private function redirectOrAppend(Codendi_Request $request, Tracker_Artifact $artifact, Tracker_Artifact_Redirect $redirect, $requested_planning, Tracker_Artifact $last_milestone_artifact = null) { |
||
274 | $planning = PlanningFactory::build()->getPlanning($requested_planning['planning_id']); |
||
275 | |||
276 | if ($planning && ! $redirect->stayInTracker()) { |
||
277 | $this->redirectToPlanning($artifact, $requested_planning, $planning, $redirect); |
||
278 | } elseif (! $redirect->stayInTracker()) { |
||
279 | $this->redirectToTopPlanning($artifact, $requested_planning, $redirect); |
||
280 | } else { |
||
281 | $this->setQueryParametersFromRequest($request, $redirect); |
||
282 | // Pass the right parameters so parent can be created in the right milestone (see updateBacklogs) |
||
283 | if ($planning && $last_milestone_artifact && $redirect->mode == Tracker_Artifact_Redirect::STATE_CREATE_PARENT) { |
||
284 | $redirect->query_parameters['child_milestone'] = $last_milestone_artifact->getId(); |
||
285 | } |
||
286 | } |
||
287 | } |
||
288 | |||
289 | private function redirectToPlanning(Tracker_Artifact $artifact, $requested_planning, Planning $planning, Tracker_Artifact_Redirect $redirect) { |
||
290 | $redirect_to_artifact = $requested_planning[AgileDashboard_PaneRedirectionExtractor::ARTIFACT_ID]; |
||
291 | if ($redirect_to_artifact == -1) { |
||
292 | $redirect_to_artifact = $artifact->getId(); |
||
293 | } |
||
294 | $redirect->base_url = '/plugins/agiledashboard/'; |
||
295 | $redirect->query_parameters = array( |
||
296 | 'group_id' => $planning->getGroupId(), |
||
297 | 'planning_id' => $planning->getId(), |
||
298 | 'action' => 'show', |
||
299 | 'aid' => $redirect_to_artifact, |
||
300 | 'pane' => $requested_planning[AgileDashboard_PaneRedirectionExtractor::PANE], |
||
301 | ); |
||
302 | } |
||
303 | |||
304 | private function redirectToTopPlanning(Tracker_Artifact $artifact, $requested_planning, Tracker_Artifact_Redirect $redirect) { |
||
305 | $redirect->base_url = '/plugins/agiledashboard/'; |
||
306 | $group_id = null; |
||
307 | |||
308 | if ($artifact->getTracker() && $artifact->getTracker()->getProject()) { |
||
309 | $group_id = $artifact->getTracker()->getProject()->getID(); |
||
310 | } |
||
311 | |||
312 | $redirect->query_parameters = array( |
||
313 | 'group_id' => $group_id, |
||
314 | 'action' => 'show-top', |
||
315 | 'pane' => $requested_planning['pane'], |
||
316 | ); |
||
317 | } |
||
318 | |||
319 | public function tracker_event_build_artifact_form_action($params) { |
||
320 | $this->setQueryParametersFromRequest($params['request'], $params['redirect']); |
||
321 | if ($params['request']->exist('child_milestone')) { |
||
322 | $params['redirect']->query_parameters['child_milestone'] = $params['request']->getValidated('child_milestone', 'uint', 0); |
||
323 | } |
||
324 | } |
||
325 | |||
326 | private function setQueryParametersFromRequest(Codendi_Request $request, Tracker_Artifact_Redirect $redirect) { |
||
327 | $params_extractor = new AgileDashboard_PaneRedirectionExtractor(); |
||
328 | $requested_planning = $params_extractor->extractParametersFromRequest($request); |
||
329 | if ($requested_planning) { |
||
330 | $key = 'planning['. $requested_planning[AgileDashboard_PaneRedirectionExtractor::PANE] .']['. $requested_planning[AgileDashboard_PaneRedirectionExtractor::PLANNING_ID] .']'; |
||
331 | $value = $requested_planning[AgileDashboard_PaneRedirectionExtractor::ARTIFACT_ID]; |
||
332 | $redirect->query_parameters[$key] = $value; |
||
333 | } |
||
334 | } |
||
335 | |||
336 | /** |
||
337 | * @return AgileDashboardPluginInfo |
||
338 | */ |
||
339 | public function getPluginInfo() { |
||
340 | if (!$this->pluginInfo) { |
||
341 | $this->pluginInfo = new AgileDashboardPluginInfo($this); |
||
342 | } |
||
343 | return $this->pluginInfo; |
||
0 ignored issues
–
show
The expression
$this->pluginInfo; of type AgileDashboardPluginInfo|AdminDelegationPluginInfo adds the type AdminDelegationPluginInfo to the return on line 343 which is incompatible with the return type documented by AgileDashboardPlugin::getPluginInfo of type AgileDashboardPluginInfo .
![]() |
|||
344 | } |
||
345 | |||
346 | public function cssfile($params) { |
||
347 | if ($this->isAnAgiledashboardRequest()) { |
||
348 | echo '<link rel="stylesheet" type="text/css" href="'.$this->getThemePath().'/css/style.css" />'; |
||
349 | |||
350 | if ($this->isPlanningV2URL()) { |
||
351 | echo '<link rel="stylesheet" type="text/css" href="'.$this->getPluginPath().'/js/planning-v2/bin/assets/planning-v2.css" />'; |
||
352 | } |
||
353 | } |
||
354 | } |
||
355 | |||
356 | public function javascript_file() { |
||
357 | if ($this->isAnAgiledashboardRequest()) { |
||
358 | if ($this->isPlanningV2URL()) { |
||
359 | echo '<script type="text/javascript" src="' . $this->getPluginPath() . '/js/planning-v2/bin/assets/planning-v2.js"></script>'; |
||
360 | } elseif ($this->isKanbanURL()) { |
||
361 | echo '<script type="text/javascript" src="js/resize-content.js"></script>'."\n"; |
||
362 | } |
||
363 | } |
||
364 | } |
||
365 | |||
366 | private function isAnAgiledashboardRequest() { |
||
367 | return strpos($_SERVER['REQUEST_URI'], $this->getPluginPath()) === 0; |
||
368 | } |
||
369 | |||
370 | private function isKanbanURL() { |
||
371 | $request = HTTPRequest::instance(); |
||
372 | |||
373 | return $request->get('action') === 'showKanban'; |
||
374 | } |
||
375 | |||
376 | private function isPlanningV2URL() { |
||
377 | $request = HTTPRequest::instance(); |
||
378 | $pane_info_identifier = new AgileDashboard_PaneInfoIdentifier(); |
||
379 | |||
380 | return $pane_info_identifier->isPaneAPlanningV2($request->get('pane')); |
||
381 | } |
||
382 | |||
383 | public function combined_scripts($params) { |
||
384 | $params['scripts'] = array_merge( |
||
385 | $params['scripts'], |
||
386 | array( |
||
387 | $this->getPluginPath().'/js/load-more-milestones.js', |
||
388 | $this->getPluginPath().'/js/display-angular-feedback.js', |
||
389 | $this->getPluginPath().'/js/MilestoneContent.js', |
||
390 | $this->getPluginPath().'/js/planning.js', |
||
391 | $this->getPluginPath().'/js/OuterGlow.js', |
||
392 | $this->getPluginPath().'/js/expand-collapse.js', |
||
393 | $this->getPluginPath().'/js/planning-view.js', |
||
394 | $this->getPluginPath().'/js/ContentFilter.js', |
||
395 | $this->getPluginPath().'/js/home.js', |
||
396 | ) |
||
397 | ); |
||
398 | } |
||
399 | |||
400 | public function process(Codendi_Request $request) { |
||
401 | $builder = new AgileDashboardRouterBuilder(); |
||
402 | $router = $builder->build($request); |
||
403 | |||
404 | $router->route($request); |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * Builds a new PlanningFactory instance. |
||
409 | * |
||
410 | * @return PlanningFactory |
||
411 | */ |
||
412 | protected function getPlanningFactory() { |
||
413 | return PlanningFactory::build(); |
||
414 | } |
||
415 | |||
416 | /** |
||
417 | * Builds a new Planning_MilestoneFactory instance. |
||
418 | * @return Planning_MilestoneFactory |
||
419 | */ |
||
420 | protected function getMilestoneFactory() { |
||
421 | return new Planning_MilestoneFactory( |
||
422 | $this->getPlanningFactory(), |
||
423 | $this->getArtifactFactory(), |
||
424 | Tracker_FormElementFactory::instance(), |
||
425 | $this->getTrackerFactory(), |
||
426 | $this->getStatusCounter(), |
||
427 | new PlanningPermissionsManager(), |
||
428 | new AgileDashboard_Milestone_MilestoneDao() |
||
429 | ); |
||
430 | } |
||
431 | |||
432 | private function getArtifactFactory() { |
||
433 | return Tracker_ArtifactFactory::instance(); |
||
434 | } |
||
435 | |||
436 | private function getHierarchyFactory() { |
||
437 | return Tracker_HierarchyFactory::instance(); |
||
438 | } |
||
439 | |||
440 | private function getBacklogStrategyFactory() { |
||
441 | return new AgileDashboard_Milestone_Backlog_BacklogStrategyFactory( |
||
442 | new AgileDashboard_BacklogItemDao(), |
||
443 | $this->getArtifactFactory(), |
||
444 | PlanningFactory::build() |
||
445 | ); |
||
446 | } |
||
447 | |||
448 | public function tracker_event_artifact_association_edited($params) { |
||
449 | if ($params['request']->isAjax()) { |
||
450 | |||
451 | $milestone_factory = $this->getMilestoneFactory(); |
||
452 | $milestone = $milestone_factory->getBareMilestoneByArtifact($params['user'], $params['artifact']); |
||
453 | |||
454 | $milestone_with_contextual_info = $milestone_factory->updateMilestoneContextualInfo($params['user'], $milestone); |
||
0 ignored issues
–
show
It seems like
$milestone defined by $milestone_factory->getB...], $params['artifact']) on line 452 can be null ; however, Planning_MilestoneFactor...lestoneContextualInfo() does not accept null , maybe add an additional type check?
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: /** @return stdClass|null */
function mayReturnNull() { }
function doesNotAcceptNull(stdClass $x) { }
// With potential error.
function withoutCheck() {
$x = mayReturnNull();
doesNotAcceptNull($x); // Potential error here.
}
// Safe - Alternative 1
function withCheck1() {
$x = mayReturnNull();
if ( ! $x instanceof stdClass) {
throw new \LogicException('$x must be defined.');
}
doesNotAcceptNull($x);
}
// Safe - Alternative 2
function withCheck2() {
$x = mayReturnNull();
if ($x instanceof stdClass) {
doesNotAcceptNull($x);
}
}
![]() |
|||
455 | |||
456 | $capacity = $milestone_with_contextual_info->getCapacity(); |
||
457 | $remaining_effort = $milestone_with_contextual_info->getRemainingEffort(); |
||
458 | |||
459 | header('Content-type: application/json'); |
||
460 | echo json_encode(array( |
||
461 | 'remaining_effort' => $remaining_effort, |
||
462 | 'is_over_capacity' => $capacity !== null && $remaining_effort !== null && $capacity < $remaining_effort, |
||
463 | )); |
||
464 | } |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * @see Event::TRACKER_EVENT_MANAGE_SEMANTICS |
||
469 | */ |
||
470 | public function tracker_event_manage_semantics($parameters) { |
||
471 | $tracker = $parameters['tracker']; |
||
472 | /* @var $semantics Tracker_SemanticCollection */ |
||
473 | $semantics = $parameters['semantics']; |
||
474 | |||
475 | $effort_semantic = AgileDashBoard_Semantic_InitialEffort::load($tracker); |
||
476 | $semantics->add($effort_semantic->getShortName(), $effort_semantic); |
||
477 | } |
||
478 | |||
479 | /** |
||
480 | * @see Event::TRACKER_EVENT_SEMANTIC_FROM_XML |
||
481 | */ |
||
482 | public function tracker_event_semantic_from_xml(&$parameters) { |
||
483 | $tracker = $parameters['tracker']; |
||
484 | $xml = $parameters['xml']; |
||
485 | $xmlMapping = $parameters['xml_mapping']; |
||
486 | $type = $parameters['type']; |
||
487 | |||
488 | if ($type == AgileDashBoard_Semantic_InitialEffort::NAME) { |
||
489 | $parameters['semantic'] = $this->getSemanticInitialEffortFactory()->getInstanceFromXML($xml, $xmlMapping, $tracker); |
||
490 | } |
||
491 | } |
||
492 | |||
493 | /** |
||
494 | * @see TRACKER_EVENT_GET_SEMANTIC_FACTORIES |
||
495 | */ |
||
496 | public function tracker_event_get_semantic_factories($params) { |
||
497 | $params['factories'][] = $this->getSemanticInitialEffortFactory(); |
||
498 | } |
||
499 | |||
500 | protected function getSemanticInitialEffortFactory() { |
||
501 | return AgileDashboard_Semantic_InitialEffortFactory::instance(); |
||
502 | } |
||
503 | |||
504 | /** |
||
505 | * Augment $params['semantics'] with names of AgileDashboard semantics |
||
506 | * |
||
507 | * @see TRACKER_EVENT_SOAP_SEMANTICS |
||
508 | */ |
||
509 | public function tracker_event_soap_semantics(&$params) { |
||
510 | $params['semantics'][] = AgileDashBoard_Semantic_InitialEffort::NAME; |
||
511 | } |
||
512 | |||
513 | /** |
||
514 | * |
||
515 | * @param array $param |
||
0 ignored issues
–
show
There is no parameter named
$param . Did you maybe mean $params ?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit. Consider the following example. The parameter /**
* @param array $germany
* @param array $ireland
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was changed, but the annotation was not. ![]() |
|||
516 | * Expected key/ values: |
||
517 | * project_id int The ID of the project for the import |
||
518 | * xml_content SimpleXmlObject A string of valid xml |
||
519 | * mapping array An array of mappings between xml tracker IDs and their true IDs |
||
520 | * |
||
521 | */ |
||
522 | public function import_xml_project_cardwall_done($params) { |
||
523 | $request = new HTTPRequest($params); |
||
524 | $request->set('action', 'import'); |
||
525 | $request->set('xml_content', $params['xml_content']); |
||
526 | $request->set('mapping', $params['mapping']); |
||
527 | $request->set('project_id', $params['project_id']); |
||
528 | |||
529 | $this->process($request); |
||
530 | } |
||
531 | |||
532 | public function plugin_statistics_service_usage($params) { |
||
533 | $dao = new AgileDashboard_Dao(); |
||
534 | $statistic_aggregator = new AgileDashboardStatisticsAggregator(); |
||
535 | $params['csv_exporter']->buildDatas($dao->getProjectsWithADActivated(), "Agile Dashboard activated"); |
||
536 | foreach ($statistic_aggregator->getStatisticsLabels() as $statistic_key => $statistic_name) { |
||
537 | $statistic_data = $statistic_aggregator->getStatistics( |
||
538 | $statistic_key, |
||
539 | $params['start_date'], |
||
540 | $params['end_date'] |
||
541 | ); |
||
542 | $params['csv_exporter']->buildDatas($statistic_data, $statistic_name); |
||
543 | } |
||
544 | } |
||
545 | |||
546 | /** |
||
547 | * @see REST_PROJECT_ADDITIONAL_INFORMATIONS |
||
548 | */ |
||
549 | public function rest_project_additional_informations($params) { |
||
550 | $planning_representation_class = '\\Tuleap\\AgileDashboard\\REST\\v1\\PlanningRepresentation'; |
||
551 | |||
552 | $root_planning = $this->getPlanningFactory()->getRootPlanning($this->getCurrentUser(), $params['project']->getGroupId()); |
||
553 | if (! $root_planning) { |
||
554 | return; |
||
555 | } |
||
556 | |||
557 | $planning_representation = new $planning_representation_class(); |
||
558 | $planning_representation->build($root_planning); |
||
559 | |||
560 | $params['informations'][$this->getName()]['root_planning'] = $planning_representation; |
||
561 | } |
||
562 | |||
563 | /** |
||
564 | * @see REST_RESOURCES |
||
565 | */ |
||
566 | public function rest_resources($params) { |
||
567 | $injector = new AgileDashboard_REST_ResourcesInjector(); |
||
568 | $injector->populate($params['restler']); |
||
569 | |||
570 | EventManager::instance()->processEvent( |
||
571 | AGILEDASHBOARD_EVENT_REST_RESOURCES, |
||
572 | $params |
||
573 | ); |
||
574 | } |
||
575 | |||
576 | /** |
||
577 | * @see REST_RESOURCES_V2 |
||
578 | */ |
||
579 | public function rest_resources_v2($params) { |
||
580 | $injector = new AgileDashboard_REST_v2_ResourcesInjector(); |
||
581 | $injector->populate($params['restler']); |
||
582 | } |
||
583 | |||
584 | /** |
||
585 | * @see REST_GET_PROJECT_PLANNINGS |
||
586 | */ |
||
587 | public function rest_get_project_plannings($params) { |
||
588 | $user = $this->getCurrentUser(); |
||
589 | $planning_resource = $this->buildRightVersionOfProjectPlanningsResource($params['version']); |
||
590 | |||
591 | $params['result'] = $planning_resource->get( |
||
592 | $user, |
||
593 | $params['project'], |
||
594 | $params['limit'], |
||
595 | $params['offset'] |
||
596 | ); |
||
597 | } |
||
598 | |||
599 | /** |
||
600 | * @see REST_OPTIONS_PROJECT_PLANNINGS |
||
601 | */ |
||
602 | public function rest_options_project_plannings($params) { |
||
603 | $user = $this->getCurrentUser(); |
||
604 | $planning_resource = $this->buildRightVersionOfProjectPlanningsResource($params['version']); |
||
605 | |||
606 | $params['result'] = $planning_resource->options( |
||
607 | $user, |
||
608 | $params['project'], |
||
609 | $params['limit'], |
||
610 | $params['offset'] |
||
611 | ); |
||
612 | } |
||
613 | |||
614 | private function buildRightVersionOfProjectPlanningsResource($version) { |
||
615 | $class_with_right_namespace = '\\Tuleap\\AgileDashboard\\REST\\'.$version.'\\ProjectPlanningsResource'; |
||
616 | return new $class_with_right_namespace; |
||
617 | } |
||
618 | |||
619 | /** |
||
620 | * @see Event::REST_PROJECT_RESOURCES |
||
621 | */ |
||
622 | public function rest_project_resources(array $params) { |
||
623 | $injector = new AgileDashboard_REST_ResourcesInjector(); |
||
624 | $injector->declareProjectPlanningResource($params['resources'], $params['project']); |
||
625 | } |
||
626 | |||
627 | /** |
||
628 | * @see REST_GET_PROJECT_MILESTONES |
||
629 | */ |
||
630 | public function rest_get_project_milestones($params) { |
||
631 | $user = $this->getCurrentUser(); |
||
632 | $milestone_resource = $this->buildRightVersionOfProjectMilestonesResource($params['version']); |
||
633 | |||
634 | $params['result'] = $milestone_resource->get( |
||
635 | $user, |
||
636 | $params['project'], |
||
637 | $params['representation_type'], |
||
638 | $params['query'], |
||
639 | $params['limit'], |
||
640 | $params['offset'], |
||
641 | $params['order'] |
||
642 | ); |
||
643 | } |
||
644 | |||
645 | /** |
||
646 | * @see REST_OPTIONS_PROJECT_MILESTONES |
||
647 | */ |
||
648 | public function rest_options_project_milestones($params) { |
||
649 | $user = $this->getCurrentUser(); |
||
650 | $milestone_resource = $this->buildRightVersionOfProjectMilestonesResource($params['version']); |
||
651 | |||
652 | $params['result'] = $milestone_resource->options( |
||
653 | $user, |
||
654 | $params['project'], |
||
655 | $params['limit'], |
||
656 | $params['offset'] |
||
657 | ); |
||
658 | } |
||
659 | |||
660 | private function buildRightVersionOfProjectMilestonesResource($version) { |
||
661 | $class_with_right_namespace = '\\Tuleap\\AgileDashboard\\REST\\'.$version.'\\ProjectMilestonesResource'; |
||
662 | return new $class_with_right_namespace; |
||
663 | } |
||
664 | |||
665 | /** |
||
666 | * @see REST_GET_PROJECT_BACKLOG |
||
667 | */ |
||
668 | public function rest_get_project_backlog($params) { |
||
669 | $user = $this->getCurrentUser(); |
||
670 | $project_backlog_resource = $this->buildRightVersionOfProjectBacklogResource($params['version']); |
||
671 | |||
672 | $params['result'] = $project_backlog_resource->get( |
||
673 | $user, |
||
674 | $params['project'], |
||
675 | $params['limit'], |
||
676 | $params['offset'] |
||
677 | ); |
||
678 | } |
||
679 | |||
680 | /** |
||
681 | * @see REST_OPTIONS_PROJECT_BACKLOG |
||
682 | */ |
||
683 | public function rest_options_project_backlog($params) { |
||
684 | $user = $this->getCurrentUser(); |
||
685 | $project_backlog_resource = $this->buildRightVersionOfProjectBacklogResource($params['version']); |
||
686 | |||
687 | $params['result'] = $project_backlog_resource->options( |
||
688 | $user, |
||
689 | $params['project'], |
||
690 | $params['limit'], |
||
691 | $params['offset'] |
||
692 | ); |
||
693 | } |
||
694 | |||
695 | /** |
||
696 | * @see REST_PUT_PROJECT_BACKLOG |
||
697 | */ |
||
698 | public function rest_put_project_backlog($params) { |
||
699 | $user = $this->getCurrentUser(); |
||
700 | $project_backlog_resource = $this->buildRightVersionOfProjectBacklogResource($params['version']); |
||
701 | |||
702 | $params['result'] = $project_backlog_resource->put( |
||
703 | $user, |
||
704 | $params['project'], |
||
705 | $params['ids'] |
||
706 | ); |
||
707 | } |
||
708 | |||
709 | /** |
||
710 | * @see REST_PATCH_PROJECT_BACKLOG |
||
711 | */ |
||
712 | public function rest_patch_project_backlog($params) { |
||
713 | $user = UserManager::instance()->getCurrentUser(); |
||
714 | $project_backlog_resource = $this->buildRightVersionOfProjectBacklogResource($params['version']); |
||
715 | |||
716 | $params['result'] = $project_backlog_resource->patch( |
||
717 | $user, |
||
718 | $params['project'], |
||
719 | $params['order'], |
||
720 | $params['add'] |
||
721 | ); |
||
722 | } |
||
723 | |||
724 | /** |
||
725 | * @see ITEM_PRIORITY_CHANGE |
||
726 | */ |
||
727 | public function item_priority_change($params) { |
||
728 | $planning_id = $this->getPlanningIdFromParameters($params); |
||
729 | |||
730 | $params['user_is_authorized'] = $this->getPlanningPermissionsManager()->userHasPermissionOnPlanning( |
||
731 | $planning_id, |
||
732 | $params['group_id'], |
||
733 | $params['user'], |
||
734 | PlanningPermissionsManager::PERM_PRIORITY_CHANGE |
||
735 | ); |
||
736 | } |
||
737 | |||
738 | private function getPlanningIdFromParameters($params) { |
||
739 | if ($params['milestone_id'] == 0) { |
||
740 | $planning = $this->getPlanningFactory()->getRootPlanning( |
||
741 | $params['user'], |
||
742 | $params['group_id'] |
||
743 | ); |
||
744 | |||
745 | return $planning->getId(); |
||
746 | } |
||
747 | |||
748 | $artifact = $this->getArtifactFactory()->getArtifactById($params['milestone_id']); |
||
749 | $milestone = $this->getMilestoneFactory()->getMilestoneFromArtifact($artifact); |
||
750 | |||
751 | return $milestone->getPlanningId(); |
||
752 | |||
753 | } |
||
754 | |||
755 | private function buildRightVersionOfProjectBacklogResource($version) { |
||
756 | $class_with_right_namespace = '\\Tuleap\\AgileDashboard\\REST\\'.$version.'\\ProjectBacklogResource'; |
||
757 | return new $class_with_right_namespace; |
||
758 | } |
||
759 | |||
760 | private function getStatusCounter() { |
||
761 | return new AgileDashboard_Milestone_MilestoneStatusCounter( |
||
762 | new AgileDashboard_BacklogItemDao(), |
||
763 | new Tracker_ArtifactDao(), |
||
764 | $this->getArtifactFactory() |
||
765 | ); |
||
766 | } |
||
767 | |||
768 | /** @see Event::GET_PROJECTID_FROM_URL */ |
||
769 | public function get_projectid_from_url($params) { |
||
770 | if (strpos($params['url'],'/plugins/agiledashboard/') === 0) { |
||
771 | $params['project_id'] = $params['request']->get('group_id'); |
||
772 | } |
||
773 | } |
||
774 | |||
775 | /** |
||
776 | * @see TRACKER_EVENT_FIELD_AUGMENT_DATA_FOR_REPORT |
||
777 | */ |
||
778 | public function tracker_event_field_augment_data_for_report($params) { |
||
779 | if (! $this->isFieldPriority($params['field'])) { |
||
780 | return; |
||
781 | } |
||
782 | |||
783 | $params['result'] = $this->getFieldPriorityAugmenter()->getAugmentedDataForFieldPriority( |
||
784 | $this->getCurrentUser(), |
||
785 | $params['field']->getTracker()->getProject(), |
||
786 | $params['additional_criteria'], |
||
787 | $params['artifact_id'] |
||
788 | ); |
||
789 | } |
||
790 | |||
791 | private function getFieldPriorityAugmenter() { |
||
792 | return new AgileDashboard_FieldPriorityAugmenter( |
||
793 | $this->getSequenceIdManager(), |
||
794 | $this->getMilestoneFactory() |
||
795 | ); |
||
796 | } |
||
797 | |||
798 | private function isFieldPriority(Tracker_FormElement_Field $field) { |
||
799 | return $field instanceof Tracker_FormElement_Field_Priority; |
||
800 | } |
||
801 | |||
802 | private function getSequenceIdManager() { |
||
803 | if (! $this->sequence_id_manager) { |
||
804 | $this->sequence_id_manager = new AgileDashboard_SequenceIdManager( |
||
805 | $this->getBacklogStrategyFactory(), |
||
806 | $this->getBacklogItemCollectionFactory() |
||
807 | ); |
||
808 | } |
||
809 | |||
810 | return $this->sequence_id_manager; |
||
811 | } |
||
812 | |||
813 | private function getBacklogItemCollectionFactory() { |
||
814 | return new AgileDashboard_Milestone_Backlog_BacklogItemCollectionFactory( |
||
815 | new AgileDashboard_BacklogItemDao(), |
||
816 | $this->getArtifactFactory(), |
||
817 | Tracker_FormElementFactory::instance(), |
||
818 | $this->getMilestoneFactory(), |
||
819 | $this->getPlanningFactory(), |
||
820 | new AgileDashboard_Milestone_Backlog_BacklogItemBuilder() |
||
821 | ); |
||
822 | } |
||
823 | |||
824 | public function cardwall_event_use_standard_javascript($params) { |
||
825 | $request = HTTPRequest::instance(); |
||
826 | $pane_info_identifier = new AgileDashboard_PaneInfoIdentifier(); |
||
827 | if ($pane_info_identifier->isPaneAPlanningV2($request->get('pane')) || $this->isKanbanURL()) { |
||
828 | $params['use_standard'] = false; |
||
829 | } |
||
830 | } |
||
831 | |||
832 | |||
833 | public function rest_project_agile_endpoints($params) { |
||
834 | $params['available'] = true; |
||
835 | } |
||
836 | |||
837 | public function tracker_event_trackers_cannot_use_in_hierarchy($params) { |
||
838 | $params['result'] = array_merge( |
||
839 | $params['result'], |
||
840 | $this->getHierarchyChecker()->getDeniedTrackersForATrackerHierarchy($params['tracker'], $params['user']) |
||
841 | ); |
||
842 | } |
||
843 | |||
844 | /** |
||
845 | * @return TrackerFactory |
||
846 | */ |
||
847 | private function getTrackerFactory() { |
||
848 | return TrackerFactory::instance(); |
||
849 | } |
||
850 | |||
851 | /** |
||
852 | * @return AgileDashboard_KanbanManager |
||
853 | */ |
||
854 | private function getKanbanManager() { |
||
855 | return new AgileDashboard_KanbanManager( |
||
856 | new AgileDashboard_KanbanDao(), |
||
857 | $this->getTrackerFactory(), |
||
858 | $this->getHierarchyChecker() |
||
859 | ); |
||
860 | } |
||
861 | |||
862 | private function getCurrentUser() { |
||
863 | return UserManager::instance()->getCurrentUser(); |
||
864 | } |
||
865 | |||
866 | private function getPlanningPermissionsManager() { |
||
867 | return new PlanningPermissionsManager(); |
||
868 | } |
||
869 | |||
870 | /** |
||
871 | * @return AgileDashboard_HierarchyChecker |
||
872 | */ |
||
873 | private function getHierarchyChecker() { |
||
874 | return new AgileDashboard_HierarchyChecker( |
||
875 | $this->getPlanningFactory(), |
||
876 | $this->getKanbanFactory(), |
||
877 | $this->getTrackerFactory() |
||
878 | ); |
||
879 | } |
||
880 | |||
881 | /** |
||
882 | * @return AgileDashboard_KanbanFactory |
||
883 | */ |
||
884 | private function getKanbanFactory() { |
||
885 | return new AgileDashboard_KanbanFactory( |
||
886 | TrackerFactory::instance(), |
||
887 | new AgileDashboard_KanbanDao() |
||
888 | |||
889 | ); |
||
890 | } |
||
891 | } |
||
892 |
This check marks private properties in classes that are never used. Those properties can be removed.