Exemple #1
0
 /**
  * Search for deleted properties and use the editor to delete these entries
  *
  * @param Config    $oldconfig  The config representing the state before the change
  * @param Config    $newconfig  The config representing the state after the change
  * @param Document  $doc
  *
  * @throws ProgrammingError
  */
 protected function diffPropertyDeletions(Config $oldconfig, Config $newconfig, Document $doc)
 {
     // Iterate over all properties in the old configuration file and remove those that don't
     // exist in the new config
     foreach ($oldconfig->toArray() as $section => $directives) {
         if (!is_array($directives)) {
             Logger::warning('Section-less property ' . (string) $directives . ' was ignored.');
             continue;
         }
         if ($newconfig->hasSection($section)) {
             $newSection = $newconfig->getSection($section);
             $oldDomSection = $doc->getSection($section);
             foreach ($directives as $key => $value) {
                 if ($value instanceof ConfigObject) {
                     throw new ProgrammingError('Cannot diff recursive configs');
                 }
                 if (null === $newSection->get($key) && $oldDomSection->hasDirective($key)) {
                     $oldDomSection->removeDirective($key);
                 }
             }
         } else {
             $doc->removeSection($section);
         }
     }
 }
Exemple #2
0
 /**
  * Read the ini file contained in a string and return a mutable DOM that can be used
  * to change the content of an INI file.
  *
  * @param $str                  A string containing the whole ini file
  *
  * @return Document             The mutable DOM object.
  * @throws ConfigurationError   In case the file is not parseable
  */
 public static function parseIni($str)
 {
     $doc = new Document();
     $sec = null;
     $dir = null;
     $coms = array();
     $state = self::LINE_START;
     $escaping = null;
     $token = '';
     $line = 0;
     for ($i = 0; $i < strlen($str); $i++) {
         $s = $str[$i];
         switch ($state) {
             case self::LINE_START:
                 if (ctype_space($s)) {
                     continue;
                 }
                 switch ($s) {
                     case '[':
                         $state = self::SECTION;
                         break;
                     case ';':
                         $state = self::COMMENT;
                         break;
                     default:
                         $state = self::DIRECTIVE_KEY;
                         $token = $s;
                         break;
                 }
                 break;
             case self::ESCAPE:
                 $token .= $s;
                 $state = $escaping;
                 $escaping = null;
                 break;
             case self::SECTION:
                 if ($s === "\n") {
                     self::throwParseError('Unterminated SECTION', $line);
                 } elseif ($s === '\\') {
                     $state = self::ESCAPE;
                     $escaping = self::SECTION;
                 } elseif ($s !== ']') {
                     $token .= $s;
                 } else {
                     $sec = new Section($token);
                     $sec->setCommentsPre($coms);
                     $doc->addSection($sec);
                     $dir = null;
                     $coms = array();
                     $state = self::LINE_END;
                     $token = '';
                 }
                 break;
             case self::DIRECTIVE_KEY:
                 if ($s !== '=') {
                     $token .= $s;
                 } else {
                     $dir = new Directive($token);
                     $dir->setCommentsPre($coms);
                     if (isset($sec)) {
                         $sec->addDirective($dir);
                     } else {
                         Logger::warning(sprintf('Ini parser warning: section-less directive "%s" ignored. (l. %d)', $token, $line));
                     }
                     $coms = array();
                     $state = self::DIRECTIVE_VALUE_START;
                     $token = '';
                 }
                 break;
             case self::DIRECTIVE_VALUE_START:
                 if (ctype_space($s)) {
                     continue;
                 } elseif ($s === '"') {
                     $state = self::DIRECTIVE_VALUE_QUOTED;
                 } else {
                     $state = self::DIRECTIVE_VALUE;
                     $token = $s;
                 }
                 break;
             case self::DIRECTIVE_VALUE:
                 /*
                     Escaping non-quoted values is not supported by php_parse_ini, it might
                     be reasonable to include in case we are switching completely our own
                     parser implementation
                 */
                 if ($s === "\n" || $s === ";") {
                     $dir->setValue($token);
                     $token = '';
                     if ($s === "\n") {
                         $state = self::LINE_START;
                         $line++;
                     } elseif ($s === ';') {
                         $state = self::COMMENT;
                     }
                 } else {
                     $token .= $s;
                 }
                 break;
             case self::DIRECTIVE_VALUE_QUOTED:
                 if ($s === '\\') {
                     $state = self::ESCAPE;
                     $escaping = self::DIRECTIVE_VALUE_QUOTED;
                 } elseif ($s !== '"') {
                     $token .= $s;
                 } else {
                     $dir->setValue($token);
                     $token = '';
                     $state = self::LINE_END;
                 }
                 break;
             case self::COMMENT:
             case self::COMMENT_END:
                 if ($s !== "\n") {
                     $token .= $s;
                 } else {
                     $com = new Comment();
                     $com->setContent($token);
                     $token = '';
                     // Comments at the line end belong to the current line's directive or section. Comments
                     // on empty lines belong to the next directive that shows up.
                     if ($state === self::COMMENT_END) {
                         if (isset($dir)) {
                             $dir->setCommentPost($com);
                         } else {
                             $sec->setCommentPost($com);
                         }
                     } else {
                         $coms[] = $com;
                     }
                     $state = self::LINE_START;
                     $line++;
                 }
                 break;
             case self::LINE_END:
                 if ($s === "\n") {
                     $state = self::LINE_START;
                     $line++;
                 } elseif ($s === ';') {
                     $state = self::COMMENT_END;
                 }
                 break;
         }
     }
     // process the last token
     switch ($state) {
         case self::COMMENT:
         case self::COMMENT_END:
             $com = new Comment();
             $com->setContent($token);
             if ($state === self::COMMENT_END) {
                 if (isset($dir)) {
                     $dir->setCommentPost($com);
                 } else {
                     $sec->setCommentPost($com);
                 }
             } else {
                 $coms[] = $com;
             }
             break;
         case self::DIRECTIVE_VALUE:
             $dir->setValue($token);
             $sec->addDirective($dir);
             break;
         case self::ESCAPE:
         case self::DIRECTIVE_VALUE_QUOTED:
         case self::DIRECTIVE_KEY:
         case self::SECTION:
             self::throwParseError('File ended in unterminated state ' . $state, $line);
     }
     if (!empty($coms)) {
         $doc->setCommentsDangling($coms);
     }
     return $doc;
 }