php8
[web.mtrack] / admin / project.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3 include '../../inc/common.php';
4
5 MTrackACL::requireAnyRights('Projects', 'modify');
6
7 if ($_SERVER['REQUEST_METHOD'] == 'POST') {
8   if (isset($_POST['cancel'])) {
9     header("Location: ${ABSWEB}admin/");
10     exit;
11   }
12
13   $pid = $_GET['edit'];
14   if ($pid == 'new') {
15     MTrackACL::requireAnyRights('Projects', 'create');
16     $P = new MTrackProject;
17   } else {
18     $P = MTrackProject::loadById($pid);
19     if (!$P) {
20       throw new Exception("invalid project " . htmlentities($pid));
21     }
22     MTrackACL::requireAnyRights("project:$pid", 'modify');
23   }
24
25   $P->name = $_POST["name"];
26   $P->shortname = $_POST["shortname"];
27   $P->ordinal = $_POST["ordinal"];
28   $P->notifyemail = $_POST["email"];
29   $CS = MTrackChangeset::begin("project:X",
30       $pid == 'new' ?
31       "added project $P->name" :
32       "edit project $P->name");
33   $P->save($CS);
34
35   if (MTrackACL::hasAnyRights('Components', 'modify')) {
36     MTrackDB::q('delete from components_by_project where projid = ?', $P->projid);
37     if (isset($_POST['components'])) {
38       $comps = $_POST['components'];
39       foreach ($comps as $cid) {
40         MTrackDB::q(
41             'insert into components_by_project (compid, projid) values (?, ?)',
42             $cid, $P->projid);
43       }
44     }
45   }
46
47   $CS->setObject("project:$P->projid");
48   if (isset($_POST['perms'])) {
49     MTrackACL::setACL("project:$P->projid", 0, json_decode($_POST['perms']));
50   }
51   $CS->commit();
52
53   header("Location: ${ABSWEB}admin/project.php");
54   exit;
55 }
56
57 mtrack_head("Administration - Projects");
58
59 ?>
60 <h1>Projects</h1>
61 <p>
62 Projects can be created to track development on a per-project or per-product
63 basis.  Components may be associated with a project, as well as a default
64 email distribution address.
65 </p>
66 <?php
67
68 if (isset($_GET['edit'])) {
69   $pid = $_GET['edit'];
70   if ($pid != 'new') {
71     $q = MTrackDB::q('select * from projects where projid = ?', $pid);
72     $p = null;
73     foreach ($q as $row) {
74       $p = $row;
75     }
76     if ($p == null) {
77       throw new Exception("no such project " . htmlentities($pid));
78     }
79   } else {
80     $p = array(
81       'projid' => 'new',
82       'name' => 'My New Project',
83       'shortname' => 'newproject',
84       'ordinal' => 5,
85       'notifyemail' => null
86     );
87   }
88   echo "<form method='post' action=\"{$ABSWEB}admin/project.php?edit=$pid\">";
89
90   echo "<table>";
91   $name = htmlentities($p['name'], ENT_QUOTES, 'utf-8');
92   $sname = htmlentities($p['shortname'], ENT_QUOTES, 'utf-8');
93   $ord = htmlentities($p['ordinal'], ENT_QUOTES, 'utf-8');
94   $email = htmlentities($p['notifyemail'], ENT_QUOTES, 'utf-8');
95   echo "<tr><th>Name</th>",
96     "<td><input type='text' name='name' value='$name'></td></tr>";
97   echo "<tr><th>Short Name</th>",
98     "<td><input type='text' name='shortname' value='$sname'></td></tr>";
99   echo "<tr><th>Sorting</th>",
100     "<td><input type='text' name='ordinal' value='$ord'></td></tr>";
101   echo "<tr><th>Group Email Address</th>",
102     "<td><input type='text' name='email' value='$email'></td></tr>";
103   echo "</table>";
104
105   if (MTrackACL::hasAnyRights('Components', 'modify')) {
106     $components = array();
107     foreach (MTrackDB::q(
108         'select compid, name, deleted from components order by name')
109         ->fetchAll() as $row) {
110       if ($row[2]) {
111         $row[1] .= " (deleted)";
112       }
113       $components[$row[0]] = $row[1];
114     }
115     $p_by_c = array();
116     if ($pid != 'new') {
117       foreach (MTrackDB::q(
118           'select compid from components_by_project where projid = ?', $pid)
119           ->fetchAll() as $row) {
120         $p_by_c[$row[0]] = $row[0];
121       }
122     }
123     echo "<h2>Components</h2>";
124     echo "<p>Associate component(s) with this project</p>";
125     echo mtrack_multi_select_box('components', "(select to add)",
126         $components, $p_by_c);
127   }
128
129   $repos = array();
130   foreach (MTrackDB::q('select distinct r.repoid, shortname from project_repo_link p left join repos r on p.repoid = r.repoid where projid = ?', (int)$pid) as $row) {
131     $repos[$row[0]] = $row[1];
132   }
133   foreach (MTrackDB::q("select repoid, shortname from repos where parent = 'project:' || ?", $p['shortname']) as $row) {
134     $repos[$row[0]] = $row[1];
135   }
136
137   if ($pid != 'new') {
138     echo "<h2>Groups</h2>";
139     echo "<p>The following groups are associated with this project. You may assign permissions to groups to make it easier to manage groups of users.</p>";
140
141     foreach (MTrackDB::q('select name from groups where project = ?', $pid)
142         as $row) {
143       echo "<a href='{$ABSWEB}admin/group.php?pid=$pid&amp;group=$row[0]'>"
144        . htmlentities($row[0], ENT_QUOTES, 'utf-8') . '</a><br>';
145     }
146
147     echo "<a class='button' href=\"{$ABSWEB}admin/group.php?pid=$pid\">New Group</a>";
148   }
149
150   echo "<h2>Linked Repositories</h2>";
151   if (count($repos)) {
152     echo "<ul>\n";
153     foreach ($repos as $rid => $name) {
154       echo "<li><a href=\"{$ABSWEB}admin/repo.php/$rid\">" .
155         htmlentities($name, ENT_QUOTES, 'utf-8') . "</a></li>\n";
156     }
157     echo "</ul>\n";
158   } else {
159     echo "<i>No linked repositories</i>\n";
160   }
161   echo "<br><br>\n";
162
163   if (MTrackACL::hasAnyRights("project:$pid", 'modify')) {
164     $action_map = array(
165       'Admin' => array(
166         'modify' => 'Administer via web UI',
167       ),
168     );
169
170     MTrackACL::renderACLForm('perms', "project:$pid", $action_map);
171   }
172
173   echo "<button type='submit'>Save</button>";
174   echo "<button type='submit' name='cancel'>Cancel</button>";
175
176   echo "</form>";
177 } else {
178 ?>
179 <p>
180 Select a project below to edit it, or click the "Add" button to create
181 a new project.
182 </p>
183 <?php
184
185   echo "<table>\n";
186   foreach (MTrackDB::q(
187       'select projid, name, shortname, ordinal, notifyemail
188       from projects order by ordinal') as $row) {
189
190     $pid = $row[0];
191     $name = htmlentities($row[1], ENT_QUOTES, 'utf-8');
192     $sname = htmlentities($row[2], ENT_QUOTES, 'utf-8');
193     if ($sname != $name) {
194       $sname = " ($sname)";
195     } else {
196       $sname = '';
197     }
198     $email = htmlentities($row[4], ENT_QUOTES, 'utf-8');
199
200     echo "<tr>",
201       "<td><a href=\"{$ABSWEB}admin/project.php?edit=$pid\">$name$sname</a></td>",
202       "<td>$email</td>",
203       "</tr>\n";
204
205   }
206   echo "</table><br>";
207
208   echo "<form method='get' action=\"{$ABSWEB}admin/project.php\">";
209   echo "<input type='hidden' name='edit' value='new'>";
210   echo "<button type='submit'>Add Project</button></form>";
211 }
212
213 mtrack_foot();
214