Passed
Branch develop (56c45f)
by Jens
02:42
created

CloudControl::calculateRelativePath()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 4
nop 3
dl 0
loc 21
rs 9.0534
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by jensk on 14-8-2017.
4
 */
5
6
namespace CloudControl\Cms;
7
8
use CloudControl\Cms\cc\Application;
9
use CloudControl\Cms\storage\Cache;
10
use CloudControl\Cms\storage\Repository;
11
use Composer\Script\Event;
12
13
class CloudControl
14
{
15
    /**
16
     * @param string $rootDir
17
     * @param string $configPath
18
     */
19
    public static function run($rootDir, $configPath)
20
    {
21
        new Application($rootDir, $configPath);
22
    }
23
24
    public static function postInstall(Event $event)
25
    {
26
        $event->getIO()->write("Post install");
27
        self::checkInstall($event);
28
    }
29
30
    public static function postUpdate(Event $event)
31
    {
32
        $event->getIO()->write("Post update");
33
        self::checkInstall($event);
34
    }
35
36
    /**
37
     * @param Event $event
0 ignored issues
show
Bug introduced by
The type Composer\Script\Event was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
38
     */
39
    private static function checkInstall(Event $event)
40
    {
41
        $event->getIO()->write("");
42
        $event->getIO()->write("********************************************************");
43
        $event->getIO()->write("*** Checking installation of Cloud Control framework ***");
44
        $event->getIO()->write("********************************************************");
45
        $event->getIO()->write("");
46
47
        $vendorDir = $event->getComposer()->getConfig()->get('vendor-dir');
48
        $rootDir = realpath($vendorDir . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR);
49
50
        $baseConfigTargetPath = $rootDir . DIRECTORY_SEPARATOR . 'config.json';
51
        $configObject = self::getConfig($event, $baseConfigTargetPath);
52
53
        $configObject->{'templateDir'} = self::createDir($event, $rootDir, 'templates');
54
        $configObject->{'storageDir'} = self::createDir($event, $rootDir, $configObject->{'storageDir'});
55
        $configObject->{'publicDir'} = self::createDir($event, $rootDir, 'public');
56
        $configObject->{'jsDir'} = self::createDir($event, $rootDir, $configObject->{'publicDir'} . 'js');
57
        $configObject->{'cssDir'} = self::createDir($event, $rootDir, $configObject->{'publicDir'} . 'css');
58
        $configObject->{'imagesDir'} = self::createDir($event, $rootDir, $configObject->{'publicDir'} . 'images');
59
        $configObject->{'filesDir'} = self::createDir($event, $rootDir, $configObject->{'publicDir'} . 'files');
60
        $componentsDir = self::createDir($event, $rootDir, 'components');
61
62
        $baseStorageDefaultPath = __DIR__ . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . '_storage.json';
63
        $baseStorageSqlPath = __DIR__ . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . '_storage.sql';
64
        $baseCacheSqlPath = __DIR__ . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . '_cache.sql';
65
66
        self::createStorage($configObject->{'storageDir'}, $baseStorageDefaultPath, $baseStorageSqlPath);
67
        self::createCacheStorage($rootDir . DIRECTORY_SEPARATOR . $configObject->{'storageDir'}, $baseCacheSqlPath);
68
        self::saveConfig($event, $baseConfigTargetPath, $configObject);
69
        self::copyInstallFile($event, 'public.htaccess', $configObject->{'publicDir'}, '.htaccess');
70
        self::copyInstallFile($event, 'root.htaccess', $rootDir, '.htaccess');
71
        self::copyInstallFile($event, 'base.php', $configObject->{'templateDir'});
72
        self::copyInstallFile($event, 'cms.css', $configObject->{'cssDir'});
73
        self::copyInstallFile($event, 'cms.js', $configObject->{'jsDir'});
74
        self::copyInstallFile($event, 'index.php', $configObject->{'publicDir'});
75
        self::copyInstallFile($event, 'CustomComponent.php', $componentsDir);
76
77
        $event->getIO()->write("");
78
        $event->getIO()->write("[SUCCESS] Installation is complete");
79
        $event->getIO()->write("");
80
    }
81
82
    /**
83
     * @param Event $event
84
     * @param $baseConfigTargetPath
85
     * @param $configObject
86
     */
87
    private static function saveConfig(Event $event, $baseConfigTargetPath, $configObject)
88
    {
89
        file_put_contents($baseConfigTargetPath, json_encode($configObject));
90
        $event->getIO()->write("[INFO] Saved config to: " . $baseConfigTargetPath);
91
    }
92
93
    private static function copyInstallFile(Event $event, $sourceFileName, $destinationPath, $destinationFileName = null)
94
    {
95
        $sourceFilePath = realpath(__DIR__ . DIRECTORY_SEPARATOR . 'install/_' . $sourceFileName);
96
97
98
        if ($destinationFileName === null) {
99
            $destinationFileName = $sourceFileName;
100
        }
101
102
        if (file_exists($sourceFilePath) && realpath($destinationPath) !== false) {
103
            $destinationFullPath = realpath($destinationPath) . DIRECTORY_SEPARATOR . $destinationFileName;
104
            if (file_exists($destinationFullPath)) {
105
                $event->getIO()->write("[INFO] File already exists: " . $destinationFullPath);
106
            } else {
107
                copy($sourceFilePath, $destinationFullPath);
108
                $event->getIO()->write("[INSTALL] Copied file: " . $sourceFileName . ' to ' . $destinationPath);
109
            }
110
        } else {
111
            $event->getIO()->write("[ERROR] Couldnt copy file: " . $sourceFileName . ' to ' . $destinationPath);
112
        }
113
    }
114
115
    /**
116
     * @param $storageDir
117
     * @param $baseStorageDefaultPath
118
     * @param $baseStorageSqlPath
119
     */
120
    private static function createStorage($storageDir, $baseStorageDefaultPath, $baseStorageSqlPath)
121
    {
122
        $repository = new Repository($storageDir);
123
        $repository->init($baseStorageDefaultPath, $baseStorageSqlPath);
124
    }
125
126
    private static function createDir(Event $event, $rootDir, $dirName)
127
    {
128
        $dir = $rootDir . DIRECTORY_SEPARATOR . $dirName . DIRECTORY_SEPARATOR;
129
        if (!is_dir($dir)) {
130
            if (!mkdir($dir) && !is_dir($dir)) {
131
                throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));
132
            }
133
            $event->getIO()->write("[INSTALL] Created dir: " . $dir);
134
        } else {
135
            $event->getIO()->write("[INFO] Dir already exists: " . $dir);
136
        }
137
        return self::getRelativePath($rootDir, $dir);
138
    }
139
140
    /**
141
     * @param $configTargetPath
142
     * @return mixed
143
     */
144
    private static function getConfig(Event $event, $configTargetPath)
145
    {
146
        $baseConfigDefaultPath = realpath(__DIR__ . DIRECTORY_SEPARATOR . 'install' . DIRECTORY_SEPARATOR . '_config.json');
147
148
        if (file_exists($configTargetPath)) {
149
            $config = json_decode(file_get_contents($configTargetPath));
150
            $event->getIO()->write("[INFO] Using existing config");
151
        } else {
152
            $config = json_decode(file_get_contents($baseConfigDefaultPath));
153
            $event->getIO()->write("[INSTALL] Created default config");
154
        }
155
        return $config;
156
    }
157
158
    /**
159
     * Calculate the relative path from $from to $to
160
     * Derived from https://stackoverflow.com/a/2638272/
161
     *
162
     * @param $from
163
     * @param $to
164
     * @return string
165
     */
166
    private static function getRelativePath($from, $to)
167
    {
168
        // some compatibility fixes for Windows paths
169
        $from = is_dir($from) ? rtrim($from, '\/') . DIRECTORY_SEPARATOR : $from;
170
        $to = is_dir($to) ? rtrim($to, '\/') . DIRECTORY_SEPARATOR : $to;
171
        $from = str_replace('\\', DIRECTORY_SEPARATOR, $from);
172
        $to = str_replace('\\', DIRECTORY_SEPARATOR, $to);
173
174
        $from = explode(DIRECTORY_SEPARATOR, $from);
175
        $to = explode(DIRECTORY_SEPARATOR, $to);
176
        $relPath = $to;
177
178
        $relPath = self::calculateRelativePath($from, $to, $relPath);
179
        $relPath = implode(DIRECTORY_SEPARATOR, $relPath);
180
        $relPath = self::removePointerToCurrentDir($relPath);
181
        return $relPath;
182
    }
183
184
    /**
185
     * @param $relPath
186
     * @return mixed
187
     */
188
    private static function removePointerToCurrentDir($relPath)
189
    {
190
        while (strpos($relPath, '.' . DIRECTORY_SEPARATOR . '.' . DIRECTORY_SEPARATOR) !== false) {
191
            $relPath = str_replace('.' . DIRECTORY_SEPARATOR . '.' . DIRECTORY_SEPARATOR, '.' . DIRECTORY_SEPARATOR, $relPath);
192
        }
193
        return $relPath;
194
    }
195
196
    /**
197
     * @param $from
198
     * @param $to
199
     * @param $relPath
200
     * @return array
201
     */
202
    private static function calculateRelativePath($from, $to, $relPath)
203
    {
204
        foreach ($from as $depth => $dir) {
205
            // find first non-matching dir
206
            if ($dir === $to[$depth]) {
207
                // ignore this directory
208
                array_shift($relPath);
209
            } else {
210
                // get number of remaining dirs to $from
211
                $remaining = count($from) - $depth;
212
                if ($remaining > 1) {
213
                    // add traversals up to first matching dir
214
                    $padLength = (count($relPath) + $remaining - 1) * -1;
215
                    $relPath = array_pad($relPath, $padLength, '..');
216
                    break;
217
                } else {
218
                    $relPath[0] = '.' . DIRECTORY_SEPARATOR . $relPath[0];
219
                }
220
            }
221
        }
222
        return $relPath;
223
    }
224
225
    private static function createCacheStorage($storageDir, $baseCacheSqlPath)
226
    {
227
        Cache::getInstance()->setStoragePath($storageDir);
228
        Cache::getInstance()->init($baseCacheSqlPath);
229
    }
230
231
}