UserDefinedFormWithPayPal::onBeforeWrite()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
/**
4
 */
5
6
class UserDefinedFormWithPayPal extends UserDefinedForm
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...
7
{
8
9
    /**
10
     * map Template Fields ($key) to fields used in the userdefined form
11
     * For example, if the userdefinedforms contains a fields 'LastName'
12
     * then Paypal will be presented with its value as Surname.
13
     * @var Array
14
     */
15
    private static $mapped_fields = array(
0 ignored issues
show
Unused Code introduced by
The property $mapped_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
16
        'Surname' => array("Name", "Surname", "LastName"),
17
        'FirstName' => array("FirstName", "Firstname", "Name"),
18
        'Address1' => array("Address", "Street"),
19
        'Address2' => array("Address", "Address2", "Suburb"),
20
        'City' => array("City", "Town"),
21
        'State' => array("State", "Province"),
22
        'Zip' => array("Zip", "PostalCode", "Zipcode", "Postcode"),
23
        'Country' => array("Country"),
24
        'Email' => array("Email", "E-Mail"),
25
    );
26
27
28
29
    /**
30
     * @var Array Fields on the user defined form page.
31
     */
32
    private static $db = array(
0 ignored issues
show
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
33
        "Amount" => "Double",
34
        "ProductName" => "Varchar(100)",
35
        "ProductCode" => "Varchar(10)",
36
        "CurrencyCode" => "Varchar(5)",
37
        "BusinessEmail" => "Varchar(100)",
38
        "PaypalButtonLabel" => "Varchar(100)",
39
        "BeforePaymentInstructions" => "HTMLText"
40
    );
41
42
    /**
43
     * @var Array Default values of variables when this page is created
44
     */
45
    private static $defaults = array(
0 ignored issues
show
Unused Code introduced by
The property $defaults is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
46
        'PaypalButtonLabel' => 'pay now'
47
    );
48
49
    /**
50
     * Setup the CMS Fields for the User Defined Form
51
     *
52
     * @return FieldSet
53
     */
54
    public function getCMSFields()
55
    {
56
        $fields = parent::getCMSFields();
57
58
        // define tabs
59
        $fields->findOrMakeTab('Root.Paypal', _t('UserDefinedFormWithPayPal.PAYPAL', 'PayPal'));
60
        // field editor
61
        $fields->addFieldToTab("Root.Paypal", new HeaderField("UserDefinedFormWithPayPalRequiredFields", _t('UserDefinedFormWithPayPal.REQUIREDFIELDS', 'Required Fields')));
62
        $fields->addFieldToTab("Root.Paypal", new EmailField("BusinessEmail", _t('UserDefinedFormWithPayPal.BUSINESSEMAIL', 'Email associated with your paypal account - REQUIRED')));
63
        $fields->addFieldToTab("Root.Paypal", new NumericField("Amount", _t('UserDefinedFormWithPayPal.AMOUNT', 'Amount / Charge')));
64
        $fields->addFieldToTab("Root.Paypal", new TextField("ProductCode", _t('UserDefinedFormWithPayPal.PRODUCTCODE', 'Product Code, something that uniquely identifies this form / product')));
65
        $fields->addFieldToTab("Root.Paypal", new TextField("ProductName", _t('UserDefinedFormWithPayPal.PRODUCTNAME', 'Product Name (as shown on PayPal Payment Form)')));
66
        $fields->addFieldToTab("Root.Paypal", new HeaderField("UserDefinedFormWithPayPalNOTRequiredFields", _t('UserDefinedFormWithPayPal.OPTIONALFIELDS', 'Optional Fields')));
67
        $fields->addFieldToTab("Root.Paypal", new TextField("CurrencyCode", _t('UserDefinedFormWithPayPal.CURRENCYCODE', 'Currency Code (e.g. NZD or USD or EUR)')));
68
        $fields->addFieldToTab("Root.Paypal", new TextField("PaypalButtonLabel", _t('UserDefinedFormWithPayPal.PAYPALBUTTONLABEL', 'PayPal Button Text (e.g. pay now)')));
69
        $fields->addFieldToTab("Root.Paypal", new HtmlEditorField("BeforePaymentInstructions", _t('UserDefinedFormWithPayPal.BEFOREPAYMENTINSTRUCTIONS', 'Instructions to go with payment now button (e.g. click on the button above to proceed with your payment)')));
70
        return $fields;
71
    }
72
73
    public function onBeforeWrite()
74
    {
75
        parent::onBeforeWrite();
76
        if (!$this->ProductCode) {
77
            $this->ProductCode = $this->Link();
78
        }
79
    }
80
}
81
82
/**
83
 * Controller for the {@link UserDefinedFormWithPayPal} page type.
84
 *
85
 * @package userform
86
 * @subpackage pagetypes
87
 */
88
89
class UserDefinedFormWithPayPal_Controller extends UserDefinedForm_Controller
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
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...
90
{
91
92
93
    /**
94
     *
95
     * @var SubmittedForm Object
96
     */
97
    protected $mostLikeLySubmission = null;
98
99
    /**
100
     * Process the form that is submitted through the site
101
     *
102
     * @param Array Data
103
     * @param Form Form
104
     * @return Redirection
0 ignored issues
show
Documentation introduced by
Should the return type not be Redirection|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
105
     */
106
    public function process($data, $form)
107
    {
108
        //pre process?
109
        parent::process($data, $form);
110
        //post process
111
        $this->mostLikeLySubmission = SubmittedForm::get()
112
            ->sort("Created", "DESC")
113
            ->limit(1)
114
            ->first();
115
        Session::set("UserDefinedFormWithPayPalID", $this->mostLikeLySubmission->ID);
116
        $paypalIdentifier1 = new SubmittedFormField();
117
        $paypalIdentifier1->Name = "Paypal Identifier";
118
        $paypalIdentifier1->Title = "Paypal Identifier";
119
        $paypalIdentifier1->Value = $this->getCustomCode();
120
        $paypalIdentifier1->ParentID = $this->mostLikeLySubmission->ID;
121
        $paypalIdentifier1->write();
122
        //add a double-check
123
        $paypalIdentifier2 = new SubmittedFormField();
124
        $paypalIdentifier2->Name = "Paypal DoubleCheck";
125
        $paypalIdentifier2->Title = "Paypal DoubleCheck";
126
        $paypalIdentifier2->Value = print_r($data, 1);
127
        $paypalIdentifier2->ParentID = $this->mostLikeLySubmission->ID;
128
        $paypalIdentifier2->write();
129
    }
130
131
    /**
132
     * Handle notification from PAYPAL
133
     * to be completed.
134
     */
135
    public function getnotification()
136
    {
137
        return array();
138
    }
139
140
    /**
141
     * This action handles rendering the "finished" message,
142
     * which is customisable by editing the ReceivedFormSubmission.ss
143
     * template.
144
     *
145
     * @return ViewableData
146
     */
147
    public function finished()
0 ignored issues
show
Coding Style introduced by
finished uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
148
    {
149
        $referrer = isset($_GET['referrer']) ? urldecode($_GET['referrer']) : null;
150
        $this->mostLikeLySubmission = SubmittedForm::get()
151
            ->byID(intval(Session::get("UserDefinedFormWithPayPalID"))-0);
152
        if ($this->mostLikeLySubmission && $this->BusinessEmail) {
153
            $customisedArray = array(
154
                'Link' => $referrer,
155
                'BeforePaymentInstructions' => $this->BeforePaymentInstructions,
156
                'MerchantID' => $this->BusinessEmail,
157
                'ProductName' => $this->ProductName,
158
                'Custom' => $this->getCustomCode(),
159
                'SubmittedFormID' => $this->mostLikeLySubmission->ID,
160
                'Amount' => $this->Amount,
161
                'PaypalButtonLabel' => $this->PaypalButtonLabel,
162
                'CurrencyCode' => $this->CurrencyCode,
163
                'ReturnLink' => $this->Link("paymentmade")
164
            );
165
            $mappedFields = Config::inst()->get("UserDefinedFormWithPayPal", "mapped_fields");
166
            foreach ($mappedFields as $templateField => $forFieldsArray) {
0 ignored issues
show
Bug introduced by
The expression $mappedFields of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
167
                $customisedArray[$templateField] = $this->getSubmittedFormValue($forFieldsArray);
168
            }
169
            return $this->customise(
170
                array(
171
                    'Content' => $this->customise($customisedArray)->renderWith('ReceivedFormSubmissionWithPayPal'),
172
                    'Form' => '',
173
                )
174
            );
175
        } else {
176
            return parent::finished();
177
        }
178
    }
179
180
    /**
181
     * This is the new finished method;
182
     * @return ViewableData
183
     */
184
    public function paymentmade()
185
    {
186
        return parent::finished();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (finished() instead of paymentmade()). Are you sure this is correct? If so, you might want to change this to $this->finished().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
187
    }
188
189
    /**
190
     * Checks for a list of fields in the submitted values to see
191
     * if it is part of the submitted form
192
     * e.g. if the user enters an Email in the form then we can pass this on to Paypal.
193
     * @param Array - array of fields to check for
194
     */
195
    protected function getSubmittedFormValue($nameArray)
196
    {
197
        if ($this->mostLikeLySubmission) {
198
            foreach ($nameArray as $name) {
199
                $name = Convert::raw2sql($name);
200
                $field = SubmittedFormField::get()
201
                    ->filterAny(array("Name" => $name, "Title" => $title))
0 ignored issues
show
Bug introduced by
The variable $title does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
202
                    ->filter(array("ParentID" => $this->mostLikeLySubmission->ID))
203
                    ->first();
204
                if ($field) {
205
                    return Convert::raw2att($field->Value);
206
                }
207
            }
208
        }
209
        return "";
210
    }
211
212
    /**
213
     * returns the unique identifier for the transaction
214
     * we include the page ID and Version in case we need it.
215
     * @return String
216
     */
217
    protected function getCustomCode()
218
    {
219
        return $this->ProductCode."-".$this->mostLikeLySubmission->ID."#".$this->ID."-".$this->Version;
220
    }
221
}
222