Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
check_filesystem
0.00% covered (danger)
0.00%
0 / 93
0.00% covered (danger)
0.00%
0 / 7
1260
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 33
0.00% covered (danger)
0.00%
0 / 1
6
 run
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 set_test_passed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
6
 check_file
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
156
 check_dir
0.00% covered (danger)
0.00%
0 / 28
0.00% covered (danger)
0.00%
0 / 1
210
 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\requirements\task;
15
16/**
17 * Checks filesystem requirements
18 */
19class check_filesystem extends \phpbb\install\task_base
20{
21    /**
22     * @var \phpbb\filesystem\filesystem_interface
23     */
24    protected $filesystem;
25
26    /**
27     * @var array
28     */
29    protected $files_to_check;
30
31    /**
32     * @var bool
33     */
34    protected $tests_passed;
35
36    /**
37     * @var string
38     */
39    protected $phpbb_root_path;
40
41    /**
42     * @var \phpbb\install\helper\iohandler\iohandler_interface
43     */
44    protected $response;
45
46    /**
47     * Constructor
48     *
49     * @param \phpbb\filesystem\filesystem_interface                $filesystem            filesystem handler
50     * @param \phpbb\install\helper\iohandler\iohandler_interface    $response            response helper
51     * @param string                                                $phpbb_root_path    relative path to phpBB's root
52     * @param string                                                $php_ext            extension of php files
53     * @param bool                                                    $check_config_php    Whether or not to check if config.php is writable
54     */
55    public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \phpbb\install\helper\iohandler\iohandler_interface $response, $phpbb_root_path, $php_ext, $check_config_php = true)
56    {
57        parent::__construct(true);
58
59        $this->filesystem        = $filesystem;
60        $this->response            = $response;
61        $this->phpbb_root_path    = $phpbb_root_path;
62
63        $this->tests_passed = false;
64
65        // Files/Directories to check
66        // All file/directory names must be relative to phpBB's root path
67        $this->files_to_check = array(
68            array(
69                'path' => 'cache/',
70                'failable' => false,
71                'is_file' => false,
72            ),
73            array(
74                'path' => 'store/',
75                'failable' => false,
76                'is_file' => false,
77            ),
78            array(
79                'path' => 'files/',
80                'failable' => false,
81                'is_file' => false,
82            ),
83            array(
84                'path' => 'images/avatars/upload/',
85                'failable' => true,
86                'is_file' => false,
87            ),
88        );
89
90        if ($check_config_php)
91        {
92            $this->files_to_check[] = array(
93                'path' => "config.$php_ext",
94                'failable' => false,
95                'is_file' => true,
96            );
97        }
98    }
99
100    /**
101     * {@inheritdoc}
102     */
103    public function run()
104    {
105        $this->tests_passed = true;
106
107        // Check files/directories to be writable
108        foreach ($this->files_to_check as $file)
109        {
110            if ($file['is_file'])
111            {
112                $this->check_file($file['path'], $file['failable']);
113            }
114            else
115            {
116                $this->check_dir($file['path'], $file['failable']);
117            }
118        }
119
120        return $this->tests_passed;
121    }
122
123    /**
124     * Sets $this->tests_passed
125     *
126     * @param    bool    $is_passed
127     */
128    protected function set_test_passed($is_passed)
129    {
130        // If one test failed, tests_passed should be false
131        $this->tests_passed = (!$this->tests_passed) ? false : $is_passed;
132    }
133
134    /**
135     * Check if a file is readable and writable
136     *
137     * @param string    $file        Filename
138     * @param bool        $failable    Whether failing test should interrupt installation process
139     */
140    protected function check_file($file, $failable = false)
141    {
142        $path = $this->phpbb_root_path . $file;
143        $exists = $writable = true;
144
145        // Try to create file if it does not exists
146        if (!file_exists($path))
147        {
148            if (!is_resource($fp = @fopen($path, 'w')))
149            {
150                $exists = $writable = false;
151            }
152            else
153            {
154                @fclose($fp);
155                try
156                {
157                    $this->filesystem->phpbb_chmod($path,
158                        \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE
159                    );
160                    $exists = true;
161                }
162                catch (\phpbb\filesystem\exception\filesystem_exception $e)
163                {
164                    $writable = false;
165                }
166            }
167        }
168        else if (!$this->filesystem->is_writable($path))
169        {
170            $writable = false;
171        }
172
173        $this->set_test_passed(($exists && $writable) || $failable);
174
175        if (!($exists && $writable))
176        {
177            $title = ($exists) ? 'FILE_NOT_WRITABLE' : 'FILE_NOT_EXISTS';
178            $lang_suffix = '_EXPLAIN';
179            $lang_suffix .= ($failable) ? '_OPTIONAL' : '';
180            $description = array($title . $lang_suffix, $file);
181
182            if ($failable)
183            {
184                $this->response->add_warning_message($title, $description);
185            }
186            else
187            {
188                $this->response->add_error_message($title, $description);
189            }
190        }
191    }
192
193    /**
194     * Check if a directory is readable and writable
195     *
196     * @param string    $dir        Filename
197     * @param bool        $failable    Whether failing test should abort the installation process
198     */
199    protected function check_dir($dir, $failable = false)
200    {
201        $path = $this->phpbb_root_path . $dir;
202        $exists = $writable = false;
203
204        // Try to create the directory if it does not exist
205        if (!file_exists($path))
206        {
207            try
208            {
209                $this->filesystem->mkdir($path, 0777);
210                $this->filesystem->phpbb_chmod($path,
211                    \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE
212                );
213                $exists = true;
214            }
215            catch (\phpbb\filesystem\exception\filesystem_exception $e)
216            {
217                // Do nothing
218                $this->response->add_warning_message($e->getMessage(), $e->get_filename());
219            }
220        }
221
222        // Now really check
223        if (file_exists($path) && is_dir($path))
224        {
225            try
226            {
227                $exists = true;
228                $this->filesystem->phpbb_chmod($path,
229                    \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE
230                );
231            }
232            catch (\phpbb\filesystem\exception\filesystem_exception $e)
233            {
234                $this->response->add_warning_message($e->getMessage(), $e->get_filename());
235                // Do nothing
236            }
237        }
238
239        if ($this->filesystem->is_writable($path))
240        {
241            $writable = true;
242        }
243
244        $this->set_test_passed(($exists && $writable) || $failable);
245
246        if (!($exists && $writable))
247        {
248            $title = ($exists) ? 'DIRECTORY_NOT_WRITABLE' : 'DIRECTORY_NOT_EXISTS';
249            $lang_suffix = '_EXPLAIN';
250            $lang_suffix .= ($failable) ? '_OPTIONAL' : '';
251            $description = array($title . $lang_suffix, $dir);
252
253            if ($failable)
254            {
255                $this->response->add_warning_message($title, $description);
256            }
257            else
258            {
259                $this->response->add_error_message($title, $description);
260            }
261        }
262    }
263
264    /**
265     * {@inheritdoc}
266     */
267    public static function get_step_count()
268    {
269        return 0;
270    }
271
272    /**
273     * {@inheritdoc}
274     */
275    public function get_task_lang_name()
276    {
277        return '';
278    }
279}