/**
  * Extract References from a given text and insert extracted refs into the database
  *
  * @param String  $html        Text to parse
  * @param Integer $source_id   Id of the item where the text was added
  * @param String  $source_type Nature of the source 
  * @param Integer $source_gid  Project Id of the project the source item belongs to
  * @param Integer $user_id     User who owns the text to parse
  * @param String  $source_key  Keyword to use for the reference (if different from the one associated to the nature)
  * 
  * @retrun Boolean True if no error
  */
 function extractCrossRef($html, $source_id, $source_type, $source_gid, $user_id = 0, $source_key = null)
 {
     if ($source_key == null) {
         $available_natures = $this->getAvailableNatures();
         if ($source_type == self::REFERENCE_NATURE_ARTIFACT) {
             $source_key = $this->getArtifactKeyword($source_id, $source_gid);
             if (!$source_key) {
                 $source_key = $available_natures[$source_type]['keyword'];
             }
         } else {
             $source_key = $available_natures[$source_type]['keyword'];
         }
     }
     $matches = $this->_extractAllMatches($html);
     foreach ($matches as $match) {
         // Analyse match
         $key = strtolower($match[1]);
         if ($match[2]) {
             // A target project name or ID was specified
             // remove trailing colon
             $target_project = substr($match[2], 0, strlen($match[2]) - 1);
             // id or name?
             if (is_numeric($target_project)) {
                 $ref_gid = $target_project;
             } else {
                 // project name instead...
                 $this->_initGroupHash();
                 if (isset($this->groupIdByName[$target_project])) {
                     $ref_gid = $this->groupIdByName[$target_project];
                 } else {
                     if (isset($this->groupIdByNameLower[$target_project])) {
                         $ref_gid = $this->groupIdByNameLower[$target_project];
                     } else {
                         return null;
                     }
                 }
             }
         } else {
             if ($this->tmpGroupIdForCallbackFunction) {
                 $ref_gid = $this->tmpGroupIdForCallbackFunction;
             } else {
                 if (array_key_exists('group_id', $GLOBALS)) {
                     $ref_gid = $GLOBALS['group_id'];
                     // might not be set
                 } else {
                     $ref_gid = '';
                 }
             }
         }
         $value = $match[3];
         if ($ref_gid == "") {
             $ref_gid = 100;
         }
         // use system references only
         $num_args = substr_count($value, '/') + 1;
         // Count number of arguments in detected reference
         $ref = $this->_getReferenceFromKeywordAndNumArgs($key, $ref_gid, $num_args);
         if ($ref) {
             //Cross reference
             $sqlkey = 'SELECT link, nature from reference r,reference_group rg where keyword="' . $match[1] . '" AND r.id = rg.reference_id AND rg.group_id=' . $source_gid;
             $reskey = db_query($sqlkey);
             if ($reskey && db_numrows($reskey) > 0) {
                 $key_array = db_fetch_array($reskey);
                 $target_type = $key_array['nature'];
                 $target_id = $match[3];
                 $target_key = $match[1];
                 // keyword
                 $target_gid = $ref_gid;
                 if ($user_id == 0) {
                     $user_id = user_getid();
                 }
                 $cross_ref = new CrossReference($source_id, $source_gid, $source_type, $source_key, $target_id, $target_gid, $target_type, $target_key, $user_id);
                 if (!$cross_ref->existInDb()) {
                     $cross_ref->createDbCrossRef();
                 }
             }
         }
     }
     return true;
 }
 public function insertCrossReference(CrossReference $cross_reference)
 {
     if (!$cross_reference->existInDb()) {
         return $cross_reference->createDbCrossRef();
     }
     return true;
 }