GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (4873)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

projectlinks/include/projectlinksPlugin.class.php (2 issues)

Upgrade to new PHP Analysis Engine

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) STMicroelectronics, 2007. All Rights Reserved.
4
 *
5
 * Originally written by Manuel Vacelet & Dave Kibble, 2007
6
 *
7
 * This file is a part of Codendi.
8
 *
9
 * Codendi is free software; you can redistribute it and/or modify
10
 * it under the terms of the GNU General Public License as published by
11
 * the Free Software Foundation; either version 2 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * Codendi is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with Codendi; if not, write to the Free Software
21
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
 */
23
24
require_once('common/plugin/Plugin.class.php');
25
26
//=============================================================================
27
class ProjectLinksPlugin extends Plugin {
28
    var $pluginInfo;
29
30
    //========================================================================
31
    function __construct($id) {
32
        parent::__construct($id);
33
        $this->setScope(self::SCOPE_PROJECT);
34
        $this->pluginInfo = NULL;
35
36
        $this->_addHook('admin_toolbar_configuration',
37
            'adminToolbarConfiguration', false);
38
39
        // add link - only visible when confirgured by a user from an allowed project
40
        $this->_addHook('project_summary_title',
41
            'projectSummaryTitle', false);
42
43
        // only does anythign if template authorised, or linked to
44
        $this->_addHook('register_project_creation',
45
            'registerProjectCreation', false);
46
47
        $this->_addHook('cssfile',         'cssfile',         false);
48
        $this->_addHook('widget_instance', 'widget_instance', false);
49
        $this->_addHook('widgets',         'widgets',         false);
50
    }
51
52
    //========================================================================
53
    function getPluginInfo() {
54
        if (!($this->pluginInfo instanceof ProjectLinksPluginInfo)) {
55
            require_once('ProjectLinksPluginInfo.class.php');
56
            $this->pluginInfo = new ProjectLinksPluginInfo($this);
57
        }
58
        return $this->pluginInfo;
59
    }
60
61
    //========================================================================
62
    function adminToolbarConfiguration($params) {
63
        $pM = PluginManager::instance();
64
        if ($pM->isPluginAllowedForProject($this, $params['group_id'])) {
65
            // only if allowed for this project...
66
67
            $url = $this->_adminURI().'?group_id='.$params['group_id'];
68
            $html = '<A HREF="'.$url.'">'.
69
            $GLOBALS['Language']->getText('plugin_plinks',
70
                'project_links_admin').'</A>';
71
            print ' | '.$html."\n";
72
        }
73
    }
74
75
    //========================================================================
76
    function _adminURI() {
77
        return $this->getPluginPath()."/projectlinks_admin.php";
78
    }
79
80
    //========================================================================
81
    function adminPage() {
82
        // serve the administration pages for project links
83
84
        global $Language;
85
86
        require_once('pre.php');
87
        require_once('vars.php');
88
        require_once('form_utils.php');
89
        require_once('www/project/admin/project_admin_utils.php');
90
91
        $group_id = (int) $_REQUEST['group_id'];
92
93
        // get current information
94
        $project = ProjectManager::instance()->getProject($group_id);
95
        $user    = UserManager::instance()->getCurrentUser();
96
        
97
        if (!$project) {
98
            exit_error($Language->getText('project_admin_index','invalid_p'),
99
            $Language->getText('project_admin_index','p_not_found'));
100
        }
101
102
        //if project isn't active, user must be a member of super-admin group
103
        if (!$project->isActive() && !$user->isSuperUser()) {
104
            return;
105
        }
106
107
        // must be a project admin
108
        if (!$user->isMember($group_id, 'A')) {
109
            return;
110
        }
111
112
        if (isset($_REQUEST['func'])) { // updating the database?
113
            $this->_adminPageUpdate_Service($_REQUEST);
114
        }
115
        project_admin_header(array(
116
            'title' => $Language->getText('project_admin_servicebar',
117
                'edit_s_bar'),
118
            'group' => $group_id, 'help' => 'project-links.html'));
119
        if (isset($_REQUEST['disp'])) {
120
            $disp = $_REQUEST['disp'];
121
            switch ($disp) {
122
                case 'edit_link_type':
123
                    if (isset($_REQUEST['link_type_id'])) {
124
                        $link_type_id = (int) $_REQUEST['link_type_id'];
125
                    } else {
126
                        $link_type_id = NULL;
127
                    }
128
                    $this->_adminPage_UpdateLinkType($group_id, $link_type_id);
129
                    break;
130
                case 'resync_template':
131
                    $template_id = (int) $_REQUEST['template_id'];
132
                    $this->_adminPage_ResyncTemplate($group_id, $template_id);
133
                    break;
134
            }
135
        } else {
136
            $this->_adminPage_Default($group_id, $project);
137
        }
138
        project_admin_footer(array());
139
    }
140
141
    //========================================================================
142
    function _adminPageUpdate_Service($_REQUEST) {
143
        global $Language, $feedback;
144
        $group_id = (int) $_REQUEST['group_id'];
145
        switch ($_REQUEST['func']) {
146
            case 'pl_config_update':
147
                if (isset($_REQUEST['EnableProjectLink'])) {
148
                    user_set_preference("pl_GroupId_master", $group_id);
149
                } else {
150
                    user_del_preference("pl_GroupId_master");
151
                }
152
                $feedback .= ' '.$Language->getText('plugin_plinks', 'update_ok');
153
                break;
154
155
            case 'pl_link_delete':
156
                // delete project link
157
                $link_id = (int) $_REQUEST['link_id'];
158
                // NB: use group_id to defend against malicious use
159
                if (db_query("DELETE FROM plugin_projectlinks_relationship
160
                            WHERE (master_group_id=".db_ei($group_id).")
161
                                AND (link_id=".db_ei($link_id).");"
162
                )) {
163
                    $feedback .= ' '.$Language->getText('plugin_plinks',
164
                    'project_link_deleted_OK');
165
                } else {
166
                    $feedback .= ' '.$Language->getText('plugin_plinks',
167
                    'update_failed', db_error());
168
                }
169
                break;
170
171
            case 'pl_type_delete':
172
                // delete project link type and all links using the type
173
                $link_type_id = (int) $_REQUEST['link_type_id'];
174
                // delete project relationship instances
175
                // NB: use group_id to defend against malicious use
176
                if (! db_query("DELETE FROM plugin_projectlinks_relationship
177
                    WHERE (master_group_id=".db_ei($group_id).")
178
                        AND (link_type_id=".db_ei($link_type_id).");")
179
                ) {
180
                    $feedback .= ' '.$Language->getText('plugin_plinks',
181
                    'update_failed', db_error());
182
                } else {
183
                    //delete the relationship type if no error deleting instances
184
                    if (! db_query("DELETE FROM plugin_projectlinks_link_type
185
                        WHERE (group_id=".db_ei($group_id).")
186
                            AND (link_type_id=".db_ei($link_type_id).");")
187
                    ) {
188
                        $feedback .= ' '.$Language->getText('plugin_plinks',
189
                        'update_failed', db_error());
190
                    } else {
191
                        $feedback .= ' '.$Language->getText('plugin_plinks',
192
                        'project_link_deleted_OK');
193
                    }
194
                    if (user_get_preference("pl_GroupId_master")
195
                    == $group_id) {
196
                        // switch off linking to this project - it would be better
197
                        // to check if no types left, but this works well
198
                        user_del_preference("pl_GroupId_master");
199
                    }
200
                }
201
                break;
202
203
            case 'pl_type_update':
204
                $q_name = "'".db_es($_REQUEST['name'])."'";
205
                $q_reverse_name = "'".db_es(
206
                nz($_REQUEST['reverse_name'], $_REQUEST['name']))."'";
207
                $q_description = "'".db_es($_REQUEST['description'])."'";
208
                /** **1 commented out for now - until we can decide how to deal with project links functionality
209
                 $q_uri_plus = db_es($_REQUEST['uri_plus']);
210
                 **/
211
                $q_uri_plus = "'".db_es('/projects/$projname/')."'";
212
                // $link_type_id is not set when submitting a new link
213
                if (isset($_REQUEST['link_type_id'])) {
214
                    $link_type_id = (int) $_REQUEST['link_type_id'];
215
                } else {
216
                    $link_type_id = NULL;
217
                }
218
                // check the change would not create a duplicate
219
                $pfcheck = db_query("SELECT name
220
                FROM plugin_projectlinks_link_type
221
                WHERE (((name=".$q_name.")
222
                        OR (reverse_name=".$q_reverse_name."))
223
                    AND ((group_id=".db_ei($group_id).")".
224
                (is_null($link_type_id)?"":
225
                        " AND (link_type_id<>".db_ei($link_type_id).")").
226
                    ")
227
                );");
228
                if (db_numrows($pfcheck) > 0) {
229
                    $feedback .= ' '.$Language->getText('plugin_plinks',
230
                    'project_link_type_change_makes_duplicate');
231
                } elseif (update_database("plugin_projectlinks_link_type",
232
                array(
233
                    "name" => $q_name,
234
                    "reverse_name" => $q_reverse_name,
235
                    "description" => $q_description,
236
                    "uri_plus" => $q_uri_plus,
237
                    "group_id" => $group_id
238
                ), (is_null($link_type_id)?
239
                NULL:"link_type_id=$link_type_id"))
240
                ) {
241
                    $this->addWidgetOnSummaryPage($group_id);
242
                    $feedback .= ' '.$Language->getText('plugin_plinks',
243
                    'update_ok').' ';
244
                } else {
245
                    $feedback .= ' '.$Language->getText('plugin_plinks',
246
                'update_failed', db_error());
247
                }
248
                break;
249
250
            case 'pl_link_update':
251
                $link_type_id = (int) $_REQUEST['link_type_id'];
252
                if (isset($_REQUEST['target_group_id'])) {
253
                    $target_group_id = (int) $_REQUEST['target_group_id'];
254
                } else {
255
                    $prjManager = ProjectManager::instance();
256
                    $trgProject = $prjManager->getProjectFromAutocompleter($_REQUEST['target_group']);
257
                    if ($trgProject !== false) {
258
                        $target_group_id = $trgProject->getId();
259
                    } else {
260
                        return;
261
                    }
262
                }
263
                $group_id = (int) $_REQUEST['group_id'];
264
                // NB: $link_id is not set when submitting a new link
265
                if (isset($_REQUEST['link_id'])) {
266
                    $link_id = (int) $_REQUEST['link_id'];
267
                } else {
268
                    $link_id = NULL;
269
                    // if this is a new link to a template:
270
                    //  add links to all projects already created from the template
271
                    $db_res = db_query("SELECT group_id
272
                    FROM groups
273
                    WHERE (built_from_template = ".db_ei($target_group_id).");");
274
                    while ($row = db_fetch_array($db_res)) {
275
                        $feedback .= ' '.$this->_link_unique_update($group_id,
276
                        $row['group_id'], $link_type_id);
277
                    }
278
                }
279
                $feedback .= ' '.$this->_link_unique_update(
280
                $group_id,
281
                $target_group_id,
282
                $link_type_id,
283
                $link_id);
284
                break;
285
286
            case 'template_sync_type_add':
287
                $template_type_id = (int) $_REQUEST['template_type_id'];
288
                $db_res = db_query("SELECT * FROM plugin_projectlinks_link_type
289
                                WHERE (link_type_id = ".db_ei($template_type_id).");");
290
                if (db_numrows($db_res) == 1) {
291
                    $row = db_fetch_array($db_res);
292
                    if (db_query("INSERT INTO plugin_projectlinks_link_type (
293
                        group_id,
294
                        name,
295
                        reverse_name,
296
                        description,
297
                        uri_plus
298
                    ) VALUES (
299
                    $group_id,
300
                        '".db_es($row['name'])."',
301
                        '".db_es($row['reverse_name'])."',
302
                        '".db_es($row['description'])."',
303
                        '".db_es($row['uri_plus'])."'
304
                    );")) {
305
                    $feedback .= ' '.$Language->getText('plugin_plinks', 'update_ok');
306
                    }
307
                }
308
                break;
309
310
            default:
311
                $feedback .= " not implemented: '{$_REQUEST['func']}'";
312
                break;
313
        }
314
    }
315
316
    //========================================================================
317
    function _icon($icon, $params = NULL) {
318
        // returns the HTML to display the named icon
319
        global $Language;
320
        switch ($icon) {
321
            case 'main':
322
                $src = $this->getThemePath()."/images/project_link.png";
323
                $height = 21;
324
                $width = 77;
325
                $alt = $Language->getText('plugin_plinks', 'project_links');
326
                break;
327
            case 'add':
328
                $src = $this->getThemePath()."/images/add.png";
329
                $height = 10;
330
                $width = 10;
331
                $alt = $Language->getText('plugin_plinks', 'add');
332
                break;
333
            case 'template':
334
                $src = $this->getThemePath()."/images/template.png";
335
                $height = 15;
336
                $width = 10;
337
                $alt = $Language->getText('plugin_plinks', 'template_marker');
338
                break;
339
            case 'new':
340
                $src = $this->getThemePath()."/images/new.png";
341
                $height = 10;
342
                $width = 10;
343
                $alt = $Language->getText('plugin_plinks',
344
                'newly_added', util_timestamp_to_userdateformat($params['date']));
0 ignored issues
show
Deprecated Code introduced by
The function util_timestamp_to_userdateformat() has been deprecated with message: Use DateHelper::formatForLanguage() instead

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
345
                break;
346
            case 'arrow-right':
347
                $src = $this->getThemePath()."/images/arrow-right.png";
348
                $height = 10;
349
                $width = 10;
350
                $alt = "";
351
                break;
352
            case 'trash':
353
                $src = util_get_image_theme('ic/trash.png');
354
                $height = 16;
355
                $width = 16;
356
                $alt = $Language->getText('plugin_plinks', 'delete');
357
                break;
358
            case 'matched':
359
                $src = util_get_image_theme('ic/check.png');
360
                $height = 15;
361
                $width = 16;
362
                $alt = $Language->getText('plugin_plinks', 'matched');
363
                break;
364
        }
365
        return "<IMG SRC='$src' HEIGHT='$height' WIDTH='$width' BORDER='0'
366
            ALT='$alt' TITLE='$alt'>";
367
    }
368
369
    //========================================================================
370
    function _getLinks($group_id) {
371
        // returns a record set of project link types belonging to
372
        //the passed group
373
        return db_query("SELECT link_type_id, name, reverse_name, description,
374
            uri_plus, group_id
375
            FROM plugin_projectlinks_link_type
376
            WHERE (group_id=".db_ei($group_id).")
377
            ORDER BY (name);");
378
    }
379
380
    //========================================================================
381
    function _adminPage_Default($group_id, $project) {
382
        // show the default configuration page
383
        global $HTML, $Language;
384
385
        $db_res = $this->_getLinks($group_id);
386
387
        // link types
388
        $HTML->box1_top($Language->getText('plugin_plinks', 'link_types').
389
            " &nbsp; &nbsp; &nbsp; &nbsp; ".
390
        mkAH($Language->getText('plugin_plinks', 'create_type'),
391
        $this->_adminURI()."?disp=edit_link_type&group_id=$group_id"));
392
        if (db_numrows($db_res) <= 0) {
393
            print $Language->getText('plugin_plinks',
394
                'no_link_types_enable_explanation',
395
            $Language->getText('plugin_plinks', 'create_type'));
396
        } else {
397
            print html_build_list_table_top(
398
            array(
399
            $Language->getText('plugin_plinks', 'dbfn_name'),
400
            $Language->getText('plugin_plinks', 'dbfn_reverse_name'),
401
            $Language->getText('plugin_plinks', 'dbfn_description'),
402
            /** **1 commented out for now - until we can decide how to deal with project links functionality
403
             $Language->getText('plugin_plinks', 'dbfn_uri_plus'),
404
             **/
405
                    ""
406
                    ),
407
                    false, //links_arr
408
                    false, //mass_change
409
                    true); //full_width
410
                    $cnt = 0;
411
                    while ($row = db_fetch_array($db_res)) {
412
                        $cls = "class='".html_get_alt_row_color($cnt++)."'";
413
                        print "<TR>
414
                    <td $cls style='white-space: nowrap; vertical-align: top;'>".
415
                        mkAH(htmlentities($row['name']),
416
                        $this->_adminURI()."?disp=edit_link_type".
417
                            "&amp;group_id=".$row["group_id"].
418
                            "&amp;link_type_id=".$row["link_type_id"],
419
                        $Language->getText('plugin_plinks', 'update_details')).
420
                    "</td>
421
                    <td $cls style='white-space: nowrap; vertical-align: top;'>".
422
                        htmlentities($row['reverse_name'])."</td>
423
                    <td $cls style='vertical-align: top;'>".
424
                        htmlentities($row['description'])."</td>\n";
425
                        /** **1 commented out for now - until we can decide how to deal with project links functionality
426
                         print "<td $cls style='vertical-align: top;'>".
427
                         htmlentities($row['uri_plus'])."</td>\n";
428
                         **/
429
                        print "<td $cls style='vertical-align: top;'>".
430
                        mkAH($this->_icon('trash'),
431
                        $this->_adminURI()."?func=pl_type_delete".
432
                            "&amp;group_id=$group_id".
433
                            "&amp;link_type_id=".$row["link_type_id"],
434
                        $Language->getText('plugin_plinks', 'delete_type'),
435
                        array('onclick' => "return confirm('".
436
                        $Language->getText('plugin_plinks',
437
                                    'delete_type')."?')"))."
438
                    </td>
439
                    </TR>\n";
440
                    }
441
                    print "</TABLE>\n";
442
        }
443
        $HTML->box1_bottom();
444
445
        if ($project->getTemplate() > 100) {
446
            // project was built from a proper template - don't support
447
            // re-sync with site template (yet?)
448
            form_Start();
449
            form_hiddenParams(array(
450
                "disp" => 'resync_template',
451
                "group_id" => $group_id,
452
                "template_id" => $project->getTemplate()
453
            ));
454
            form_End($Language->getText('plugin_plinks',
455
                'synchronise_with_template'), FORM_NO_RESET_BUTTON);
456
        }
457
    }
458
459
    //========================================================================
460
    function _adminPage_UpdateLinkType($group_id, $link_type_id) {
461
        global $HTML, $Language;
462
463
        if (isset($link_type_id)) {
464
            $db_res = db_query("SELECT link_type_id, group_id, name,
465
                reverse_name, description, uri_plus
466
                FROM plugin_projectlinks_link_type
467
                WHERE ((group_id = ".db_ei($group_id).")
468
                    AND (link_type_id = ".db_ei($link_type_id)."));");
469
            if (db_numrows($db_res) <> 1) {
470
                exit_error("invalid data", "2.2"); // unexpected - no i18l
471
            }
472
            $row = db_fetch_array($db_res);
473
            $def = array(
474
                    'name' => htmlentities($row['name']),
475
                    'reverse_name' => htmlentities($row['reverse_name']),
476
                    'description' => htmlentities($row['description']),
477
                    'uri_plus' => htmlentities($row['uri_plus'])
478
            );
479
        } else {
480
            $def = array(
481
                    'name' => "",
482
                    'reverse_name' => "",
483
                    'description' => "",
484
                    'uri_plus' => '/projects/$projname/'
485
                    );
486
        }
487
        $HTML->box1_top($Language->getText('plugin_plinks','project_links').
488
            " ".$this->_icon('main').
489
            " ".$Language->getText('plugin_plinks', 'link_type_update'));
490
        print mkAH("[".$Language->getText('global', 'btn_cancel')."]",
491
        $this->_adminURI()."?group_id=$group_id");
492
        print "<hr>\n";
493
        print "<table><tr><td>\n";
494
        $HTML->box1_top("");
495
        form_Start("");
496
        form_HiddenParams(array(
497
            "func" => 'pl_type_update',
498
            "group_id" => $group_id));
499
        if (isset($link_type_id)) {
500
            form_HiddenParams(array("link_type_id" => $link_type_id));
501
        }
502
        form_GenTextBox("name",
503
        htmlentities($Language->getText('plugin_plinks', 'dbfn_name')),
504
        $def['name'], 20);
505
        form_Validation("name", FORM_VAL_IS_NOT_ZERO_LENGTH);
506
        form_NewRow();
507
        form_GenTextBox("reverse_name",
508
        htmlentities($Language->getText('plugin_plinks',
509
                'dbfn_reverse_name')), $def['reverse_name'], 20);
510
        form_NewRow();
511
        form_GenTextArea("description",
512
        htmlentities($Language->getText('plugin_plinks',
513
                'dbfn_description')),
514
        $def['description']);
515
        /** **1 commented out for now - until we can decide how to deal with project links functionality
516
         form_NewRow();
517
         form_GenTextBox("uri_plus",
518
         htmlentities($Language->getText('plugin_plinks', 'dbfn_uri_plus')),
519
         $def['uri_plus'], 85);
520
         form_Validation("uri_plus", FORM_VAL_IS_NOT_ZERO_LENGTH);
521
         **/
522
        foreach (array("uri_plus", "name", "reverse_name", "description")
523
        as $ref)  {
524
            $formRefs[$ref] = form_JS_ElementRef($ref).".value";
525
        }
526
        form_End();
527
        $HTML->box1_bottom();
528
        print "</td><td>\n";
529
        $HTML->box1_top($Language->getText('plugin_plinks',
530
            'set_to_defaults'));
531
        print "<div style='padding: 5px; border: solid thin;
532
            vertical-align: middle;'>";
533
        print $Language->getText('plugin_plinks', 'replace_form_details').
534
            ":<p>";
535
        form_genJSButton($Language->getText('plugin_plinks', 'def_sp_name'),
536
            "if (confirm('".$Language->getText('plugin_plinks',
537
                'replace_form_details')."?')){".
538
        $formRefs["name"]."='".$Language->getText('plugin_plinks', 'def_sp_name')."';".
539
        $formRefs["reverse_name"]."='".$Language->getText('plugin_plinks', 'def_sp_rname')."';".
540
        $formRefs["description"]."='".$Language->getText('plugin_plinks', 'def_sp_desc')."';".
541
        /** **1 commented out for now - until we can decide how to deal with project links functionality
542
         $formRefs["uri_plus"]."='/projects/\$projname/';".
543
         **/
544
            "}");
545
        print "<p>";
546
        form_genJSButton($Language->getText('plugin_plinks', 'def_rp_name'),
547
            "if (confirm('".$Language->getText('plugin_plinks',
548
                'replace_form_details')."?')){".
549
        $formRefs["name"]."='".$Language->getText('plugin_plinks', 'def_rp_name')."';".
550
        $formRefs["reverse_name"]."='".$Language->getText('plugin_plinks', 'def_rp_rname')."';".
551
        $formRefs["description"]."='".$Language->getText('plugin_plinks', 'def_rp_desc')."';".
552
        /** **1 commented out for now - until we can decide how to deal with project links functionality
553
         $formRefs["uri_plus"]."='/projects/\$projname/';".
554
         **/
555
            "}");
556
        print "</div><p>";
557
        /** **1 commented out for now - until we can decide how to deal with project links functionality
558
         print "<div style='padding: 5px; border: solid thin;
559
         vertical-align: middle;'>";
560
         form_genJSButton($Language->getText('plugin_plinks', 'def_link_summary'),
561
         $formRefs["uri_plus"]."='/projects/\$projname/';");
562
         print "<p>";
563
         form_genJSButton($Language->getText('plugin_plinks', 'def_link_doc'),
564
         $formRefs["uri_plus"]."='/plugins/docman/?group_id=\$group_id';"
565
         );
566
         print "</div>";
567
         **/
568
        $HTML->box1_bottom();
569
        print "</td></tr></table>\n";
570
        
571
        if (isset($link_type_id)) {
572
            // Display list of linked projects
573
            $HTML->box1_top('Projects linked');
574
            print $this->_admin_links_table($link_type_id);
575
576
            // Admin can add new link
577
            print '<form name="plugin_projectlinks_add_link" method="post" action="?func=pl_link_update">';
578
            print '<input type="hidden" name="link_type_id" value="'.$link_type_id.'" />';
579
            print '<input type="hidden" name="group_id" value="'.$group_id.'" />';
580
            print '<input type="hidden" name="disp" value="edit_link_type" />';
581
            print '<p><label for="plugin_projectlinks_link_project">'.$GLOBALS['Language']->getText('plugin_plinks', 'add_project').'</label>';
582
            print '<input type="text" name="target_group" value="'.$GLOBALS['Language']->getText('plugin_plinks', 'add_project_autocompleter').'" size="60" id="plugin_projectlinks_link_project" /></p>';
583
            print '<input type="submit" value="'.$GLOBALS['Language']->getText('global', 'btn_create').'" />';
584
            print '</form>';
585
            $HTML->box1_bottom();
586
587
            $HTML->includeFooterJavascriptSnippet("new ProjectAutoCompleter('plugin_projectlinks_link_project', '".util_get_dir_image_theme()."', false);");
588
        }
589
        $HTML->box1_bottom();
590
    }
591
592
    //========================================================================
593
    function _adminPage_ResyncTemplate($group_id, $template_id) {
594
        // re-synchronise project links and types with originating template
595
        global $HTML, $Language;
596
597
        $HTML->box1_top($Language->getText('plugin_plinks','project_links').
598
            " ".$this->_icon('main')." ".
599
        $Language->getText('plugin_plinks', 'synchronise_with_template'));
600
        print mkAH("[".$Language->getText('global', 'btn_cancel')."]",
601
        $this->_adminURI()."?group_id=$group_id");
602
        // ==== compare link types ====
603
        print "<hr>\n";
604
        print "<h2>".$Language->getText('plugin_plinks','sync_type')."</h2>\n";
605
        $lt_tmplt = db_query("SELECT link_type_id, group_id, name,
606
            reverse_name, description, uri_plus
607
            FROM plugin_projectlinks_link_type
608
            WHERE (group_id = ".db_ei($template_id).");");
609
        print html_build_list_table_top(
610
        array(
611
        $Language->getText('plugin_plinks', 'action'),
612
        $Language->getText('plugin_plinks', 'dbfn_name'),
613
        $Language->getText('plugin_plinks', 'dbfn_reverse_name'),
614
        $Language->getText('plugin_plinks', 'dbfn_description'),
615
        $Language->getText('plugin_plinks', 'dbfn_uri_plus')
616
        ),
617
        false, //links_arr
618
        false, //mass_change
619
        false); //full_width
620
        $typeMatch = array();
621
        $cnt = 0;
622
        while ($ltr_tmplt = db_fetch_array($lt_tmplt)) {
623
            $cls = "class='".html_get_alt_row_color($cnt++)."'";
624
            print "<tr style=' vertical-align: top;'>\n";
625
            $diffs = array();
626
            $rs_grp = db_query("SELECT link_type_id, name, reverse_name,
627
                description, uri_plus FROM plugin_projectlinks_link_type
628
                WHERE ((group_id = ".db_ei($group_id).")
629
                    AND (name = '".db_es($ltr_tmplt['name'])."')
630
                    );");
631
            $basicURI = $this->_adminURI().
632
                "?disp=resync_template".
633
                "&amp;group_id=$group_id".
634
                "&amp;template_id=$template_id".
635
                "&amp;template_type_id={$ltr_tmplt['link_type_id']}";
636
            if (db_numrows($rs_grp) == 0) {
637
                // does not exist
638
                print "<td $cls style='text-align: center;
639
                        vertical-align: middle;'>".
640
                mkAH(
641
                $this->_icon("add"),
642
                $basicURI."&amp;func=template_sync_type_add").
643
                    "</td>";
644
            } else {
645
                // same name - any differences?
646
                $ltr_grp = db_fetch_array($rs_grp);
647
                $basicURI .= "&link_type_id={$ltr_grp['link_type_id']}";
648
                $typeMatch[$ltr_tmplt['link_type_id']] =
649
                $ltr_grp['link_type_id'];
650
                foreach (array('reverse_name', 'description', 'uri_plus')
651
                as $param) {
652
                    if ($ltr_tmplt[$param] <> $ltr_grp[$param]) {
653
                        $diffs[$param] = $ltr_grp[$param];
654
                    }
655
                }
656
                if (count($diffs) > 0) {
657
                    print "<td $cls>";
658
                    print "<table border='0' cellspacing='0' cellpadding='3'>
659
                        <tr><td>".
660
                    mkAH($Language->getText('plugin_plinks',
661
                                'sync_link_update'),
662
                    $basicURI.
663
                            "&name=".urlencode($ltr_tmplt['name']).
664
                            "&reverse_name=".urlencode(
665
                    $ltr_tmplt['reverse_name']).
666
                            "&description=".urlencode(
667
                    $ltr_tmplt['description']).
668
                            "&uri_plus=".urlencode($ltr_tmplt['uri_plus']).
669
                            "&link_type_id=".urlencode(
670
                    $ltr_grp['link_type_id']).
671
                            "&func=pl_type_update").
672
                        "</td></tr><tr>".
673
                        "<td style='text-align: right;'>".
674
                    $this->_icon("arrow-right").
675
                        "</td></tr></table>";
676
                    print "</td>";
677
                } else {
678
                    print "<td $cls style='text-align: center;
679
                        vertical-align: middle;'>".
680
                    $this->_icon('matched').
681
                        "</td>";
682
                }
683
            }
684
            print "<td $cls>";
685
            if (count($diffs) > 0) {
686
                print "<table border='0' cellspacing='0' cellpadding='3'>
687
                    <tr><td style='white-space: nowrap;'>".
688
                htmlentities($ltr_tmplt['name']).
689
                    "&nbsp; &nbsp; &nbsp; ".
690
                    "<span style='font-style:italic;'>".
691
                $Language->getText('plugin_plinks', 'project').
692
                    ":</span></td></tr><tr>
693
                    <td style='text-align: right;font-style:italic;'>".
694
                $Language->getText('plugin_plinks',
695
                        'sync_link_template').
696
                    ":</td></tr></table>";
697
            } else {
698
                print htmlentities($ltr_tmplt['name']);
699
            }
700
            print "</td>";
701
            foreach (array('reverse_name', 'description', 'uri_plus')
702
            as $param) {
703
                $style = "";
704
                if ($param <> 'description') {
705
                    $style .= "white-space: nowrap;";
706
                }
707
                if (isset($diffs[$param])) {
708
                    $style .= " font-weight: bold;";
709
                }
710
                print "<td $cls style='$style'>";
711
                if (count($diffs) > 0) {
712
                    print "<table border='0' cellspacing='0' cellpadding='3'>
713
                        <tr><td style='$style'>";
714
                }
715
                if (isset($diffs[$param])) {
716
                    print nz(htmlentities($diffs[$param]), "&nbsp;");
717
                } else {
718
                    print htmlentities($ltr_tmplt[$param]);
719
                }
720
                if (count($diffs) > 0) {
721
                    print "</td></tr><tr><td style='$style'>".
722
                    nz(htmlentities($ltr_tmplt[$param]), "&nbsp;").
723
                        "</td></tr></table>";
724
                }
725
                print "</td>";
726
            }
727
            print "</tr>\n";
728
        }
729
        print "</TABLE>\n";
730
731
        // ==== compare link instances ====
732
        print "<hr>\n";
733
        print "<h2>".$Language->getText('plugin_plinks','sync_link_new').
734
            "</h2>\n";
735
        $templLinks = db_query("
736
            SELECT plugin_projectlinks_relationship.link_type_id,
737
                name AS link_name, type, groups.group_id,
738
                group_name, unix_group_name, uri_plus,
739
                link_id, creation_date, master_group_id, target_group_id
740
            FROM plugin_projectlinks_relationship,
741
                plugin_projectlinks_link_type,groups
742
            WHERE (plugin_projectlinks_relationship.link_type_id
743
                    = plugin_projectlinks_link_type.link_type_id)
744
                AND (plugin_projectlinks_relationship.target_group_id
745
                    = groups.group_id)
746
                AND ((master_group_id = ".db_ei($template_id).")
747
                    AND (target_group_id <> ".db_ei($group_id).")
748
                    AND (status = 'A'))
749
            ORDER BY name, type, group_name;");
750
        if (db_numrows($templLinks) > 0) {
751
            print $Language->getText('plugin_plinks', 'synchronise_clickit',
752
            $this->_icon("add"));
753
            $type_missing = false;
754
            print html_build_list_table_top(
755
            array(
756
            $Language->getText('plugin_plinks', 'action'),
757
            $Language->getText('plugin_plinks', 'dbfn_link_type_id'),
758
            $Language->getText('plugin_plinks', 'project')
759
            ),
760
            false, //links_arr
761
            false, //mass_change
762
            false); //full_width
763
            $basicURI = $this->_adminURI().
764
                "?disp=resync_template".
765
                "&amp;func=pl_link_update".
766
                "&amp;group_id=$group_id".
767
                "&amp;template_id=$template_id";
768
            $cnt = 0;
769
            while ($row_templLinks = db_fetch_array($templLinks)) {
770
                $cls = "class='".html_get_alt_row_color($cnt++)."'";
771
                print "<tr valign='top'>";
772
                print "<td $cls  style='text-align: center; vertical-align: middle;'>";
773
                // is there a matching link in the project?
774
                if (isset($typeMatch[$row_templLinks['link_type_id']])) {
775
                    // we found a matching type
776
                    $findlinks = db_query("
777
                        SELECT creation_date
778
                        FROM plugin_projectlinks_relationship
779
                        WHERE ((master_group_id = ".db_ei($group_id).")
780
                            AND (target_group_id =
781
                            ".db_ei($row_templLinks['target_group_id']).")
782
                            AND (link_type_id =
783
                            ".db_ei($typeMatch[$row_templLinks['link_type_id']]).")
784
                        );");
785
                            if (db_numrows($findlinks) <= 0) {
786
                                print mkAH($this->_icon("add"),
787
                                $basicURI.
788
                            "&amp;target_group_id=".
789
                                $row_templLinks['target_group_id'].
790
                            "&amp;link_type_id=".
791
                                $typeMatch[$row_templLinks['link_type_id']]);
792
                            } else {
793
                                print $this->_icon('matched');
794
                            }
795
                } else {
796
                    $type_missing = true;
797
                    print $Language->getText('plugin_plinks',
798
                        'sync_link_needs_type');
799
                }
800
                print "</td>";
801
                print "<td $cls>".htmlentities($row_templLinks['link_name'])."</td>";
802
                print "<td $cls>".htmlentities($row_templLinks['group_name'])."</td>";
803
                print "</tr>";
804
            }
805
            print "</TABLE>\n";
806
            if ($type_missing) {
807
                print "<div style='width: 30em'><hr><i>".
808
                $Language->getText('plugin_plinks',
809
                        'sync_link_needs_type')."</i> ".
810
                $Language->getText('plugin_plinks',
811
                        'sync_link_new_no_type_explain', array(
812
                $this->_icon("add"),
813
                $Language->getText('plugin_plinks','sync_type')
814
                )
815
                ).
816
                    "</div>"
817
                    ;
818
            }
819
        }
820
        $HTML->box1_bottom();
821
    }
822
823
    //========================================================================
824
    function _link_unique_update($group_id, $target_group_id, $link_type_id, $link_id = NULL) {
825
        // update link, but check the change would not create a duplicate
826
        // (same target project and link type)
827
        global $Language;
828
829
        $targetProject = ProjectManager::instance()->getProject($target_group_id);
830
        
831
        $feedback = "";
832
        $pfcheck = db_query("SELECT link_type_id FROM
833
            plugin_projectlinks_relationship
834
            WHERE (
835
                (target_group_id=".db_ei($target_group_id).")
836
                AND (master_group_id=".db_ei($group_id).")
837
                AND (link_type_id=".db_ei($link_type_id).")
838
                ".(is_null($link_id)?"":" AND (link_id<>".db_ei($link_id).")")."
839
            )");
840
        if (db_numrows($pfcheck) > 0) {
841
            $feedback = $Language->getText('plugin_plinks',
842
                'project_link_change_makes_duplicate',
843
            $targetProject->getPublicName());
844
        } else {
845
            $updates = array(
846
                    "link_type_id" => $link_type_id,
847
                    "target_group_id" => $target_group_id,
848
                    "master_group_id" => $group_id
849
            );
850
            if (is_null($link_id)) {
851
                // new item - set date, otherwise leave it alone
852
                $updates["creation_date"] = time();
853
            }
854
            
855
            if (update_database("plugin_projectlinks_relationship", $updates, is_null($link_id)?"":"link_id=$link_id")) {
856
                $this->addWidgetOnSummaryPage($target_group_id);
857
                $feedback = $Language->getText('plugin_plinks', 'update_ok_named', $targetProject->getPublicName()).' ';
858
            } else {
859
                $feedback = $Language->getText('plugin_plinks', 'update_failed_named', array(db_error(), $targetProject->getPublicName()));
860
            }
861
        }
862
        return $feedback;
863
    }
864
865
    /**
866
     * Display the project linked by the current projet to update or delete them
867
     *
868
     * @param  Integer $group_id Group id
0 ignored issues
show
There is no parameter named $group_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
869
     * @return String
870
     */
871
    function _admin_links_table($link_type_id) {
872
        $html = '';
873
874
        $dao = $this->getProjectLinksDao();
875
        $links = $dao->searchLinksByType($link_type_id);
876
        
877
        if($links->rowCount() > 0) {
878
            $html .= html_build_list_table_top(array($GLOBALS['Language']->getText('plugin_plinks', 'dbfn_name'), ''), false, false, false);
879
880
            foreach($dao->searchLinksByType($link_type_id) as $row) {
881
                $html .= '<tr>';
882
883
                // Name
884
                $html .= '<td>'.$row['group_name'].'</td>';
885
886
                // Delete
887
                $url   = "?func=pl_link_delete&amp;disp=edit_link_type&amp;link_type_id=".$link_type_id."&amp;group_id=".$row['master_group_id']."&amp;link_id=".$row['link_id'];
888
                $warn  = $GLOBALS['Language']->getText('plugin_plinks', 'delete_link');
889
                $alt   = $GLOBALS['Language']->getText('plugin_plinks', 'delete_link');
890
                $html .= '<td>'.html_trash_link($url, $warn, $alt).'</td>';
891
892
                $html .= '</tr>';
893
            }
894
895
            $html .= '</table>';
896
        }
897
        return $html;
898
    }
899
900
    //========================================================================
901
    function registerProjectCreation($params) {
902
        // called during new project creation to inherit project links and
903
        // types from a template
904
        $group_id = $params['group_id'];
905
        $template_id = $params['template_id'];
906
907
        // 1. copy link types from the template into the new project
908
        $db_res = db_query("SELECT * FROM plugin_projectlinks_link_type
909
                            WHERE (group_id = ".db_ei($template_id).");");
910
        // documentation says we can't INSERT and SELECT in the same table in
911
        // MySQL, so we need to loop and insert
912
        while ($row = db_fetch_array($db_res)) {
913
            db_query("INSERT INTO plugin_projectlinks_link_type (
914
                    group_id,
915
                    name,
916
                    reverse_name,
917
                    description,
918
                    uri_plus
919
                ) VALUES (
920
                $group_id,
921
                    '".db_es($row['name'])."',
922
                    '".db_es($row['reverse_name'])."',
923
                    '".db_es($row['description'])."',
924
                    '".db_es($row['uri_plus'])."'
925
                );");
926
        }
927
928
        // 2. copy project links where the template is master
929
        $db_res = db_query("SELECT name, target_group_id
930
            FROM plugin_projectlinks_relationship,
931
                plugin_projectlinks_link_type
932
            WHERE ((plugin_projectlinks_relationship.link_type_id =
933
                    plugin_projectlinks_link_type.link_type_id)
934
                AND (master_group_id = ".db_ei($template_id)."));");
935
        while ($row = db_fetch_array($db_res)) {
936
            $db_res2 = db_query("SELECT link_type_id FROM
937
                plugin_projectlinks_link_type
938
                WHERE ((group_id = ".db_ei($group_id).")
939
                    AND (name='".db_es($row['name'])."'));");
940
            if (db_numrows($db_res2) > 0) {
941
                $row2 = db_fetch_array($db_res2);
942
                db_query("INSERT INTO plugin_projectlinks_relationship (
943
                        link_type_id,
944
                        master_group_id,
945
                        target_group_id,
946
                        creation_date
947
                    ) VALUES (
948
                        ".$row2['link_type_id'].",
949
                        $group_id,
950
                        ".$row['target_group_id'].",
951
                        ".time()."
952
                    );");
953
            }
954
        }
955
956
        // 3. copy project links where the template is target - NB they are
957
        // made in the master project
958
        $db_res = db_query("SELECT link_type_id, master_group_id
959
            FROM plugin_projectlinks_relationship
960
            WHERE (target_group_id = ".db_ei($template_id).");");
961
        while ($row = db_fetch_array($db_res)) {
962
            db_query("INSERT INTO plugin_projectlinks_relationship (
963
                    link_type_id,
964
                    master_group_id,
965
                    target_group_id,
966
                    creation_date
967
                ) VALUES (
968
                    ".$row['link_type_id'].",
969
                    ".$row['master_group_id'].",
970
                    $group_id,
971
                    ".time()."
972
                );");
973
        }
974
    }
975
976
    //========================================================================
977
    function registerProjectAbandon($params) {
978
        // deletes all project link information for the passed group -
979
        // usually when a user declines to accept a new project at the
980
        //  final step
981
982
        $group_id = $params['group_id'];
983
        db_query("DELETE FROM plugin_projectlinks_link_type
984
            WHERE group_id=".db_ei($group_id));
985
        db_query("DELETE FROM plugin_projectlinks_relationship
986
            WHERE ((master_group_id=".db_ei($group_id).") OR (target_group_id=".db_ei($group_id)."))"
987
        );
988
    }
989
990
    function cssfile($params) {
991
        // Only show the stylesheet if we're in project home page
992
        if (strpos($_SERVER['REQUEST_URI'], '/projects') === 0) {
993
            echo '    <link rel="stylesheet" type="text/css" href="'.$this->getThemePath().'/css/style.css" />'."\n";
994
        }
995
    }
996
997
    function widget_instance($params) {
998
        if ($params['widget'] == 'projectlinkshomepage') {
999
            include_once 'ProjectLinks_Widget_HomePageLinks.class.php';
1000
            $params['instance'] = new ProjectLinks_Widget_HomePageLinks($this);
1001
        }
1002
    }
1003
1004
    function widgets($params) {
1005
        include_once 'common/widget/WidgetLayoutManager.class.php';
1006
        if ($params['owner_type'] == WidgetLayoutManager::OWNER_TYPE_GROUP) {
1007
            $params['codendi_widgets'][] = 'projectlinkshomepage';
1008
        }
1009
    }
1010
1011
    /**
1012
     * Add a projectlink widget on project summary page if not already here
1013
     * 
1014
     * @param Integer $groupId Project id on which the widget is to add
1015
     * 
1016
     * @return void
1017
     */
1018
    function addWidgetOnSummaryPage($groupId) {
1019
        include_once 'common/widget/WidgetLayoutManager.class.php';
1020
        $widgetLayoutManager = new WidgetLayoutManager();
1021
1022
        $layoutId = 1;
1023
        // 4.0 only
1024
        // $layoutId = $widgetLayoutManager->getDefaultLayoutId($groupId, $widgetLayoutManager->OWNER_TYPE_GROUP);
1025
1026
        $sql = "SELECT NULL".
1027
               " FROM layouts_contents".
1028
               " WHERE owner_type = '". WidgetLayoutManager::OWNER_TYPE_GROUP ."'".
1029
               " AND owner_id = ". $groupId.
1030
               " AND layout_id = ". $layoutId.
1031
               " AND name = 'projectlinkshomepage'";
1032
        $res = db_query($sql);
1033
        if ($res && db_numrows($res) == 0) {
1034
            include_once 'ProjectLinks_Widget_HomePageLinks.class.php';
1035
            $request = HTTPRequest::instance();
1036
            $widget  = new ProjectLinks_Widget_HomePageLinks($this);
1037
            $widgetLayoutManager->addWidget($groupId, WidgetLayoutManager::OWNER_TYPE_GROUP, $layoutId, 'projectlinkshomepage', $widget, $request);
1038
        }
1039
    }
1040
1041
    /**
1042
     * Return ProjectLinksDao
1043
     *
1044
     * @return ProjectLinksDao
1045
     */
1046
    function getProjectLinksDao() {
1047
        include_once 'ProjectLinksDao.class.php';
1048
        return new ProjectLinksDao(CodendiDataAccess::instance());
1049
    }
1050
1051
}
1052
?>