/**
  * create a req spec tree on system from $xml data
  *
  *
  * @internal revisions
  * 20100908 - franciscom - BUGID 3762 Import Req Spec - custom fields values are ignored 
  */
 function createFromXML($xml, $tproject_id, $parent_id, $author_id, $filters = null, $options = null)
 {
     static $req_mgr;
     static $labels;
     static $missingCfMsg;
     static $linkedCF;
     static $messages;
     static $doProcessCF = false;
     // init static items
     if (is_null($labels)) {
         $labels = array('import_req_spec_created' => '', 'import_req_spec_skipped' => '', 'import_req_spec_updated' => '', 'import_req_spec_ancestor_skipped' => '', 'import_req_created' => '', 'import_req_skipped' => '', 'import_req_updated' => '');
         foreach ($labels as $key => $dummy) {
             $labels[$key] = lang_get($key);
         }
         $messages = array();
         $messages['cf_warning'] = lang_get('no_cf_defined_can_not_import');
         $messages['cfield'] = lang_get('cf_value_not_imported_missing_cf_on_testproject');
         $linkedCF = $this->cfield_mgr->get_linked_cfields_at_design($tproject_id, cfield_mgr::CF_ENABLED, null, 'requirement_spec', null, 'name');
         $doProcessCF = true;
     }
     $user_feedback = null;
     $copy_reqspec = null;
     $copy_req = null;
     $getOptions = array('output' => 'minimun');
     $my['options'] = array('skipFrozenReq' => true);
     $my['options'] = array_merge($my['options'], (array) $options);
     // echo __CLASS__ . ' ' . __FUNCTION__;
     // new dBug($options);
     // new dBug($my['options']);
     $items = $this->xmlToMapReqSpec($xml);
     $has_filters = !is_null($filters);
     if ($has_filters) {
         if (!is_null($filters['requirements'])) {
             foreach ($filters['requirements'] as $reqspec_pos => $requirements_pos) {
                 $copy_req[$reqspec_pos] = is_null($requirements_pos) ? null : array_keys($requirements_pos);
             }
         }
     }
     $loop2do = count($items);
     $container_id[0] = is_null($parent_id) || $parent_id == 0 ? $tproject_id : $parent_id;
     // items is an array of req. specs
     $skip_level = -1;
     for ($idx = 0; $idx < $loop2do; $idx++) {
         $rspec = $items[$idx]['req_spec'];
         $depth = $rspec['level'];
         if ($skip_level > 0 && $depth >= $skip_level) {
             $msgID = 'import_req_spec_ancestor_skipped';
             $user_feedback[] = array('doc_id' => $rspec['doc_id'], 'title' => $rspec['title'], 'import_status' => sprintf($labels[$msgID], $rspec['doc_id']));
             continue;
         }
         $req_spec_order = isset($rspec['node_order']) ? $rspec['node_order'] : 0;
         // 20100320 -
         // Check if req spec with same DOCID exists, inside container_id
         // If there is a hit
         //	  We will go in update
         // If Check fails, need to repeat check on WHOLE Testproject.
         // If now there is a HIT we can not import this branch
         // If Check fails => we can import creating a new one.
         //
         // Important thing:
         // Working in this way, i.e. doing check while walking the structure to import
         // we can end importing struct with 'holes'.
         //
         $check_in_container = $this->getByDocID($rspec['doc_id'], $tproject_id, $container_id[$depth], $getOptions);
         $skip_level = $depth + 1;
         $result['status_ok'] = 0;
         $msgID = 'import_req_spec_skipped';
         if (is_null($check_in_container)) {
             $check_in_tproject = $this->getByDocID($rspec['doc_id'], $tproject_id, null, $getOptions);
             if (is_null($check_in_tproject)) {
                 $msgID = 'import_req_spec_created';
                 $result = $this->create($tproject_id, $container_id[$depth], $rspec['doc_id'], $rspec['title'], $rspec['scope'], $rspec['total_req'], $author_id, $rspec['type'], $req_spec_order);
             }
         } else {
             $msgID = 'import_req_spec_updated';
             $reqSpecID = key($check_in_container);
             $result = $this->update($reqSpecID, $rspec['doc_id'], $rspec['title'], $rspec['scope'], $rspec['total_req'], $author_id, $rspec['type'], $req_spec_order);
             $result['id'] = $reqSpecID;
         }
         $user_feedback[] = array('doc_id' => $rspec['doc_id'], 'title' => $rspec['title'], 'import_status' => sprintf($labels[$msgID], $rspec['doc_id']));
         // 20100908 - Custom Fields
         if ($result['status_ok'] && $doProcessCF && isset($rspec['custom_fields']) && !is_null($rspec['custom_fields'])) {
             $cf2insert = null;
             foreach ($rspec['custom_fields'] as $cfname => $cfvalue) {
                 $cfname = trim($cfname);
                 if (isset($linkedCF[$cfname])) {
                     $cf2insert[$linkedCF[$cfname]['id']] = array('type_id' => $linkedCF[$cfname]['type'], 'cf_value' => $cfvalue);
                 } else {
                     if (!isset($missingCfMsg[$cfname])) {
                         $missingCfMsg[$cfname] = sprintf($messages['cfield'], $cfname, $labels['requirement']);
                     }
                     $user_feedback[] = array('doc_id' => $rspec['docid'], 'title' => $rspec['title'], 'import_status' => $missingCfMsg[$cfname]);
                 }
             }
             if (!is_null($cf2insert)) {
                 $this->cfield_mgr->design_values_to_db($cf2insert, $result['id'], null, 'simple');
             }
         }
         if ($result['status_ok']) {
             $skip_level = -1;
             $container_id[$depth + 1] = $reqSpecID = $result['id'];
             $reqSet = $items[$idx]['requirements'];
             $create_req = (!$has_filters || isset($copy_req[$idx])) && !is_null($reqSet);
             if ($create_req) {
                 if (is_null($req_mgr)) {
                     $req_mgr = new requirement_mgr($this->db);
                 }
                 $items_qty = isset($copy_req[$idx]) ? count($copy_req[$idx]) : count($reqSet);
                 $keys2insert = isset($copy_req[$idx]) ? $copy_req[$idx] : array_keys($reqSet);
                 for ($jdx = 0; $jdx < $items_qty; $jdx++) {
                     $req = $reqSet[$keys2insert[$jdx]];
                     $dummy = $req_mgr->createFromMap($req, $tproject_id, $reqSpecID, $author_id, null, $my['options']);
                     $user_feedback = array_merge($user_feedback, $dummy);
                 }
             }
             // if($create_req)
         }
         // if($result['status_ok'])
     }
     return $user_feedback;
 }