Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 77
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
file_check
0.00% covered (danger)
0.00%
0 / 77
0.00% covered (danger)
0.00%
0 / 5
702
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 6
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
0.00% covered (danger)
0.00%
0 / 68
0.00% covered (danger)
0.00%
0 / 1
506
 get_step_count
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_task_lang_name
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 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\module\update_filesystem\task;
15
16use phpbb\filesystem\filesystem;
17use phpbb\install\exception\resource_limit_reached_exception;
18use phpbb\install\helper\config;
19use phpbb\install\helper\iohandler\iohandler_interface;
20use phpbb\install\helper\update_helper;
21use phpbb\install\task_base;
22
23/**
24 * Updater task performing file checking
25 */
26class file_check extends task_base
27{
28    /**
29     * @var filesystem
30     */
31    protected $filesystem;
32
33    /**
34     * @var config
35     */
36    protected $installer_config;
37
38    /**
39     * @var iohandler_interface
40     */
41    protected $iohandler;
42
43    /**
44     * @var update_helper
45     */
46    protected $update_helper;
47
48    /**
49     * @var string
50     */
51    protected $phpbb_root_path;
52
53    /**
54     * Construct
55     *
56     * @param filesystem            $filesystem
57     * @param config                $config
58     * @param iohandler_interface    $iohandler
59     * @param update_helper            $update_helper
60     * @param string                $phpbb_root_path
61     */
62    public function __construct(filesystem $filesystem, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path)
63    {
64        $this->filesystem        = $filesystem;
65        $this->installer_config    = $config;
66        $this->iohandler        = $iohandler;
67        $this->update_helper    = $update_helper;
68        $this->phpbb_root_path    = $phpbb_root_path;
69
70        parent::__construct(false);
71    }
72
73    /**
74     * {@inheritdoc}
75     */
76    public function check_requirements()
77    {
78        return $this->installer_config->get('do_update_files', false);
79    }
80
81    /**
82     * {@inheritdoc}
83     */
84    public function run()
85    {
86        if (!$this->installer_config->has_restart_point('check_update_files'))
87        {
88            $this->installer_config->create_progress_restart_point('check_update_files');
89        }
90
91        $old_path = $this->update_helper->get_path_to_old_update_files();
92        $new_path = $this->update_helper->get_path_to_new_update_files();
93
94        $update_info = $this->installer_config->get('update_info', array());
95        $file_update_info = $this->installer_config->get('update_files', array());
96
97        if (empty($update_info))
98        {
99            $root_path = $this->phpbb_root_path;
100
101            $update_info = $this->installer_config->get('update_info_unprocessed', array());
102
103            $file_update_info = array();
104            $file_update_info['update_without_diff'] = array_diff($update_info['binary'], $update_info['deleted']);
105
106            foreach ($file_update_info['update_without_diff'] as $key => $binary_file)
107            {
108                $new_file = $new_path . $binary_file;
109                $file = $this->phpbb_root_path . $binary_file;
110
111                if (!$this->filesystem->exists($file))
112                {
113                    continue;
114                }
115
116                if (md5_file($file) === md5_file($new_file))
117                {
118                    // File already up to date
119                    unset($file_update_info['update_without_diff'][$key]);
120                }
121            }
122
123            // Remove update without diff info if empty
124            if (count($file_update_info['update_without_diff']) < 1)
125            {
126                unset($file_update_info['update_without_diff']);
127            }
128
129            // Filter out files that are already deleted
130            $file_update_info['delete'] = array_filter(
131                $update_info['deleted'],
132                function ($filename) use ($root_path)
133                {
134                    return file_exists($root_path . $filename);
135                }
136            );
137
138            // Remove files to delete list if empty
139            if (count($file_update_info['delete']) < 1)
140            {
141                unset($file_update_info['delete']);
142            }
143        }
144
145        $progress_count = $this->installer_config->get('file_check_progress_count', 0);
146        $task_count = count($update_info['files']);
147        $this->iohandler->set_task_count($task_count);
148        $this->iohandler->set_progress('UPDATE_CHECK_FILES', 0);
149
150        // Create list of default extensions that should have been added prior
151        // to this update
152        $default_update_extensions = [];
153        foreach (\phpbb\install\module\update_database\task\update_extensions::$default_extensions_update as $version => $extensions)
154        {
155            if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>='))
156            {
157                $default_update_extensions = array_merge($default_update_extensions, $extensions);
158            }
159        }
160
161        foreach ($update_info['files'] as $key => $filename)
162        {
163            $old_file = $old_path . $filename;
164            $new_file = $new_path . $filename;
165            $file = $this->phpbb_root_path . $filename;
166
167            if ($this->installer_config->get_time_remaining() <= 0 || $this->installer_config->get_memory_remaining() <= 0)
168            {
169                // Save progress
170                $this->installer_config->set('update_info', $update_info);
171                $this->installer_config->set('file_check_progress_count', $progress_count);
172                $this->installer_config->set('update_files', $file_update_info);
173
174                // Request refresh
175                throw new resource_limit_reached_exception();
176            }
177
178            $progress_count++;
179            $this->iohandler->set_progress('UPDATE_CHECK_FILES', $progress_count);
180
181            // Do not copy default extension again if the previous version was
182            // packaged with it but it does not exist (e.g. deleted by admin)
183            if (strpos($file, $this->phpbb_root_path . 'ext/') !== false)
184            {
185                $skip_file = false;
186                foreach ($default_update_extensions as $ext_name)
187                {
188                    if (strpos($file, $this->phpbb_root_path . 'ext/' . $ext_name) !== false &&
189                        !$this->filesystem->exists($this->phpbb_root_path . 'ext/' . $ext_name . '/composer.json'))
190                    {
191                        $skip_file = true;
192                        break;
193                    }
194                }
195
196                if ($skip_file)
197                {
198                    continue;
199                }
200            }
201
202            if (!$this->filesystem->exists($file))
203            {
204                $file_update_info['new'][] = $filename;
205            }
206            else
207            {
208                $file_checksum = md5_file($file);
209
210                if ($file_checksum === md5_file($new_file))
211                {
212                    // File already up to date
213                    continue;
214                }
215                else if ($this->filesystem->exists($old_file) && $file_checksum === md5_file($old_file))
216                {
217                    // No need to diff the file
218                    $file_update_info['update_without_diff'][] = $filename;
219                }
220                else
221                {
222                    $file_update_info['update_with_diff'][] = $filename;
223                }
224            }
225
226            unset($update_info['files'][$key]);
227        }
228
229        $this->installer_config->set('update_files', $file_update_info);
230        $this->installer_config->set('update_info', array());
231    }
232
233    /**
234     * {@inheritdoc}
235     */
236    public static function get_step_count()
237    {
238        return 0;
239    }
240
241    /**
242     * {@inheritdoc}
243     */
244    public function get_task_lang_name()
245    {
246        return '';
247    }
248}