getPosts()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
crap 2
1
<?php
2
class Intraface_modules_debtor_Controller_Collection extends k_Component
3
{
4
    protected $error;
5
    protected $debtor;
6
    protected $template;
7
    protected $gateway;
8
    protected $doctrine;
9
10
    function __construct(k_TemplateFactory $template, Doctrine_Connection_Common $doctrine)
11
    {
12
        $this->template = $template;
13
        $this->doctrine = $doctrine;
14
    }
15
16
    function map($name)
17
    {
18
        if (is_numeric($name)) {
19
            return 'Intraface_modules_debtor_Controller_Show';
20
        } elseif ($name == 'create') {
21
            return 'Intraface_modules_debtor_Controller_Create';
22
        }
23
    }
24
25
    function renderHtml()
0 ignored issues
show
Coding Style introduced by
renderHtml 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...
26
    {
27
        $debtor_module = $this->getKernel()->module('debtor');
0 ignored issues
show
Unused Code introduced by
$debtor_module 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...
28
        $contact_module = $this->getKernel()->useModule('contact');
0 ignored issues
show
Unused Code introduced by
$contact_module 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...
29
        $product_module = $this->getKernel()->useModule('product');
0 ignored issues
show
Unused Code introduced by
$product_module 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...
30
31
        $this->getGateway()->setType($this->getType());
32
33
        if (intval($this->query("contact_id")) != 0) {
34
            $this->getGateway()->getDBQuery()->setFilter("contact_id", $this->query("contact_id"));
35
        }
36
37
        if (intval($this->query("product_id")) != 0) {
38
            $this->getGateway()->getDBQuery()->setFilter("product_id", $this->query("product_id"));
39
            if (isset($_GET['product_variation_id'])) {
40
                $this->getGateway()->getDBQuery()->setFilter("product_variation_id", $_GET["product_variation_id"]);
41
            }
42
        }
43
44
        // søgning
45
        if (isset($_GET["text"]) && $_GET["text"] != "") {
46
            $this->getGateway()->getDBQuery()->setFilter("text", $_GET["text"]);
47
        }
48
        if (isset($_GET["date_field"]) && $_GET["date_field"] != "") {
49
            $this->getGateway()->getDBQuery()->setFilter("date_field", $_GET["date_field"]);
50
        }
51
52
        if (isset($_GET["from_date"]) && $_GET["from_date"] != "") {
53
            $this->getGateway()->getDBQuery()->setFilter("from_date", $_GET["from_date"]);
54
        }
55
56
        if (isset($_GET["to_date"]) && $_GET["to_date"] != "") {
57
            $this->getGateway()->getDBQuery()->setFilter("to_date", $_GET["to_date"]);
58
        }
59
60
        if ($this->getGateway()->getDBQuery()->checkFilter("contact_id")) {
61
            $this->getGateway()->getDBQuery()->setFilter("status", "-1");
62 View Code Duplication
        } elseif (isset($_GET["status"]) && $_GET['status'] != '') {
63
            $this->getGateway()->getDBQuery()->setFilter("status", $_GET["status"]);
64
        } else {
65
            $this->getGateway()->getDBQuery()->setFilter("status", "-2");
66
        }
67
68
        if (!empty($_GET['not_stated']) and $_GET['not_stated'] == 'true') {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
69
            $this->getGateway()->getDBQuery()->setFilter("not_stated", true);
70
        }
71
72
        if (isset($_GET['sorting']) && $_GET['sorting'] != 0) {
73
            $this->getGateway()->getDBQuery()->setFilter("sorting", $_GET['sorting']);
74
        }
75
76
        $this->getGateway()->getDBQuery()->usePaging("paging", $this->getKernel()->setting->get('user', 'rows_pr_page'));
77
        $this->getGateway()->getDBQuery()->storeResult("use_stored", $this->getType(), "toplevel");
78
        //$debtor->getDBQuery()->setExtraUri('&amp;type='.$debtor->get("type"));
0 ignored issues
show
Unused Code Comprehensibility introduced by
78% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
79
        $this->getGateway()->getDBQuery()->setUri($this->url(null, array('use_stored' => 'true')));
80
81
        $data = array(
82
            'posts' => $this->getGateway()->findAll(),
83
            'debtor' => $this->getGateway());
84
85
86
        // @todo kan følgende ikke lige så godt hente fra $this->query()
87
        if (intval($this->getGateway()->getDBQuery()->getFilter('product_id')) != 0) {
88
            $data['product'] = new Product($this->getKernel(), $this->getGateway()->getDBQuery()->getFilter('product_id'));
89 View Code Duplication
            if (intval($this->getGateway()->getDBQuery()->getFilter('product_variation_id')) != 0) {
90
                $data['variation'] = $data['product']->getVariation($this->getGateway()->getDBQuery()->getFilter('product_variation_id'));
91
            }
92
        }
93 View Code Duplication
        if (intval($this->getGateway()->getDBQuery()->getFilter('contact_id')) != 0) {
94
            $data['contact'] = new Contact($this->getKernel(), $this->getGateway()->getDBQuery()->getFilter('contact_id'));
95
        }
96
97
        $smarty = $this->template->create(dirname(__FILE__) . '/templates/collection');
98
        return $smarty->render($this, $data);
99
    }
100
101
    function postForm()
0 ignored issues
show
Coding Style introduced by
postForm uses the super-global variable $_POST 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...
102
    {
103
        $debtor = $this->getDebtor();
0 ignored issues
show
Bug introduced by
The method getDebtor() does not seem to exist on object<Intraface_modules..._Controller_Collection>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
104
        $contact = new Contact($this->getKernel(), $_POST["contact_id"]);
105
106
        if (isset($_POST["contact_person_id"]) && $_POST["contact_person_id"] == "-1") {
107
            $contact_person = new ContactPerson($contact);
108
            $person["name"] = $_POST['contact_person_name'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$person was never initialized. Although not strictly required by PHP, it is generally a good practice to add $person = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
109
            $person["email"] = $_POST['contact_person_email'];
110
            $contact_person->save($person);
111
            $contact_person->load();
112
            $_POST["contact_person_id"] = $contact_person->get("id");
113
        }
114
115
        if ($this->getKernel()->intranet->hasModuleAccess('currency') && !empty($_POST['currency_id'])) {
116
            $currency_module = $this->getKernel()->useModule('currency', false); // false = ignore user access
0 ignored issues
show
Unused Code introduced by
$currency_module 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...
117
            $gateway = new Intraface_modules_currency_Currency_Gateway($this->doctrine);
118
            $currency = $gateway->findById($_POST['currency_id']);
119
            if ($currency == false) {
120
                throw new Exception('Invalid currency');
121
            }
122
123
            $_POST['currency'] = $currency;
124
        }
125
126
        if ($debtor->update($_POST)) {
127
            return new k_SeeOther($this->url('../list/' . $debtor->get('id')));
128
        }
129
130
        return $this->render();
131
    }
132
133
    function renderXls()
0 ignored issues
show
Coding Style introduced by
renderXls 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...
134
    {
135
        if ($this->query('simple')) {
136
            Intraface_Doctrine_Intranet::singleton($this->getKernel()->intranet->getId());
137
138
            $debtor = Debtor::factory($this->getKernel(), intval($_GET["id"]), $this->getType());
139
            $dbquery = $debtor->getDbQuery();
140
            $type = $this->getType();
141
            unset($debtor);
142
143
            $dbquery->storeResult("use_stored", $type, "toplevel");
144
            $dbquery->loadStored();
145
146
            $gateway = new Intraface_modules_debtor_DebtorDoctrineGateway($this->doctrine, $this->getKernel()->user);
147
            // echo number_format(memory_get_usage())." After gateway initializd<br />"; die;
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
148
            $posts = $gateway->findByDbQuerySearch($dbquery);
149
150
            /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
68% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
151
            echo '<pre>';
152
            var_dump($posts->getFirst()->toArray()); die();
153
            print_r($posts->toArray(true));
154
            echo '</pre>';
155
            echo number_format(memory_get_usage())." After gateway initializd<br />"; die;
156
            */
157
158
            // spreadsheet
159
            $workbook = new Spreadsheet_Excel_Writer();
160
            $workbook->setVersion(8);
161
162
            $workbook->send('debtor.xls');
163
164
            $format_bold = $workbook->addFormat();
165
            $format_bold->setBold();
166
            $format_bold->setSize(8);
167
168
            $format_italic = $workbook->addFormat();
169
            $format_italic->setItalic();
170
            $format_italic->setSize(8);
171
172
            $format = $workbook->addFormat();
173
            $format->setSize(8);
174
175
            // Creating a worksheet
176
            $worksheet = $workbook->addWorksheet(ucfirst($this->t($this->getType())));
177
            $worksheet->setInputEncoding('UTF-8');
178
179
            $i = 1;
180
            $worksheet->write($i, 0, $this->getKernel()->intranet->get('name'), $format_bold);
181
            $i++;
182
183
            $status_types = array(
184
                -3 => 'Afskrevet',
185
                -2 => 'Åbne',
186
                -1 => 'Alle',
187
                0 => 'Oprettet',
188
                1 => 'Sendt',
189
                2 => 'Afsluttet',
190
                3 => 'Annulleret');
191
192
            $worksheet->write($i, 0, 'Status', $format_italic);
193
            $worksheet->write($i, 1, $status_types[$dbquery->getFilter('status')], $format_italic);
194
            $i++;
195
196
            $worksheet->write($i, 0, 'Søgetekst', $format_italic);
197
            $worksheet->write($i, 1, $dbquery->getFilter('text'), $format_italic);
198
            $i++;
199
200
            if ($dbquery->checkFilter('product_id')) {
201
                $product = new Product($this->getKernel(), $dbquery->getFilter('product_id'));
202
203
                $worksheet->write($i, 0, 'Produkt', $format_italic);
204
                $worksheet->write($i, 1, $product->get('name'), $format_italic);
205
                $i++;
206
            }
207
208
            if ($dbquery->checkFilter('contact_id')) {
209
                $contact = new Contact($this->getKernel(), $dbquery->getFilter('contact_id'));
210
211
                $worksheet->write($i, 0, 'Kontakt', $format_italic);
212
                $worksheet->write($i, 1, $contact->address->get('name'), $format_italic);
213
                $i++;
214
            }
215
216
            $worksheet->write($i, 0, "Antal i søgningen", $format_italic);
217
            $worksheet->write($i, 1, count($posts), $format_italic);
218
            $i++;
219
220
            $i++;
221
            $worksheet->write($i, 0, 'Nummer', $format_bold);
222
            $worksheet->write($i, 1, 'Kontakt nummer', $format_bold);
223
            $worksheet->write($i, 2, 'Kontakt navn', $format_bold);
224
            $worksheet->write($i, 3, 'Beskrivelse', $format_bold);
225
            $worksheet->write($i, 4, 'Beløb', $format_bold);
226
            $worksheet->write($i, 5, 'Oprettet', $format_bold);
227
            $worksheet->write($i, 6, 'Sendt', $format_bold);
228
            //$worksheet->write($i, 7, __("due_date"), $format_bold);
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
229
            $c = 8;
230
            if ($type == 'invoice') {
231
                $worksheet->write($i, $c, 'Forfaldsbeløb', $format_bold);
232
                $c++;
233
            }
234
            $worksheet->write($i, $c, 'Kontaktnøgleord', $format_bold);
235
            $c++;
236
237 View Code Duplication
            if (!empty($product) && is_object($product) && get_class($product) == 'product') {
238
                $worksheet->write($i, $c, 'Antal valgte produkt', $format_bold);
239
                $c++;
240
            }
241
242
            $i++;
243
244
            $due_total = 0;
245
            $sent_total = 0;
246
            $total = 0;
247
248
            foreach ($posts as $debtor) {
249
                if (strtotime($debtor->getDueDate()->getAsIso()) < time() && ($debtor->getStatus() == "created" or $debtor->getStatus() == "sent")) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
250
                    $due_total += $debtor->getTotal()->getAsIso(2);
251
                }
252
                if ($debtor->getStatus() == "sent") {
253
                    $sent_total += $debtor->getTotal()->getAsIso(2);
254
                }
255
                    $total += $debtor->getTotal()->getAsIso(2);
256
257
                    /**
258
                     * @todo this could be done with Doctrine, but this seems only to have minimal memory usage
259
                     */
260
                    $contact = new Contact($this->getKernel(), $debtor->contact_id);
261
                    $worksheet->write($i, 0, $debtor->getNumber());
262
                    $worksheet->write($i, 1, $contact->get('number')); // $posts[$j]['contact']['number']
0 ignored issues
show
Unused Code Comprehensibility introduced by
91% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
263
                    $worksheet->write($i, 2, $contact->get('name'));
264
                    $worksheet->write($i, 3, $debtor->getDescription());
265
                    $worksheet->writeNumber($i, 4, $debtor->getTotal()->getAsIso());
266
                    $worksheet->write($i, 5, $debtor->getDebtorDate()->getAsLocal('da_DK'));
267
268
                if ($debtor->getStatus() != "created") {
269
                    $worksheet->write($i, 6, $debtor->getDateSent()->getAsLocal('da_DK'));
270
                } else {
271
                    $worksheet->write($i, 6, "Nej");
272
                }
273
274
                if ($debtor->getStatus() == "executed" || $debtor->getStatus() == "canceled") {
275
                    $worksheet->write($i, 7, $this->t($debtor->getStatus()));
276
                } else {
277
                    $worksheet->write($i, 7, $debtor->getDueDate()->getAsLocal('da_DK'));
278
                }
279
                    $c = 8;
280
                if ($type == 'invoice') {
281
                    $worksheet->write($i, $c, '-'); // $posts[$j]['arrears']
0 ignored issues
show
Unused Code Comprehensibility introduced by
88% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
282
                    $c++;
283
                }
284
285
                    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
286
                    // not implemented
287
                    $keywords = array();
288
                    $contact = new Contact($this->getKernel(), $posts[$j]['contact']['id']);
289
                    $appender = $contact->getKeywordAppender();
290
                    $keyword_ids = $appender->getConnectedKeywords();
291
                    if (count($keyword_ids) > 0) {
292
                        foreach ($keyword_ids AS $keyword_id) {
293
                            $keyword = new Keyword($contact, $keyword_id);
294
                            $keywords[] = $keyword->getKeyword();
295
                        }
296
                        $worksheet->write($i, $c, implode(', ', $keywords));
297
                        $c++;
298
                    }*/
299
300
                    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
301
                    // not implemented
302
                    if (!empty($product) && is_object($product) && get_class($product) == 'product') {
303
                        $quantity_product = 0;
304
                        if (count($posts[$j]['items']) > 0) {
305
                            foreach ($posts[$j]['items'] AS $item) {
306
                                if ($item['product_id'] == $product->get('id')) {
307
                                    $quantity_product += $item['quantity'];
308
                                }
309
                            }
310
                        }
311
                        $worksheet->write($i, $c, $quantity_product);
312
                        $c++;
313
                    }*/
314
315
                    $i++;
316
            }
317
318
319
            $i++;
320
            $i++;
321
322
            $worksheet->write($i, 0, 'Forfaldne', $format_italic);
323
            $worksheet->write($i, 1, number_format($due_total, 2, ",", "."), $format_italic);
324
            $i++;
325
326
            $worksheet->write($i, 0, 'Udestående (sendt):', $format_italic);
327
            $worksheet->write($i, 1, number_format($sent_total, 2, ",", "."), $format_italic);
328
            $i++;
329
330
            $worksheet->write($i, 0, 'Total:', $format_italic);
331
            $worksheet->write($i, 1, number_format($total, 2, ",", "."), $format_italic);
332
            $i++;
333
334
            // $worksheet->write($i, 0, number_format(memory_get_usage()));
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
335
336
            $worksheet->hideGridLines();
337
338
            return $workbook->close();
339
        }
340
341
        $debtor_module = $this->getKernel()->module('debtor');
0 ignored issues
show
Unused Code introduced by
$debtor_module 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...
342
343
        $this->getGateway()->getDBQuery()->storeResult("use_stored", $this->getType(), "toplevel");
344
345
        $posts = $this->getGateway()->findAll();
346
347
        // spreadsheet
348
        $workbook = new Spreadsheet_Excel_Writer();
349
350
        $workbook->send('debtor.xls');
351
352
        $format_bold = $workbook->addFormat();
353
        $format_bold->setBold();
354
        $format_bold->setSize(8);
355
356
        $format_italic = $workbook->addFormat();
357
        $format_italic->setItalic();
358
        $format_italic->setSize(8);
359
360
        $format = $workbook->addFormat();
361
        $format->setSize(8);
362
363
        // Creating a worksheet
364
        $worksheet = $workbook->addWorksheet(ucfirst($this->t($this->getType())));
365
366
        $i = 1;
367
        $worksheet->write($i, 0, $this->getKernel()->intranet->get('name'), $format_bold);
368
        $i++;
369
370
        $status_types = array(
371
            -3 => 'Afskrevet',
372
            -2 => 'Åbne',
373
            -1 => 'Alle',
374
            0 => 'Oprettet',
375
            1 => 'Sendt',
376
            2 => 'Afsluttet',
377
            3 => 'Annulleret');
378
379
        $worksheet->write($i, 0, 'Status', $format_italic);
380
        $worksheet->write($i, 1, $status_types[$this->getGateway()->getDBQuery()->getFilter('status')], $format_italic);
381
        $i++;
382
383
        $worksheet->write($i, 0, 'Søgetekst', $format_italic);
384
        $worksheet->write($i, 1, $this->getGateway()->getDBQuery()->getFilter('text'), $format_italic);
385
        $i++;
386
387 View Code Duplication
        if ($this->getGateway()->getDbQuery()->checkFilter('product_id')) {
388
            $product = new Product($this->getKernel(), $this->getGateway()->getDbQuery()->getFilter('product_id'));
389
390
            $worksheet->write($i, 0, 'Produkt', $format_italic);
391
            $worksheet->write($i, 1, $product->get('name'), $format_italic);
392
            $i++;
393
        }
394
395 View Code Duplication
        if ($this->getGateway()->getDbQuery()->checkFilter('contact_id')) {
396
            $contact = new Contact($this->getKernel(), $this->getGateway()->getDbQuery()->getFilter('contact_id'));
397
398
            $worksheet->write($i, 0, 'Kontakt', $format_italic);
399
            $worksheet->write($i, 1, $contact->address->get('name'), $format_italic);
400
            $i++;
401
        }
402
403
        $worksheet->write($i, 0, "Antal i søgningen", $format_italic);
404
        $worksheet->write($i, 1, count($posts), $format_italic);
405
        $i++;
406
407
        $i++;
408
        $worksheet->write($i, 0, 'Nummer', $format_bold);
409
        $worksheet->write($i, 1, 'Kontakt nummer', $format_bold);
410
        $worksheet->write($i, 2, 'Kontakt navn', $format_bold);
411
        $worksheet->write($i, 3, 'Beskrivelse', $format_bold);
412
        $worksheet->write($i, 4, 'Beløb', $format_bold);
413
        $worksheet->write($i, 5, 'Oprettet', $format_bold);
414
        $worksheet->write($i, 6, 'Sendt', $format_bold);
415
        //$worksheet->write($i, 7, __("due_date"), $format_bold);
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
416
        $c = 8;
417
        if ($this->getGateway()->getType() == 'invoice') {
418
            $worksheet->write($i, $c, 'Forfaldsbeløb', $format_bold);
419
            $c++;
420
        }
421
        $worksheet->write($i, $c, 'Kontaktnøgleord', $format_bold);
422
        $c++;
423
424 View Code Duplication
        if (!empty($product) && is_object($product) && get_class($product) == 'product') {
425
            $worksheet->write($i, $c, 'Antal valgte produkt', $format_bold);
426
            $c++;
427
        }
428
429
        // HACK unsetting debtor which is actually ok to avoid memory problems //
430
        $type = $this->getType();
431
        unset($debtor);
432
        // HACK end //
433
434
        $i++;
435
436
        $due_total = 0;
437
        $sent_total = 0;
438
        $total = 0;
439
440
        foreach ($posts as $post) {
441
            if ($post["due_date"] < date("Y-m-d") && ($post["status"] == "created" or $post["status"] == "sent")) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
442
                $due_total += $post["total"];
443
            }
444
            if ($post["status"] == "sent") {
445
                $sent_total += $post["total"];
446
            }
447
            $total += $post["total"];
448
449
            $worksheet->write($i, 0, $post["number"]);
450
            $worksheet->write($i, 1, $post['contact']['number']);
451
            $worksheet->write($i, 2, $post["name"]);
452
            $worksheet->write($i, 3, $post["description"]);
453
            $worksheet->writeNumber($i, 4, $post["total"]);
454
            $worksheet->write($i, 5, $post["dk_this_date"]);
455
456
            if ($posts[$j]["status"] != "created") {
0 ignored issues
show
Bug introduced by
The variable $j 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...
457
                $worksheet->write($i, 6, $post["dk_date_sent"]);
458
            } else {
459
                $worksheet->write($i, 6, "Nej");
460
            }
461
462
            if ($posts[$j]["status"] == "executed" || $post["status"] == "canceled") {
463
                $worksheet->write($i, 7, $this->t($post["status"], 'debtor'));
0 ignored issues
show
Documentation introduced by
'debtor' is of type string, but the function expects a null|object<k_Language>.

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...
464
            } else {
465
                $worksheet->write($i, 7, $post["dk_due_date"]);
466
            }
467
            $c = 8;
468
            if ($type == 'invoice') {
469
                $worksheet->write($i, $c, $post['arrears']);
470
                $c++;
471
            }
472
473
            /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
474
            $keywords = array();
475
            $contact = new Contact($this->getKernel(), $post['contact']['id']);
476
            $appender = $contact->getKeywordAppender();
477
            $keyword_ids = $appender->getConnectedKeywords();
478
            if (count($keyword_ids) > 0) {
479
            foreach ($keyword_ids AS $keyword_id) {
480
                $keyword = new Keyword($contact, $keyword_id);
481
                $keywords[] = $keyword->getKeyword();
482
            }
483
            $worksheet->write($i, $c, implode(', ', $keywords));
484
            $c++;
485
            }
486
487
            if (!empty($product) && is_object($product) && get_class($product) == 'product') {
488
            $quantity_product = 0;
489
            if (count($post['items']) > 0) {
490
                foreach ($post['items'] AS $item) {
491
                    if ($item['product_id'] == $product->get('id')) {
492
                        $quantity_product += $item['quantity'];
493
                    }
494
                }
495
            }
496
            $worksheet->write($i, $c, $quantity_product);
497
            $c++;
498
            }
499
            */
500
501
            $i++;
502
        }
503
504
        $i++;
505
        $i++;
506
507
        $worksheet->write($i, 0, 'Forfaldne', $format_italic);
508
        $worksheet->write($i, 1, number_format($due_total, 2, ",", "."), $format_italic);
509
        $i++;
510
511
        $worksheet->write($i, 0, 'Udestående (sendt):', $format_italic);
512
        $worksheet->write($i, 1, number_format($sent_total, 2, ",", "."), $format_italic);
513
        $i++;
514
515
        $worksheet->write($i, 0, 'Total:', $format_italic);
516
        $worksheet->write($i, 1, number_format($total, 2, ",", "."), $format_italic);
517
        $i++;
518
519
        $worksheet->hideGridLines();
520
521
        return $workbook->close();
522
    }
523
524
    function renderHtmlCreate()
525
    {
526
        return new k_SeeOther($this->url('create'));
527
    }
528
529
    function getReturnUrl($contact_id)
530
    {
531
        return $this->url(null, array('create', 'contact_id' => $contact_id));
532
    }
533
534
    function getValues()
535
    {
536
        return array(
537
            'number' => ''
538
        );
539
    }
540
541
    function getAction()
542
    {
543
        return 'Create';
544
    }
545
546
    function getType()
547
    {
548
        return $this->context->getType();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface k_Context as the method getType() does only exist in the following implementations of said interface: Intraface_modules_accoun...ller_State_Depreciation, Intraface_modules_debtor_Controller_Collection, Intraface_modules_debtor_Controller_Create, Intraface_modules_debtor_Controller_Depreciation, Intraface_modules_debtor_Controller_Depreciations, Intraface_modules_debtor_Controller_Payment, Intraface_modules_debtor_Controller_Payments, Intraface_modules_debtor_Controller_Reminder, Intraface_modules_debtor_Controller_Show, Intraface_modules_debtor_Controller_Typenegotiator.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
549
    }
550
551
    function getContact()
552
    {
553
        $module = $this->getKernel()->module('contact');
0 ignored issues
show
Unused Code introduced by
$module 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...
554
        return new Contact($this->getKernel(), $this->query('contact_id'));
555
    }
556
557
    function getGateway()
558
    {
559
        Intraface_Doctrine_Intranet::singleton($this->getKernel()->intranet->getId());
560
561
        if (!empty($this->gateway)) {
562
            return $this->gateway;
563
        }
564
565
        $this->gateway = new Intraface_modules_debtor_DebtorGateway($this->getKernel());
566
        return $this->gateway;
567
    }
568
569
    /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
570
    function getDebtor()
571
    {
572
        if (is_object($this->debtor)) {
573
            return $this->debtor;
574
        }
575
576
        return ($this->debtor = Debtor::factory($this->getKernel(), $this->query('id'), $this->getType()));
577
    }
578
    */
579
580
    function getPosts()
581
    {
582
        return $this->getGateway()->findAll();
583
    }
584
585
    function getKernel()
586
    {
587
        return $this->context->getKernel();
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface k_Context as the method getKernel() does only exist in the following implementations of said interface: Intraface_Controller_Index, Intraface_Controller_ModuleGatekeeper, Intraface_Controller_ModulePackage_Process, Intraface_Controller_Restricted, Intraface_Controller_SwitchIntranet, Intraface_Filehandler_Controller_Batchedit, Intraface_Filehandler_Controller_CKEditor, Intraface_Filehandler_Controller_Crop, Intraface_Filehandler_Controller_Index, Intraface_Filehandler_Controller_SelectFile, Intraface_Filehandler_Controller_Show, Intraface_Filehandler_Controller_Size, Intraface_Filehandler_Controller_Sizes, Intraface_Filehandler_Controller_Upload, Intraface_Filehandler_Controller_UploadMultiple, Intraface_Filehandler_Controller_UploadScript, Intraface_Fileimport_Controller_Index, Intraface_Keyword_Controller_Connect, Intraface_Keyword_Controller_Index, Intraface_Keyword_Controller_Show, Intraface_modules_accoun...ontroller_Account_Index, Intraface_modules_accoun...ontroller_Account_Popup, Intraface_modules_accoun...Controller_Account_Show, Intraface_modules_accounting_Controller_Daybook, Intraface_modules_accounting_Controller_Index, Intraface_modules_accounting_Controller_Post_Index, Intraface_modules_accounting_Controller_Post_Show, Intraface_modules_accounting_Controller_Search, Intraface_modules_accounting_Controller_Settings, Intraface_modules_accounting_Controller_State, Intraface_modules_accoun...roller_State_Creditnote, Intraface_modules_accoun...ller_State_Depreciation, Intraface_modules_accoun...ontroller_State_Invoice, Intraface_modules_accoun...ontroller_State_Payment, Intraface_modules_accoun...oller_State_Procurement, Intraface_modules_accoun...ntroller_State_Reminder, Intraface_modules_accoun...roller_State_SelectYear, Intraface_modules_accounting_Controller_Vat_Index, Intraface_modules_accounting_Controller_Vat_Show, Intraface_modules_accoun...ontroller_Voucher_Index, Intraface_modules_accoun...Controller_Voucher_Show, Intraface_modules_accounting_Controller_Year_Edit, Intraface_modules_accounting_Controller_Year_End, Intraface_modules_accounting_Controller_Year_Index, Intraface_modules_accoun...troller_Year_Primosaldo, Intraface_modules_accounting_Controller_Year_Show, Intraface_modules_administration_Controller_Index, Intraface_modules_admini...ion_Controller_Intranet, Intraface_modules_cms_Controller_Element, Intraface_modules_cms_Controller_Elements, Intraface_modules_cms_Controller_Index, Intraface_modules_cms_Controller_Navigation, Intraface_modules_cms_Controller_Page, Intraface_modules_cms_Controller_Pages, Intraface_modules_cms_Controller_Section, Intraface_modules_cms_Controller_Sections, Intraface_modules_cms_Controller_Site, Intraface_modules_cms_Controller_Stylesheet, Intraface_modules_cms_Controller_Template, Intraface_modules_cms_Co...ler_TemplateSectionEdit, Intraface_modules_cms_Controller_TemplateSections, Intraface_modules_cms_Controller_Templates, Intraface_modules_contac...troller_BatchNewsletter, Intraface_modules_contact_Controller_Choosecontact, Intraface_modules_contac...ntroller_Contactpersons, Intraface_modules_contact_Controller_Import, Intraface_modules_contact_Controller_Index, Intraface_modules_contact_Controller_Memos, Intraface_modules_contact_Controller_Merge, Intraface_modules_contact_Controller_Sendemail, Intraface_modules_contact_Controller_Show, Intraface_modules_contro...ntroller_ChangePassword, Intraface_modules_controlpanel_Controller_Index, Intraface_modules_controlpanel_Controller_User, Intraface_modules_contro...troller_UserPreferences, Intraface_modules_curren...ller_ExchangeRate_Index, Intraface_modules_curren...changeRate_ProductPrice, Intraface_modules_currency_Controller_Index, Intraface_modules_currency_Controller_Show, Intraface_modules_debtor_Controller_Collection, Intraface_modules_debtor_Controller_Create, Intraface_modules_debtor_Controller_Depreciation, Intraface_modules_debtor_Controller_Depreciations, Intraface_modules_debtor_Controller_Index, Intraface_modules_debtor_Controller_Item, Intraface_modules_debtor_Controller_Items, Intraface_modules_debtor_Controller_Payment, Intraface_modules_debtor_Controller_Payments, Intraface_modules_debtor_Controller_Reminder, Intraface_modules_debtor_Controller_Reminders, Intraface_modules_debtor_Controller_Settings, Intraface_modules_debtor_Controller_Show, Intraface_modules_debtor_Controller_Typenegotiator, Intraface_modules_email_Controller_Email, Intraface_modules_email_Controller_Index, Intraface_modules_fileimport_Controller_Index, Intraface_modules_filemanager_Controller_Index, Intraface_modules_intran...enance_Controller_Index, Intraface_modules_intran...ntroller_Intranet_Index, Intraface_modules_intran...Controller_Intranet_Key, Intraface_modules_intran...ler_Intranet_Permission, Intraface_modules_intran...ontroller_Intranet_Show, Intraface_modules_intran...ance_Controller_Modules, Intraface_modules_intran...e_Controller_User_Index, Intraface_modules_intran...troller_User_Permission, Intraface_modules_intran...ce_Controller_User_Show, Intraface_modules_module...e_Controller_AddPackage, Intraface_modules_modulepackage_Controller_Index, Intraface_modules_modulepackage_Controller_Package, Intraface_modules_modulepackage_Controller_Payment, Intraface_modules_module...age_Controller_PostForm, Intraface_modules_modulepackage_Controller_Process, Intraface_modules_newsletter_Controller_Index, Intraface_modules_newsletter_Controller_Letter, Intraface_modules_newsletter_Controller_Letters, Intraface_modules_newsletter_Controller_List, Intraface_modules_newsletter_Controller_Lists, Intraface_modules_newsletter_Controller_Log, Intraface_modules_newsletter_Controller_Send, Intraface_modules_newsle..._Controller_Subscribers, Intraface_modules_onlinepayment_Controller_Index, Intraface_modules_online...ent_Controller_Settings, Intraface_modules_payment_Controller_Index, Intraface_modules_payment_Controller_Show, Intraface_modules_procurement_Controller_Index, Intraface_modules_procurement_Controller_Item, Intraface_modules_procurement_Controller_Items, Intraface_modules_procur...ontroller_PurchasePrice, Intraface_modules_procurement_Controller_Show, Intraface_modules_produc...troller_AttributeGroups, Intraface_modules_produc...tributeGroups_Attribute, Intraface_modules_produc...er_AttributeGroups_Show, Intraface_modules_product_Controller_BatchEdit, Intraface_modules_produc...oller_BatchPriceChanger, Intraface_modules_product_Controller_Index, Intraface_modules_produc...r_Productattributegroup, Intraface_modules_product_Controller_Related, Intraface_modules_product_Controller_Selectproduct, Intraface_modules_produc..._Selectproductvariation, Intraface_modules_product_Controller_Show, Intraface_modules_produc...ntroller_Show_PlainText, Intraface_modules_produc...troller_Show_Variations, Intraface_modules_produc...s_SelectAttributeGroups, Intraface_modules_product_Controller_Variation, Intraface_modules_shop_C...r_BasketEvaluation_Edit, Intraface_modules_shop_C..._BasketEvaluation_Index, Intraface_modules_shop_C...r_BasketEvaluation_Show, Intraface_modules_shop_Controller_Categories, Intraface_modules_shop_C...oller_Categories_Create, Intraface_modules_shop_Controller_Categories_Show, Intraface_modules_shop_C...oller_DiscountCampaigns, Intraface_modules_shop_Controller_FeaturedProducts, Intraface_modules_shop_Controller_Index, Intraface_modules_shop_Controller_Show, Intraface_modules_stock_Controller_Index, Intraface_modules_stock_Controller_Product, Intraface_modules_stock_Controller_Variations, Intraface_modules_todo_Controller_Edit, Intraface_modules_todo_Controller_Index, Intraface_modules_todo_Controller_Todo.

Let’s take a look at an example:

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

class MyUser implements 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 implementation 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 interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
588
    }
589
590
    function getError()
591
    {
592
        if (is_object($this->error)) {
593
            return $this->error;
594
        }
595
        return ($this->error = new Intraface_Error());
596
    }
597
}
598