X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=WEB-INF%2Flib%2FttOrgImportHelper.class.php;h=1bfa07c722ba6d7e4718fb14428ccb832907b0ec;hb=f05a2db179417c20c7d841f0363bca4988c8a2ca;hp=a14d9714b737a8779ffbb9d69488f30b08f77d28;hpb=6ebd9b5c4aa66017858979cf00ac1db700f9d643;p=timetracker.git diff --git a/WEB-INF/lib/ttOrgImportHelper.class.php b/WEB-INF/lib/ttOrgImportHelper.class.php index a14d9714..1bfa07c7 100644 --- a/WEB-INF/lib/ttOrgImportHelper.class.php +++ b/WEB-INF/lib/ttOrgImportHelper.class.php @@ -45,7 +45,7 @@ class ttOrgImportHelper { var $firstPass = true; // True during first pass through the file. var $org_id = null; // Organization id (same as top group_id). var $current_group_id = null; // Current group id during parsing. - var $current_parent_group_id = null; // Current parent group id during parsing. + var $parents = array(); // A stack of parent group ids for current group all the way to the root including self. var $top_role_id = 0; // Top role id. // Entity maps for current group. They map XML ids with database ids. @@ -106,9 +106,10 @@ class ttOrgImportHelper { if ($name == 'GROUP') { // Create a new group. $this->current_group_id = $this->createGroup(array( - 'parent_id' => $this->current_parent_group_id, + 'parent_id' => $this->current_group_id, // Note: after insert current_group_id changes. 'org_id' => $this->org_id, 'name' => $attrs['NAME'], + 'description' => $attrs['DESCRIPTION'], 'currency' => $attrs['CURRENCY'], 'decimal_mark' => $attrs['DECIMAL_MARK'], 'lang' => $attrs['LANG'], @@ -134,8 +135,8 @@ class ttOrgImportHelper { $sql = "update tt_groups set org_id = $this->current_group_id where org_id is NULL and id = $this->current_group_id"; $affected = $mdb2->exec($sql); } - // Set parent group to create subgroups with this group as parent at next entry here. - $this->current_parent_group_id = $this->current_group_id; + // Add self to parent stack. + array_push($this->parents, $this->current_group_id); return; } @@ -330,7 +331,7 @@ class ttOrgImportHelper { if ($name == 'LOG_ITEM') { // We get here when processing tags for the current group. - $log_item_id = ttTimeHelper::insert(array( + $log_item_id = $this->insertLogEntry(array( 'user_id' => $this->currentGroupUserMap[$attrs['USER_ID']], 'group_id' => $this->current_group_id, 'org_id' => $this->org_id, @@ -338,11 +339,11 @@ class ttOrgImportHelper { 'start' => $attrs['START'], 'finish' => $attrs['FINISH'], 'duration' => $attrs['DURATION'], - 'client' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], - 'project' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], - 'task' => $this->currentGroupTaskMap[$attrs['TASK_ID']], - 'invoice' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], - 'note' => (isset($attrs['COMMENT']) ? $attrs['COMMENT'] : ''), + 'client_id' => $this->currentGroupClientMap[$attrs['CLIENT_ID']], + 'project_id' => $this->currentGroupProjectMap[$attrs['PROJECT_ID']], + 'task_id' => $this->currentGroupTaskMap[$attrs['TASK_ID']], + 'invoice_id' => $this->currentGroupInvoiceMap[$attrs['INVOICE_ID']], + 'comment' => (isset($attrs['COMMENT']) ? $attrs['COMMENT'] : ''), 'billable' => $attrs['BILLABLE'], 'paid' => $attrs['PAID'], 'status' => $attrs['STATUS'])); @@ -540,6 +541,22 @@ class ttOrgImportHelper { } } + // endElement - callback handler for ending tags in XML. + // We use this only for process element endings and + // set current_group_id to an immediate parent. + // This is required to import group hierarchy correctly. + function endElement($parser, $name) { + // No need to care about first or second pass, as this is used only in second pass. + // See 2nd xml_set_element_handler, where this handler is set. + if ($name == 'GROUP') { + // Remove self from the parent stack. + $self = array_pop($this->parents); + // Set current group id to an immediate parent. + $len = count($this->parents); + $this->current_group_id = $len ? $this->parents[$len-1] : null; + } + } + // importXml - uncompresses the file, reads and parses its content. During parsing, // startElement, endElement, and dataElement functions are called as many times as necessary. // Actual import occurs in the endElement handler. @@ -574,7 +591,7 @@ class ttOrgImportHelper { // Initialize XML parser. $parser = xml_parser_create(); xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', false); + xml_set_element_handler($parser, 'startElement', false); // No need to process end tags in 1st pass. // We need to parse the file 2 times: // 1) First pass: determine if import is possible. @@ -607,9 +624,9 @@ class ttOrgImportHelper { // Now we can do a second pass, where real work is done. $parser = xml_parser_create(); xml_set_object($parser, $this); - xml_set_element_handler($parser, 'startElement', false); + xml_set_element_handler($parser, 'startElement', 'endElement'); // Need to process ending tags too. - // Read and parse the content of the file. During parsing, startElement is called back for each tag. + // Read and parse the content of the file. During parsing, startElement and endElement are called back for each tag. $file = fopen($filename, 'r'); while (($data = fread($file, 4096)) && $this->errors->no()) { if (!xml_parse($parser, $data, feof($file))) { @@ -655,7 +672,7 @@ class ttOrgImportHelper { global $i18n; $mdb2 = getConnection(); - $columns = '(parent_id, org_id, name, currency, decimal_mark, lang, date_format, time_format'. + $columns = '(parent_id, org_id, name, description, currency, decimal_mark, lang, date_format, time_format'. ', week_start, tracking_mode, project_required, task_required, record_type, bcc_email'. ', allow_ip, password_complexity, plugins, lock_spec'. ', workday_minutes, config, created, created_ip, created_by)'; @@ -664,6 +681,7 @@ class ttOrgImportHelper { $values .= $mdb2->quote($fields['parent_id']); $values .= ', '.$mdb2->quote($fields['org_id']); $values .= ', '.$mdb2->quote(trim($fields['name'])); + $values .= ', '.$mdb2->quote(trim($fields['description'])); $values .= ', '.$mdb2->quote(trim($fields['currency'])); $values .= ', '.$mdb2->quote($fields['decimal_mark']); $values .= ', '.$mdb2->quote($fields['lang']); @@ -962,6 +980,51 @@ class ttOrgImportHelper { return $last_id; } + // insertLogEntry - a helper function to insert a time log entry. + private function insertLogEntry($fields) { + global $user; + $mdb2 = getConnection(); + + $group_id = (int) $fields['group_id']; + $org_id = (int) $fields['org_id']; + $user_id = (int) $fields['user_id']; + $date = $fields['date']; + $start = $fields['start']; + $duration = $fields['duration']; + $client_id = $fields['client_id']; + $project_id = $fields['project_id']; + $task_id = $fields['task_id']; + $invoice_id = $fields['invoice_id']; + $comment = $fields['comment']; + $billable = (int) $fields['billable']; + $paid = (int) $fields['paid']; + $status = $fields['status']; + + $sql = "insert into tt_log". + " (user_id, group_id, org_id, date, start, duration, client_id, project_id, task_id, invoice_id, comment". + ", billable, paid, created, created_ip, created_by, status)". + " values ($user_id, $group_id, $org_id". + ", ".$mdb2->quote($date). + ", ".$mdb2->quote($start). + ", ".$mdb2->quote($duration). + ", ".$mdb2->quote($client_id). + ", ".$mdb2->quote($project_id). + ", ".$mdb2->quote($task_id). + ", ".$mdb2->quote($invoice_id). + ", ".$mdb2->quote($comment). + ", $billable, $paid". + ", now(), ".$mdb2->quote($_SERVER['REMOTE_ADDR']).", ".$mdb2->quote($user->id). + ", ". $mdb2->quote($status).")"; + $affected = $mdb2->exec($sql); + if (is_a($affected, 'PEAR_Error')) { + $this->errors->add($i18n->get('error.db')); // TODO: review whether or not to add error here in all insert calls. + return false; + } + + $log_id = $mdb2->lastInsertID('tt_log', 'id'); + return $log_id; + } + // insertCustomFieldLogEntry - a helper function to insert a custom field log entry. private function insertCustomFieldLogEntry($fields) { $mdb2 = getConnection();