3 * one-off script to import tracker items (limited)
6 * Thorsten “mirabilos” Glaser <t.glaser@tarent.de>
9 * This file is part of FusionForge. FusionForge is free software;
10 * you can redistribute it and/or modify it under the terms of the
11 * GNU General Public License as published by the Free Software
12 * Foundation; either version 2 of the Licence, or (at your option)
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * Edit below; comments inline. Imports a JSON generated by tracker-export
25 * into a tracker, although only a very small part of the data.
28 require "/usr/share/gforge/common/include/env.inc.php";
29 require_once $gfcommon."include/pre.php";
30 require_once $gfcommon.'include/minijson.php';
31 require_once $gfcommon.'tracker/Artifact.class.php';
32 require_once $gfcommon.'tracker/ArtifactFile.class.php';
33 require_once $gfwww.'tracker/include/ArtifactFileHtml.class.php';
34 require_once $gfcommon.'tracker/ArtifactType.class.php';
35 require_once $gfwww.'tracker/include/ArtifactTypeHtml.class.php';
36 require_once $gfwww.'tracker/include/ArtifactHtml.class.php';
37 require_once $gfcommon.'tracker/ArtifactCanned.class.php';
38 require_once $gfcommon.'tracker/ArtifactTypeFactory.class.php';
40 function usage($rc=1) {
41 echo "Usage: .../tracker-import.php 123 <t_123.json\n" .
42 "\twhere 123 is the group_artifact_id of the tracker to append to\n";
46 if (count($argv) != 2) {
49 $argv0 = array_shift($argv);
50 $argv1 = array_shift($argv);
55 if (!($trk = util_nat0($argv1))) {
59 /* read input and ensure it’s a JSON Array or Object */
61 if (!minijson_decode(file_get_contents('php://stdin'), $iv)) {
62 echo "input is invalid JSON: $iv\n";
66 echo "input top-level element is not an Array or Object\n";
70 /* validate input elements */
76 * These are the fields we require in each entry. Note how we only
77 * list those we actually import; so, if you change the below code
78 * to import more, list them here, too.
80 $required_fields = array(
81 array(IT_STR, "_permalink"),
82 array(IT_STR, "details"),
83 array(IT_NUM, "last_modified_date"),
84 array(IT_NUM, "open_date"),
85 array(IT_NUM, "priority"),
86 array(IT_NUM, "submitted_by"),
87 array(IT_STR, "submitted_unixname"),
88 array(IT_STR, "summary"),
93 echo "$ic tracker items to consider\n";
96 * iterate over all elements in the top-level Array or Object,
97 * ensuring each is a JSON Object and has all required fields
99 foreach ($iv as $k => $v) {
101 echo "item $k is not an Object\n";
104 foreach ($required_fields as $r) {
105 if (!isset($v[$r[1]])) {
106 echo "item $k missing required field: " . $r[1] . "\n";
111 /* test for scalar (not Array or Object) Value */
112 if (is_array($v[$r[1]])) {
113 echo "item $k field " . $r[1] .
114 " is not a scalar!\n";
119 /* test for scalar (not Array or Object) Value */
120 if (is_array($v[$r[1]])) {
121 echo "item $k field " . $r[1] .
122 " is not a scalar!\n";
125 /* test Value for integer >= 0 */
126 if (util_nat0($v[$r[1]]) === false) {
127 echo "item $k field " . $r[1] .
128 " is not a positive-or-zero integer!\n";
133 /* test Value is a JSON Array or Object */
134 if (!is_array($v[$r[1]])) {
135 echo "item $k field " . $r[1] .
136 " is not an array!\n";
141 /* someone made a boo-boo editing this script */
142 echo "internal error: unknown type " . $r[0] .
143 " for required field: " . $r[1] . "\n";
148 echo "syntactically ok\n";
150 /* begin the import for sure */
155 /* get the Tracker */
156 $at =& artifactType_get_object($trk);
157 if (!$at || !is_object($at) || $at->isError()) {
158 echo "cannot get tracker object\n";
162 /* absolute minimum needed for creating tracker items in $at */
163 $extra_fields = array();
164 if ($at->usesCustomStatuses()) {
165 $i = $at->getCustomStatusField();
166 $res = db_query_params('SELECT element_id
167 FROM artifact_extra_field_elements
168 WHERE extra_field_id=$1
169 ORDER BY element_pos ASC, element_id ASC
172 $extra_fields[$i] = db_result($res, 0, 'element_id');
175 /* now import the items, one by one */
179 foreach ($iv as $k => $v) {
180 echo "importing $k (" . ++$i . "/$ic)\n";
181 $importData = array();
183 /* get all standard data fields (we use) */
185 $summary = $v["summary"];
186 $details = $v["details"];
187 /* assign to Nobody by default */
189 $priority = $v["priority"];
190 $importData['time'] = (int)$v["open_date"];
192 /* take over the submitter, but only if they exist */
193 if ($v["submitted_by"] != 100 && ($submitter =&
194 user_get_object_by_name($v["submitted_unixname"])) &&
195 is_object($submitter) && !($submitter->isError())) {
196 /* map the unixname of the submitter to our local user */
197 $importData['user'] = $submitter->getID();
199 /* submitted by Nobody, though we ignore the email */
200 $importData['user'] = 100;
203 /* prepend the old permalink in front of the details */
204 $details = "Imported from: " . $v["_permalink"] . "\n\n" . $details;
206 /* instantiate a new item */
207 $ah = new Artifact($at);
208 if (!$ah || !is_object($ah) || $ah->isError()) {
209 echo "cannot get the object\n";
214 /* actually create the item */
215 if (!$ah->create($summary, $details, $assigned_to, $priority,
216 $extra_fields, $importData)) {
217 echo "cannot import: " . $ah->getErrorMessage() . "\n";
221 /* log the import action */
222 $ah->addHistory("last-modified-before-import", date('Y-m-d H:i',
223 $v["last_modified_date"]), $now);