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            $fp = @fopen($path, 'w');
149            @fclose($fp);
150            try
151            {
152                $this->filesystem->phpbb_chmod($path,
153                    \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE
154                );
155                $exists = true;
156            }
157            catch (\phpbb\filesystem\exception\filesystem_exception $e)
158            {
159                // Do nothing
160            }
161        }
162
163        if (file_exists($path))
164        {
165            if (!$this->filesystem->is_writable($path))
166            {
167                $writable = false;
168            }
169        }
170        else
171        {
172            $exists = $writable = false;
173        }
174
175        $this->set_test_passed(($exists && $writable) || $failable);
176
177        if (!($exists && $writable))
178        {
179            $title = ($exists) ? 'FILE_NOT_WRITABLE' : 'FILE_NOT_EXISTS';
180            $lang_suffix = '_EXPLAIN';
181            $lang_suffix .= ($failable) ? '_OPTIONAL' : '';
182            $description = array($title . $lang_suffix, $file);
183
184            if ($failable)
185            {
186                $this->response->add_warning_message($title, $description);
187            }
188            else
189            {
190                $this->response->add_error_message($title, $description);
191            }
192        }
193    }
194
195    /**
196     * Check if a directory is readable and writable
197     *
198     * @param string    $dir        Filename
199     * @param bool        $failable    Whether failing test should abort the installation process
200     */
201    protected function check_dir($dir, $failable = false)
202    {
203        $path = $this->phpbb_root_path . $dir;
204        $exists = $writable = false;
205
206        // Try to create the directory if it does not exist
207        if (!file_exists($path))
208        {
209            try
210            {
211                $this->filesystem->mkdir($path, 0777);
212                $this->filesystem->phpbb_chmod($path,
213                    \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE
214                );
215                $exists = true;
216            }
217            catch (\phpbb\filesystem\exception\filesystem_exception $e)
218            {
219                // Do nothing
220                $this->response->add_warning_message($e->getMessage(), $e->get_filename());
221            }
222        }
223
224        // Now really check
225        if (file_exists($path) && is_dir($path))
226        {
227            try
228            {
229                $exists = true;
230                $this->filesystem->phpbb_chmod($path,
231                    \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE
232                );
233            }
234            catch (\phpbb\filesystem\exception\filesystem_exception $e)
235            {
236                $this->response->add_warning_message($e->getMessage(), $e->get_filename());
237                // Do nothing
238            }
239        }
240
241        if ($this->filesystem->is_writable($path))
242        {
243            $writable = true;
244        }
245
246        $this->set_test_passed(($exists && $writable) || $failable);
247
248        if (!($exists && $writable))
249        {
250            $title = ($exists) ? 'DIRECTORY_NOT_WRITABLE' : 'DIRECTORY_NOT_EXISTS';
251            $lang_suffix = '_EXPLAIN';
252            $lang_suffix .= ($failable) ? '_OPTIONAL' : '';
253            $description = array($title . $lang_suffix, $dir);
254
255            if ($failable)
256            {
257                $this->response->add_warning_message($title, $description);
258            }
259            else
260            {
261                $this->response->add_error_message($title, $description);
262            }
263        }
264    }
265
266    /**
267     * {@inheritdoc}
268     */
269    public static function get_step_count()
270    {
271        return 0;
272    }
273
274    /**
275     * {@inheritdoc}
276     */
277    public function get_task_lang_name()
278    {
279        return '';
280    }
281}