ElectronicDelivery_OrderStep::addOrderStepFields()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php
2
3
/**
4
 * This file contains the tricks for delivering an order electronically.
5
 *
6
 * Firstly there is a step you can include as an order step.
7
 *
8
 * The order step works out the files to be added to the order
9
 * and the Order Status Log contains all the downloadable files.
10
 *
11
 *
12
 *
13
 * NOTA BENE: your buyable MUST have the following method:
14
 * DownloadFiles();
15
 *
16
 * TODO: add ability to first "disable" and then delete files...
17
 * TODO: add ability to restor downloads
18
 *
19
 *
20
 */
21
22
23
class ElectronicDelivery_OrderStep extends OrderStep
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...
24
{
25
    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...
26
        "SendMessageToCustomer" => "Boolean",
27
        "NumberOfHoursBeforeDownloadGetsDeleted" => "Float"
28
    );
29
30
    private static $many_many = 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 $many_many 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...
31
        "AdditionalFiles" => "File"
32
    );
33
34
    private static $field_labels = 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 $field_labels 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...
35
        "SendMessageToCustomer" => "Send a message to the customer with download details?",
36
        "NumberOfHoursBeforeDownloadGetsDeleted" => "Number of hours before download expires (you can use decimals (e.g. 0.5 equals half-an-hour)."
37
    );
38
39
    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...
40
        "Name" => "Download",
41
        "Code" => "DOWNLOAD",
42
        "Description" => "Customer downloads the files",
43
        "NumberOfHoursBeforeDownloadGetsDeleted" => 72,
44
        "SendMessageToCustomer" => true,
45
46
        //customer privileges
47
        "CustomerCanEdit" => 0,
48
        "CustomerCanCancel" => 0,
49
        "CustomerCanPay" => 0,
50
        //What to show the customer...
51
        "ShowAsUncompletedOrder" => 0,
52
        "ShowAsInProcessOrder" => 1,
53
        "ShowAsCompletedOrder" => 0,
54
        //sort
55
        "Sort" => 37,
56
    );
57
58
    /**
59
     * The method that provides a datalist of files to be downloaded for a buyable.
60
     * @var String
61
     */
62
    private static $download_method_in_byable = "DownloadFiles";
0 ignored issues
show
Unused Code introduced by
The property $download_method_in_byable 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...
63
64
    /**
65
     * The OrderStatusLog that is relevant to the particular step.
66
     * @var String
67
     */
68
    protected $relevantLogEntryClassName = "ElectronicDelivery_OrderLog";
69
70
    /**
71
     * @var String
72
     */
73
    protected $emailClassName = "Order_StatusEmail";
74
75
76
    public function getCMSFields()
77
    {
78
        $fields = parent::getCMSFields();
79
        $fields->addFieldToTab("Root.Main", new HeaderField("NumberOfHoursBeforeDownloadGetsDeleted_Header", _t("ElectronicDelivery_OrderStep.NUMBEROFHOURSBEFOREDOWNLOADGETSDELETED", "Download Management"), 3), "NumberOfHoursBeforeDownloadGetsDeleted");
80
        $fields->addFieldToTab("Root.Main", new HeaderField("SendMessageToCustomer_Header", _t("ElectronicDelivery_OrderStep.SendMessageToCustomer", "Send a message to the customer?"), 3), "SendMessageToCustomer");
81
        $fields->addFieldToTab("Root.AdditionalFiles", new UploadField("AdditionalFiles", _t("ElectronicDelivery_OrderStep.ADDITIONALFILE", "Files to be added to download")));
82
        return $fields;
83
    }
84
85
    /**
86
     * Can always run step.
87
     * remove anything that is expired...
88
     * @param Order $order
89
     * @return Boolean
90
     **/
91
    public function initStep(Order $order)
92
    {
93
        return true;
94
    }
95
96
    /**
97
     * Add the member to the order, in case the member is not an admin.
98
     * @param Order $order
99
     * @return Boolean
100
     **/
101
    public function doStep(Order $order)
102
    {
103
        $logClassName = $this->getRelevantLogEntryClassName();
104
        $obj = $logClassName::get()
105
            ->filter(array("OrderID" => $order->ID))
106
            ->first();
107
        if (!$obj) {
108
            $files = new ArrayList();
109
            $items = $order->Items();
110
            if ($items && $items->count()) {
111
                foreach ($items as $item) {
112
                    $buyable = $item->Buyable();
113
                    if ($buyable) {
114
                        $method = $this->Config()->get("download_method_in_byable");
115
                        if ($buyable->hasMethod($method)) {
116
                            $itemDownloadFiles = $buyable->$method();
117
                            if ($itemDownloadFiles) {
118
                                if ($itemDownloadFiles instanceof DataList) {
119
                                    if ($itemDownloadFiles->count()) {
120
                                        foreach ($itemDownloadFiles as $itemDownloadFile) {
121
                                            $files->push($itemDownloadFile);
122
                                        }
123
                                    }
124
                                } else {
125
                                    user_error("$method should return a Datalist. Specifically watch for has_one methods as they return a DataObject.", E_USER_NOTICE);
126
                                }
127
                            }
128
                        }
129
                    }
130
                }
131
            }
132
            if ($files->count()) {
133
                //additional files ar only added to orders
134
                //with downloads
135
                $additionalFiles = $this->AdditionalFiles();
0 ignored issues
show
Documentation Bug introduced by
The method AdditionalFiles does not exist on object<ElectronicDelivery_OrderStep>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
136
                foreach ($additionalFiles as $additionalFile) {
137
                    $files->push($additionalFile);
138
                }
139
                //create log with information...
140
                $obj = $logClassName::create();
141
                $obj->OrderID = $order->ID;
142
                $obj->AuthorID = $order->MemberID;
143
                $obj->NumberOfHoursBeforeDownloadGetsDeleted = $this->NumberOfHoursBeforeDownloadGetsDeleted;
0 ignored issues
show
Documentation introduced by
The property NumberOfHoursBeforeDownloadGetsDeleted does not exist on object<ElectronicDelivery_OrderStep>. 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...
144
                $obj->write();
145
                $obj->AddFiles($files);
146
            } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
147
                //do nothingh....
148
            }
149
        }
150
        return true;
151
    }
152
153
    /**
154
     * nextStep:
155
     * returns the next step (after it checks if everything is in place for the next step to run...)
156
     * @see Order::doNextStatus
157
     *
158
     * @param Order $order
159
     *
160
     * @return OrderStep | Null (next step OrderStep object)
0 ignored issues
show
Documentation introduced by
Should the return type not be OrderStep|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...
161
     **/
162
    public function nextStep(Order $order)
163
    {
164
        if ($orderLog = $this->RelevantLogEntry($order)) {
165
            if ($this->SendDetailsToCustomer) {
0 ignored issues
show
Documentation introduced by
The property SendDetailsToCustomer does not exist on object<ElectronicDelivery_OrderStep>. 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...
166
                if (!$this->hasBeenSent($order)) {
167
                    $subject = $this->EmailSubject;
0 ignored issues
show
Documentation introduced by
The property EmailSubject does not exist on object<ElectronicDelivery_OrderStep>. 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...
168
                    $message = $this->CustomerMessage;
0 ignored issues
show
Documentation introduced by
The property CustomerMessage does not exist on object<ElectronicDelivery_OrderStep>. 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...
169
                    $order->sendEmail($subject, $message, $resend = false, $adminOnly = false, $this->getEmailClassName());
0 ignored issues
show
Documentation introduced by
$resend = false is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
$this->getEmailClassName() is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
170
                }
171
            }
172
            if ($orderLog->IsExpired()) {
173
                $orderLog->write();
174
                return parent::nextStep($order);
175
            }
176
        }
177
        //we immediately go to the next step if there is
178
        //nothing to download ...
179
        else {
180
            return parent::nextStep($order);
181
        }
182
        return null;
183
    }
184
185
    /**
186
     * Allows the opportunity for the Order Step to add any fields to Order::getCMSFields
187
     *
188
     * @param FieldList $fields
189
     * @param Order $order
190
     *
191
     * @return FieldList
192
     **/
193
    public function addOrderStepFields(FieldList $fields, Order $order)
194
    {
195
        $fields = parent::addOrderStepFields($fields, $order);
196
        $fields->addFieldToTab("Root.Next", new HeaderField("DownloadFiles", _t("ElectronicDelivery_OrderStep.AVAILABLE_FOR_DOWNLOAD", "Files are available for download"), 3), "ActionNextStepManually");
197
        return $fields;
198
    }
199
200
    /**
201
     * Explains the current order step.
202
     * @return String
203
     */
204
    protected function myDescription()
205
    {
206
        return _t("OrderStep.DOWNLOADED_DESCRIPTION", _t("ElectronicDelivery_OrderStep.description", "During this step the customer downloads her or his order. The shop admininistrator does not do anything during this step."));
207
    }
208
209
210
    /**
211
     * For some ordersteps this returns true...
212
     * @return Boolean
213
     **/
214
    protected function hasCustomerMessage()
215
    {
216
        return $this->SendMessageToCustomer;
0 ignored issues
show
Documentation introduced by
The property SendMessageToCustomer does not exist on object<ElectronicDelivery_OrderStep>. 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
}
219