Implement extension registration from an extension.json file
[mediawiki.git] / includes / content / JsonContent.php
blobff3b25b8b262079528219b551f5cfbf93ec9b32e
1 <?php
2 /**
3 * JSON Content Model
5 * This class requires the root structure to be an object (not primitives or arrays).
7 * @file
9 * @author Ori Livneh <ori@wikimedia.org>
10 * @author Kunal Mehta <legoktm@gmail.com>
13 /**
14 * Represents the content of a JSON content.
15 * @since 1.24
17 class JsonContent extends TextContent {
19 /**
20 * @since 1.25
21 * @var Status
23 protected $jsonParse;
25 /**
26 * @param string $text JSON
28 public function __construct( $text ) {
29 parent::__construct( $text, CONTENT_MODEL_JSON );
32 /**
33 * Decodes the JSON into a PHP associative array.
35 * @deprecated since 1.25 Use getData instead.
36 * @return array|null
38 public function getJsonData() {
39 wfDeprecated( __METHOD__, '1.25' );
40 return FormatJson::decode( $this->getNativeData(), true );
43 /**
44 * Decodes the JSON string into a PHP object.
46 * @return Status
48 public function getData() {
49 if ( $this->jsonParse === null ) {
50 $this->jsonParse = FormatJson::parse( $this->getNativeData() );
52 return $this->jsonParse;
55 /**
56 * @return bool Whether content is valid.
58 public function isValid() {
59 return $this->getData()->isGood() && is_object( $this->getData()->getValue() );
62 /**
63 * Pretty-print JSON.
65 * If called before validation, it may return JSON "null".
67 * @return string
69 public function beautifyJSON() {
70 return FormatJson::encode( $this->getData()->getValue(), true );
73 /**
74 * Beautifies JSON prior to save.
76 * @param Title $title Title
77 * @param User $user User
78 * @param ParserOptions $popts
79 * @return JsonContent
81 public function preSaveTransform( Title $title, User $user, ParserOptions $popts ) {
82 // FIXME: WikiPage::doEditContent invokes PST before validation. As such, native data
83 // may be invalid (though PST result is discarded later in that case).
84 if ( !$this->isValid() ) {
85 return $this;
88 return new static( $this->beautifyJSON() );
91 /**
92 * Set the HTML and add the appropriate styles.
94 * @param Title $title
95 * @param int $revId
96 * @param ParserOptions $options
97 * @param bool $generateHtml
98 * @param ParserOutput $output
100 protected function fillParserOutput( Title $title, $revId,
101 ParserOptions $options, $generateHtml, ParserOutput &$output
103 // FIXME: WikiPage::doEditContent generates parser output before validation.
104 // As such, native data may be invalid (though output is discarded later in that case).
105 if ( $generateHtml && $this->isValid() ) {
106 $output->setText( $this->objectTable( $this->getData()->getValue() ) );
107 $output->addModuleStyles( 'mediawiki.content.json' );
108 } else {
109 $output->setText( '' );
114 * Construct an HTML representation of a JSON object.
116 * Called recursively via valueCell().
118 * @param stdClass $mapping
119 * @return string HTML
121 protected function objectTable( $mapping ) {
122 $rows = array();
123 $empty = true;
125 foreach ( $mapping as $key => $val ) {
126 $rows[] = $this->objectRow( $key, $val );
127 $empty = false;
129 if ( $empty ) {
130 $rows[] = Html::rawElement( 'tr', array(),
131 Html::element( 'td', array( 'class' => 'mw-json-empty' ),
132 wfMessage( 'content-json-empty-object' )->text()
136 return Html::rawElement( 'table', array( 'class' => 'mw-json' ),
137 Html::rawElement( 'tbody', array(), join( "\n", $rows ) )
142 * Construct HTML representation of a single key-value pair.
143 * @param string $key
144 * @param mixed $val
145 * @return string HTML.
147 protected function objectRow( $key, $val ) {
148 $th = Xml::elementClean( 'th', array(), $key );
149 $td = self::valueCell( $val );
150 return Html::rawElement( 'tr', array(), $th . $td );
154 * Constructs an HTML representation of a JSON array.
156 * Called recursively via valueCell().
158 * @param array $mapping
159 * @return string HTML
161 protected function arrayTable( $mapping ) {
162 $rows = array();
163 $empty = true;
165 foreach ( $mapping as $val ) {
166 $rows[] = $this->arrayRow( $val );
167 $empty = false;
169 if ( $empty ) {
170 $rows[] = Html::rawElement( 'tr', array(),
171 Html::element( 'td', array( 'class' => 'mw-json-empty' ),
172 wfMessage( 'content-json-empty-array' )->text()
176 return Html::rawElement( 'table', array( 'class' => 'mw-json' ),
177 Html::rawElement( 'tbody', array(), join( "\n", $rows ) )
182 * Construct HTML representation of a single array value.
183 * @param mixed $val
184 * @return string HTML.
186 protected function arrayRow( $val ) {
187 $td = self::valueCell( $val );
188 return Html::rawElement( 'tr', array(), $td );
192 * Construct HTML representation of a single value.
193 * @param mixed $val
194 * @return string HTML.
196 protected function valueCell( $val ) {
197 if ( is_object( $val ) ) {
198 return Html::rawElement( 'td', array(), self::objectTable( $val ) );
200 if ( is_array( $val ) ) {
201 return Html::rawElement( 'td', array(), self::arrayTable( $val ) );
203 if ( is_string( $val ) ) {
204 $val = '"' . $val . '"';
205 } else {
206 $val = FormatJson::encode( $val );
209 return Xml::elementClean( 'td', array( 'class' => 'value' ), $val );