__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 4
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 7
cp 0
crap 2
1
<?php
2
class Intraface_modules_debtor_Controller_Show extends k_Component
3
{
4
    public $email_send_with_success;
5
    public $onlinepayment_show_cancel_option;
6
    public $onlinepayment;
7
    protected $debtor;
8
    protected $translation;
9
    protected $template;
10
    protected $mdb2;
11
    protected $doctrine;
12
13
    function __construct(k_TemplateFactory $template, Translation2 $translation, MDB2_Driver_Common $mdb2, Doctrine_Connection_Common $doctrine)
14
    {
15
        $this->translation = $translation;
16
        $this->template = $template;
17
        $this->mdb2 = $mdb2;
18
        $this->doctrine = $doctrine;
19
    }
20
21
    function dispatch()
22
    {
23
        if ($this->getDebtor()->getId() == 0) {
24
            throw new k_PageNotFound();
25
        }
26
        if ($this->context->getType() != $this->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...
27
            return new k_SeeOther($this->url('../../../' . $this->getType() . '/list/' . $this->getDebtor()->getId()));
28
        }
29
30
        return parent::dispatch();
31
    }
32
33
    function map($name)
34
    {
35
        if ($name == 'contact') {
36
            return 'Intraface_modules_contact_Controller_Choosecontact';
37
        } elseif ($name == 'selectproduct') {
38
            return 'Intraface_modules_product_Controller_Selectproduct';
39
        } elseif ($name == 'selectmultipleproductwithquantity') {
40
            return 'Intraface_modules_product_Controller_Selectproduct';
41
        } elseif ($name == 'selectproductvariation') {
42
            return 'Intraface_modules_product_Controller_Selectproductvariation';
43
        } elseif ($name == 'payment') {
44
            return 'Intraface_modules_debtor_Controller_Payments';
45
        } elseif ($name == 'depreciation') {
46
            return 'Intraface_modules_debtor_Controller_Depreciations';
47
        } elseif ($name == 'state') {
48
            if ($this->getType() == 'credit_note') {
49
                return 'Intraface_modules_accounting_Controller_State_Creditnote';
50
            } elseif ($this->getType() == 'invoice') {
51
                return 'Intraface_modules_accounting_Controller_State_Invoice';
52
            } else {
53
                throw new Exception('Cannot state type ' . $this->getType());
54
            }
55
        } elseif ($name == 'item') {
56
            return 'Intraface_modules_debtor_Controller_Items';
57
        } elseif ($name == 'onlinepayment') {
58
            return 'Intraface_modules_onlinepayment_Controller_Index';
59
        } elseif ($name == 'send') {
60
            return 'Intraface_modules_debtor_Controller_Send';
61
        }
62
    }
63
64
    function GET()
0 ignored issues
show
Coding Style introduced by
GET 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...
65
    {
66
        if ($this->query("action") == "send_onlinepaymentlink") {
67
            $shared_email = $this->getKernel()->useShared('email');
0 ignored issues
show
Unused Code introduced by
$shared_email 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...
68
            $shared_filehandler = $this->getKernel()->useModule('filemanager');
0 ignored issues
show
Unused Code introduced by
$shared_filehandler 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...
69
            if ($this->getDebtor()->getPaymentMethodKey() == 5 and $this->getDebtor()->getWhereToId() == 0) {
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...
70
                try {
71
                    // echo $this->getDebtor()->getWhereFromId();
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% 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...
72
                    // @todo We should use a shop gateway here instead
73
                    $shop = Doctrine::getTable('Intraface_modules_shop_Shop')->findOneById($this->getDebtor()->getWhereFromId());
74
                    if ($shop) {
75
                        $payment_url = $this->getDebtor()->getPaymentLink($shop->getPaymentUrl());
76
                    }
77
                } catch (Doctrine_Record_Exeption $e) {
0 ignored issues
show
Bug introduced by
The class Doctrine_Record_Exeption does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
78
                    throw new Exception('Could not send an e-mail with onlinepayment-link');
79
                }
80
            }
81
82 View Code Duplication
            if ($this->getKernel()->intranet->get("pdf_header_file_id") != 0) {
83
                $file = new FileHandler($this->getKernel(), $this->getKernel()->intranet->get("pdf_header_file_id"));
84
            } else {
85
                $file = null;
86
            }
87
88
            $body = 'Tak for din bestilling i vores onlineshop. Vi har ikke registreret nogen onlinebetaling sammen med bestillingen, hvilket kan skyldes flere ting.
89
90
    1) Du fortrudt bestillingen, da du skulle til at betale. I så fald må du meget gerne skrive tilbage og annullere din bestilling.
91
    2) Der er sket en fejl under betalingen. I det tilfælde må du gerne betale ved at gå ind på nedenstående link:
92
93
    ' .  $payment_url;
0 ignored issues
show
Bug introduced by
The variable $payment_url does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
94
            $subject = 'Betaling ikke modtaget';
95
96
            // gem debtoren som en fil i filsystemet
97
            $filehandler = new FileHandler($this->getKernel());
98
            $tmp_file = $filehandler->createTemporaryFile($this->t($this->getDebtor()->get("type")).$this->getDebtor()->get('number').'.pdf');
99
100 View Code Duplication
            if (($this->getDebtor()->get("type") == "order" || $this->getDebtor()->get("type") == "invoice") && $this->getKernel()->intranet->hasModuleAccess('onlinepayment')) {
101
                $this->getKernel()->useModule('onlinepayment', true); // true: ignore_user_access
102
                $onlinepayment = OnlinePayment::factory($this->getKernel());
103
            } else {
104
                $onlinepayment = null;
105
            }
106
107
            // @todo the language on an invoice should be decided by the contacts preference
108
            $translation = $this->translation;
109
            $translation->setLang('dk');
110
111
            // Her gemmes filen
112
            $report = new Intraface_modules_debtor_Visitor_Pdf($translation, $file);
113
            $report->visit($this->getDebtor(), $onlinepayment);
114
115
            $report->output('file', $tmp_file->getFilePath());
116
117
118
            // gem filen med filehandleren
119
            $filehandler = new FileHandler($this->getKernel());
120 View Code Duplication
            if (!$file_id = $filehandler->save($tmp_file->getFilePath(), $tmp_file->getFileName(), 'hidden', 'application/pdf')) {
121
                echo $filehandler->error->view();
122
                throw new Exception('Filen kunne ikke gemmes');
123
            }
124
125
            $input['accessibility'] = 'intranet';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$input was never initialized. Although not strictly required by PHP, it is generally a good practice to add $input = 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...
126
            if (!$file_id = $filehandler->update($input)) {
127
                echo $filehandler->error->view();
128
                throw new Exception('Oplysninger om filen kunne ikke opdateres');
129
            }
130
131
            switch ($this->getKernel()->getSetting()->get('intranet', 'debtor.sender')) {
132
                case 'intranet':
133
                    $from_email = '';
134
                    $from_name = '';
135
                    break;
136 View Code Duplication
                case 'user':
137
                    $from_email = $this->getKernel()->user->getAddress()->get('email');
138
                    $from_name = $this->getKernel()->user->getAddress()->get('name');
139
                    break;
140 View Code Duplication
                case 'defined':
141
                    $from_email = $this->getKernel()->getSetting()->get('intranet', 'debtor.sender.email');
142
                    $from_name = $this->getKernel()->getSetting()->get('intranet', 'debtor.sender.name');
143
                    break;
144
                default:
145
                    throw new Exception("Invalid sender!");
146
            }
147
            $contact = new Contact($this->getKernel(), $this->getDebtor()->get('contact_id'));
148
            $signature = new Intraface_shared_email_Signature($this->context->getKernel()->user, $this->context->getKernel()->intranet, $this->context->getKernel()->getSetting());
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...
149
150
            // opret e-mailen
151
            $email = new Email($this->getKernel());
152 View Code Duplication
            if (!$email->save(array(
0 ignored issues
show
Documentation introduced by
array('contact_id' => $c...getDebtor()->get('id')) is of type array<string,?,{"contact...eger","belong_to":"?"}>, but the function expects a object<Struct>.

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...
153
                    'contact_id' => $contact->get('id'),
154
                    'subject' => $subject,
155
                    'body' => $body . "\n\n" . $signature->getAsText(),
156
                    'from_email' => $from_email,
157
                    'from_name' => $from_name,
158
                    'type_id' => 10, // electronic invoice
159
                    'belong_to' => $this->getDebtor()->get('id')
160
            ))) {
161
                echo $email->error->view();
162
                throw new Exception('E-mailen kunne ikke gemmes');
163
            }
164
165
            // tilknyt fil
166 View Code Duplication
            if (!$email->attachFile($file_id, $filehandler->get('file_name'))) {
167
                echo $email->error->view();
168
                throw new Exception('Filen kunne ikke vedhæftes');
169
            }
170
171
            $redirect = Intraface_Redirect::factory($this->getKernel(), 'go');
172
            $shared_email = $this->getKernel()->useModule('email');
173
174
            // First vi set the last, because we need this id to the first.
175
            $url = $redirect->setDestination($shared_email->getPath().$email->get('id') . '?edit', NET_SCHEME . NET_HOST . $this->url());
176
            $redirect->setIdentifier('send_onlinepaymentlink');
177
            $redirect->askParameter('send_onlinepaymentlink_status');
178
179
            return new k_SeeOther($url);
180
        }
181
182
183
        // delete item
184
        if ($this->query("action") == "delete_item") {
185
            $this->getDebtor()->loadItem(intval($_GET["item_id"]));
186
            $this->getDebtor()->item->delete();
187
            return new k_SeeOther($this->url(null, array('flare' => 'Item has been deleted')));
188
        }
189
        // move item
190 View Code Duplication
        if ($this->query("action") == "moveup") {
191
            $this->getDebtor()->loadItem(intval($_GET['item_id']));
192
            $this->getDebtor()->item->getPosition($this->mdb2)->moveUp();
193
        }
194
195
        // move item
196 View Code Duplication
        if ($this->query("action") == "movedown") {
197
            $this->getDebtor()->loadItem(intval($_GET['item_id']));
198
            $this->getDebtor()->item->getPosition($this->mdb2)->moveDown();
199
        }
200
201
        // registrere onlinepayment
202
        if ($this->getKernel()->user->hasModuleAccess('onlinepayment') && isset($_GET['onlinepayment_action']) && $_GET['onlinepayment_action'] != "") {
203
            if ($_GET['onlinepayment_action'] != 'capture' || ($this->getDebtor()->get("type") == "invoice" && $this->getDebtor()->get("status") == "sent")) {
204
                $onlinepayment_module = $this->getKernel()->useModule('onlinepayment'); // true: ignore user permisssion
0 ignored issues
show
Unused Code introduced by
$onlinepayment_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...
205
                $this->onlinepayment = OnlinePayment::factory($this->getKernel(), 'id', intval($_GET['onlinepayment_id']));
206
207
                if (!$this->onlinepayment->transactionAction($_GET['onlinepayment_action'])) {
208
                    $this->onlinepayment_show_cancel_option = true;
209
                }
210
211
                $this->getDebtor()->load();
212
213
                // @todo vi skulle faktisk kun videre, hvis det ikke er en tilbagebetaling eller hvad?
214
                if ($this->getDebtor()->get("type") == "invoice" && $this->getDebtor()->get("status") == "sent" and !$this->onlinepayment->error->isError()) {
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...
215
                    if ($this->getKernel()->user->hasModuleAccess('accounting')) {
216
                        return new k_SeeOther($this->url('payment/' . $this->onlinepayment->get('create_payment_id') . '/state'));
217
                    }
218
                }
219
            }
220
        }
221
222
        // edit contact
223
        if ($this->query('edit_contact')) {
224
            $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...
225
            $contact_module = $this->getKernel()->getModule('contact');
226
            $redirect = Intraface_Redirect::factory($this->getKernel(), 'go');
227
            $url = $redirect->setDestination($contact_module->getPath().intval($this->getDebtor()->contact->get('id') . '&edit'), NET_SCHEME . NET_HOST . $this->url());
228
            return new k_SeeOther($url . '&edit');
229
        }
230
231
        // Redirect til tilføj produkt
232
        if ($this->query('add_item')) {
233
            $redirect = Intraface_Redirect::factory($this->getKernel(), 'go');
234
            $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...
235
            $redirect->setIdentifier('add_item');
236
237
            $url = $redirect->setDestination(NET_SCHEME . NET_HOST . $this->url('selectproduct', array('set_quantity' => true)), NET_SCHEME . NET_HOST . $this->url());
238
239
            $redirect->askParameter('product_id', 'multiple');
240
241
            return new k_SeeOther($url);
242
        }
243
244
245
        // Returns from add product and send mail
246
        if ($this->query('return_redirect_id')) {
247
            $return_redirect = Intraface_Redirect::factory($this->getKernel(), 'return');
248
249
            if ($return_redirect->get('identifier') == 'add_item') {
250
                $selected_products = $return_redirect->getParameter('product_id', 'with_extra_value');
251
                foreach ($selected_products as $product) {
252
                    $this->getDebtor()->loadItem();
253
                    $product['value'] = unserialize($product['value']);
254
                    $this->getDebtor()->item->save(array('product_id' => $product['value']['product_id'], 'product_variation_id' => $product['value']['product_variation_id'], 'quantity' => $product['extra_value'], 'description' => ''));
255
                }
256
                $return_redirect->delete();
257
                $this->getDebtor()->load();
258
            } elseif ($return_redirect->get('identifier') == 'send_email') {
259
                if ($return_redirect->getParameter('send_email_status') == 'sent' or $return_redirect->getParameter('send_email_status') == 'outbox') {
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...
260
                    $this->email_send_with_success = true;
261
                    // if invoice has been resent the status should not be set again
262
                    if ($this->getDebtor()->get('status') != 'sent' && $this->getDebtor()->get('status') != 'executed') {
263
                        $this->getDebtor()->setStatus('sent');
264
                    }
265
                    $return_redirect->delete();
266
267 View Code Duplication
                    if (($this->getDebtor()->get("type") == 'credit_note' || $this->getDebtor()->get("type") == 'invoice') and !$this->getDebtor()->isStated() and $this->getKernel()->user->hasModuleAccess('accounting')) {
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...
268
                        return new k_SeeOther($this->url('state'));
269
                    }
270
                }
271
            }
272
        }
273
274
        return parent::GET();
275
    }
276
277
    function renderHtml()
278
    {
279
        if ($this->getKernel()->user->hasModuleAccess('onlinepayment')) {
280
            $online_module = $this->getKernel()->useModule('onlinepayment');
0 ignored issues
show
Unused Code introduced by
$online_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...
281
        }
282
        if ($this->getKernel()->user->hasModuleAccess('administration')) {
283
            $module_administration = $this->getKernel()->useModule('administration');
0 ignored issues
show
Unused Code introduced by
$module_administration 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...
284
        }
285
        $contact_module = $this->getKernel()->getModule('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...
286
287
        $tpl = $this->template->create(dirname(__FILE__) . '/templates/show');
288
        return $tpl->render($this);
289
    }
290
291
    function renderHtmlEdit()
292
    {
293
        $tpl = $this->template->create(dirname(__FILE__) . '/templates/edit');
294
        return $tpl->render($this);
295
    }
296
297
    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...
298
    {
299
        // delete the debtor
300
        if ($this->body('delete')) {
301
            $type = $this->getDebtor()->get("type");
0 ignored issues
show
Unused Code introduced by
$type 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...
302
            $this->getDebtor()->delete();
303
            return new k_SeeOther($this->url('../', array('use_stored' => 'true')));
304
        } elseif ($this->body('send_electronic_invoice')) {
305
            return new k_SeeOther($this->url('send', array('send' => 'electronic_email')));
306
        } elseif ($this->body('send_email')) {
307
            return new k_SeeOther($this->url('send', array('send' => 'email')));
308
        } // cancel debtor
309
        elseif ($this->body('cancel') and ($this->getDebtor()->get("type") == "quotation" || $this->getDebtor()->get("type") == "order") && ($this->getDebtor()->get('status') == "created" || $this->getDebtor()->get('status') == "sent")) {
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...
310
            $this->getDebtor()->setStatus('cancelled');
311
        } // sets status to sent
312
        elseif ($this->body('sent')) {
313
            $this->getDebtor()->setStatus('sent');
314
315 View Code Duplication
            if (($this->getDebtor()->get("type") == 'credit_note' || $this->getDebtor()->get("type") == 'invoice') and $this->getKernel()->user->hasModuleAccess('accounting')) {
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...
316
                return new k_SeeOther($this->url('state'));
317
            }
318
            return new k_SeeOther($this->url());
319
        } // transfer quotation to order
320 View Code Duplication
        elseif ($this->body('order')) {
321
            if ($this->getKernel()->user->hasModuleAccess('order') && $this->getDebtor()->get("type") == "quotation") {
322
                $this->getKernel()->useModule("order");
323
                $order = new Order($this->getKernel());
324
                if ($id = $order->create($this->getDebtor())) {
325
                    return new k_SeeOther($this->url('../'.$id));
326
                }
327
            }
328
        } // transfer forder to invoice
329 View Code Duplication
        elseif ($this->body('invoice')) {
330
            if ($this->getKernel()->user->hasModuleAccess('invoice') && ($this->getDebtor()->get("type") == "quotation" || $this->getDebtor()->get("type") == "order")) {
331
                $this->getKernel()->useModule("invoice");
332
                $invoice = new Invoice($this->getKernel());
333
                if ($id = $invoice->create($this->getDebtor())) {
334
                    return new k_SeeOther($this->url('../' . $id));
335
                }
336
            }
337
        } // Quick process order
338
        elseif ($this->body('quickprocess_order')) {
339 View Code Duplication
            if ($this->getKernel()->user->hasModuleAccess('invoice') && ($this->getDebtor()->get("type") == "quotation" || $this->getDebtor()->get("type") == "order")) {
340
                $this->getKernel()->useModule("invoice");
341
                $invoice = new Invoice($this->getKernel());
342
                if ($id = $invoice->create($this->getDebtor())) {
0 ignored issues
show
Unused Code introduced by
$id 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...
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies 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 if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

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

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
343
                }
344
            }
345
346
            if ($this->getKernel()->user->hasModuleAccess('invoice')) {
347
                $this->getKernel()->useModule("invoice");
348
                $invoice->setStatus('sent');
0 ignored issues
show
Bug introduced by
The variable $invoice does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
349
350
                if ($this->getKernel()->intranet->hasModuleAccess('onlinepayment')) {
351
                    $onlinepayment_module = $this->getKernel()->useModule('onlinepayment', true); // true: ignore user permisssion
0 ignored issues
show
Unused Code introduced by
$onlinepayment_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...
352
                    $onlinepayment = OnlinePayment::factory($this->getKernel());
353
                    $onlinepayment->getDBQuery()->setFilter('belong_to', $invoice->get("type"));
354
                    $onlinepayment->getDBQuery()->setFilter('belong_to_id', $invoice->get('id'));
355
                    $actions = $onlinepayment->getTransactionActions();
0 ignored issues
show
Unused Code introduced by
$actions 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...
356
                    $payment_list = $onlinepayment->getlist();
357
358
                    $payment_gateway = new Intraface_modules_onlinepayment_OnlinePaymentGateway($this->getKernel());
359
360
                    $success_on_all_payments = true;
361
362
                    foreach ($payment_list as $payment) {
363
                        $onlinepayment = $payment_gateway->findById($payment['id']);
364
                        try {
365
                            if (!$onlinepayment->transactionAction('capture')) {
366
                                $success_on_all_payments = true;
367
                            }
368
                        } catch (Exception $e) {
369
                            $success_on_all_payments = true;
370
                        }
371
                    }
372
                }
373
374
                if ($success_on_all_payments === true) {
0 ignored issues
show
Bug introduced by
The variable $success_on_all_payments does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
375
                    $invoice->setStatus('executed');
376
                }
377
378
                return new k_SeeOther($this->url('../' . $invoice->get('id')));
379
            }
380
        } // Execute invoice
381
        elseif ($this->body('quickprocess_invoice')) {
382
            if ($this->getKernel()->user->hasModuleAccess('invoice')) {
383
                $this->getKernel()->useModule("invoice");
384
                $this->getDebtor()->setStatus('sent');
385
386
                if ($this->getKernel()->user->hasModuleAccess('onlinepayment')) {
387
                    $onlinepayment_module = $this->getKernel()->useModule('onlinepayment', true); // true: ignore user permisssion
0 ignored issues
show
Unused Code introduced by
$onlinepayment_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...
388
                    $onlinepayment = OnlinePayment::factory($this->getKernel());
389
                    $onlinepayment->getDBQuery()->setFilter('belong_to', $this->getDebtor()->get("type"));
390
                    $onlinepayment->getDBQuery()->setFilter('belong_to_id', $this->getDebtor()->get('id'));
391
                    $actions = $onlinepayment->getTransactionActions();
0 ignored issues
show
Unused Code introduced by
$actions 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...
392
                    $payment_list = $onlinepayment->getlist();
393
394
                    foreach ($payment_list as $payment) {
395
                        $onlinepayment = OnlinePayment::factory($this->getKernel(), 'id', $payment['id']);
396
                        try {
397
                            if (!$onlinepayment->transactionAction('capture')) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies 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 if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

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

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
398
                            }
399
                        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
400
                        }
401
                    }
402
                }
403
404
                $this->getDebtor()->setStatus('executed');
405
                return new k_SeeOther($this->url(null . '.pdf'));
406
            }
407
        } // create credit note
408
        elseif ($this->body('credit_note')) {
409
            if ($this->getKernel()->user->hasModuleAccess('invoice') && $this->getDebtor()->get("type") == "invoice") {
410
                $credit_note = new CreditNote($this->getKernel());
411
412
                if ($id = $credit_note->create($this->getDebtor())) {
413
                    return new k_SeeOther($this->url('../'.$id));
414
                }
415
            }
416
        } // cancel onlinepayment
417
        elseif ($this->body('onlinepayment_cancel') && $this->getKernel()->user->hasModuleAccess('onlinepayment')) {
418
            $onlinepayment_module = $this->getKernel()->useModule('onlinepayment');
0 ignored issues
show
Unused Code introduced by
$onlinepayment_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...
419
            $this->onlinepayment = OnlinePayment::factory($this->getKernel(), 'id', intval($_POST['onlinepayment_id']));
420
421
            $this->onlinepayment->setStatus('cancelled');
422
            $this->getDebtor()->load();
423
        } else {
424
            $debtor = $this->getDebtor();
425
            $contact = new Contact($this->getKernel(), $_POST["contact_id"]);
426
427 View Code Duplication
            if ($this->body("contact_person_id") == "-1") {
428
                $contact_person = new ContactPerson($contact);
429
                $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...
430
                $person["email"] = $_POST['contact_person_email'];
431
                $contact_person->save($person);
432
                $contact_person->load();
433
                $_POST["contact_person_id"] = $contact_person->get("id");
434
            }
435
436 View Code Duplication
            if ($this->getKernel()->intranet->hasModuleAccess('currency') && $this->body('currency_id')) {
437
                $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...
438
                $gateway = new Intraface_modules_currency_Currency_Gateway($this->doctrine);
439
                $currency = $gateway->findById($_POST['currency_id']);
440
                if ($currency == false) {
441
                    throw new Exception('Invalid currency');
442
                }
443
444
                $_POST['currency'] = $currency;
445
            }
446
447
            if ($debtor->update($_POST)) {
448
                return new k_SeeOther($this->url(null));
449
            }
450
        }
451
452
        return new k_SeeOther($this->url());
453
    }
454
455
    function getValues()
456
    {
457
        return $this->getDebtor()->get();
458
    }
459
460
    function getAction()
461
    {
462
        return 'Update';
463
    }
464
465
    function getContact()
466
    {
467
        return $this->getDebtor()->getContact();
468
    }
469
470
    function getModel()
471
    {
472
        return $this->getDebtor();
473
    }
474
475
    function getObject()
476
    {
477
        return $this->getDebtor();
478
    }
479
480
    function getType()
481
    {
482
        return $this->getDebtor()->get('type');
483
    }
484
485
    function isValidSender()
486
    {
487
        switch ($this->getKernel()->getSetting()->get('intranet', 'debtor.sender')) {
488
            case 'intranet':
489
                if ($this->getKernel()->intranet->address->get('name') == '' || $this->getKernel()->intranet->address->get('email') == '') {
490
                    return false;
491
                }
492
                break;
493
            case 'user':
494
                if ($this->getKernel()->user->getAddress()->get('name') == '' || $this->getKernel()->user->getAddress()->get('email') == '') {
495
                    return false;
496
                }
497
                break;
498
            case 'defined':
499
                if ($this->getKernel()->getSetting()->get('intranet', 'debtor.sender.name') == '' || $this->getKernel()->getSetting()->get('intranet', 'debtor.sender.email') == '') {
500
                    return false;
501
                }
502
                break;
503
        }
504
        return true;
505
    }
506
507
    function isValidScanInContact()
508
    {
509
        $scan_in_contact_id = $this->getKernel()->getSetting()->get('intranet', 'debtor.scan_in_contact');
510
        $scan_in_contact = new Contact($this->getKernel(), $scan_in_contact_id);
511
        if ($scan_in_contact->get('id') == 0) {
512
            return false;
513
        } elseif (!$scan_in_contact->address->get('email')) {
514
            return false;
515
        }
516
        return true;
517
    }
518
519
    function getMessageAboutEmail()
520
    {
521
        $msg = '';
522
        $contact_module = $this->getKernel()->getModule('contact');
523
        $debtor_module = $this->getKernel()->getModule('debtor');
524
525
        switch ($this->getDebtor()->contact->get('preferred_invoice')) {
526
            case 2: // if the customer prefers e-mail
527
                switch ($this->getKernel()->getSetting()->get('intranet', 'debtor.sender')) {
528
                    case 'intranet':
529
                        if ($this->getKernel()->intranet->address->get('name') == '' || $this->getKernel()->intranet->address->get('email') == '') {
530
                            if ($this->getKernel()->user->hasModuleAccess('administration')) {
531
                                $msg = '<div class="message-dependent"><p>'.$this->t('You need to fill in an e-mail address to send e-mail').'. <a href="'.url('../../../../administration/intranet', array('edit')) . '">'.t('do it now').'</a>.</p></div>';
532
                            } else {
533
                                $msg = '<div class="message-dependent"><p>'.$this->t('You need to ask your administrator to fill in an e-mail address, so that you can send emails').'</p></div>';
534
                            }
535
                        }
536
                        break;
537
                    case 'user':
538
                        if ($this->getKernel()->user->getAddress()->get('name') == '' || $this->getKernel()->user->getAddress()->get('email') == '') {
539
                            $msg = '<div class="message-dependent"><p>'.$this->t('You need to fill in an e-mail address to send e-mail').'. <a href="'.url('../../../../controlpanel/user', array('edit')).'">'.t('do it now').'</a>.</p></div>';
540
                        }
541
                        break;
542
                    case 'defined':
543
                        if ($this->getKernel()->getSetting()->get('intranet', 'debtor.sender.name') == '' || $this->getKernel()->getSetting()->get('intranet', 'debtor.sender.email') == '') {
544
                            if ($this->getKernel()->user->hasModuleAccess('administration')) {
545
                                $msg = '<div class="message-dependent"><p>'.$this->t('You need to fill in an e-mail address to send e-mail').'. <a href="'.$module_debtor->getPath().'settings">'.t('do it now').'</a>.</p></div>';
0 ignored issues
show
Bug introduced by
The variable $module_debtor 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...
546
                            } else {
547
                                $msg = '<div class="message-dependent"><p>'.$this->t('You need to ask your administrator to fill in an e-mail address, so that you can send emails').'</p></div>';
548
                            }
549
                        }
550
                        break;
551
                    default:
552
                        throw new Exception("Invalid sender!");
553
                }
554
555 View Code Duplication
                if ($this->getDebtor()->contact->address->get('email') == '') {
556
                    $msg = '<div class="message-dependent"><p>'.$this->t('You need to register an e-mail to the contact, so you can send e-mails').'</p></div>';
557
                }
558
559
                break;
560
561
            case 3: // electronic email, we make check that everything is as it should be
562 View Code Duplication
                if ($this->getDebtor()->contact->address->get('ean') == '') {
563
                    $msg = '<div class="message-dependent"><p>'.$this->t('To be able to send electronic e-mails you need to fill out the EAN location number for the contact').'</p></div>';
564
                }
565
566
                $scan_in_contact_id = $this->getKernel()->getSetting()->get('intranet', 'debtor.scan_in_contact');
567
                $valid_scan_in_contact = true;
0 ignored issues
show
Unused Code introduced by
$valid_scan_in_contact 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...
568
569
                $scan_in_contact = new Contact($this->getKernel(), $scan_in_contact_id);
570
                if ($scan_in_contact->get('id') == 0) {
571
                    $valid_scan_in_contact = false;
0 ignored issues
show
Unused Code introduced by
$valid_scan_in_contact 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...
572
                    $msg = '<div class="message-dependent"><p>';
573
                    $msg .= $this->t('A contact for the scan in bureau is needed to send electronic invoices').'. ';
574
                    if ($this->getKernel()->user->hasModuleAccess('administration')) {
575
                        $msg .= '<a href="'.$debtor_module->getPath().'settings">'.$this->t('Add it now').'</a>.';
576
                    }
577
                    $msg .= '</p></div>';
578
                } elseif (!$scan_in_contact->address->get('email')) {
579
                    $valid_scan_in_contact = false;
0 ignored issues
show
Unused Code introduced by
$valid_scan_in_contact 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...
580
                    $msg = '<div class="message-dependent"><p>';
581
                    $msg .= $this->t('You need to provide a valid e-mail address to the contact for the scan in bureau').'.';
582
                    $msg .= ' <a href="'.$contact_module->getPath().$scan_in_contact->get('id').'">'.t('Add it now').'</a>.';
583
                    $msg .= '</p></div>';
584
                }
585
                break;
586
        }
587
588
        return $msg;
589
    }
590
591
    function addItem($product, $quantity = 1)
592
    {
593
        $this->getDebtor()->loadItem();
594
        $this->getDebtor()->item->save(array('product_id' => $product['product_id'], 'product_variation_id' => $product['product_variation_id'], 'quantity' => $quantity, 'description' => ''));
595
    }
596
597
    function getKernel()
598
    {
599
        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...
600
    }
601
602
    function getDebtor()
603
    {
604
        $contact_module = $this->getKernel()->getModule('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...
605
606
        if (is_object($this->debtor)) {
607
            return $this->debtor;
608
        }
609
610
        return ($this->debtor = $this->context->getGateway()->findById(intval($this->name())));
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 getGateway() does only exist in the following implementations of said interface: Intraface_Filehandler_Controller_CKEditor, Intraface_Filehandler_Controller_Index, Intraface_Filehandler_Controller_SelectFile, Intraface_modules_contact_Controller_Index, Intraface_modules_debtor_Controller_Collection, Intraface_modules_debtor_Controller_Reminders, Intraface_modules_email_Controller_Index, Intraface_modules_filemanager_Controller_Index, Intraface_modules_product_Controller_Index, Intraface_modules_product_Controller_Selectproduct, Intraface_modules_product_Controller_Show, Intraface_modules_produc...ntroller_Show_PlainText.

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...
611
    }
612
613
    function renderPdf()
614
    {
615 View Code Duplication
        if (($this->getDebtor()->get("type") == "order" || $this->getDebtor()->get("type") == "invoice") && $this->getKernel()->intranet->hasModuleAccess('onlinepayment')) {
616
            $this->getKernel()->useModule('onlinepayment', true); // true: ignore_user_access
617
            $onlinepayment = OnlinePayment::factory($this->getKernel());
618
        } else {
619
            $onlinepayment = null;
620
        }
621
622 View Code Duplication
        if ($this->getKernel()->intranet->get("pdf_header_file_id") != 0) {
623
            $this->getKernel()->useModule('filemanager');
624
            $filehandler = new FileHandler($this->getKernel(), $this->getKernel()->intranet->get("pdf_header_file_id"));
625
        } else {
626
            $filehandler = null;
627
        }
628
629
        $report = new Intraface_modules_debtor_Visitor_Pdf($this->translator(), $filehandler);
630
        $report->visit($this->getDebtor(), $onlinepayment);
631
632
        return $report->output('stream');
633
    }
634
635
    function renderHtmlDelete()
636
    {
637
        $this->getDebtor()->delete();
638
        return new k_SeeOther($this->url('../', array('use_stored' => true)));
639
    }
640
641
    function renderOioxml()
642
    {
643
        require_once dirname(__FILE__) . '/../Visitor/OIOXML.php';
644
        $render = new Debtor_Report_OIOXML;
645
        return $render->output($this->getDebtor());
646
    }
647
648
    function renderTxt()
649
    {
650
        require_once dirname(__FILE__) . '/../Visitor/Text.php';
651
        $render = new Debtor_Report_Text;
652
        return $render->output($this->getDebtor());
653
    }
654
}
655