Completed
Pull Request — master (#114)
by Naman
27:16
created

AuthorizeNetSOAP::getSoapMethods()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3
Metric Value
dl 0
loc 14
ccs 10
cts 10
cp 1
rs 9.4285
cc 3
eloc 10
nc 3
nop 0
crap 3
1
<?php
2
/**
3
 * A simple wrapper for the SOAP API as well as a helper function
4
 * to generate a documentation file from the WSDL.
5
 *
6
 * @package    AuthorizeNet
7
 * @subpackage AuthorizeNetSoap
8
 */
9
10
/**
11
 * A simple wrapper for the SOAP API as well as a helper function
12
 * to generate a documentation file from the WSDL.
13
 *
14
 * @package    AuthorizeNet
15
 * @subpackage AuthorizeNetSoap
16
 * @todo       Make the doc file a usable class.
17
 */
18
class AuthorizeNetSOAP extends SoapClient
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
19
{
20
    const WSDL_URL = "https://api2.authorize.net/soap/v1/Service.asmx?WSDL";
21
    const LIVE_URL = "https://api2.authorize.net/soap/v1/Service.asmx";
22
    const SANDBOX_URL = "https://apitest.authorize.net/soap/v1/Service.asmx";
23
    
24
    public $sandbox;
25
    
26
    /**
27
     * Constructor
28
     */
29 2
    public function __construct()
30
    {
31 2
        parent::__construct(self::WSDL_URL);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class SoapClient as the method __construct() does only exist in the following sub-classes of SoapClient: AuthorizeNetSOAP. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
32 2
        $this->__setLocation(self::SANDBOX_URL);
33 2
    }
34
    
35
    /**
36
     * Switch between the sandbox or production gateway.
37
     *
38
     * @param bool
39
     */
40
    public function setSandbox($bool)
41
    {
42
        $this->__setLocation(($bool ? self::SANDBOX_URL : self::LIVE_URL));
43
    }
44
45
    /**
46
     * Get all types as PHP Code.
47
     * @return string
48
     */
49 1
    public function getSoapTypes()
50
    {
51 1
        $string = "";
52 1
        $types = $this->__getTypes();
53 1
        foreach ($types as $type) {
54 1
            if (preg_match("/struct /",$type)) {
55 1
                $type = preg_replace("/struct /","class ",$type);
56 1
                $type = preg_replace("/ (\w+) (\w+);/","    // $1\n    public \$$2;",$type);
57 1
                $string .= $type ."\n";
58
            }
59
        }
60 1
        return $string;
61
    }
62
    
63
    /**
64
     * Get all methods as PHP Code.
65
     * @return string
66
     */
67 1
    public function getSoapMethods()
68
    {
69 1
        $string = "";
70 1
        $functions = array();
71 1
        $methods = $this->__getFunctions();
72 1
        foreach ($methods as $index => $method) {
73 1
            $sig = explode(" ", $method, 2);
74 1
            if (!isset($functions[$sig[1]])) {
75 1
                $string .= "    /**\n     * @return {$sig[0]}\n    */\n    public function {$sig[1]} {}\n\n";
76 1
                $functions[$sig[1]] = true;
77
            }
78
        }
79 1
        return $string;
80
    }
81
    
82
    /**
83
     * Create a file from the WSDL for reference.
84
     */
85 1
    public function saveSoapDocumentation($path)
86
    {
87 1
        $string =  "<?php\n";
88 1
        $string .= "/**\n";
89 1
        $string .= " * Auto generated documentation for the AuthorizeNetSOAP API.\n";
90 1
        $string .= " * Generated " . date("m/d/Y") . "\n";
91 1
        $string .= " */\n";
92 1
        $string .= "class AuthorizeNetSOAP\n";
93 1
        $string .= "{\n" . $this->getSoapMethods() . "\n}\n\n" . $this->getSoapTypes() ."\n\n ?>";
94 1
        return file_put_contents($path, $string);
95
    }
96
    
97
    
98
    
99
}