Completed
Push — master ( 90072e...c81959 )
by Daniel
11:23
created

i18nTestManifest::popManifests()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\i18n\Tests;
4
5
use SilverStripe\Control\Director;
6
use SilverStripe\Core\Injector\Injector;
7
use SilverStripe\Core\Manifest\ClassManifest;
8
use SilverStripe\Core\Manifest\ClassLoader;
9
use SilverStripe\i18n\i18n;
10
use SilverStripe\i18n\Messages\MessageProvider;
11
use SilverStripe\i18n\Messages\Symfony\ModuleYamlLoader;
12
use SilverStripe\i18n\Messages\Symfony\SymfonyMessageProvider;
13
use SilverStripe\i18n\Messages\YamlReader;
14
use SilverStripe\i18n\Tests\i18nTest\MyObject;
15
use SilverStripe\i18n\Tests\i18nTest\MySubObject;
16
use SilverStripe\i18n\Tests\i18nTest\TestDataObject;
17
use SilverStripe\View\SSViewer;
18
use SilverStripe\View\SSViewer_DataPresenter;
19
use SilverStripe\View\ThemeResourceLoader;
20
use SilverStripe\View\ThemeManifest;
21
use SilverStripe\View\ViewableData;
22
use Symfony\Component\Translation\Loader\ArrayLoader;
23
use Symfony\Component\Translation\Translator;
24
25
/**
26
 * Helper trait for bootstrapping test manifest for i18n tests
27
 */
28
trait i18nTestManifest
29
{
30
    /**
31
     * Fake webroot with a single module /i18ntestmodule which contains some files with _t() calls.
32
     *
33
     * @var string
34
     */
35
    protected $alternateBasePath;
36
37
    /**
38
     * Number of test manifests
39
     *
40
     * @var int
41
     */
42
    protected $manifests = 0;
43
44
    protected function getExtraDataObjects()
45
    {
46
        return [
47
            TestDataObject::class,
48
            MyObject::class,
49
            MySubObject::class,
50
        ];
51
    }
52
53
    /**
54
     * @var ThemeResourceLoader
55
     */
56
    protected $oldThemeResourceLoader = null;
57
58
    /**
59
     * @var string
60
     */
61
    protected $originalLocale = null;
62
63
    public function setupManifest()
64
    {
65
        // force SSViewer_DataPresenter to cache global template vars before we switch to the
66
        // test-project class manifest (since it will lose visibility of core classes)
67
        $presenter = new SSViewer_DataPresenter(new ViewableData());
68
        unset($presenter);
69
70
        // Switch to test manifest
71
        $s = DIRECTORY_SEPARATOR;
72
        $this->alternateBasePath = __DIR__ . $s . 'i18nTest' . $s . "_fakewebroot";
73
        Director::config()->update('alternate_base_folder', $this->alternateBasePath);
74
75
        // Replace old template loader with new one with alternate base path
76
        $this->oldThemeResourceLoader = ThemeResourceLoader::instance();
77
        ThemeResourceLoader::set_instance($loader = new ThemeResourceLoader($this->alternateBasePath));
78
        $loader->addSet(
79
            '$default',
80
            new ThemeManifest(
81
                $this->alternateBasePath,
82
                project(),
83
                false,
84
                true
85
            )
86
        );
87
88
        SSViewer::set_themes([
89
            'testtheme1',
90
            '$default',
91
        ]);
92
93
        $this->originalLocale = i18n::get_locale();
94
        i18n::set_locale('en_US');
95
96
        // Set new manifest against the root
97
        $classManifest = new ClassManifest($this->alternateBasePath, true, true, false);
98
        $this->pushManifest($classManifest);
99
100
        // Setup uncached translator
101
        // This should pull the module list from the above manifest
102
        $translator = new Translator('en');
103
        $translator->setFallbackLocales(['en']);
104
        $loader = new ModuleYamlLoader();
105
        $loader->setReader(new YamlReader());
106
        $translator->addLoader('ss', $loader); // Standard ss module loader
107
        $translator->addLoader('array', new ArrayLoader()); // Note: array loader isn't added by default
108
        $provider = new SymfonyMessageProvider();
109
        $provider->setTranslator($translator);
110
        Injector::inst()->registerService($provider, MessageProvider::class);
111
    }
112
113
    public function tearDownManifest()
114
    {
115
        ThemeResourceLoader::set_instance($this->oldThemeResourceLoader);
116
        i18n::set_locale($this->originalLocale);
117
118
        // Reset any manifests pushed during this test
119
        $this->popManifests();
120
    }
121
122
    /**
123
     * Safely push a new class manifest.
124
     * These will be cleaned up on tearDown()
125
     *
126
     * @param ClassManifest $manifest
127
     */
128
    protected function pushManifest(ClassManifest $manifest)
129
    {
130
        $this->manifests++;
131
        ClassLoader::instance()->pushManifest($manifest);
132
    }
133
134
    /**
135
     * Pop off all extra manifests
136
     */
137
    protected function popManifests()
138
    {
139
        // Reset any manifests pushed during this test
140
        while ($this->manifests > 0) {
141
            ClassLoader::instance()->popManifest();
142
            $this->manifests--;
143
        }
144
    }
145
}
146