Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
61.54% covered (warning)
61.54%
32 / 52
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
module_base
61.54% covered (warning)
61.54%
32 / 52
57.14% covered (warning)
57.14%
4 / 7
36.43
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setup
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 is_essential
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 check_requirements
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 run
50.00% covered (danger)
50.00%
18 / 36
0.00% covered (danger)
0.00%
0 / 1
26.12
 recover_progress
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 get_step_count
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2/**
3 *
4 * This file is part of the phpBB Forum Software package.
5 *
6 * @copyright (c) phpBB Limited <https://www.phpbb.com>
7 * @license GNU General Public License, version 2 (GPL-2.0)
8 *
9 * For full copyright and license information, please see
10 * the docs/CREDITS.txt file.
11 *
12 */
13
14namespace phpbb\install;
15
16use phpbb\di\ordered_service_collection;
17use phpbb\install\exception\resource_limit_reached_exception;
18use phpbb\install\helper\config;
19use phpbb\install\helper\iohandler\iohandler_interface;
20
21/**
22 * Base class for installer module
23 */
24abstract class module_base implements module_interface
25{
26    /**
27     * @var config
28     */
29    protected $install_config;
30
31    /**
32     * @var iohandler_interface
33     */
34    protected $iohandler;
35
36    /**
37     * @var bool
38     */
39    protected $is_essential;
40
41    /**
42     * Array of tasks for installer module
43     *
44     * @var ordered_service_collection
45     */
46    protected $task_collection;
47
48    /**
49     * @var array
50     */
51    protected $task_step_count;
52
53    /**
54     * @var bool
55     */
56    protected $allow_progress_bar;
57
58    /**
59     * Installer module constructor
60     *
61     * @param ordered_service_collection    $tasks                array of installer tasks for installer module
62     * @param bool                            $essential            flag indicating whether the module is essential or not
63     * @param bool                            $allow_progress_bar    flag indicating whether or not to send progress information from within the module
64     */
65    public function __construct(ordered_service_collection $tasks, $essential = true, $allow_progress_bar = true)
66    {
67        $this->task_collection        = $tasks;
68        $this->is_essential            = $essential;
69        $this->allow_progress_bar    = $allow_progress_bar;
70    }
71
72    /**
73     * Dependency getter
74     *
75     * @param config                $config
76     * @param iohandler_interface    $iohandler
77     */
78    public function setup(config $config, iohandler_interface $iohandler)
79    {
80        $this->install_config    = $config;
81        $this->iohandler        = $iohandler;
82    }
83
84    /**
85     * {@inheritdoc}
86     */
87    public function is_essential()
88    {
89        return $this->is_essential;
90    }
91
92    /**
93     * {@inheritdoc}
94     *
95     * Overwrite this method if your task is non-essential!
96     */
97    public function check_requirements()
98    {
99        return true;
100    }
101
102    /**
103     * {@inheritdoc}
104     */
105    public function run()
106    {
107        // Recover install progress
108        $task_index    = $this->recover_progress();
109        /** @psalm-suppress InvalidTemplateParam */
110        $iterator    = $this->task_collection->getIterator();
111
112        if ($task_index < $iterator->count())
113        {
114            $iterator->seek($task_index);
115        }
116        else
117        {
118            $this->install_config->set_finished_task(0);
119            return;
120        }
121
122        while ($iterator->valid())
123        {
124            $task = $iterator->current();
125            $name = $iterator->key();
126
127            // Check if we can run the task
128            if (!$task->is_essential() && !$task->check_requirements())
129            {
130                $this->iohandler->add_log_message(array(
131                    'SKIP_TASK',
132                    $name,
133                ));
134
135                $this->install_config->increment_current_task_progress($this->task_step_count[$name] ?? false);
136            }
137            else
138            {
139                // Send progress information
140                if ($this->allow_progress_bar)
141                {
142                    $this->iohandler->set_progress(
143                        $task->get_task_lang_name(),
144                        $this->install_config->get_current_task_progress()
145                    );
146
147                    $this->iohandler->send_response();
148                }
149
150                $task->run();
151
152                if ($this->allow_progress_bar)
153                {
154                    // Only increment progress by one, as if a task has more than one steps
155                    // then that should be incremented in the task itself
156                    $this->install_config->increment_current_task_progress();
157                }
158            }
159
160            $task_index++;
161            $this->install_config->set_finished_task($task_index);
162            $iterator->next();
163
164            // Send progress information
165            if ($this->allow_progress_bar)
166            {
167                $this->iohandler->set_progress(
168                    $task->get_task_lang_name(),
169                    $this->install_config->get_current_task_progress()
170                );
171            }
172
173            $this->iohandler->send_response();
174
175            // Stop execution if resource limit is reached
176            if ($iterator->valid() && ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0))
177            {
178                throw new resource_limit_reached_exception();
179            }
180        }
181
182        // Module finished, so clear task progress
183        $this->install_config->set_finished_task(0);
184    }
185
186    /**
187     * Returns the next task's name
188     *
189     * @return int    Index of the array element of the next task
190     */
191    protected function recover_progress(): int
192    {
193        $progress_array = $this->install_config->get_progress_data();
194        return (int) $progress_array['last_task_index'];
195    }
196
197    /**
198     * {@inheritdoc}
199     */
200    public function get_step_count()
201    {
202        $task_step_count = 0;
203        $task_class_names = $this->task_collection->get_service_classes();
204
205        foreach ($task_class_names as $name => $task_class)
206        {
207            $step_count = $task_class::get_step_count();
208            $task_step_count += $step_count;
209            $this->task_step_count[$name] = $step_count;
210        }
211
212        return $task_step_count;
213    }
214}