Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
CargoLuaLibrary
0.00% covered (danger)
0.00%
0 / 63
0.00% covered (danger)
0.00%
0 / 4
650
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 cargoQuery
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
182
 cargoFormat
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
30
 convertLuaTableToArray
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
42
1<?php
2
3/**
4 * Class for exposing the parser functions for Cargo to Lua.
5 * The functions are available via mw.ext.cargo Lua table.
6 *
7 * @author Yaron Koren.
8 * @author Alexander Mashin.
9 */
10class CargoLuaLibrary extends Scribunto_LuaLibraryBase {
11
12    /**
13     * Register two Lua bindings: mw.ext.cargo.query and mw.ext.cargo.format
14     * @return array|null
15     */
16    public function register() {
17        $lib = [
18            'query' => [ $this, 'cargoQuery' ],
19            'format' => [ $this, 'cargoFormat' ]
20        ];
21        return $this->getEngine()->registerInterface( __DIR__ . '/../cargo.lua', $lib, [] );
22    }
23
24    /**
25     * Implementation of mw.ext.cargo.query.
26     *
27     * @param string $tables
28     * @param string $fields
29     * @param array|null $args
30     * @return array[]
31     * @throws MWException
32     * @throws Scribunto_LuaError
33     */
34    public function cargoQuery( $tables, $fields, $args ): array {
35        $this->checkType( 'query', 1, $tables, 'string' );
36        $this->checkType( 'query', 2, $fields, 'string' );
37        $this->checkTypeOptional( 'query', 3, $args, 'table', [] );
38
39        if ( isset( $args['where'] ) ) {
40            $where = $args['where'];
41        } else {
42            $where = null;
43        }
44        if ( isset( $args['join'] ) ) {
45            $join = $args['join'];
46        } else {
47            $join = null;
48        }
49        if ( isset( $args['groupBy'] ) ) {
50            $groupBy = $args['groupBy'];
51        } else {
52            $groupBy = null;
53        }
54        if ( isset( $args['having'] ) ) {
55            $having = $args['having'];
56        } else {
57            $having = null;
58        }
59        if ( isset( $args['orderBy'] ) ) {
60            $orderBy = $args['orderBy'];
61        } else {
62            $orderBy = null;
63        }
64        if ( isset( $args['limit'] ) ) {
65            $limit = $args['limit'];
66        } else {
67            $limit = null;
68        }
69        if ( isset( $args['offset'] ) ) {
70            $offset = $args['offset'];
71        } else {
72            $offset = null;
73        }
74
75        try {
76            $query = CargoSQLQuery::newFromValues( $tables, $fields, $where, $join,
77                $groupBy, $having, $orderBy, $limit, $offset );
78            $rows = $query->run();
79        } catch ( Exception $e ) {
80            // Allow for error handling within Lua.
81            throw new Scribunto_LuaError( $e->getMessage() );
82        }
83
84        $result = [];
85
86        $fieldArray = CargoUtils::smartSplit( ',', $fields );
87
88        $rowIndex = 1; // because Lua arrays start at 1
89        foreach ( $rows as $row ) {
90            $values = [];
91            foreach ( $fieldArray as $fieldString ) {
92                $alias = $query->getAliasForFieldString( $fieldString );
93                if ( !isset( $row[$alias] ) ) {
94                    if ( !$GLOBALS["wgCargoLegacyNullLuaFieldsAsEmptyString"] ) {
95                        continue;
96                    }
97                    $row[$alias] = "";
98                }
99                $nameArray = CargoUtils::smartSplit( '=', $fieldString );
100                $name = $nameArray[ count( $nameArray ) - 1 ];
101                $values[$name] = htmlspecialchars_decode( $row[$alias] );
102            }
103            $result[$rowIndex++] = $values;
104        }
105
106        return [ $result ];
107    }
108
109    /**
110     * Implementation of mw.ext.cargo.formatTable().
111     *
112     * @param array[] $values A 2D row-based array of associative arrays corresponding to a Lua table.
113     * @param array $params Parameters, as passed to {{#cargo_query:}}.
114     * @return array [ [ 0 => string, 'noparse' => bool, 'isHTML' => bool ] ].
115     */
116    public function cargoFormat( array $values, array $params ): array {
117        $mappings = [];
118        $rows = [];
119        foreach ( self::convertLuaTableToArray( $values ) as $row ) {
120            if ( is_array( $row ) ) {
121                $rows[] = $row;
122                foreach ( $row as $key => $value ) {
123                    if ( !isset( $mappings[$key] ) ) {
124                        $mappings[$key] = $key;
125                    }
126                }
127            }
128        }
129        return [
130            CargoDisplayFormat::formatArray( $this->getParser(), $rows, $mappings, self::convertLuaTableToArray( $params ) )
131        ];
132    }
133
134    /**
135     * Convert 1-based Lua table to 0-based PHP array.
136     *
137     * @param mixed $table
138     *
139     * @return mixed
140     */
141    private static function convertLuaTableToArray( $table ) {
142        if ( is_array( $table ) ) {
143            $converted = [];
144            foreach ( $table as $key => $value ) {
145                if ( is_int( $key ) || is_string( $key ) ) {
146                    $new_key = is_int( $key ) ? $key - 1 : $key;
147                    $converted[$new_key] = self::convertLuaTableToArray( $value );
148                }
149            }
150            return $converted;
151        }
152        return $table;
153    }
154}