Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
28.00% covered (danger)
28.00%
14 / 50
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
JCLuaLibrary
28.00% covered (danger)
28.00%
14 / 50
25.00% covered (danger)
25.00%
1 / 4
138.93
0.00% covered (danger)
0.00%
0 / 1
 register
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 get
37.93% covered (danger)
37.93%
11 / 29
0.00% covered (danger)
0.00%
0 / 1
33.91
 objectToArray
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 reindexTabularData
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3namespace JsonConfig;
4
5use MediaWiki\MediaWikiServices;
6use Scribunto_LuaError;
7use Scribunto_LuaLibraryBase;
8
9class JCLuaLibrary extends Scribunto_LuaLibraryBase {
10
11    public function register() {
12        $functions = [ 'get' => [ $this, 'get' ] ];
13        $moduleFileName = __DIR__ . DIRECTORY_SEPARATOR . 'JCLuaLibrary.lua';
14        return $this->getEngine()->registerInterface( $moduleFileName, $functions, [] );
15    }
16
17    /**
18     * Returns data page as a data table
19     * @param string $titleStr name of the page in the Data namespace
20     * @param string $langCode language code. If '_' is given, returns all codes
21     * @return false[]|mixed[]
22     * @throws Scribunto_LuaError
23     */
24    public function get( $titleStr, $langCode ) {
25        $this->checkType( 'get', 1, $titleStr, 'string' );
26        if ( $langCode === null ) {
27            $language = $this->getParser()->getTargetLanguage();
28        } elseif ( $langCode !== '_' ) {
29            $this->checkType( 'get', 2, $langCode, 'string' );
30            $services = MediaWikiServices::getInstance();
31            if ( $services->getLanguageNameUtils()->isValidCode( $langCode ) ) {
32                $language = $services->getLanguageFactory()->getLanguage( $langCode );
33            } else {
34                throw new Scribunto_LuaError( 'bad argument #2 to "get" (not a valid language code)' );
35            }
36        } else {
37            $language = null;
38        }
39
40        $jct = JCSingleton::parseTitle( $titleStr, NS_DATA );
41        if ( !$jct ) {
42            throw new Scribunto_LuaError( 'bad argument #1 to "get" (not a valid title)' );
43        }
44
45        $content = JCSingleton::getContentFromLocalCache( $jct );
46        if ( $content === null ) {
47            $this->incrementExpensiveFunctionCount();
48            $content = JCSingleton::getContent( $jct );
49
50            $prop = 'jsonconfig_getdata';
51            $output = $this->getParser()->getOutput();
52            $prevValue = (int)( $output->getPageProperty( $prop ) ?? 0 );
53            $output->setNumericPageProperty( $prop, 1 + $prevValue );
54        }
55
56        if ( !$content ) {
57            $result = false;
58        } else {
59            if ( $language === null || !method_exists( $content, 'getLocalizedData' ) ) {
60                $result = $content->getData();
61            } else {
62                /** @var JCDataContent $content */
63                // @phan-suppress-next-line PhanUndeclaredMethod
64                $result = $content->getLocalizedData( $language );
65            }
66            // Always re-index tabular data
67            if ( $content instanceof JCTabularContent ) {
68                self::reindexTabularData( $result );
69            }
70        }
71
72        return [ self::objectToArray( $result ) ];
73    }
74
75    /**
76     * Replace objects with arrays, recursively
77     *
78     * Since LuaSandbox 3.0.0, we can't return objects to Lua anymore. And it
79     * never worked with Scribunto's LuaStandalone engine.
80     *
81     * @param mixed $v
82     * @return mixed
83     */
84    private static function objectToArray( $v ) {
85        if ( is_object( $v ) ) {
86            $v = get_object_vars( $v );
87        }
88        if ( is_array( $v ) ) {
89            $v = array_map( [ self::class, 'objectToArray' ], $v );
90        }
91        return $v;
92    }
93
94    /**
95     * Reindex tabular data so it can be processed by Lua more easily
96     * @param \stdClass $data
97     */
98    public static function reindexTabularData( $data ) {
99        $columnCount = count( $data->schema->fields );
100        $rowCount = count( $data->data );
101        if ( $columnCount > 0 ) {
102            $rowIndexes = range( 1, $columnCount );
103            $data->schema->fields = array_combine( $rowIndexes, $data->schema->fields );
104            if ( $rowCount > 0 ) {
105                $data->data =
106                    array_combine( range( 1, $rowCount ),
107                        array_map( static function ( $row ) use ( $rowIndexes ) {
108                            return array_combine( $rowIndexes, $row );
109                        }, $data->data ) );
110            }
111        } elseif ( $rowCount > 0 ) {
112            // Weird, but legal
113            $data->data = array_combine( range( 1, $rowCount ), $data->data );
114        }
115    }
116}