GridFieldExportSalesButton::getURLHandlers()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 6
rs 10
c 0
b 0
f 0
nc 1
nop 1
1
<?php
2
3
/**
4
 * Adds an "Export list" button to the bottom of a {@link GridField}.
5
 *
6
 * @package forms
7
 * @subpackage fields-gridfield
8
 */
9
10
class GridFieldExportSalesButton extends GridFieldExportButton implements GridField_HTMLProvider, GridField_ActionProvider, GridField_URLHandler
11
{
12
13
    /**
14
     * Array of fields to be exporoted
15
     * @var array
16
     */
17
    private static $fields_and_methods_to_be_exported = array(
18
        'OrderID',
19
        'InternalItemID',
20
        'TableTitle',
21
        'TableSubTitleNOHTML',
22
        'UnitPrice',
23
        'Quantity',
24
        'CalculatedTotal',
25
    );
26
27
28
29
30
    /**
31
     * export is an action button
32
     */
33
    public function getActions($gridField)
34
    {
35
        return array('exportsales');
36
    }
37
38
    public function handleAction(GridField $gridField, $actionName, $arguments, $data)
39
    {
40
        if ($actionName == 'exportsales') {
41
            return $this->handleSales($gridField);
42
        }
43
    }
44
45
    /**
46
     * it is also a URL
47
     */
48
    public function getURLHandlers($gridField)
49
    {
50
        return array(
51
            'exportsales' => 'handleSales',
52
        );
53
    }
54
55
    /**
56
     * Handle the export, for both the action button and the URL
57
      */
58
    public function handleSales($gridField, $request = null)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
59
    {
60
        $now = Date("d-m-Y-H-i");
61
        $fileName = "sales-$now.csv";
62
63
        if ($fileData = $this->generateExportFileData($gridField)) {
64
            return SS_HTTPRequest::send_file($fileData, $fileName, 'text/csv');
65
        }
66
    }
67
68
69
    /**
70
     * Place the export button in a <p> tag below the field
71
     */
72
    public function getHTMLFragments($gridField)
73
    {
74
        $button = new GridField_FormAction(
75
            $gridField,
76
            'exportsales',
77
            _t('TableListField.CSVEXPORT_SALES', 'Export Row Items'),
78
            'exportsales',
79
            null
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

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...
80
        );
81
        $button->setAttribute('data-icon', 'download-csv');
82
        $button->addExtraClass('no-ajax action_export');
83
        $button->setForm($gridField->getForm());
84
        return array(
85
            $this->targetFragment => '<p class="grid-csv-button">' . $button->Field() . '</p>',
86
        );
87
    }
88
89
    /**
90
     * Generate export fields for CSV.
91
     *
92
     * @param GridField $gridField
93
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be string|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...
94
     */
95
    public function generateExportFileData($gridField)
96
    {
97
        //reset time limit
98
        set_time_limit(1200);
99
100
        $idArray = array();
101
102
        $items = $gridField->getManipulatedList();
103
104
        foreach ($items->limit(null) as $item) {
105
            if (!$item->hasMethod('canView') || $item->canView()) {
106
                $idArray[$item->ID] = $item->ID;
107
            }
108
        }
109
110
        //file data
111
        $now = Date('d-m-Y-H-i');
112
        $fileName = "export-$now.csv";
0 ignored issues
show
Unused Code introduced by
$fileName 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...
113
114
        //data object variables
115
        $orderStatusSubmissionLog = EcommerceConfig::get('OrderStatusLog', 'order_status_log_class_used_for_submitting_order');
0 ignored issues
show
Unused Code introduced by
$orderStatusSubmissionLog 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...
116
        $fileData = '';
117
        $offset = 0;
118
        $count = 50;
119
        $orders = $this->getMyOrders($idArray, $count, $offset);
120
121
        while (
122
            $orders->count()
123
        ) {
124
            $offset = $offset + $count;
125
            foreach ($orders as $order) {
126
                if ($order->IsSubmitted()) {
127
                    $memberIsOK = false;
128
                    if (!$order->MemberID) {
129
                        $memberIsOK = true;
130
                    } elseif (!$order->Member()) {
131
                        $memberIsOK = true;
132
                    } elseif ($member = $order->Member()) {
133
                        $memberIsOK = true;
134
                        if ($member->IsShopAdmin()) {
135
                            $memberIsOK = false;
136
                        }
137
                    }
138
                    if ($memberIsOK) {
139
                        $items = OrderItem::get()->filter(array('OrderID' => $order->ID));
140
                        if ($items && $items->count()) {
141
                            $fileData .= $this->generateExportFileDataDetails($order->getOrderEmail(), $order->SubmissionLog()->Created, $items);
142
                        }
143
                    }
144
                }
145
            }
146
            unset($orders);
147
            $orders = $this->getMyOrders($idArray, $count, $offset);
148
        }
149
        if ($fileData) {
150
            return $fileData;
151
        } else {
152
            return null;
153
        }
154
    }
155
156
    /**
157
     *
158
     *
159
     * @param  array    $idArray Order IDs
160
     * @param  int      $count
161
     * @param  int      $offset
162
     * @return DataList
163
     */
164
    protected function getMyOrders($idArray, $count, $offset)
165
    {
166
        return  Order::get()
167
            ->sort('"Order"."ID" ASC')
168
            ->filter(array('ID' => $idArray))
169
            ->leftJoin('Member', '"Member"."ID" = "Order"."MemberID"')
170
            ->limit($count, $offset);
171
    }
172
173
    private $isFirstRow = true;
174
175
    public function generateExportFileDataDetails($email, $date, $orderItems)
176
    {
177
        $separator = $this->csvSeparator;
178
        $fileData = '';
179
        $columnData = array();
0 ignored issues
show
Unused Code introduced by
$columnData 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...
180
        $exportFields = Config::inst()->get('GridFieldExportSalesButton', 'fields_and_methods_to_be_exported');
181
        if ($this->isFirstRow) {
182
            $fileData = '"Email"'.$separator.'"SubmittedDate"'.$separator.'"'.implode('"'.$separator.'"', $exportFields).'"'."\n";
183
            $this->isFirstRow = false;
184
        }
185
        if ($orderItems) {
186
            foreach ($orderItems as $item) {
187
                $columnData = array();
188
                $columnData[] = '"'.$email.'"';
189
                $columnData[] = '"'.$date.'"';
190
                foreach ($exportFields as $field) {
0 ignored issues
show
Bug introduced by
The expression $exportFields 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...
191
                    if ($item->hasMethod($field)) {
192
                        $value = $item->$field();
193
                    } else {
194
                        $value = $item->$field;
195
                    }
196
                    $value = preg_replace('/\s+/', ' ', $value);
197
                    $value = preg_replace('/\s+/', ' ', $value);
198
                    $value = str_replace(array("\r", "\n"), "\n", $value);
199
                    $value = str_replace(array("\r", "\n"), "\n", $value);
200
                    $tmpColumnData = '"'.str_replace('"', '\"', $value).'"';
201
                    $columnData[] = $tmpColumnData;
202
                }
203
                $fileData .= implode($separator, $columnData);
204
                $fileData .= "\n";
205
                $item->destroy();
206
                unset($item);
207
                unset($columnData);
208
            }
209
210
            return $fileData;
211
        } else {
212
            return '';
213
        }
214
    }
215
}
216