1<?php
2
3/**
4 * DokuWiki Plugin upgrade (Admin Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr <andi@splitbrain.org>
8 */
9
10require_once __DIR__ . '/vendor/autoload.php';
11
12class admin_plugin_upgrade extends DokuWiki_Admin_Plugin
13{
14    protected $haderrors = false;
15
16    /** @var helper_plugin_upgrade */
17    protected $helper;
18
19    /**
20     * initialize helper
21     */
22    public function __construct()
23    {
24        $this->helper = plugin_load('helper', 'upgrade');
25        $this->helper->setLogger($this);
26    }
27
28    /** @inheritDoc */
29    public function getMenuSort()
30    {
31        return 555;
32    }
33
34    /** @inheritDoc */
35    public function handle()
36    {
37        if (!empty($_REQUEST['step']) && !checkSecurityToken()) {
38            unset($_REQUEST['step']);
39        }
40    }
41
42    public function html()
43    {
44        $abrt = false;
45        $next = false;
46        $ok = true;
47
48        echo '<h1>' . $this->getLang('menu') . '</h1>';
49
50        echo '<div id="plugin__upgrade">';
51        // enable auto scroll
52        ?>
53        <script type="text/javascript">
54            var plugin_upgrade = window.setInterval(function () {
55                var obj = document.getElementById('plugin__upgrade');
56                if (obj) obj.scrollTop = obj.scrollHeight;
57            }, 25);
58        </script>
59        <?php
60
61        // handle current step
62        $this->nextStep($abrt, $next, $ok);
63
64        // disable auto scroll
65        ?>
66        <script type="text/javascript">
67            window.setTimeout(function () {
68                window.clearInterval(plugin_upgrade);
69            }, 50);
70        </script>
71        <?php
72        echo '</div>';
73
74        $careful = '';
75        if (!$ok) {
76            echo '<div id="plugin__upgrade_careful">' . $this->getLang('careful') . '</div>';
77            $careful = 'careful';
78        }
79
80        $action = script();
81        echo '<form action="' . $action . '" method="post" id="plugin__upgrade_form">';
82        echo '<input type="hidden" name="do" value="admin" />';
83        echo '<input type="hidden" name="page" value="upgrade" />';
84        echo '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />';
85        if ($next) {
86            echo '<button type="submit"
87                          name="step[' . $next . ']"
88                          value="1"
89                          class="button continue ' . $careful . '">' .
90                $this->getLang('btn_continue') .
91                ' ➡</button>';
92        }
93        if ($abrt) {
94            echo '<button type="submit"
95                          name="step[cancel]"
96                          value="1"
97                          class="button abort">✖ ' .
98                $this->getLang('btn_abort') .
99                '</button>';
100        }
101        echo '</form>';
102
103        $this->displayProgressBar($next);
104    }
105
106    /**
107     * Display a progress bar of all steps
108     *
109     * @param string $next the next step
110     */
111    private function displayProgressBar($next)
112    {
113        $steps = ['version', 'download', 'unpack', 'check', 'upgrade'];
114        $active = true;
115        $count = 0;
116
117        echo '<div id="plugin__upgrade_meter"><ol>';
118        foreach ($steps as $step) {
119            $count++;
120            if ($step == $next) $active = false;
121            if ($active) {
122                echo '<li class="active">';
123                echo '<span class="step">✔</span>';
124            } else {
125                echo '<li>';
126                echo '<span class="step">' . $count . '</span>';
127            }
128
129            echo '<span class="stage">' . $this->getLang('step_' . $step) . '</span>';
130            echo '</li>';
131        }
132        echo '</ol></div>';
133    }
134
135    /**
136     * Decides the current step and executes it
137     *
138     * @param bool $abrt
139     * @param bool $next
140     * @param bool $ok
141     */
142    private function nextStep(&$abrt, &$next, &$ok)
143    {
144
145        if (isset($_REQUEST['step']) && is_array($_REQUEST['step'])) {
146            $keys = array_keys($_REQUEST['step']);
147            $step = array_shift($keys);
148        } else {
149            $step = '';
150        }
151
152        if ($step == 'cancel' || $step == 'done') {
153            $ok = $this->helper->cleanup();
154            if ($step == 'cancel') $step = '';
155        }
156
157        if ($step) {
158            $abrt = true;
159            $next = false;
160            if ($step == 'version') {
161                $ok = $this->helper->checkVersions();
162                $next = 'download';
163            } elseif ($step == 'done') {
164                echo $this->locale_xhtml('final');
165                $next = '';
166                $abrt = '';
167            } elseif (!file_exists($this->helper->tgzfile)) {
168                if ($ok = $this->helper->downloadTarball()) $next = 'unpack';
169            } elseif (!is_dir($this->helper->tgzdir)) {
170                if ($ok = $this->helper->extractTarball()) $next = 'check';
171            } elseif ($step != 'upgrade') {
172                if ($ok = $this->helper->checkPermissions()) $next = 'upgrade';
173            } elseif ($step == 'upgrade') {
174                if ($ok = $this->helper->copyFiles()) {
175                    $ok = $this->helper->deleteObsoleteFiles();
176                    $this->helper->cleanup();
177                    $next = 'done';
178                    $abrt = '';
179                }
180            } else {
181                echo 'uhm. what happened? where am I? This should not happen';
182            }
183        } else {
184            # first time run, show intro
185            echo $this->locale_xhtml('step0');
186            $this->helper->cleanup(); // make sure we start clean
187            $abrt = false;
188            $next = 'version';
189        }
190    }
191
192    /**
193     * Print the given message and flush buffers
194     *
195     * @param string $level
196     * @param string $message
197     */
198    public function log($level, $message)
199    {
200        echo '<div class="log-' . $level . '">' . $message . '</div>';
201        flush();
202        ob_flush();
203    }
204}
205