Completed
Push — develop ( c5339b...ea5663 )
by Adrien
19:12
created

Ods::createZip()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 17
Code Lines 8

Duplication

Lines 5
Ratio 29.41 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 8
c 0
b 0
f 0
nc 6
nop 1
dl 5
loc 17
ccs 0
cts 8
cp 0
crap 20
rs 9.2
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Writer;
4
5
use PhpOffice\PhpSpreadsheet\Spreadsheet;
6
use ZipArchive;
7
8
/**
9
 * Copyright (c) 2006 - 2015 PhpSpreadsheet.
10
 *
11
 * This library is free software; you can redistribute it and/or
12
 * modify it under the terms of the GNU Lesser General Public
13
 * License as published by the Free Software Foundation; either
14
 * version 2.1 of the License, or (at your option) any later version.
15
 *
16
 * This library is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
 * Lesser General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Lesser General Public
22
 * License along with this library; if not, write to the Free Software
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
 *
25
 * @category   PhpSpreadsheet
26
 *
27
 * @copyright  Copyright (c) 2006 - 2015 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
28
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
29
 */
30
class Ods extends BaseWriter implements IWriter
31
{
32
    /**
33
     * Private writer parts.
34
     *
35
     * @var Ods\WriterPart[]
36
     */
37
    private $writerParts = [];
38
39
    /**
40
     * Private PhpSpreadsheet.
41
     *
42
     * @var PhpSpreadsheet
43
     */
44
    private $spreadSheet;
45
46
    /**
47
     * Create a new Ods.
48
     *
49
     * @param \PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet
50
     */
51 2
    public function __construct(\PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
52
    {
53 2
        $this->setSpreadsheet($spreadsheet);
54
55
        $writerPartsArray = [
56 2
            'content' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Content::class,
57
            'meta' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Meta::class,
58
            'meta_inf' => \PhpOffice\PhpSpreadsheet\Writer\Ods\MetaInf::class,
59
            'mimetype' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype::class,
60
            'settings' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Settings::class,
61
            'styles' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Styles::class,
62
            'thumbnails' => \PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails::class,
63
        ];
64
65 2
        foreach ($writerPartsArray as $writer => $class) {
66 2
            $this->writerParts[$writer] = new $class($this);
67
        }
68 2
    }
69
70
    /**
71
     * Get writer part.
72
     *
73
     * @param string $pPartName Writer part name
74
     *
75
     * @return Ods\WriterPart|null
76
     */
77 View Code Duplication
    public function getWriterPart($pPartName = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
78
    {
79
        if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
80
            return $this->writerParts[strtolower($pPartName)];
81
        }
82
83
        return null;
84
    }
85
86
    /**
87
     * Save PhpSpreadsheet to file.
88
     *
89
     * @param string $pFilename
90
     *
91
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
92
     */
93
    public function save($pFilename = null)
94
    {
95
        if (!$this->spreadSheet) {
96
            throw new \PhpOffice\PhpSpreadsheet\Writer\Exception('PhpSpreadsheet object unassigned.');
97
        }
98
99
        // garbage collect
100
        $this->spreadSheet->garbageCollect();
101
102
        // If $pFilename is php://output or php://stdout, make it a temporary file...
103
        $originalFilename = $pFilename;
104 View Code Duplication
        if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
            $pFilename = @tempnam(\PhpOffice\PhpSpreadsheet\Shared\File::sysGetTempDir(), 'phpxltmp');
106
            if ($pFilename == '') {
107
                $pFilename = $originalFilename;
108
            }
109
        }
110
111
        $zip = $this->createZip($pFilename);
112
113
        $zip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method writeManifest() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\MetaInf. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
114
        $zip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method writeThumbnail() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\Thumbnails. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
115
        $zip->addFromString('content.xml', $this->getWriterPart('content')->write());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method write() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\Content, PhpOffice\PhpSpreadsheet\Writer\Ods\Meta, PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype, PhpOffice\PhpSpreadsheet\Writer\Ods\Settings, PhpOffice\PhpSpreadsheet\Writer\Ods\Styles. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
116
        $zip->addFromString('meta.xml', $this->getWriterPart('meta')->write());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method write() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\Content, PhpOffice\PhpSpreadsheet\Writer\Ods\Meta, PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype, PhpOffice\PhpSpreadsheet\Writer\Ods\Settings, PhpOffice\PhpSpreadsheet\Writer\Ods\Styles. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
117
        $zip->addFromString('mimetype', $this->getWriterPart('mimetype')->write());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method write() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\Content, PhpOffice\PhpSpreadsheet\Writer\Ods\Meta, PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype, PhpOffice\PhpSpreadsheet\Writer\Ods\Settings, PhpOffice\PhpSpreadsheet\Writer\Ods\Styles. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
118
        $zip->addFromString('settings.xml', $this->getWriterPart('settings')->write());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method write() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\Content, PhpOffice\PhpSpreadsheet\Writer\Ods\Meta, PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype, PhpOffice\PhpSpreadsheet\Writer\Ods\Settings, PhpOffice\PhpSpreadsheet\Writer\Ods\Styles. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
119
        $zip->addFromString('styles.xml', $this->getWriterPart('styles')->write());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart as the method write() does only exist in the following sub-classes of PhpOffice\PhpSpreadsheet\Writer\Ods\WriterPart: PhpOffice\PhpSpreadsheet\Writer\Ods\Content, PhpOffice\PhpSpreadsheet\Writer\Ods\Meta, PhpOffice\PhpSpreadsheet\Writer\Ods\Mimetype, PhpOffice\PhpSpreadsheet\Writer\Ods\Settings, PhpOffice\PhpSpreadsheet\Writer\Ods\Styles. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
120
121
        // Close file
122
        if ($zip->close() === false) {
123
            throw new \PhpOffice\PhpSpreadsheet\Writer\Exception("Could not close zip file $pFilename.");
124
        }
125
126
        // If a temporary file was used, copy it to the correct file stream
127 View Code Duplication
        if ($originalFilename != $pFilename) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
            if (copy($pFilename, $originalFilename) === false) {
129
                throw new \PhpOffice\PhpSpreadsheet\Writer\Exception("Could not copy temporary zip file $pFilename to $originalFilename.");
130
            }
131
            @unlink($pFilename);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
132
        }
133
    }
134
135
    /**
136
     * Create zip object.
137
     *
138
     * @param string $pFilename
139
     *
140
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
141
     *
142
     * @return ZipArchive
143
     */
144
    private function createZip($pFilename)
145
    {
146
        // Create new ZIP file and open it for writing
147
        $zip = new ZipArchive();
148
149
        if (file_exists($pFilename)) {
150
            unlink($pFilename);
151
        }
152
        // Try opening the ZIP file
153 View Code Duplication
        if ($zip->open($pFilename, ZipArchive::OVERWRITE) !== true) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
154
            if ($zip->open($pFilename, ZipArchive::CREATE) !== true) {
155
                throw new \PhpOffice\PhpSpreadsheet\Writer\Exception("Could not open $pFilename for writing.");
156
            }
157
        }
158
159
        return $zip;
160
    }
161
162
    /**
163
     * Get Spreadsheet object.
164
     *
165
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
166
     *
167
     * @return Spreadsheet
168
     */
169 2
    public function getSpreadsheet()
170
    {
171 2
        if ($this->spreadSheet !== null) {
172 2
            return $this->spreadSheet;
173
        }
174
        throw new \PhpOffice\PhpSpreadsheet\Writer\Exception('No PhpSpreadsheet assigned.');
175
    }
176
177
    /**
178
     * Set Spreadsheet object.
179
     *
180
     * @param \PhpOffice\PhpSpreadsheet\Spreadsheet $spreadsheet PhpSpreadsheet object
181
     *
182
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
183
     *
184
     * @return self
185
     */
186 2
    public function setSpreadsheet(\PhpOffice\PhpSpreadsheet\SpreadSheet $spreadsheet = null)
187
    {
188 2
        $this->spreadSheet = $spreadsheet;
0 ignored issues
show
Documentation Bug introduced by
It seems like $spreadsheet can also be of type object<PhpOffice\PhpSpreadsheet\Spreadsheet>. However, the property $spreadSheet is declared as type object<PhpOffice\PhpSpre...\Writer\PhpSpreadsheet>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
189
190 2
        return $this;
191
    }
192
}
193