Completed
Push — master ( f7714d...033cf2 )
by
unknown
01:51
created

OrderStepPaymentCheck::getCMSFields()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 19
nc 1
nop 0
1
<?php
2
class OrderStepPaymentCheck extends OrderStep implements OrderStepInterface
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...
3
{
4
    private static $verbose = false;
0 ignored issues
show
Unused Code introduced by
The property $verbose 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...
5
6
    /**
7
     * @var String
8
     */
9
    protected $emailClassName = "OrderStepPaymentCheck_Email";
10
11
    private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
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...
12
        'SendPaymentCheckEmail' => 'Boolean',
13
        'MinDays' => 'Int',
14
        'MaxDays' => 'Int',
15
        'LinkText' => 'Varchar'
16
    );
17
18
    private static $defaults = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
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...
19
        'CustomerCanEdit' => 0,
20
        'CustomerCanCancel' => 0,
21
        'CustomerCanPay' => 0,
22
        'Name' => 'Send Payment Reminder',
23
        'Code' => 'PAYMENTCHECK',
24
        "ShowAsInProcessOrder" => true,
25
        "HideStepFromCustomer" => true,
26
        'SendPaymentCheckEmail' => true,
27
        'MinDays' => 10,
28
        'MaxDays' => 20
29
    );
30
31
32
    public function getCMSFields()
33
    {
34
        $fields = parent::getCMSFields();
35
        $fields->addFieldsToTab(
36
            'Root.CustomerMessage',
37
            array(
38
                CheckboxField::create('SendPaymentCheckEmail', 'Send payment reminder email to customer?'),
39
                $minDaysField = NumericField::create('MinDays', "<strong>Min Days</strong> before sending e-mail"),
40
                $maxDaysField = NumericField::create('MaxDays', "<strong>Max Days</strong> before cancelling order")
41
            ),
42
            "EmailSubject"
43
        );
44
        $minDaysField->setRightTitle('What is the <strong>mininum number of days to wait after the order has been placed</strong> before this email should be sent?');
45
        $maxDaysField->setRightTitle('What is the <strong>maxinum number of days to wait after the order has been placed </strong> before the order should be cancelled.');
46
        $fields->addFieldsToTab(
47
            'Root.CustomerMessage',
48
            array(
49
                TextField::create(
50
                    'LinkText',
51
                    _t('OrderStepPaymentCheck.BUTTONTEXT', 'Link Text')
52
                )->setRightTitle('This is the text displayed on the "complete your order" link/button')
53
            )
54
        );
55
        return $fields;
56
    }
57
58
    public function initStep(Order $order)
59
    {
60
        //make sure we can send emails at all.
61
        if ($this->SendPaymentCheckEmail) {
0 ignored issues
show
Documentation introduced by
The property SendPaymentCheckEmail does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
62
            Config::inst()->update("OrderStep", "number_of_days_to_send_update_email", $this->MaxDays);
0 ignored issues
show
Documentation introduced by
The property MaxDays does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
63
        }
64
65
        return true;
66
    }
67
68
    public function doStep(Order $order)
69
    {
70
        //if the order has been paid then do not worry about it at all!
71
        if ($order->IsPaid()) {
72
            return true;
73
        }
74
        //do we send at all?
75
        elseif ($this->SendPaymentCheckEmail) {
0 ignored issues
show
Documentation introduced by
The property SendPaymentCheckEmail does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
76
            // too late to send
77
            if ($this->isExpiredPaymentCheckStep($order)) {
78
                //cancel order ....
79
                if ($this->Config()->get("verbose")) {
80
                    DB::alteration_message(" - Time to send payment reminder is expired ... archive email");
81
                }
82
                // cancel as the member placing the order
83
                $member = $order->CreateOrReturnExistingMember();
84
                if (! $member) {
85
                    $member = EcommerceRole::get_default_shop_admin_user();
86
                }
87
                $order->Cancel(
88
                    $member,
0 ignored issues
show
Compatibility introduced by
$member of type object<DataObject> is not a sub-type of object<Member>. It seems like you assume a child class of the class DataObject to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
89
                    _t('OrderStep.CANCELLED_DUE_TO_NON_PAYMENT', 'Cancelled due to non-payment')
90
                );
91
92
                return true;
93
            }
94
            //is now the right time to send?
95
            elseif ($this->isReadyToGo($order)) {
96
                $subject = $this->EmailSubject;
0 ignored issues
show
Documentation introduced by
The property EmailSubject does not exist on object<OrderStepPaymentCheck>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
97
                $message = $this->CustomerMessage;
0 ignored issues
show
Documentation introduced by
The property CustomerMessage does not exist on object<OrderStepPaymentCheck>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
98
                if ($this->hasBeenSent($order, false)) {
99
                    if ($this->Config()->get("verbose")) {
100
                        DB::alteration_message(" - already sent!");
101
                    }
102
103
                    return true; //do nothing
104
                } else {
105
                    if ($this->Config()->get("verbose")) {
106
                        DB::alteration_message(" - Sending it now!");
107
                    }
108
                    return $order->sendEmail(
109
                        $subject,
110
                        $message,
111
                        $resend = false,
112
                        $adminOnly = false,
113
                        $this->getEmailClassName()
114
                    );
115
                }
116
            }
117
            //wait until later....
118
            else {
119
                if ($this->Config()->get("verbose")) {
120
                    DB::alteration_message(" - We need to wait until minimum number of days.");
121
                }
122
                return false;
123
            }
124
        } else {
125
            return true;
126
        }
127
    }
128
129
    /**
130
     * can continue if emails has been sent or if there is no need to send a receipt.
131
     * @param DataObject $order Order
132
     * @return DataObject | Null - DataObject = next OrderStep
0 ignored issues
show
Documentation introduced by
Should the return type not be DataObject|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...
133
     **/
134
    public function nextStep(Order $order)
135
    {
136
        if ($this->isExpiredPaymentCheckStep($order)) {
137
            //archive order as we have cancelled...
138
139
            return $lastOrderStep = OrderStep::get()->last();
0 ignored issues
show
Unused Code introduced by
$lastOrderStep is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
140
        } elseif (
141
             $order->IsPaid()
142
        ) {
143
            if ($this->Config()->get("verbose")) {
144
                DB::alteration_message(" - Moving to next step");
145
            }
146
            return parent::nextStep($order);
147
        } else {
148
            if ($this->Config()->get("verbose")) {
149
                DB::alteration_message(" - no next step: has not been sent");
150
            }
151
            return null;
152
        }
153
    }
154
155
    /**
156
     * For some ordersteps this returns true...
157
     * @return Boolean
158
     **/
159
    protected function hasCustomerMessage()
160
    {
161
        return true;
162
    }
163
164
    /**
165
     * Explains the current order step.
166
     * @return String
167
     */
168
    protected function myDescription()
169
    {
170
        return "The customer is sent a payment reminder email.";
171
    }
172
173
    /**
174
     * returns true if the Minimum number of days is met....
175
     * @param Order
176
     * @return Boolean
177
     */
178
    protected function isReadyToGo(Order $order)
179
    {
180
        if ($this->MinDays) {
0 ignored issues
show
Documentation introduced by
The property MinDays does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
181
            $log = $order->SubmissionLog();
182
            if ($log) {
183
                $createdTS = strtotime($log->Created);
184
                $nowTS = strtotime('now');
185
                $startSendingTS = strtotime("+{$this->MinDays} days", $createdTS);
0 ignored issues
show
Documentation introduced by
The property MinDays does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
186
                //current TS = 10
187
                //order TS = 8
188
                //add 4 days: 12
189
                //thus if 12 <= now then go for it (start point in time has passed)
190
                if ($this->Config()->get("verbose")) {
191
                    DB::alteration_message("Time comparison: Start Sending TS: ".$startSendingTS." current TS: ".$nowTS.". If SSTS > NowTS then Go for it.");
192
                }
193
                return ($startSendingTS <= $nowTS) ? true : false;
194
            } else {
195
                user_error("can not find order log for ".$order->ID);
196
                return false;
197
            }
198
        } else {
199
            //send immediately
200
            return true;
201
        }
202
    }
203
204
    /**
205
     * returns true if it is too late to send the  payment reminder step
206
     * @param Order
207
     * @return Boolean
208
     */
209
    protected function isExpiredPaymentCheckStep(Order $order)
210
    {
211
        if ($this->MaxDays) {
0 ignored issues
show
Documentation introduced by
The property MaxDays does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
212
            $log = $order->SubmissionLog();
213
            if ($log) {
214
                $createdTS = strtotime($log->Created);
215
                $nowTS = strtotime('now');
216
                $stopSendingTS = strtotime('+'.$this->MaxDays.' days', $createdTS);
0 ignored issues
show
Documentation introduced by
The property MaxDays does not exist on object<OrderStepPaymentCheck>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
217
218
                return ($stopSendingTS < $nowTS) ? true : false;
219
            } else {
220
                user_error("can not find order log for ".$order->ID);
221
                return false;
222
            }
223
        } else {
224
            return true;
225
        }
226
    }
227
228
    public function hasBeenSent(Order $order, $checkDateOfOrder = true)
229
    {
230
        return OrderEmailRecord::get()->filter(
231
            array(
232
                "OrderEmailRecord.OrderID" => $order->ID,
233
                "OrderEmailRecord.OrderStepID" => $this->ID,
234
                "OrderEmailRecord.Result" => 1
235
            )
236
        )->count() ? true : parent::hasBeenSent($order, $checkDateOfOrder);
237
    }
238
}
239