Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
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 / 55
0.00% covered (danger)
0.00%
0 / 4
342
0.00% covered (danger)
0.00%
0 / 1
 register
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 cargoQuery
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
42
 cargoFormat
0.00% covered (danger)
0.00%
0 / 11
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        $where = $args['where'] ?? null;
40        $join = $args['join'] ?? null;
41        $groupBy = $args['groupBy'] ?? null;
42        $having = $args['having'] ?? null;
43        $orderBy = $args['orderBy'] ?? null;
44        $limit = $args['limit'] ?? null;
45        $offset = $args['offset'] ?? null;
46
47        try {
48            $query = CargoSQLQuery::newFromValues( $tables, $fields, $where, $join,
49                $groupBy, $having, $orderBy, $limit, $offset );
50            $rows = $query->run();
51        } catch ( Exception $e ) {
52            // Allow for error handling within Lua.
53            throw new Scribunto_LuaError( $e->getMessage() );
54        }
55
56        $result = [];
57
58        $fieldArray = CargoUtils::smartSplit( ',', $fields );
59
60        $rowIndex = 1; // because Lua arrays start at 1
61        foreach ( $rows as $row ) {
62            $values = [];
63            foreach ( $fieldArray as $fieldString ) {
64                $alias = $query->getAliasForFieldString( $fieldString );
65                if ( !isset( $row[$alias] ) ) {
66                    if ( !$GLOBALS["wgCargoLegacyNullLuaFieldsAsEmptyString"] ) {
67                        continue;
68                    }
69                    $row[$alias] = "";
70                }
71                $nameArray = CargoUtils::smartSplit( '=', $fieldString );
72                $name = $nameArray[ count( $nameArray ) - 1 ];
73                $values[$name] = htmlspecialchars_decode( $row[$alias] );
74            }
75            $result[$rowIndex++] = $values;
76        }
77
78        return [ $result ];
79    }
80
81    /**
82     * Implementation of mw.ext.cargo.formatTable().
83     *
84     * @param array[] $values A 2D row-based array of associative arrays corresponding to a Lua table.
85     * @param array $params Parameters, as passed to {{#cargo_query:}}.
86     * @return array [ [ 0 => string, 'noparse' => bool, 'isHTML' => bool ] ].
87     */
88    public function cargoFormat( array $values, array $params ): array {
89        $mappings = [];
90        $rows = [];
91        foreach ( self::convertLuaTableToArray( $values ) as $row ) {
92            if ( is_array( $row ) ) {
93                $rows[] = $row;
94                foreach ( $row as $key => $value ) {
95                    if ( !isset( $mappings[$key] ) ) {
96                        $mappings[$key] = $key;
97                    }
98                }
99            }
100        }
101        return [
102            CargoDisplayFormat::formatArray( $this->getParser(), $rows, $mappings, self::convertLuaTableToArray( $params ) )
103        ];
104    }
105
106    /**
107     * Convert 1-based Lua table to 0-based PHP array.
108     *
109     * @param mixed $table
110     *
111     * @return mixed
112     */
113    private static function convertLuaTableToArray( $table ) {
114        if ( is_array( $table ) ) {
115            $converted = [];
116            foreach ( $table as $key => $value ) {
117                if ( is_int( $key ) || is_string( $key ) ) {
118                    $new_key = is_int( $key ) ? $key - 1 : $key;
119                    $converted[$new_key] = self::convertLuaTableToArray( $value );
120                }
121            }
122            return $converted;
123        }
124        return $table;
125    }
126}