aboutsummaryrefslogblamecommitdiffstats
path: root/src/XmlRpcMethod.php
blob: 001169bacab699cbac13ba7e9b9f6464daa26e45 (plain) (tree)
1
2
3
4
5
6
7
8
9








                                                       

              
















                                                                              
                                
       
                                                            
     
                                                      
 
                                        
 


                            
 






                                                                
                            
                                       


                          










                                                           







                              














                                                           











                                                                            
<?php

// SPDX-FileCopyrightText: 2024 Eilertsens Kodeknekkeri
// SPDX-FileCopyrightText: 2024 Harald Eilertsen
//
// SPDX-License-Identifier: AGPL-3.0-or-later

namespace VolseNet\Webtrap;

use XMLReader;

/**
 * A representation of an XML-RPC method call.
 *
 * This is just a representation to hold information about the attempted
 * call. It does not try to perform any action on it.
 */
class XmlRpcMethod
{
    /**
     * Parse raw XML to an XmlRpcMethod object.
     *
     * We're not very strict when parsing, but trying to extract the
     * most useful information. At the moment that is the method `name`,
     * and an array of the `params` passed to the method.
     *
     * @param string $payload   The raw XML representation of the method call.
     *
     * @return XmlRpcMethod|null
     */
    public static function parse(string $payload): self|null
    {
        $errorflag = libxml_use_internal_errors(true);

        $xml = XMLReader::XML($payload);

        $method_name = null;
        $params = [];
        $expect = null;

        while ($xml->read()) {
            $tag = strtolower($xml->name);
            switch ($tag) {
                case 'methodname':
                case 'value':
                    if ($xml->nodeType === XMLReader::ELEMENT) {
                        $expect = $tag;
                    } else {
                        $expect = null;
                    }
                    break;

                case '#text':
                    if ($xml->hasValue) {
                        switch ($expect) {
                            case 'methodname':
                                $method_name = $xml->value;
                                break;

                            case 'value':
                                $params[] = $xml->value;
                                break;
                        }
                    }
                    break;

                default:
                    // nothing
            }
        }

        $errors = libxml_get_errors();
        libxml_use_internal_errors($errorflag);

        if (! empty($errors)) {
            throw new \RuntimeException(
                'errors while parsing XML',
                $errors[0]->code
            );
        }

        if (! empty($method_name)) {
            return new XmlRpcMethod($method_name, $params);
        }

        return null;
    }

    /**
     * Constructs a new XmlRpcMethod object from the method name and params.
     *
     * @param string $name      The method name
     * @param array $params     An array or params for the method call.
     */
    public function __construct(public string $name, public array $params)
    {
    }
}