Completed
Push — symfony4 ( c6a911...b0a2f3 )
by
unknown
37:19
created

FileBaseIntegrationTest::setAllServicesPublic()   C

Complexity

Conditions 17
Paths 18

Size

Total Lines 34

Duplication

Lines 34
Ratio 100 %

Importance

Changes 0
Metric Value
cc 17
nc 18
nop 1
dl 34
loc 34
rs 5.2166
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace eZ\Publish\SPI\Tests\FieldType;
4
5
use eZ\Publish\Core\IO\IOServiceInterface;
6
use RecursiveIteratorIterator;
7
use RecursiveDirectoryIterator;
8
use FileSystemIterator;
9
use Symfony\Component\Filesystem\Filesystem as FilesystemComponent;
10
use Symfony\Component\DependencyInjection\ContainerBuilder;
11
use Symfony\Component\Config\FileLocator;
12
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
13
14
abstract class FileBaseIntegrationTest extends BaseIntegrationTest
15
{
16
    /**
17
     * Temporary storage directory.
18
     *
19
     * @var string
20
     */
21
    protected static $tmpDir;
22
23
    /** @var IOServiceInterface */
24
    protected $ioService;
25
26
    /**
27
     * @see EZP-23534
28
     */
29
    public function testLoadingContentWithMissingFileWorks()
30
    {
31
        $contentType = $this->createContentType();
32
        $content = $this->createContent($contentType, $this->getInitialValue());
33
34
        // delete the binary file object
35
        $this->deleteStoredFile($content);
36
37
        // try loading the content again. It should work even though the image isn't physically here
38
        $this->getCustomHandler()->contentHandler()->load($content->versionInfo->contentInfo->id, 1);
39
    }
40
41
    /**
42
     * Deletes the binary file stored in the field.
43
     *
44
     * @param $content
45
     *
46
     * @return mixed
47
     */
48
    protected function deleteStoredFile($content)
49
    {
50
        return $this->ioService->deleteBinaryFile(
51
            $this->ioService->loadBinaryFile($content->fields[1]->value->externalData['id'])
52
        );
53
    }
54
55
    /**
56
     * Returns prefix used by the IOService.
57
     *
58
     * @return string
59
     */
60
    abstract protected function getStoragePrefix();
61
62
    /**
63
     * Sets up a temporary directory and stores its path in self::$tmpDir.
64
     */
65
    public static function setUpBeforeClass()
66
    {
67
        $calledClass = get_called_class();
68
69
        $tmpFile = tempnam(
70
            sys_get_temp_dir(),
71
            'eZ_' . substr($calledClass, strrpos($calledClass, '\\') + 1)
72
        );
73
74
        // Convert file into directory
75
        unlink($tmpFile);
76
        mkdir($tmpFile);
77
78
        self::$tmpDir = $tmpFile;
79
80
        $storageDir = self::$tmpDir . '/var/ezdemo_site/storage';
81
        if (!file_exists($storageDir)) {
82
            $fs = new FilesystemComponent();
83
            $fs->mkdir($storageDir);
84
        }
85
86
        self::$setUp = false;
87
88
        parent::setUpBeforeClass();
89
    }
90
91
    /**
92
     * Removes the temp dir.
93
     */
94
    public static function tearDownAfterClass()
95
    {
96
        self::removeRecursive(self::$tmpDir);
97
        parent::tearDownAfterClass();
98
    }
99
100
    /**
101
     * Removes the given directory path recursively.
102
     *
103
     * @param string $dir
104
     */
105
    protected static function removeRecursive($dir)
106
    {
107
        $iterator = new RecursiveIteratorIterator(
108
            new RecursiveDirectoryIterator(
109
                $dir,
110
                FileSystemIterator::KEY_AS_PATHNAME | FileSystemIterator::SKIP_DOTS | FileSystemIterator::CURRENT_AS_FILEINFO
111
            ),
112
            RecursiveIteratorIterator::CHILD_FIRST
113
        );
114
115
        foreach ($iterator as $path => $fileInfo) {
116
            if ($fileInfo->isDir()) {
117
                rmdir($path);
118
            } else {
119
                unlink($path);
120
            }
121
        }
122
123
        rmdir($dir);
124
    }
125
126 View Code Duplication
    protected function getContainer()
127
    {
128
        $config = include __DIR__ . '/../../../../../config.php';
129
        $installDir = $config['install_dir'];
130
131
        $containerBuilder = new ContainerBuilder();
132
        $settingsPath = $installDir . '/eZ/Publish/Core/settings/';
133
        $loader = new YamlFileLoader($containerBuilder, new FileLocator($settingsPath));
134
135
        $loader->load('fieldtypes.yml');
136
        $loader->load('io.yml');
137
        $loader->load('repository.yml');
138
        $loader->load('repository/inner.yml');
139
        $loader->load('repository/signalslot.yml');
140
        $loader->load('repository/siteaccessaware.yml');
141
        $loader->load('fieldtype_external_storages.yml');
142
        $loader->load('storage_engines/common.yml');
143
        $loader->load('storage_engines/shortcuts.yml');
144
        $loader->load('storage_engines/legacy.yml');
145
        $loader->load('search_engines/legacy.yml');
146
        $loader->load('storage_engines/cache.yml');
147
        $loader->load('settings.yml');
148
        $loader->load('fieldtype_services.yml');
149
        $loader->load('utils.yml');
150
        $loader->load('tests/common.yml');
151
        $loader->load('policies.yml');
152
153
        $containerBuilder->setParameter('ezpublish.kernel.root_dir', $installDir);
154
155
        $containerBuilder->setParameter(
156
            'legacy_dsn',
157
            $this->getDsn()
158
        );
159
        $containerBuilder->setParameter(
160
            'io_root_dir',
161
            self::$tmpDir . '/var/ezdemo_site/storage'
162
        );
163
164
        $this->setAllServicesPublic($containerBuilder);
165
166
        $containerBuilder->compile();
167
168
        return $containerBuilder;
169
    }
170
171
    /**
172
     * Asserts that the IO File with uri $uri exists.
173
     *
174
     * @param string $uri
175
     */
176
    protected function assertIOUriExists($uri)
177
    {
178
        $this->assertFileExists(
179
            self::$tmpDir . '/' . $uri,
180
            "Stored file uri $uri does not exist"
181
        );
182
    }
183
184
    /**
185
     * Asserts that the IO File with id $id exists.
186
     *
187
     * @param string $id
188
     */
189
    protected function assertIOIdExists($id)
190
    {
191
        $path = $this->getPathFromId($id);
192
        $this->assertFileExists(
193
            $path,
194
            "Stored file $path does not exists"
195
        );
196
    }
197
198
    /**
199
     * Returns the physical path to the file with id $id.
200
     */
201
    protected function getPathFromId($id)
202
    {
203
        return $this->getStorageDir() . '/' . $this->getStoragePrefix() . '/' . $id;
204
    }
205
206
    protected function getStorageDir()
207
    {
208
        return (self::$tmpDir ? self::$tmpDir . '/' : '') . self::$container->getParameter('storage_dir');
209
    }
210
211
    protected function getFilesize($binaryFileId)
212
    {
213
        return filesize($this->getPathFromId($binaryFileId));
214
    }
215
216
    /**
217
     * Overrides all services to be public.
218
     *
219
     * It is a workaround to the change in Symfony 4 which makes all services private by default.
220
     * Our integration tests are not prepared for this as they get services directly from the Container.
221
     *
222
     * Inspired by {@link \Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass}
223
     *
224
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $containerBuilder
225
     */
226 View Code Duplication
    private function setAllServicesPublic(ContainerBuilder $containerBuilder): void
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
227
    {
228
        $definitions = $containerBuilder->getDefinitions();
229
230
        foreach ($definitions as $id => $definition) {
231
            if (
232
                $id && '.' !== $id[0]
233
                && (!$definition->isPublic() || $definition->isPrivate())
234
                && !$definition->getErrors()
235
                && !$definition->isAbstract()
236
            ) {
237
                $definition->setPrivate(false);
238
                $definition->setPublic(true);
239
            }
240
        }
241
242
        $aliases = $containerBuilder->getAliases();
243
        foreach ($aliases as $id => $alias) {
244
            if ($id && '.' !== $id[0] && (!$alias->isPublic() || $alias->isPrivate())) {
245
                while (isset($aliases[$target = (string) $alias])) {
246
                    $alias = $aliases[$target];
247
                }
248
                if (
249
                    isset($definitions[$target])
250
                    && !$definitions[$target]->getErrors()
251
                    && !$definitions[$target]->isAbstract()
252
                ) {
253
254
                    $definition->setPrivate(false);
0 ignored issues
show
Bug introduced by
The variable $definition seems to be defined by a foreach iteration on line 230. Are you sure the iterator is never empty, otherwise this variable is not defined?

It seems like you are relying on a variable being defined by an iteration:

foreach ($a as $b) {
}

// $b is defined here only if $a has elements, for example if $a is array()
// then $b would not be defined here. To avoid that, we recommend to set a
// default value for $b.


// Better
$b = 0; // or whatever default makes sense in your context
foreach ($a as $b) {
}

// $b is now guaranteed to be defined here.
Loading history...
255
                    $definition->setPublic(true);
256
                }
257
            }
258
        }
259
    }
260
}
261