[ Index ]

PHP Cross Reference of MantisBT

title

Body

[close]

/plugins/XmlImportExport/ -> ImportXml.php (source)

   1  <?php
   2  # MantisBT - A PHP based bugtracking system
   3  # Copyright (C) 2002 - 2011  MantisBT Team - mantisbt-dev@lists.sourceforge.net
   4  # MantisBT is free software: you can redistribute it and/or modify
   5  # it under the terms of the GNU General Public License as published by
   6  # the Free Software Foundation, either version 2 of the License, or
   7  # (at your option) any later version.
   8  #
   9  # MantisBT is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  14  # You should have received a copy of the GNU General Public License
  15  # along with MantisBT.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  require_once ( 'ImportXml' . DIRECTORY_SEPARATOR . 'Mapper.php' );
  18  require_once ( 'ImportXml' . DIRECTORY_SEPARATOR . 'Issue.php' );
  19  
  20  class SourceData {
  21      public $version;
  22      public $urlbase;
  23      public $issuelink;
  24      public $notelink;
  25      public $format;
  26  
  27  	public function get_issue_url( $issue_id ) {
  28          return $this->urlbase . 'view.php?id=' . $issue_id;
  29      }
  30  
  31  	public function get_note_url( $issue_id, $note_id ) {
  32          return $this->urlbase . 'view.php?id=' . $issue_id . '#c' . $note_id;
  33      }
  34  }
  35  
  36  /**
  37    * Perform import from an XML file
  38    */
  39  class ImportXML {
  40      private $source_;
  41      private $reader_;
  42      private $itemsMap_;
  43      private $strategy_;
  44      private $fallback_;
  45  
  46      // issues specific options
  47      private $keepCategory_;
  48      private $defaultCategory_;
  49  
  50      /**
  51        * Constructor
  52        *
  53        * @param string $filename name of the file to read
  54        * @param string $strategy conversion strategy; one of "renumber", "link" or "disable"
  55        * @param string $fallback alternative conversion strategy when "renumber" does not apply
  56        */
  57  	public function __construct( $filename, $strategy, $fallback, $keepCategory, $defaultCategory ) {
  58          $this->source_ = new SourceData;
  59          $this->reader_ = new XMLReader( );
  60          $this->itemsMap_ = new ImportXml_Mapper;
  61          $this->strategy_ = $strategy;
  62          $this->fallback_ = $fallback;
  63          $this->keepCategory_ = $keepCategory;
  64          $this->defaultCategory_ = $defaultCategory;
  65  
  66          $this->reader_->open( $filename['tmp_name'] );
  67      }
  68  
  69      /**
  70       * Perform import from an XML file
  71   *
  72       * @param string $p_filename name of the file to read
  73       * @param string $p_strategy conversion strategy; one of "renumber", "link" or "disable"
  74       */
  75  	public function import( ) {
  76          // Read the <mantis> element and it's attributes
  77          while( $this->reader_->read( ) && $this->reader_->name == 'mantis' ) {
  78              $this->source_->version = $this->reader_->getAttribute( 'version' );
  79              $this->source_->urlbase = $this->reader_->getAttribute( 'urlbase' );
  80              $this->source_->issuelink = $this->reader_->getAttribute( 'issuelink' );
  81              $this->source_->notelink = $this->reader_->getAttribute( 'notelink' );
  82              $this->source_->format = $this->reader_->getAttribute( 'format' );
  83          }
  84  
  85          echo 'Importing file, please wait...';
  86  
  87          // loop through the elements
  88          while( $this->reader_->read( ) ) {
  89              switch( $this->reader_->nodeType ) {
  90                  case XMLReader::ELEMENT:
  91  
  92                      /* element start */
  93                      $t_element_name = $this->reader_->localName;
  94                      $t_importer = $this->get_importer_object( $t_element_name );
  95                      if( !is_null( $t_importer ) ) {
  96                          $t_importer->process( $this->reader_ );
  97                          $t_importer->update_map( $this->itemsMap_ );
  98                      }
  99                      break;
 100              }
 101          }
 102  
 103          echo " Done\n";
 104  
 105          // replace references in bug description and additional information
 106          $importedIssues = $this->itemsMap_->getall( 'issue' );
 107          printf( "Processing cross-references for %s issues...", count( $importedIssues ) );
 108          foreach( $importedIssues as $oldId => $newId ) {
 109              $bugData = bug_get( $newId, true );
 110  
 111              $bugLinkRegexp = '/(^|[^\w])(' . preg_quote( $this->source_->issuelink, '/' ) . ')(\d+)\b/e';
 112              // replace links in description
 113              preg_match_all( $bugLinkRegexp, $bugData->description, $matches );
 114              if ( is_array( $matches[3] && count( $matches[3] ) > 0 ) ) {
 115                  $content_replaced = true;
 116                  foreach ( $matches[3] as $old_id ) {
 117                      $bugData->description = str_replace( $this->source_->issuelink . $old_id, $this->getReplacementString( $this->source_->issuelink, $old_id ), $bugData->description);
 118                  }
 119              }
 120              // replace links in additional information
 121              preg_match_all( $bugLinkRegexp, $bugData->additional_information, $matches );
 122              if ( is_array( $matches[3] && count( $matches[3] ) > 0 ) ) {
 123                  $content_replaced = true;
 124                  foreach ( $matches[3] as $old_id ) {
 125                      $bugData->additional_information = str_replace( $this->source_->issuelink . $old_id, $this->getReplacementString( $this->source_->issuelink, $old_id ), $bugData->additional_information);
 126                  }
 127              }
 128              if ( $content_replaced ) {
 129                  // only update bug if necessary (otherwise last update date would be unnecessarily overwritten)
 130                  $bugData->update( true );
 131              }
 132          }
 133  
 134          // @todo: replace references within bugnotes
 135          echo " Done\n";
 136      }
 137  
 138      /**
 139       * Compute and return the new link
 140       *
 141       */
 142  	private function getReplacementString( $oldLinkTag, $oldId ) {
 143          $linkTag = config_get( 'bug_link_tag' );
 144  
 145          $replacement = '';
 146          switch( $this->strategy_ ) {
 147              case 'link':
 148                  $replacement = $this->source_->get_issue_url( $oldId );
 149                  break;
 150  
 151              case 'disable':
 152                  $replacement = htmlFullEntities( $oldLinkTag ) . $oldId;
 153                  break;
 154  
 155              case 'renumber':
 156                  if( $this->itemsMap_->exists( 'issue', $oldId ) ) {
 157                      // regular renumber
 158                      $replacement = $linkTag . $this->itemsMap_->getNewID( 'issue', $oldId );
 159                  } else {
 160                      // fallback strategy
 161                      if( $this->fallback_ == 'link' ) {
 162                          $replacement = $this->source_->get_issue_url( $oldId );
 163                      }
 164                      if( $this->fallback_ == 'disable' ) {
 165                          $replacement = htmlFullEntities( $oldLinkTag ) . $oldId;
 166                      }
 167                  }
 168                  break;
 169  
 170              default:
 171                  echo "Unknown method";
 172          }
 173  
 174          //echo "$oldId -> $replacement\n"; // DEBUG
 175          return $replacement;
 176      }
 177  
 178  	private function get_importer_object( $p_element_name ) {
 179          $importer = null;
 180          switch( $p_element_name ) {
 181              case 'issue':
 182                  $importer = new ImportXml_Issue( $this->keepCategory_, $this->defaultCategory_ );
 183                  break;
 184          }
 185          return $importer;
 186      }
 187  }
 188  
 189  /** candidates for string api **/
 190  
 191  /**
 192   * Convert each character of the passed string to the
 193   * corresponding HTML entity.
 194   */
 195  function htmlFullEntities( $string ) {
 196      $chars = str_split( $string );
 197      $escaped = array_map( 'getEntity', $chars );
 198      return implode( '', $escaped );
 199  }
 200  
 201  function getEntity( $char ) {
 202      return '&#' . ord( $char ) . ';';
 203  }


Generated: Thu Jul 28 15:48:31 2011 Cross-referenced by PHPXref 0.7