1<?php 2 3/** 4 * A linter which uses [[http://php.net/simplexml | SimpleXML]] to detect 5 * errors and potential problems in XML files. 6 */ 7final class ArcanistXMLLinter extends ArcanistLinter { 8 9 public function getInfoName() { 10 return pht('SimpleXML Linter'); 11 } 12 13 public function getInfoDescription() { 14 return pht('Uses SimpleXML to detect formatting errors in XML files.'); 15 } 16 17 public function getLinterName() { 18 return 'XML'; 19 } 20 21 public function getLinterConfigurationName() { 22 return 'xml'; 23 } 24 25 public function canRun() { 26 return extension_loaded('libxml') && extension_loaded('simplexml'); 27 } 28 29 public function getCacheVersion() { 30 return LIBXML_VERSION; 31 } 32 33 public function lintPath($path) { 34 libxml_use_internal_errors(true); 35 libxml_clear_errors(); 36 37 if (simplexml_load_string($this->getData($path))) { 38 // XML appears to be valid. 39 return; 40 } 41 42 foreach (libxml_get_errors() as $error) { 43 $message = id(new ArcanistLintMessage()) 44 ->setPath($path) 45 ->setLine($error->line) 46 ->setChar($error->column ? $error->column : null) 47 ->setCode($this->getLintMessageFullCode($error->code)) 48 ->setName(pht('LibXML Error')) 49 ->setDescription(trim($error->message)); 50 51 switch ($error->level) { 52 case LIBXML_ERR_NONE: 53 $message->setSeverity(ArcanistLintSeverity::SEVERITY_DISABLED); 54 break; 55 56 case LIBXML_ERR_WARNING: 57 $message->setSeverity(ArcanistLintSeverity::SEVERITY_WARNING); 58 break; 59 60 case LIBXML_ERR_ERROR: 61 case LIBXML_ERR_FATAL: 62 $message->setSeverity(ArcanistLintSeverity::SEVERITY_ERROR); 63 break; 64 65 default: 66 $message->setSeverity(ArcanistLintSeverity::SEVERITY_ADVICE); 67 break; 68 } 69 70 $this->addLintMessage($message); 71 } 72 } 73 74} 75