Completed
Push — master ( 48cc3d...5640fa )
by Craig
12:32 queued 05:19
created

BlocksModuleInstaller::isSerialized()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
/*
4
 * This file is part of the Zikula package.
5
 *
6
 * Copyright Zikula Foundation - http://zikula.org/
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zikula\BlocksModule;
13
14
use Zikula\BlocksModule\Entity\BlockEntity;
15
use Zikula\BlocksModule\Entity\BlockPlacementEntity;
16
use Zikula\BlocksModule\Entity\BlockPositionEntity;
17
use Zikula\BlocksModule\Helper\InstallerHelper;
18
use Zikula\Core\AbstractExtensionInstaller;
19
20
/**
21
 * Installation and upgrade routines for the blocks module.
22
 */
23
class BlocksModuleInstaller extends AbstractExtensionInstaller
24
{
25
    /**
26
     * @var array
27
     */
28
    private $entities = [
29
        'Zikula\BlocksModule\Entity\BlockEntity',
30
        'Zikula\BlocksModule\Entity\BlockPositionEntity',
31
        'Zikula\BlocksModule\Entity\BlockPlacementEntity',
32
    ];
33
34
    /**
35
     * initialise the blocks module
36
     *
37
     * @return bool true on success, false otherwise
38
     */
39
    public function install()
40
    {
41
        try {
42
            $this->schemaTool->create($this->entities);
43
        } catch (\Exception $e) {
44
            return false;
45
        }
46
47
        // Set a default value for a module variable
48
        $this->setVar('collapseable', false);
49
50
        $this->hookApi->installSubscriberHooks($this->bundle->getMetaData());
51
52
        // Initialisation successful
53
        return true;
54
    }
55
56
    /**
57
     * upgrade the blocks module
58
     *
59
     * @param string $oldversion version being upgraded
60
     *
61
     * @return bool true if successful, false otherwise
62
     */
63
    public function upgrade($oldversion)
64
    {
65
        // Upgrade dependent on old version number
66
        switch ($oldversion) {
67
            case '3.8.1':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
68
                $this->hookApi->installSubscriberHooks($this->bundle->getMetaData());
69
            case '3.8.2':
70
            case '3.9.0':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
71
                $sql = "SELECT * FROM blocks";
72
                $blocks = $this->entityManager->getConnection()->fetchAll($sql);
73
                foreach ($blocks as $block) {
74
                    $content = $block['content'];
75
                    if ($this->isSerialized($content)) {
76
                        $content = unserialize($content);
77
                        foreach ($content as $k => $item) {
78
                            if (is_string($item)) {
79
                                if (strpos($item, 'blocks_block_extmenu_topnav.tpl') !== false) {
80
                                    $content[$k] = str_replace('blocks_block_extmenu_topnav.tpl', 'Block/Extmenu/topnav.tpl', $item);
81
                                } elseif (strpos($item, 'blocks_block_extmenu.tpl') !== false) {
82
                                    $content[$k] = str_replace('blocks_block_extmenu.tpl', 'Block/Extmenu/extmenu.tpl', $item);
83
                                } elseif (strpos($item, 'menutree/blocks_block_menutree_') !== false) {
84
                                    $content[$k] = str_replace('menutree/blocks_block_menutree_', 'Block/Menutree/', $item);
85
                                }
86
                            }
87
                        }
88
                        $this->entityManager->getConnection()->executeUpdate("UPDATE blocks SET content=? WHERE bid=?", [serialize($content), $block['bid']]);
89
                    }
90
                }
91
92
                // check if request is available (#2073)
93
                $templateWarning = $this->__('Warning: Block template locations modified, you may need to fix your template overrides if you have any.');
94
                if (is_object($this->container->get('request')) && method_exists($this->container->get('request'), 'getSession') && is_object($this->container->get('request')->getSession())) {
95
                    $this->addFlash('warning', $templateWarning);
96
                }
97
            case '3.9.1':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
98
                // make all content fields of blocks serialized.
99
                $sql = "SELECT * FROM blocks";
100
                $blocks = $this->entityManager->getConnection()->fetchAll($sql);
101
                $oldContent = [];
102
                foreach ($blocks as $block) {
103
                    $block['content'] = !empty($block['content']) ? $block['content'] : '';
104
                    $oldContent[$block['bid']] = $this->isSerialized($block['content']) ? unserialize($block['content']) : ['content' => $block['content']];
105
                }
106
                $this->schemaTool->update($this->entities);
107
                $this->entityManager->getConnection()->executeQuery("UPDATE blocks SET properties='a:0:{}'");
108
109
                $blocks = $this->entityManager->getRepository('ZikulaBlocksModule:BlockEntity')->findAll();
110
                $installerHelper = new InstallerHelper();
111
                /** @var \Zikula\BlocksModule\Entity\BlockEntity $block */
112
                foreach ($blocks as $block) {
113
                    $block->setProperties($oldContent[$block->getBid()]);
114
                    $block->setFilters($installerHelper->upgradeFilterArray($block->getFilters()));
115
                    $block->setBlocktype(preg_match('/.*Block$/', $block->getBkey()) ? substr($block->getBkey(), 0, -5) : $block->getBkey());
116
                    $block->setBkey($installerHelper->upgradeBkeyToFqClassname($this->container->get('kernel'), $block));
117
                }
118
                $this->entityManager->flush();
119
120
                $collapseable = $this->getVar('collapseable');
121
                $this->setVar('collapseable', (bool) $collapseable);
122
123
            case '3.9.2':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
124
                // convert Text and Html block types so properties is proper array
125
                $blocks = $this->entityManager->getRepository('ZikulaBlocksModule:BlockEntity')->findBy(['blocktype' => ['Html', 'Text']]);
126
                foreach ($blocks as $block) {
127
                    $properties = $block->getProperties();
128
                    if (!is_array($properties)) {
129
                        $block->setProperties(['content' => $properties]);
130
                    }
131
                }
132
                $this->entityManager->flush();
133
            case '3.9.3':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
134
                $this->schemaTool->drop(['Zikula\BlocksModule\Entity\UserBlockEntity']);
135
            case '3.9.4':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
136
                // convert integer values to boolean for search block settings
137
                $searchBlocks = $this->entityManager->getRepository('ZikulaBlocksModule:BlockEntity')->findBy(['blocktype' => 'Search']);
138
                foreach ($searchBlocks as $searchBlock) {
139
                    $properties = $searchBlock->getProperties();
140
                    $properties['displaySearchBtn'] = (bool) $properties['displaySearchBtn'];
141
                    if (isset($properties['active'])) {
142
                        foreach ($properties['active'] as $module => $active) {
1 ignored issue
show
Bug introduced by
The expression $properties['active'] of type boolean is not traversable.
Loading history...
143
                            $properties['active'][$module] = (bool) $active;
144
                        }
145
                    }
146
                    $searchBlock->setProperties($properties);
147
                }
148
                $this->entityManager->flush();
149
            case '3.9.5':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
150
                $loginBlocks = $this->entityManager->getRepository('ZikulaBlocksModule:BlockEntity')->findBy(['blocktype' => 'Login']);
151
                foreach ($loginBlocks as $loginBlock) {
152
                    $filters = $loginBlock->getFilters();
153
                    $filters[] = [
154
                        'attribute' => '_route',
155
                        'queryParameter' => null,
156
                        'comparator' => '!=',
157
                        'value' => 'zikulausersmodule_access_login'
158
                    ];
159
                    $loginBlock->setFilters($filters);
160
                }
161
                $this->entityManager->flush();
162
            case '3.9.6':
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
163
                $blocks = $this->entityManager->getConnection()->executeQuery("SELECT * FROM blocks WHERE blocktype = 'Lang'");
164
                if (count($blocks) > 0) {
165
                    $this->entityManager->getConnection()->executeQuery("UPDATE blocks set bkey=?, blocktype=?, properties=? WHERE blocktype = 'Lang'", [
166
                        'ZikulaSettingsModule:Zikula\SettingsModule\Block\LocaleBlock',
167
                        'Locale',
168
                        'a:0:{}'
169
                    ]);
170
                    $this->addFlash('success', $this->__('All instances of LangBlock have been converted to LocaleBlock.'));
171
                }
172
                $this->entityManager->getConnection()->executeQuery("UPDATE group_perms SET component = REPLACE(component, 'Languageblock', 'LocaleBlock') WHERE component LIKE 'Languageblock%'");
173
            case '3.9.7':
174
                // future upgrade routines
175
        }
176
177
        // Update successful
178
        return true;
179
    }
180
181
    /**
182
     * delete the blocks module
183
     *
184
     * Since the blocks module should never be deleted we'all always return false here
185
     * @return bool false
186
     */
187
    public function uninstall()
188
    {
189
        // Deletion not allowed
190
        return false;
191
    }
192
193
    /**
194
     * Add default block data for new installs
195
     * This is called after a complete installation since the blocks
196
     * need to be populated with module id's which are only available
197
     * once the install has been completed
198
     */
199
    public function defaultdata()
200
    {
201
        // create the default block positions - left, right and center for the traditional 3 column layout
202
        $positions = [
203
            'left' => $this->__('Left blocks'),
204
            'right' => $this->__('Right blocks'),
205
            'center' => $this->__('Center blocks'),
206
            'search' => $this->__('Search block'),
207
            'header' => $this->__('Header block'),
208
            'footer' => $this->__('Footer block'),
209
            'topnav' => $this->__('Top navigation block'),
210
            'bottomnav' => $this->__('Bottom navigation block'),
211
            ];
212
        foreach ($positions as $name => $description) {
213
            $positions[$name] = new BlockPositionEntity();
214
            $positions[$name]->setName($name);
215
            $positions[$name]->setDescription($description);
0 ignored issues
show
Bug introduced by
It seems like $description defined by $description on line 212 can also be of type object<Zikula\BlocksModu...ty\BlockPositionEntity>; however, Zikula\BlocksModule\Enti...ntity::setDescription() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
216
            $this->entityManager->persist($positions[$name]);
217
        }
218
        $this->entityManager->flush();
219
220
        $hellomessage = $this->__('<p><a href="http://zikula.org/">Zikula</a> is a content management system (CMS) and application framework. It is secure and stable, and is a good choice for sites with a large volume of traffic.</p><p>With Zikula:</p><ul><li>you can customise all aspects of the site\'s appearance through themes, with support for CSS style sheets, JavaScript, Flash and all other modern web development technologies;</li><li>you can mark content as being suitable for either a single language or for all languages, and can control all aspects of localisation and internationalisation of your site;</li><li>you can be sure that your pages will display properly in all browsers, thanks to Zikula\'s full compliance with W3C HTML standards;</li><li>you get a standard application-programming interface (API) that lets you easily augment your site\'s functionality through modules, blocks and other extensions;</li><li>you can get help and support from the Zikula community of webmasters and developers at <a href="http://www.zikula.org">zikula.org</a>.</li></ul><p>Enjoy using Zikula!</p><p><strong>The Zikula team</strong></p><p><em>Note: Zikula is Free Open Source Software (FOSS) licensed under the GNU General Public License.</em></p>');
221
222
        $blocks = [];
223
        $extensionRepo = $this->entityManager->getRepository('\Zikula\ExtensionsModule\Entity\ExtensionEntity');
224
        $blocksModuleEntity = $extensionRepo->findOneBy(['name' => 'ZikulaBlocksModule']);
225
        $searchModuleEntity = $extensionRepo->findOneBy(['name' => 'ZikulaSearchModule']);
226
        $usersModuleEntity = $extensionRepo->findOneBy(['name' => 'ZikulaUsersModule']);
227
        $blocks[] = [
228
            'bkey' => 'ZikulaSearchModule:\Zikula\SearchModule\Block\SearchBlock',
229
            'blocktype' => 'Search',
230
            'language' => '',
231
            'module' => $searchModuleEntity,
232
            'title' => $this->__('Search box'),
233
            'description' => $this->__('Search block'),
234
            'properties' => [
235
                'displaySearchBtn' => true,
236
                'active' => ['ZikulaUsersModule' => 1]
237
            ],
238
            'position' => $positions['left']
239
        ];
240
        $blocks[] = [
241
            'bkey' => 'ZikulaBlocksModule:\Zikula\BlocksModule\Block\HtmlBlock',
242
            'blocktype' => 'Html',
243
            'language' => '',
244
            'module' => $blocksModuleEntity,
245
            'title' => $this->__("This site is powered by Zikula!"),
246
            'description' => $this->__('HTML block'),
247
            'properties' => ['content' => $hellomessage],
248
            'position' => $positions['center']
249
        ];
250
        $blocks[] = [
251
            'bkey' => 'ZikulaUsersModule:\Zikula\UsersModule\Block\LoginBlock',
252
            'blocktype' => 'Login',
253
            'language' => '',
254
            'module' => $usersModuleEntity,
255
            'title' => $this->__('User log-in'),
256
            'description' => $this->__('Login block'),
257
            'position' => $positions['topnav'],
258
            'order' => 1,
259
            'filters' => [[
260
                'attribute' => '_route',
261
                'queryParameter' => null,
262
                'comparator' => '!=',
263
                'value' => 'zikulausersmodule_access_login'
264
            ]]
265
        ];
266
267
        foreach ($blocks as $block) {
268
            $blockEntity = new BlockEntity();
269
            $position = $block['position'];
270
            $sortOrder = !empty($block['order']) ? $block['order'] : 0;
271
            unset($block['position'], $block['order']);
272
            $blockEntity->merge($block);
273
            $this->entityManager->persist($blockEntity);
274
            $placement = new BlockPlacementEntity();
275
            $placement->setBlock($blockEntity);
276
            $placement->setPosition($position);
277
            $placement->setSortorder($sortOrder);
278
            $this->entityManager->persist($placement);
279
        }
280
        $this->entityManager->flush();
281
282
        return;
283
    }
284
285
    private function isSerialized($string)
286
    {
287
        return $string === 'b:0;' || @unserialize($string) !== false;
288
    }
289
}
290