1<?php
2
3declare(strict_types=1);
4
5namespace PhpMyAdmin\Import;
6
7use PhpMyAdmin\Core;
8use function extension_loaded;
9use function function_exists;
10use function ini_get;
11use function json_encode;
12use function ucwords;
13use function uniqid;
14
15/**
16 * Handles plugins that show the upload progress.
17 */
18final class Ajax
19{
20    /**
21     * Sets up some variables for upload progress
22     */
23    public static function uploadProgressSetup(): array
24    {
25        /**
26         * constant for differentiating array in $_SESSION variable
27         */
28        $SESSION_KEY = '__upload_status';
29
30        /**
31         * sets default plugin for handling the import process
32         */
33        $_SESSION[$SESSION_KEY]['handler'] = '';
34
35        /**
36         * unique ID for each upload
37         */
38        $upload_id = uniqid('');
39
40        /**
41         * list of available plugins
42         */
43        $plugins = [
44            // in PHP 5.4 session-based upload progress was problematic, see closed bug 3964
45            //"session",
46            'progress',
47            'apc',
48            'noplugin',
49        ];
50
51        // select available plugin
52        foreach ($plugins as $plugin) {
53            $check = $plugin . 'Check';
54
55            if (self::$check()) {
56                $upload_class = 'PhpMyAdmin\Plugins\Import\Upload\Upload' . ucwords(
57                    $plugin
58                );
59                $_SESSION[$SESSION_KEY]['handler'] = $upload_class;
60                break;
61            }
62        }
63
64        return [
65            $SESSION_KEY,
66            $upload_id,
67            $plugins,
68        ];
69    }
70
71    /**
72     * Checks if APC bar extension is available and configured correctly.
73     *
74     * @return bool true if APC extension is available and if rfc1867 is enabled,
75     * false if it is not
76     */
77    public static function apcCheck()
78    {
79        if (! extension_loaded('apc')
80            || ! function_exists('apc_fetch')
81            || ! function_exists('getallheaders')
82        ) {
83            return false;
84        }
85
86        return ini_get('apc.enabled') && ini_get('apc.rfc1867');
87    }
88
89    /**
90     * Checks if PhpMyAdmin\Plugins\Import\Upload\UploadProgress bar extension is
91     * available.
92     *
93     * @return bool true if PhpMyAdmin\Plugins\Import\Upload\UploadProgress
94     * extension is available, false if it is not
95     */
96    public static function progressCheck(): bool
97    {
98        return function_exists('uploadprogress_get_info')
99            && function_exists('getallheaders');
100    }
101
102    /**
103     * Checks if PHP 5.4 session upload-progress feature is available.
104     *
105     * @return bool true if PHP 5.4 session upload-progress is available,
106     * false if it is not
107     */
108    public static function sessionCheck(): bool
109    {
110        return ini_get('session.upload_progress.enabled') === '1';
111    }
112
113    /**
114     * Default plugin for handling import.
115     * If no other plugin is available, noplugin is used.
116     *
117     * @return true
118     */
119    public static function nopluginCheck(): bool
120    {
121        return true;
122    }
123
124    /**
125     * The function outputs json encoded status of uploaded.
126     * It uses PMA_getUploadStatus, which is defined in plugin's file.
127     *
128     * @param string $id ID of transfer, usually $upload_id
129     */
130    public static function status($id): void
131    {
132        Core::headerJSON();
133        echo json_encode(
134            $_SESSION[$GLOBALS['SESSION_KEY']]['handler']::getUploadStatus($id)
135        );
136    }
137}
138